From 3731cbf1a081281a92aac58c531623a2350fe748 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl?= <61149845+RaphaelSve@users.noreply.github.com> Date: Wed, 1 May 2024 21:18:46 +0200 Subject: [PATCH 001/510] Create README-fr_FR.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Raphaël <61149845+RaphaelSve@users.noreply.github.com> --- README-fr_FR.md | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 README-fr_FR.md diff --git a/README-fr_FR.md b/README-fr_FR.md new file mode 100644 index 0000000000..316344024e --- /dev/null +++ b/README-fr_FR.md @@ -0,0 +1,76 @@ +[![headline](docs/assets/headline.png)](https://backstage.io/) + +# [Backstage](https://backstage.io) + +Français \| English(README.md) \| [한국어](README-ko_kr.md) \| [中文版](README-zh_Hans.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) +[![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) + +## Qu'est-ce que Backstage? + +[Backstage](https://backstage.io/) est un framework open source conçu pour créer des portails à destination des développeur. Avec l'idée de fournir un catalogue d'applications centralisé, Backstage remet de l'ordre dans vos microservices et votre infrastructure, ce qui permet à vos équipes produit de coder rapidement et de manière efficace sans perdre en autonomie. + +Backstage rassemble tous vos outils d'infrastructure, services et documentation pour créer un environnement de développement fluide de bout en bout. + +![software-catalog](docs/assets/header.png) + +Out-of-the-box, Backstage comprend : + +- [Backstage Software Catalog](https://backstage.io/docs/features/software-catalog/) pour gérer tous vos logiciels tels que les microservices, les bibliothèques, les pipelines de données, les sites web et les modèles ML. +- [Backstage Software Templates](https://backstage.io/docs/features/software-templates/) pour créer rapidement de nouveaux projets et uniformiser vos outils selon les meilleures pratiques de votre organisation. +- [Backstage TechDocs](https://backstage.io/docs/features/techdocs/) pour faciliter la création, la maintenance, la recherche et l'utilisation de la documentation technique, en adoptant une approche "docs like code". +- De plus, un écosystème croissant de [plugins open source](https://github.com/backstage/backstage/tree/master/plugins) qui étendent davantage la personnalisation et les fonctionnalités de Backstage. + +Backstage a été initialement développé par Spotify, mais il est désormais hébergé par la [Cloud Native Computing Foundation (CNCF)](https://www.cncf.io) en tant que projet en stade d'incubation. Pour en savoir plus, consultez l'[annonce](https://backstage.io/blog/2022/03/16/backstage-turns-two#out-of-the-sandbox-and-into-incubation). + +## Roadmap du projet + +Pour des informations sur la roadmap détaillée du projet, y compris les jalons atteints, consultez [la Roadmap](https://backstage.io/docs/overview/roadmap). + +## Démarrage + +Pour commencer à utiliser Backstage, consultez [Getting Started documentation](https://backstage.io/docs/getting-started). + +## Documentation + +La documentation de Backstage inclus: + +- [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) + +## Communauté + +Si vous voulez contribuer et vous impliquer dans notre communauté, voici les ressources à votre disposition : + +- [Discord chatroom](https://discord.gg/backstage-687207715902193673) - Pour obtenir de l'aide ou discuter du projet +- [Contributing to Backstage](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md) - Rendez-vous ici si vous souhaitez contribuer +- [RFCs](https://github.com/backstage/backstage/labels/rfc) - Contribuez à définir la direction technique +- [FAQ](https://backstage.io/docs/FAQ) - FAQ +- [Code of Conduct](CODE_OF_CONDUCT.md) - C'est comme ça qu'on fonctionne +- [Adopters](ADOPTERS.md) - Les entreprises utilisent déjà Backstage +- [Blog](https://backstage.io/blog/) - Annonces et mises à jour +- [Newsletter](https://spoti.fi/backstagenewsletter) - Abonnez-vous à notre newsletter par e-mail +- [Backstage Community Sessions](https://github.com/backstage/community) - Participez aux rencontres mensuelles et découvrez la communauté Backstage +- Donnez-nous une étoile ⭐️ - Si vous utilisez Backstage ou si vous trouvez que c'est un projet intéressant, nous apprécierions beaucoup votre soutien. ❤️ + +## Licence + +Copyright 2020-2024 © Les auteurs de Backstage. Tous droits réservés. La Linux Foundation détient des marques déposées et utilise des marques commerciales. Pour une liste des marques de commerce de la Linux Foundation, veuillez consulter notre page d'utilisation des marques : +Sous licence Apache, version 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + +## Sécurité + +Veuillez signaler les problèmes de sécurité sensibles en utilisant le [programme de bug-bounty](https://hackerone.com/spotify) de Spotify plutôt que GitHub. + +Pour plus de détails, consultez notre processus complet de [publication de sécurité](SECURITY.md). From cd3cb0d1d28f2c3bb3a00bd42f271dda88c0ee08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl?= <61149845+RaphaelSve@users.noreply.github.com> Date: Wed, 1 May 2024 21:22:21 +0200 Subject: [PATCH 002/510] Add French to language choices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Raphaël <61149845+RaphaelSve@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6cea4235e0..2c4defc971 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # [Backstage](https://backstage.io) -English \| [한국어](README-ko_kr.md) \| [中文版](README-zh_Hans.md) +English \| [한국어](README-ko_kr.md) \| [中文版](README-zh_Hans.md) \| [Français](README-fr_FR.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 13098239c84286a8b7a1ca917878a9725738820d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl?= <61149845+RaphaelSve@users.noreply.github.com> Date: Wed, 1 May 2024 21:24:24 +0200 Subject: [PATCH 003/510] Update README-fr_FR.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Raphaël <61149845+RaphaelSve@users.noreply.github.com> --- README-fr_FR.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README-fr_FR.md b/README-fr_FR.md index 316344024e..c923b467e9 100644 --- a/README-fr_FR.md +++ b/README-fr_FR.md @@ -56,13 +56,13 @@ Si vous voulez contribuer et vous impliquer dans notre communauté, voici les re - [Discord chatroom](https://discord.gg/backstage-687207715902193673) - Pour obtenir de l'aide ou discuter du projet - [Contributing to Backstage](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md) - Rendez-vous ici si vous souhaitez contribuer - [RFCs](https://github.com/backstage/backstage/labels/rfc) - Contribuez à définir la direction technique -- [FAQ](https://backstage.io/docs/FAQ) - FAQ +- [FAQ](https://backstage.io/docs/FAQ) - [Code of Conduct](CODE_OF_CONDUCT.md) - C'est comme ça qu'on fonctionne - [Adopters](ADOPTERS.md) - Les entreprises utilisent déjà Backstage - [Blog](https://backstage.io/blog/) - Annonces et mises à jour - [Newsletter](https://spoti.fi/backstagenewsletter) - Abonnez-vous à notre newsletter par e-mail - [Backstage Community Sessions](https://github.com/backstage/community) - Participez aux rencontres mensuelles et découvrez la communauté Backstage -- Donnez-nous une étoile ⭐️ - Si vous utilisez Backstage ou si vous trouvez que c'est un projet intéressant, nous apprécierions beaucoup votre soutien. ❤️ +- Donnez-nous une étoile ⭐️ - Si vous utilisez Backstage ou si vous trouvez que c'est un projet intéressant, nous apprécierions beaucoup votre soutien ❤️ ## Licence From d64aa610152bf1563f2f739eb2c569669cf4279b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl?= <61149845+RaphaelSve@users.noreply.github.com> Date: Wed, 1 May 2024 21:24:51 +0200 Subject: [PATCH 004/510] Update README-fr_FR.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Raphaël <61149845+RaphaelSve@users.noreply.github.com> --- README-fr_FR.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README-fr_FR.md b/README-fr_FR.md index c923b467e9..8e756b417c 100644 --- a/README-fr_FR.md +++ b/README-fr_FR.md @@ -2,7 +2,7 @@ # [Backstage](https://backstage.io) -Français \| English(README.md) \| [한국어](README-ko_kr.md) \| [中文版](README-zh_Hans.md) +Français \| [English](README.md) \| [한국어](README-ko_kr.md) \| [中文版](README-zh_Hans.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 9d486f61bd05980f7369206bc6e2d9960b2a500f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl?= <61149845+RaphaelSve@users.noreply.github.com> Date: Wed, 1 May 2024 21:31:32 +0200 Subject: [PATCH 005/510] Update README-fr_FR.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Raphaël <61149845+RaphaelSve@users.noreply.github.com> --- README-fr_FR.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README-fr_FR.md b/README-fr_FR.md index 8e756b417c..2eb06393c6 100644 --- a/README-fr_FR.md +++ b/README-fr_FR.md @@ -60,14 +60,15 @@ Si vous voulez contribuer et vous impliquer dans notre communauté, voici les re - [Code of Conduct](CODE_OF_CONDUCT.md) - C'est comme ça qu'on fonctionne - [Adopters](ADOPTERS.md) - Les entreprises utilisent déjà Backstage - [Blog](https://backstage.io/blog/) - Annonces et mises à jour -- [Newsletter](https://spoti.fi/backstagenewsletter) - Abonnez-vous à notre newsletter par e-mail +- [Newsletter](https://spoti.fi/backstagenewsletter) - Abonnez-vous à notre newsletter par mail - [Backstage Community Sessions](https://github.com/backstage/community) - Participez aux rencontres mensuelles et découvrez la communauté Backstage - Donnez-nous une étoile ⭐️ - Si vous utilisez Backstage ou si vous trouvez que c'est un projet intéressant, nous apprécierions beaucoup votre soutien ❤️ ## Licence -Copyright 2020-2024 © Les auteurs de Backstage. Tous droits réservés. La Linux Foundation détient des marques déposées et utilise des marques commerciales. Pour une liste des marques de commerce de la Linux Foundation, veuillez consulter notre page d'utilisation des marques : -Sous licence Apache, version 2.0 : http://www.apache.org/licenses/LICENSE-2.0 +Copyright 2020-2024 © Les auteurs de Backstage. Tous droits réservés. La Linux Foundation détient des marques déposées et utilise des marques commerciales. Pour une liste des marques de commerce de la Linux Foundation, veuillez consulter notre page d'utilisation des marques: https://www.linuxfoundation.org/trademark-usage + +Sous licence Apache, version 2.0: http://www.apache.org/licenses/LICENSE-2.0 ## Sécurité From 743c07f19c61e36a98ce9713207b8c72439e3582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl?= <61149845+RaphaelSve@users.noreply.github.com> Date: Thu, 9 May 2024 09:40:10 +0200 Subject: [PATCH 006/510] Update README-fr_FR.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Thomas Cardonne Signed-off-by: Raphaël <61149845+RaphaelSve@users.noreply.github.com> --- README-fr_FR.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README-fr_FR.md b/README-fr_FR.md index 2eb06393c6..3363c21ef0 100644 --- a/README-fr_FR.md +++ b/README-fr_FR.md @@ -16,7 +16,7 @@ Français \| [English](README.md) \| [한국어](README-ko_kr.md) \| [中文版] ## Qu'est-ce que Backstage? -[Backstage](https://backstage.io/) est un framework open source conçu pour créer des portails à destination des développeur. Avec l'idée de fournir un catalogue d'applications centralisé, Backstage remet de l'ordre dans vos microservices et votre infrastructure, ce qui permet à vos équipes produit de coder rapidement et de manière efficace sans perdre en autonomie. +[Backstage](https://backstage.io/) est un framework open source conçu pour créer des portails à destination des développeurs. Avec l'idée de fournir un catalogue d'applications centralisé, Backstage remet de l'ordre dans vos microservices et votre infrastructure, ce qui permet à vos équipes produit de coder rapidement et de manière efficace sans perdre en autonomie. Backstage rassemble tous vos outils d'infrastructure, services et documentation pour créer un environnement de développement fluide de bout en bout. From bb96ccf110db93aa4182e85f6db459b5e6a95c6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl?= <61149845+RaphaelSve@users.noreply.github.com> Date: Thu, 9 May 2024 09:40:47 +0200 Subject: [PATCH 007/510] Update README-fr_FR.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Thomas Cardonne Signed-off-by: Raphaël <61149845+RaphaelSve@users.noreply.github.com> --- README-fr_FR.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README-fr_FR.md b/README-fr_FR.md index 3363c21ef0..e91f30d991 100644 --- a/README-fr_FR.md +++ b/README-fr_FR.md @@ -18,7 +18,7 @@ Français \| [English](README.md) \| [한국어](README-ko_kr.md) \| [中文版] [Backstage](https://backstage.io/) est un framework open source conçu pour créer des portails à destination des développeurs. Avec l'idée de fournir un catalogue d'applications centralisé, Backstage remet de l'ordre dans vos microservices et votre infrastructure, ce qui permet à vos équipes produit de coder rapidement et de manière efficace sans perdre en autonomie. -Backstage rassemble tous vos outils d'infrastructure, services et documentation pour créer un environnement de développement fluide de bout en bout. +Backstage rassemble tous vos outils d'infrastructure, services et documentations pour créer un environnement de développement fluide de bout en bout. ![software-catalog](docs/assets/header.png) From 9b4852c27a691967044eb4200fa893fae023143c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl?= <61149845+RaphaelSve@users.noreply.github.com> Date: Thu, 9 May 2024 09:41:10 +0200 Subject: [PATCH 008/510] Update README-fr_FR.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Thomas Cardonne Signed-off-by: Raphaël <61149845+RaphaelSve@users.noreply.github.com> --- README-fr_FR.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README-fr_FR.md b/README-fr_FR.md index e91f30d991..e0cffaa5c5 100644 --- a/README-fr_FR.md +++ b/README-fr_FR.md @@ -58,7 +58,7 @@ Si vous voulez contribuer et vous impliquer dans notre communauté, voici les re - [RFCs](https://github.com/backstage/backstage/labels/rfc) - Contribuez à définir la direction technique - [FAQ](https://backstage.io/docs/FAQ) - [Code of Conduct](CODE_OF_CONDUCT.md) - C'est comme ça qu'on fonctionne -- [Adopters](ADOPTERS.md) - Les entreprises utilisent déjà Backstage +- [Adopters](ADOPTERS.md) - Les entreprises utilisant déjà Backstage - [Blog](https://backstage.io/blog/) - Annonces et mises à jour - [Newsletter](https://spoti.fi/backstagenewsletter) - Abonnez-vous à notre newsletter par mail - [Backstage Community Sessions](https://github.com/backstage/community) - Participez aux rencontres mensuelles et découvrez la communauté Backstage From fe47a3e15ea2af602b8bef6a6f5ba3db43071f74 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 28 May 2024 16:29:51 +0200 Subject: [PATCH 009/510] refactor: rename service config to options Signed-off-by: Camila Belo --- .changeset/tall-walls-learn.md | 9 +++ packages/backend-plugin-api/api-report.md | 47 +++++++++++--- packages/backend-plugin-api/src/deprecated.ts | 52 ++++++++++++++++ packages/backend-plugin-api/src/index.ts | 1 + .../src/services/system/index.ts | 6 +- .../src/services/system/types.ts | 62 ++++++++++--------- 6 files changed, 135 insertions(+), 42 deletions(-) create mode 100644 .changeset/tall-walls-learn.md create mode 100644 packages/backend-plugin-api/src/deprecated.ts diff --git a/.changeset/tall-walls-learn.md b/.changeset/tall-walls-learn.md new file mode 100644 index 0000000000..d79c439221 --- /dev/null +++ b/.changeset/tall-walls-learn.md @@ -0,0 +1,9 @@ +--- +'@backstage/backend-plugin-api': patch +--- + +All service config types were renamed to option types in order to standardize frontend and backend `create*` function signatures: + +- The `ServiceRefConfig` type was renamed to`ServiceRefOptions`; +- The `RootServiceFactoryConfig` type was renamed to `RootServiceFactoryOptions`; +- The `PluginServiceFactoryConfig` type was renamed to `PluginServiceFactoryOptions` diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index 5e59378760..e157187d26 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -256,7 +256,7 @@ export function createServiceFactory< }, TOpts extends object | undefined = undefined, >( - config: RootServiceFactoryConfig, + options: RootServiceFactoryOptions, ): () => ServiceFactory; // @public @@ -268,7 +268,9 @@ export function createServiceFactory< }, TOpts extends object | undefined = undefined, >( - config: (options?: TOpts) => RootServiceFactoryConfig, + options: ( + options?: TOpts, + ) => RootServiceFactoryOptions, ): (options?: TOpts) => ServiceFactory; // @public @@ -281,7 +283,7 @@ export function createServiceFactory< TContext = undefined, TOpts extends object | undefined = undefined, >( - config: PluginServiceFactoryConfig, + options: PluginServiceFactoryOptions, ): () => ServiceFactory; // @public @@ -294,19 +296,19 @@ export function createServiceFactory< TContext = undefined, TOpts extends object | undefined = undefined, >( - config: ( + options: ( options?: TOpts, - ) => PluginServiceFactoryConfig, + ) => PluginServiceFactoryOptions, ): (options?: TOpts) => ServiceFactory; // @public export function createServiceRef( - config: ServiceRefConfig, + options: ServiceRefOptions, ): ServiceRef; // @public export function createServiceRef( - config: ServiceRefConfig, + options: ServiceRefOptions, ): ServiceRef; // @public @@ -450,8 +452,18 @@ export interface PluginMetadataService { getId(): string; } +// @public @deprecated (undocumented) +export type PluginServiceFactoryConfig< + TService, + TContext, + TImpl extends TService, + TDeps extends { + [name in string]: ServiceRef; + }, +> = PluginServiceFactoryOptions; + // @public (undocumented) -export interface PluginServiceFactoryConfig< +export interface PluginServiceFactoryOptions< TService, TContext, TImpl extends TService, @@ -549,8 +561,17 @@ export interface RootLifecycleService extends LifecycleService {} // @public (undocumented) export interface RootLoggerService extends LoggerService {} +// @public @deprecated (undocumented) +export type RootServiceFactoryConfig< + TService, + TImpl extends TService, + TDeps extends { + [name in string]: ServiceRef; + }, +> = RootServiceFactoryOptions; + // @public (undocumented) -export interface RootServiceFactoryConfig< +export interface RootServiceFactoryOptions< TService, TImpl extends TService, TDeps extends { @@ -674,8 +695,14 @@ export type ServiceRef< $$type: '@backstage/ServiceRef'; }; +// @public @deprecated (undocumented) +export type ServiceRefConfig< + TService, + TScope extends 'root' | 'plugin', +> = ServiceRefOptions; + // @public (undocumented) -export interface ServiceRefConfig { +export interface ServiceRefOptions { // (undocumented) defaultFactory?: ( service: ServiceRef, diff --git a/packages/backend-plugin-api/src/deprecated.ts b/packages/backend-plugin-api/src/deprecated.ts new file mode 100644 index 0000000000..17ccccf320 --- /dev/null +++ b/packages/backend-plugin-api/src/deprecated.ts @@ -0,0 +1,52 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + ServiceRef, + ServiceRefOptions, + RootServiceFactoryOptions, + PluginServiceFactoryOptions, +} from './services'; + +/** + * @public + * @deprecated Use {@link ServiceRefOptions} instead + */ +export type ServiceRefConfig< + TService, + TScope extends 'root' | 'plugin', +> = ServiceRefOptions; + +/** + * @public + * @deprecated Use {@link RootServiceFactoryOptions} instead + */ +export type RootServiceFactoryConfig< + TService, + TImpl extends TService, + TDeps extends { [name in string]: ServiceRef }, +> = RootServiceFactoryOptions; + +/** + * @public + * @deprecated Use {@link PluginServiceFactoryOptions} instead + */ +export type PluginServiceFactoryConfig< + TService, + TContext, + TImpl extends TService, + TDeps extends { [name in string]: ServiceRef }, +> = PluginServiceFactoryOptions; diff --git a/packages/backend-plugin-api/src/index.ts b/packages/backend-plugin-api/src/index.ts index c2e2a13a89..342b33dd2e 100644 --- a/packages/backend-plugin-api/src/index.ts +++ b/packages/backend-plugin-api/src/index.ts @@ -24,3 +24,4 @@ export * from './services'; export type { BackendFeature } from './types'; export * from './paths'; export * from './wiring'; +export * from './deprecated'; diff --git a/packages/backend-plugin-api/src/services/system/index.ts b/packages/backend-plugin-api/src/services/system/index.ts index 2b91758cbc..9f62968ecd 100644 --- a/packages/backend-plugin-api/src/services/system/index.ts +++ b/packages/backend-plugin-api/src/services/system/index.ts @@ -16,10 +16,10 @@ export type { ServiceRef, - ServiceRefConfig, + ServiceRefOptions, ServiceFactory, - PluginServiceFactoryConfig, - RootServiceFactoryConfig, + PluginServiceFactoryOptions, + RootServiceFactoryOptions, ServiceFactoryOrFunction, } from './types'; export { createServiceRef, createServiceFactory } from './types'; diff --git a/packages/backend-plugin-api/src/services/system/types.ts b/packages/backend-plugin-api/src/services/system/types.ts index 13252ba6e4..2d6951ffea 100644 --- a/packages/backend-plugin-api/src/services/system/types.ts +++ b/packages/backend-plugin-api/src/services/system/types.ts @@ -78,7 +78,7 @@ export interface InternalServiceFactory< export type ServiceFactoryOrFunction = ServiceFactory | (() => ServiceFactory); /** @public */ -export interface ServiceRefConfig { +export interface ServiceRefOptions { id: string; scope?: TScope; defaultFactory?: ( @@ -92,7 +92,7 @@ export interface ServiceRefConfig { * @public */ export function createServiceRef( - config: ServiceRefConfig, + options: ServiceRefOptions, ): ServiceRef; /** @@ -101,12 +101,13 @@ export function createServiceRef( * @public */ export function createServiceRef( - config: ServiceRefConfig, + options: ServiceRefOptions, ): ServiceRef; + export function createServiceRef( - config: ServiceRefConfig, + options: ServiceRefOptions, ): ServiceRef { - const { id, scope = 'plugin', defaultFactory } = config; + const { id, scope = 'plugin', defaultFactory } = options; return { id, scope, @@ -114,7 +115,7 @@ export function createServiceRef( throw new Error(`tried to read ServiceRef.T of ${this}`); }, toString() { - return `serviceRef{${config.id}}`; + return `serviceRef{${options.id}}`; }, $$type: '@backstage/ServiceRef', __defaultFactory: defaultFactory, @@ -134,7 +135,7 @@ type ServiceRefsToInstances< }; /** @public */ -export interface RootServiceFactoryConfig< +export interface RootServiceFactoryOptions< TService, TImpl extends TService, TDeps extends { [name in string]: ServiceRef }, @@ -156,7 +157,7 @@ export interface RootServiceFactoryConfig< } /** @public */ -export interface PluginServiceFactoryConfig< +export interface PluginServiceFactoryOptions< TService, TContext, TImpl extends TService, @@ -188,7 +189,7 @@ export interface PluginServiceFactoryConfig< * Creates a root scoped service factory without options. * * @public - * @param config - The service factory configuration. + * @param options - The service factory configuration. */ export function createServiceFactory< TService, @@ -196,13 +197,13 @@ export function createServiceFactory< TDeps extends { [name in string]: ServiceRef }, TOpts extends object | undefined = undefined, >( - config: RootServiceFactoryConfig, + options: RootServiceFactoryOptions, ): () => ServiceFactory; /** * Creates a root scoped service factory with optional options. * * @public - * @param config - The service factory configuration. + * @param options - The service factory configuration. */ export function createServiceFactory< TService, @@ -210,13 +211,15 @@ export function createServiceFactory< TDeps extends { [name in string]: ServiceRef }, TOpts extends object | undefined = undefined, >( - config: (options?: TOpts) => RootServiceFactoryConfig, + options: ( + options?: TOpts, + ) => RootServiceFactoryOptions, ): (options?: TOpts) => ServiceFactory; /** * Creates a plugin scoped service factory without options. * * @public - * @param config - The service factory configuration. + * @param options - The service factory configuration. */ export function createServiceFactory< TService, @@ -225,13 +228,13 @@ export function createServiceFactory< TContext = undefined, TOpts extends object | undefined = undefined, >( - config: PluginServiceFactoryConfig, + options: PluginServiceFactoryOptions, ): () => ServiceFactory; /** * Creates a plugin scoped service factory with optional options. * * @public - * @param config - The service factory configuration. + * @param options - The service factory configuration. */ export function createServiceFactory< TService, @@ -240,9 +243,9 @@ export function createServiceFactory< TContext = undefined, TOpts extends object | undefined = undefined, >( - config: ( + options: ( options?: TOpts, - ) => PluginServiceFactoryConfig, + ) => PluginServiceFactoryOptions, ): (options?: TOpts) => ServiceFactory; export function createServiceFactory< TService, @@ -251,23 +254,24 @@ export function createServiceFactory< TContext, TOpts extends object | undefined = undefined, >( - config: - | RootServiceFactoryConfig - | PluginServiceFactoryConfig - | ((options: TOpts) => RootServiceFactoryConfig) + options: + | RootServiceFactoryOptions + | PluginServiceFactoryOptions + | ((options: TOpts) => RootServiceFactoryOptions) | (( options: TOpts, - ) => PluginServiceFactoryConfig) - | (() => RootServiceFactoryConfig) - | (() => PluginServiceFactoryConfig), + ) => PluginServiceFactoryOptions) + | (() => RootServiceFactoryOptions) + | (() => PluginServiceFactoryOptions), ): (options: TOpts) => ServiceFactory { - const configCallback = typeof config === 'function' ? config : () => config; + const configCallback = + typeof options === 'function' ? options : () => options; const factory = ( - options: TOpts, + o: TOpts, ): InternalServiceFactory => { - const anyConf = configCallback(options); + const anyConf = configCallback(o); if (anyConf.service.scope === 'root') { - const c = anyConf as RootServiceFactoryConfig; + const c = anyConf as RootServiceFactoryOptions; return { $$type: '@backstage/BackendFeature', version: 'v1', @@ -277,7 +281,7 @@ export function createServiceFactory< factory: async (deps: TDeps) => c.factory(deps), }; } - const c = anyConf as PluginServiceFactoryConfig< + const c = anyConf as PluginServiceFactoryOptions< TService, TContext, TImpl, From 90a7340efd87f1174018093dc671f07bff02e733 Mon Sep 17 00:00:00 2001 From: Ooi Yee Fei Date: Sat, 1 Jun 2024 15:09:02 +0800 Subject: [PATCH 010/510] fix: Prefer accountId for AwsOrganizationCloudAccountProcessor authentication Signed-off-by: Ooi Yee Fei --- .changeset/swift-kings-sparkle.md | 5 +++ .../catalog-backend-module-aws/config.d.ts | 6 +++ .../src/awsOrganization/config.test.ts | 2 + .../src/awsOrganization/config.ts | 7 +++ .../AwsOrganizationCloudAccountProcessor.ts | 44 ++++++++++++------- 5 files changed, 48 insertions(+), 16 deletions(-) create mode 100644 .changeset/swift-kings-sparkle.md diff --git a/.changeset/swift-kings-sparkle.md b/.changeset/swift-kings-sparkle.md new file mode 100644 index 0000000000..18a37b82f1 --- /dev/null +++ b/.changeset/swift-kings-sparkle.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-aws': patch +--- + +AwsOrganizationCloudAccountProcessor configuration field roleArn is deprecated in favor of new field accountId diff --git a/plugins/catalog-backend-module-aws/config.d.ts b/plugins/catalog-backend-module-aws/config.d.ts index 4c9c98512e..0a9d9c97db 100644 --- a/plugins/catalog-backend-module-aws/config.d.ts +++ b/plugins/catalog-backend-module-aws/config.d.ts @@ -26,8 +26,14 @@ export interface Config { provider: { /** * The role to be assumed by this processor + * @deprecated Use `accountId` instead. */ roleArn?: string; + + /** + * The AWS account ID to query for organizational data + */ + accountId?: string; }; }; }; diff --git a/plugins/catalog-backend-module-aws/src/awsOrganization/config.test.ts b/plugins/catalog-backend-module-aws/src/awsOrganization/config.test.ts index 7e0dc58559..a84c65abda 100644 --- a/plugins/catalog-backend-module-aws/src/awsOrganization/config.test.ts +++ b/plugins/catalog-backend-module-aws/src/awsOrganization/config.test.ts @@ -22,11 +22,13 @@ describe('readAwsOrganizationConfig', () => { const config = { provider: { roleArn: 'aws::arn::foo', + accountId: '111111111111', }, }; const actual = readAwsOrganizationConfig(new ConfigReader(config)); const expected = { roleArn: 'aws::arn::foo', + accountId: '111111111111', }; expect(actual).toEqual(expected); }); diff --git a/plugins/catalog-backend-module-aws/src/awsOrganization/config.ts b/plugins/catalog-backend-module-aws/src/awsOrganization/config.ts index e6096b932b..ff00af48e4 100644 --- a/plugins/catalog-backend-module-aws/src/awsOrganization/config.ts +++ b/plugins/catalog-backend-module-aws/src/awsOrganization/config.ts @@ -24,6 +24,11 @@ export type AwsOrganizationProviderConfig = { * The role to assume for the processor. */ roleArn?: string; + + /** + * The AWS accountId + */ + accountId?: string; }; export function readAwsOrganizationConfig( @@ -32,7 +37,9 @@ export function readAwsOrganizationConfig( const providerConfig = config.getOptionalConfig('provider'); const roleArn = providerConfig?.getOptionalString('roleArn'); + const accountId = providerConfig?.getOptionalString('accountId'); return { roleArn, + accountId, }; } diff --git a/plugins/catalog-backend-module-aws/src/processors/AwsOrganizationCloudAccountProcessor.ts b/plugins/catalog-backend-module-aws/src/processors/AwsOrganizationCloudAccountProcessor.ts index 4a454fce6f..b843503a28 100644 --- a/plugins/catalog-backend-module-aws/src/processors/AwsOrganizationCloudAccountProcessor.ts +++ b/plugins/catalog-backend-module-aws/src/processors/AwsOrganizationCloudAccountProcessor.ts @@ -59,10 +59,18 @@ export class AwsOrganizationCloudAccountProcessor implements CatalogProcessor { static async fromConfig(config: Config, options: { logger: LoggerService }) { const c = config.getOptionalConfig('catalog.processors.awsOrganization'); const orgConfig = c ? readAwsOrganizationConfig(c) : undefined; + + if (orgConfig?.roleArn) { + options.logger.warn( + 'The roleArn configuration for AwsOrganizationCloudAccountProcessor ignores the role name, use accountId configuration instead', + ); + } + const awsCredentialsManager = DefaultAwsCredentialsManager.fromConfig(config); const credProvider = await awsCredentialsManager.getCredentialProvider({ arn: orgConfig?.roleArn, + accountId: orgConfig?.accountId, }); return new AwsOrganizationCloudAccountProcessor( credProvider, @@ -98,23 +106,27 @@ export class AwsOrganizationCloudAccountProcessor implements CatalogProcessor { this.logger?.info('Discovering AWS Organization Account objects'); - (await this.getAwsAccounts()) - .map(account => this.mapAccountToComponent(account)) - .filter(entity => { - if (location.target !== '') { - if (entity.metadata.annotations) { - return ( - entity.metadata.annotations[ORGANIZATION_ANNOTATION] === - location.target - ); + try { + (await this.getAwsAccounts()) + .map(account => this.mapAccountToComponent(account)) + .filter(entity => { + if (location.target !== '') { + if (entity.metadata.annotations) { + return ( + entity.metadata.annotations[ORGANIZATION_ANNOTATION] === + location.target + ); + } + return false; } - return false; - } - return true; - }) - .forEach(entity => { - emit(processingResult.entity(location, entity)); - }); + return true; + }) + .forEach(entity => { + emit(processingResult.entity(location, entity)); + }); + } catch (e) { + this.logger?.error(e); + } return true; } From 3ddd51dc36c3189d8561588613bd176dc3c1f1b6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 15:38:15 +0000 Subject: [PATCH 011/510] fix(deps): update dependency @pmmmwh/react-refresh-webpack-plugin to v0.5.15 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index 72587183c5..3cdf50a03c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13331,15 +13331,15 @@ __metadata: linkType: hard "@pmmmwh/react-refresh-webpack-plugin@npm:^0.5.7": - version: 0.5.13 - resolution: "@pmmmwh/react-refresh-webpack-plugin@npm:0.5.13" + version: 0.5.15 + resolution: "@pmmmwh/react-refresh-webpack-plugin@npm:0.5.15" dependencies: - ansi-html-community: ^0.0.8 + ansi-html: ^0.0.9 core-js-pure: ^3.23.3 error-stack-parser: ^2.0.6 html-entities: ^2.1.0 loader-utils: ^2.0.4 - schema-utils: ^3.0.0 + schema-utils: ^4.2.0 source-map: ^0.7.3 peerDependencies: "@types/webpack": 4.x || 5.x @@ -13363,7 +13363,7 @@ __metadata: optional: true webpack-plugin-serve: optional: true - checksum: 9f931cf79945f58ee31569b83f4b294ae0849ea8232b6c79e690b46a3d7f2b981aa72718a4bd7517ab82657dddfed2a691c9d9e37295a87dfd0b18b2693d4aa6 + checksum: 82df6244146209d63a12f0ca2e70b05274ee058c7e6d6eb4ced1228afde3b039a7f3f3cc0c76f1bb4b28deadbcf08bc2821c814f0bfee06979128578300fff3d languageName: node linkType: hard @@ -19681,6 +19681,15 @@ __metadata: languageName: node linkType: hard +"ansi-html@npm:^0.0.9": + version: 0.0.9 + resolution: "ansi-html@npm:0.0.9" + bin: + ansi-html: bin/ansi-html + checksum: a03754d6f66bae33938ed8bb3dd98174b7f4895ebe45226185036ed4a1388a7aaf2f2b9581608f0626432ba7add92cfc590aa6475a78bbb90d9d1e1d1af8cbe6 + languageName: node + linkType: hard + "ansi-regex@npm:*, ansi-regex@npm:^6.0.1": version: 6.0.1 resolution: "ansi-regex@npm:6.0.1" @@ -39180,7 +39189,7 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^3.0.0, schema-utils@npm:^3.1.1, schema-utils@npm:^3.2.0": +"schema-utils@npm:^3.1.1, schema-utils@npm:^3.2.0": version: 3.3.0 resolution: "schema-utils@npm:3.3.0" dependencies: From f7bdceae07bf08f9ac80e8285063bb10db0e81bd Mon Sep 17 00:00:00 2001 From: Adam Wallis Date: Wed, 29 May 2024 16:59:04 -0400 Subject: [PATCH 012/510] Adds ProviderTransformer to msgraph catalog plugin for dynamic config Signed-off-by: Adam Wallis --- .changeset/clever-geese-jump.md | 5 +++ docs/integrations/azure/org.md | 34 ++++++++++++++++++- .../api-report-alpha.md | 6 ++++ .../api-report.md | 10 ++++++ .../src/microsoftGraph/index.ts | 1 + .../src/microsoftGraph/types.ts | 14 +++++++- ...ogModuleMicrosoftGraphOrgEntityProvider.ts | 24 +++++++++++++ .../MicrosoftGraphOrgEntityProvider.ts | 23 ++++++++++++- 8 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 .changeset/clever-geese-jump.md diff --git a/.changeset/clever-geese-jump.md b/.changeset/clever-geese-jump.md new file mode 100644 index 0000000000..1c4694fa33 --- /dev/null +++ b/.changeset/clever-geese-jump.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-msgraph': patch +--- + +Adds a dynamic provider for the plugin-catalog-backend-module-msgraph. Configuration is now runtime configurable through the ProviderConfigTransformer. diff --git a/docs/integrations/azure/org.md b/docs/integrations/azure/org.md index 89abd4813b..6a72527b94 100644 --- a/docs/integrations/azure/org.md +++ b/docs/integrations/azure/org.md @@ -169,6 +169,23 @@ microsoftGraphOrg: select: ['id', 'displayName', 'description'] ``` +### Using Provider Config Transformer + +Dynamic configuration scaling allows the `msgraph` catalog plugin to adjust its settings at runtime without requiring a redeploy. This feature is useful for scenarios where configuration needs to be updated based on real-time events or changing conditions. For example, you can dynamically adjust synchronization schedules, filters, and search parameters to optimize performance and responsiveness. + +:::note +Adjusting fields that are not used on each scheduled ingestion (e.g., `id`, `schedule`) will have no effect. +::: + +:::warning +Dynamically changing configuration on the fly can introduce unintended consequences, such as system instability and configuration errors. Please review your transformer carefully to ensure that it is working as anticipated! +::: + +#### Example Use Cases: + +- **Filter Scaling**: Adjust filters like `userGroupMember` and `groupFilter` dynamically. +- **Search Parameter Adjustment**: Change search parameters such as `groupSearch` and `userSelect` on-the-fly. + ### Using Custom Transformers Transformers can be configured by extending `microsoftGraphOrgEntityProviderTransformExtensionPoint`. Here is an example: @@ -180,6 +197,7 @@ import { myUserTransformer, myGroupTransformer, myOrganizationTransformer, + myProviderConfigTransformer, } from './transformers'; backend.add( @@ -201,6 +219,9 @@ backend.add( microsoftGraphTransformers.setOrganizationTransformer( myOrganizationTransformer, ); + microsoftGraphTransformers.setProviderConfigTransformer( + myProviderConfigTransformer, + ); /* highlight-add-end */ }, }); @@ -209,7 +230,7 @@ backend.add( ); ``` -The `myUserTransformer`, `myGroupTransformer`, and `myOrganizationTransformer` transformer functions are from the examples in the section below. +The `myUserTransformer`, `myGroupTransformer`, `myOrganizationTransformer`, and `myProviderConfigTransformer` transformer functions are from the examples in the section below. ### Transformer Examples @@ -221,6 +242,7 @@ import { defaultGroupTransformer, defaultUserTransformer, defaultOrganizationTransformer, + MicrosoftGraphProviderConfig, } from '@backstage/plugin-catalog-backend-module-msgraph'; import { GroupEntity, UserEntity } from '@backstage/catalog-model'; @@ -263,6 +285,16 @@ export async function myOrganizationTransformer( ): Promise { return undefined; } + +// Example config transformer that expands the group filter to also include 'azure-group-a' +export async function myProviderConfigTransformer( + provider: MicrosoftGraphProviderConfig, +): Promise { + if (!provider.groupFilter?.includes('azure-group-a')) { + provider.groupFilter = `${provider.groupFilter} or displayName eq 'azure-group-a'`; + } + return provider; +} ``` ## Troubleshooting diff --git a/plugins/catalog-backend-module-msgraph/api-report-alpha.md b/plugins/catalog-backend-module-msgraph/api-report-alpha.md index b9c96e7798..7b0ced8625 100644 --- a/plugins/catalog-backend-module-msgraph/api-report-alpha.md +++ b/plugins/catalog-backend-module-msgraph/api-report-alpha.md @@ -7,6 +7,7 @@ import { BackendFeature } from '@backstage/backend-plugin-api'; import { ExtensionPoint } from '@backstage/backend-plugin-api'; import { GroupTransformer } from '@backstage/plugin-catalog-backend-module-msgraph'; import { OrganizationTransformer } from '@backstage/plugin-catalog-backend-module-msgraph'; +import { ProviderConfigTransformer } from '@backstage/plugin-catalog-backend-module-msgraph'; import { UserTransformer } from '@backstage/plugin-catalog-backend-module-msgraph'; // @alpha @@ -26,6 +27,11 @@ export interface MicrosoftGraphOrgEntityProviderTransformsExtensionPoint { | OrganizationTransformer | Record, ): void; + setProviderConfigTransformer( + transformer: + | ProviderConfigTransformer + | Record, + ): void; setUserTransformer( transformer: UserTransformer | Record, ): void; diff --git a/plugins/catalog-backend-module-msgraph/api-report.md b/plugins/catalog-backend-module-msgraph/api-report.md index 86170e2910..9640f3708b 100644 --- a/plugins/catalog-backend-module-msgraph/api-report.md +++ b/plugins/catalog-backend-module-msgraph/api-report.md @@ -126,6 +126,7 @@ export class MicrosoftGraphOrgEntityProvider implements EntityProvider { userTransformer?: UserTransformer; groupTransformer?: GroupTransformer; organizationTransformer?: OrganizationTransformer; + providerConfigTransformer?: ProviderConfigTransformer; }); // (undocumented) connect(connection: EntityProviderConnection): Promise; @@ -145,6 +146,7 @@ export interface MicrosoftGraphOrgEntityProviderLegacyOptions { id: string; logger: LoggerService; organizationTransformer?: OrganizationTransformer; + providerConfigTransformer?: ProviderConfigTransformer; schedule: 'manual' | TaskRunner; target: string; userTransformer?: UserTransformer; @@ -162,6 +164,9 @@ export type MicrosoftGraphOrgEntityProviderOptions = organizationTransformer?: | OrganizationTransformer | Record; + providerConfigTransformer?: + | ProviderConfigTransformer + | Record; }; // @public @deprecated @@ -233,6 +238,11 @@ export type OrganizationTransformer = ( organization: MicrosoftGraph.Organization, ) => Promise; +// @public +export type ProviderConfigTransformer = ( + provider: MicrosoftGraphProviderConfig, +) => Promise; + // @public @deprecated export function readMicrosoftGraphConfig( config: Config, diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/index.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/index.ts index 4db3fb69c6..81f6f21ce2 100644 --- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/index.ts +++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/index.ts @@ -39,4 +39,5 @@ export type { GroupTransformer, OrganizationTransformer, UserTransformer, + ProviderConfigTransformer, } from './types'; diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/types.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/types.ts index ef60d7b018..bc9270238b 100644 --- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/types.ts +++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/types.ts @@ -16,7 +16,7 @@ import { GroupEntity, UserEntity } from '@backstage/catalog-model'; import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; - +import { MicrosoftGraphProviderConfig } from './config'; /** * Customize the ingested User entity * @@ -45,3 +45,15 @@ export type GroupTransformer = ( group: MicrosoftGraph.Group, groupPhoto?: string, ) => Promise; + +/** + * Customize the MSGraph Provider Config Dynamically + * + * Transforming fields that are not used for each scheduled ingestion (e.g., id, schedule) + * will have no effect. + * + * @public + */ +export type ProviderConfigTransformer = ( + provider: MicrosoftGraphProviderConfig, +) => Promise; diff --git a/plugins/catalog-backend-module-msgraph/src/module/catalogModuleMicrosoftGraphOrgEntityProvider.ts b/plugins/catalog-backend-module-msgraph/src/module/catalogModuleMicrosoftGraphOrgEntityProvider.ts index 193f07889f..e1a15a3468 100644 --- a/plugins/catalog-backend-module-msgraph/src/module/catalogModuleMicrosoftGraphOrgEntityProvider.ts +++ b/plugins/catalog-backend-module-msgraph/src/module/catalogModuleMicrosoftGraphOrgEntityProvider.ts @@ -23,6 +23,7 @@ import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/ import { GroupTransformer, OrganizationTransformer, + ProviderConfigTransformer, UserTransformer, } from '@backstage/plugin-catalog-backend-module-msgraph'; import { MicrosoftGraphOrgEntityProvider } from '../processors'; @@ -58,6 +59,18 @@ export interface MicrosoftGraphOrgEntityProviderTransformsExtensionPoint { | OrganizationTransformer | Record, ): void; + + /** + * Set the function that transforms provider config dynamically. + * Optionally, you can pass separate transformers per provider ID. + * Note: adjusting fields that are not used on each scheduled ingestion + * (e.g., id, schedule) will have no effect. + */ + setProviderConfigTransformer( + transformer: + | ProviderConfigTransformer + | Record, + ): void; } /** @@ -94,6 +107,10 @@ export const catalogModuleMicrosoftGraphOrgEntityProvider = createBackendModule( | OrganizationTransformer | Record | undefined; + let providerConfigTransformer: + | ProviderConfigTransformer + | Record + | undefined; env.registerExtensionPoint( microsoftGraphOrgEntityProviderTransformExtensionPoint, @@ -116,6 +133,12 @@ export const catalogModuleMicrosoftGraphOrgEntityProvider = createBackendModule( } organizationTransformer = transformer; }, + setProviderConfigTransformer(transformer) { + if (providerConfigTransformer) { + throw new Error('Provider transformer may only be set once'); + } + providerConfigTransformer = transformer; + }, }, ); @@ -134,6 +157,7 @@ export const catalogModuleMicrosoftGraphOrgEntityProvider = createBackendModule( userTransformer: userTransformer, groupTransformer: groupTransformer, organizationTransformer: organizationTransformer, + providerConfigTransformer: providerConfigTransformer, }), ); }, diff --git a/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgEntityProvider.ts b/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgEntityProvider.ts index 3c8b903e69..21995d2b8d 100644 --- a/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgEntityProvider.ts +++ b/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgEntityProvider.ts @@ -34,6 +34,7 @@ import { MICROSOFT_GRAPH_USER_ID_ANNOTATION, MicrosoftGraphClient, MicrosoftGraphProviderConfig, + ProviderConfigTransformer, OrganizationTransformer, readMicrosoftGraphConfig, readMicrosoftGraphOrg, @@ -94,6 +95,13 @@ export type MicrosoftGraphOrgEntityProviderOptions = organizationTransformer?: | OrganizationTransformer | Record; + + /** + * The function that transforms provider config dynamically. + */ + providerConfigTransformer?: + | ProviderConfigTransformer + | Record; }; /** @@ -152,6 +160,11 @@ export interface MicrosoftGraphOrgEntityProviderLegacyOptions { * The function that transforms an organization entry in msgraph to an entity. */ organizationTransformer?: OrganizationTransformer; + + /** + * The function that transforms provider config dynamically. + */ + providerConfigTransformer?: ProviderConfigTransformer; } /** @@ -216,6 +229,10 @@ export class MicrosoftGraphOrgEntityProvider implements EntityProvider { providerConfig.id, options.organizationTransformer, ), + providerConfigTransformer: getTransformer( + providerConfig.id, + options.providerConfigTransformer, + ), }); if (taskRunner !== 'manual') { @@ -257,6 +274,7 @@ export class MicrosoftGraphOrgEntityProvider implements EntityProvider { userTransformer: options.userTransformer, groupTransformer: options.groupTransformer, organizationTransformer: options.organizationTransformer, + providerConfigTransformer: options.providerConfigTransformer, logger, provider, }); @@ -276,6 +294,7 @@ export class MicrosoftGraphOrgEntityProvider implements EntityProvider { userTransformer?: UserTransformer; groupTransformer?: GroupTransformer; organizationTransformer?: OrganizationTransformer; + providerConfigTransformer?: ProviderConfigTransformer; }, ) {} @@ -300,7 +319,9 @@ export class MicrosoftGraphOrgEntityProvider implements EntityProvider { } const logger = options?.logger ?? this.options.logger; - const provider = this.options.provider; + const provider = this.options.providerConfigTransformer + ? await this.options.providerConfigTransformer(this.options.provider) + : this.options.provider; const { markReadComplete } = trackProgress(logger); const client = MicrosoftGraphClient.create(this.options.provider); const { users, groups } = await readMicrosoftGraphOrg( From 771a4c2cf4f77e5f63f8cf82177e35c4b8062c36 Mon Sep 17 00:00:00 2001 From: Martin Marosi Date: Mon, 27 May 2024 13:50:45 +0200 Subject: [PATCH 013/510] beps/0002: add dynamic FE plugins cli,backend,loading proposals Signed-off-by: Martin Marosi --- beps/0002-dynamic-frontend-plugins/README.md | 754 +++++++++++++----- .../dependency-sharing-schema.json | 43 + .../share-config-sample.json | 17 + 3 files changed, 633 insertions(+), 181 deletions(-) create mode 100644 beps/0002-dynamic-frontend-plugins/dependency-sharing-schema.json create mode 100644 beps/0002-dynamic-frontend-plugins/share-config-sample.json diff --git a/beps/0002-dynamic-frontend-plugins/README.md b/beps/0002-dynamic-frontend-plugins/README.md index f26a3b488d..34c6e2d435 100644 --- a/beps/0002-dynamic-frontend-plugins/README.md +++ b/beps/0002-dynamic-frontend-plugins/README.md @@ -156,12 +156,247 @@ Each plugin is required to provide manifest file (metadata) in predefined format Plugin discovery is a pre-requisite for Plugin registry. This should be responsible for scanning for available plugins and generating/modifying the plugin registry to always keep it up to date. +### CLI + +The following sections contains proposal of new CLI scripts to support the dynamic frontend plugins. + +#### Static and Dynamic Plugin Build Differences + +The major difference between static and dynamic plugins lies in their dependencies and how they are "installed" into a Backstage instance and whether they are bundled into final JS output during the build. + +While static plugins can define their dependencies using the dependencies field inside `package.json`, dynamic (module federation-based) plugins can't. + +A dynamic plugin requires all dependencies to be present in the build output. Module sharing is then used to optimize the "output size" at runtime. If a shared package is not found in the browser scope, or if the version range does not match the requirement, it falls back and loads additional JS assets from the "private" build and adds them to the scope. + +Webpack is also not the best tool for building traditional NPM packages. Dependencies can be externalized, but Webpack brings additional code into the bundles. Using Webpack external dependencies also conflicts with module federation shared modules. Externals will not be included even as a shared module fallback. As a result, such shared module can't be used because the dependency will not be defined in the init container. + +If the vision is to still support "static" plugins installed via NPM, it makes sense to keep the static and dynamic plugin builds separate and build two different bundles. Both can still be published as a single NPM package (not recommended), but to achieve optimal performance for both, there cannot be a shared output. + +#### Dynamic export CLI + +```sh +backstage-cli plugin export-dynamic +``` + +Similar to the current build command, instead of producing static plugin output, it builds a dynamic plugin using Webpack and module federation plugins. + +**Internal arguments** + +Some configuration is required, but they can be internal using the script `cwd`. + +- _path_ + - path to the plugin `package.json` +- _export-name_ + - Export name from where the plugin root is accessible + - defaults to `pluginEntry` + +**Shared modules** + +> NOTE: Details of module sharing are described in the [Module sharing](#module-sharing) section. + +Short summary of dependency sharing: + +- Predefined set of singleton packages +- Generated granular config of modules for MUI dependencies +- Share all other dependencies listed in package.json + +To allow additional customization of module sharing, extra configuration will be required. The extra module haring configuration can be embedded inside `package.json`. + +- [Schema proposal draft](./dependency-sharing-schema.json) +- [Config draft](./share-config-sample.json) + +#### Generate module sharing map + +> NOTE: RedHat has similar internal generators that are used in combination with Scalprum. These can be built upon, moved to Scalprum, and exposed. If there is interest, the Backstage maintainers do not have to be responsible for maintaining the source code. + +A simple program to traverse the AST and find exports from the `main` or `module` script of a dependency. Any exposed modules from the dependency entry will be traced to their source files, and a module map can be generated. + +> NOTE: It is important that import paths in source code are also directly targeting the "traced" modules or are transformed at build time. + +**The script should be triggered by the plugin build cli** + +Generates a module map (exported module source file location) for module sharing. + +**Arguments** + +- _path_ + - path to the module root (directory with package.json) + +[module map generator using TS example](#simplistic-minimal-example-of-module-map-generator) + +### Dynamic assets server + +A simple static asset server is sufficient to serve the dynamic assets. The asset server can collect the necessary metadata at boot or runtime. The asset server can be added to the `app-backend` + +It's important to consider old deployments as part of this storage, to make sure that dynamic chunks are still available to users who have not yet refreshed the page to load the latest version of the app. + +#### Plugin separation + +- Each plugin should be separated into a directory. +- Each plugin can be viewed as a `private` workspace package in a npm workspaces environment. + +```sh +path/to/assets/plugin/dynamic-plugins/ +└── dynamic-backstage.plugin-user-settings + ├── dist + ├── package.json + └── plugin-manifest.json +``` + +#### Boot time initialization + +**Dynamically build plugins** + +Only dynamic plugins can be hosted in the backend. The plugins has to provide the [manifest](#plugin-manifest). It the manifest is not found, plugin will not be considered dynamic and will be enabled for loading. + +**File system assets management** + +Once plugins are installed and fully dynamic, the asset server has to "discover" what plugins are loadable. + +This can be done by scanning the "assets" (dynamic-plugins in the dir example) for individual plugin manifests. Simple `glob` lookup for `path/dynamic-plugins/**/plugins-manifest.json` pattern should give required results. + +With this data the assets server should be able to generate a "plugin registry" with necessary metadata for the frontend. See the [Plugin Registry](#plugin-registry-1) for format details. + +The during the collection, the program can also add the `assetHost` prefix to the manifest location attribute described in the [webpack configuration](#sample-webpack-configuration) section. + +**Alternative means of assets management** + +To manage the assets by other means than just using filesystem, the file system should be treated only as an entry point for the plugins. Leveraging other means such as DB/cache/object storage should be also an option. The storage method should be mandated as long as a plugin registry and assets are available. + +**Singleton dependencies verification (optional)** + +With [module sharing](#module-sharing) and its singleton option, it is critical that the singleton dependencies versions are matching. + +The singleton configuration from the shell application can be extracted as well as from all dynamic plugins (included in the generated [manifest](#plugin-manifest)). A semver check can be used to prevent a plugin from initializing if a version mismatch is found. A version check also has to be made between plugins. New plugin singleton dependencies must match both the shell and all previously loaded plugins. + +#### Runtime updates + +It is fully expected that plugins can be added or removed at the asset server runtime. The same tasks can be performed as during boot time initialization. It is critical that the plugin registry is not cached and updated immediately if assets change. + +The server **should not remove older JS/CSS assets** immediately after updates. It is highly likely user can have older version still loaded in their browsers. A retention period is required for the assets. Using proper content hashes for builds will help with keep the duplicate assets to a minimum. + +#### Asset server API + +> NOTE Routes names are purely arbitrary at this point. + +The API can be very simplistic + +_GET /dynamic-plugins/plugin-registry_ + +Returns generated [Plugin Registry](#plugin-registry-1). + +\*GET /dynamic-plugins/assets/\*\* + +Static assets endpoint. Can be handled via the `express.static` middleware. + +### Plugin loading + +> NOTE: Only viable for the new frontend plugin system. + +The feature loader is a perfect place to initialize a new dynamic plugin as it already accepts async loaders. + +An example of [integration with scalprum](https://github.com/backstage/backstage/commit/23085aa8dfbc73d4648c100cf06b6b67e8e31764). + +#### Integration to core + +**Dynamic Feature configuration** + +The dynamic remote loading can be added directly into the [`createApp`](https://github.com/backstage/backstage/blob/master/packages/frontend-app-api/src/wiring/createApp.tsx#L234) function. + +The current `feature` type can be expanded with a `DynamicFrontendFeature` type: + +```ts +// current +type Features: (FrontendFeature | CreateAppFeatureLoader)[]; + +// with dynamic plugins +type DynamicFrontendFeature = { + name: string; + manifestLocation: string // URI with host enhanced with the "DEFAULT_API_PATH" or "assetHost" prefix +} + +type Features: (FrontendFeature | CreateAppFeatureLoader | DynamicFrontendFeature)[]; +``` + +**Dynamic Feature boot loading** + +Scalprum can be initialized with the metadata originating from the dynamic backend plugin. In order to properly load a plugin with `publicPath` set to `auto`, a small transformation of the manifest has to happen before it is loaded. A sample Scalprum config with such transformation: + +```TS +import { initialize } from '@scalprum/core'; +import { ScalprumProviderProps } from '@scalprum/react-core'; + +// get the pluginRegistry from the backend plugin +const pluginRegistry = await loadRemoteConfig() + +const pluginSDKOptions: ScalprumProviderProps['pluginSDKOptions'] = { + pluginLoaderOptions: { + transformPluginManifest: manifest => { + return { + ...manifest, + loadScripts: manifest.loadScripts.map(script => { + // Any additional transformations can happen here in case the manifest format needs to be adjusted further. + // the init scripts URL is enhanced with the asset location to add the host: + return `${manifest.customProperties.assetHost ?? DEFAULT_API_PATH}${script}`; + }), + }; + }, + }, +}; + +// Initialize Scalprum instance +const scalprum = initialize({ + appsConfig: pluginRegistry, + pluginLoaderOptions: pluginSDKOptions.pluginLoaderOptions, +}); +``` + +Because the [`appLoader`](https://github.com/backstage/backstage/blob/master/packages/frontend-app-api/src/wiring/createApp.tsx#L193) is already async, it is a perfect place to load the plugin registry and init the dynamic plugins. + +Initializing the dynamic feature is just a case of mapping the `DynamicFrontendFeature` to `FrontendFeature` via Scalprum: + +```ts +import { processManifest, getModule } from '@scalprum/core'; +// a ID of the module withing module federation container, can be customized, depends on the build +const DEFAULT_MODULE_NAME = 'pluginEntry'; + +async function loadScalprumFeature({ manifestLocation, name }) { + // initialize dynamic remote within scalprum cache + await processManifest(manifestLocation, name, DEFAULT_MODULE_NAME); + // gets the actual JS module from scalprum + const feature = await getModule(name, DEFAULT_MODULE_NAME); + + return feature; +} +const providedFeatures: FrontendFeature[] = []; +for (const entry of options?.features ?? []) { + if ('manifestLocation' in entry && 'name' in entry) { + // some error handling required + const dynamicFeature = loadScalprumFeature(entry); + providedFeatures.push(dynamicFeature); + } else if ('load' in entry) { + // plugin with load function + } else { + // #static plugin + } +} + +const app = createSpecializedApp({ + icons: options?.icons, + config, + features: [...discoveredFeatures, ...providedFeatures], + bindRoutes: options?.bindRoutes, +}).createRoot(); +``` + +The federated modules are now available as if they were static plugins. + ## Design Details -> NOTE The details are based on the Janus implementation of dynamic frontend plugins. The implementation leverages [Scalprum](https://github.com/scalprum/scaffolding) which is a Webpack based dynamic plugin manager for React applications. - ### Module federation implementation experiments +> NOTE Experiments were tested and documented. Decision was mated to leverage [Scalprum](https://github.com/scalprum/scaffolding) and [dynamic-plugins-sdk](https://github.com/openshift/dynamic-plugin-sdk). Instead of native webpack module federation the [@module-federation/enhanced](https://www.npmjs.com/package/@module-federation/enhanced) plugin will be used to ensure future compatibility with other bundlers. + Test should consist of trying to run permutations of webpack/Rspack/vite based shell apps/plugins and discover if we can freely choose any tool, or if we should restrict the tooling to just a subset of the available options. The outcome of initial testing is positive and it is possible to mix and match different build tools and consume different remote modules in a single shell application. @@ -217,70 +452,7 @@ This config ensures that only those modules (from @mui/material) that are used i This can be checked by debugging network traffic and shared scopes: -![notifications system architecture diagram](./scope-sharing.png) - -#### Limitations - -A limitation of module sharing is that each module name can only appear once in each context. This means that if you're trying to build a bundle of shared modules with a deeper dependency tree, you may end up needing to resolve conflicts by renaming some modules that appear multiple times with different versions. This will in turn limit sharing of those modules with other bundles. - -There is also a conflict with the chunk splitting currently used in the Backstage CLI that means that some singleton modules need to be configured to be eagerly loaded. More broadly we may also want to re-evaluate the chunk splitting strategy in the Backstage CLI when adding support for module federation. - -### Plugin manifest - -Each plugin should have a manifest file with important metadata. This metadata is used to load the remote assets to browser. The plugin manifest should be part of a build output. - -A manifest should have: - -- name of plugin -- how can be the init container accessed -- what is the base URL (assets pathname) -- name of the entry script(s) - -#### Scalprum compatible manifest - -```TS -type PluginManifest = { - name: string; - version: string; - dependencies?: Record; - customProperties?: AnyObject; - baseURL: string; - extensions: Extension[]; - loadScripts: string[]; - registrationMethod: 'callback' | 'custom'; - buildHash?: string; -} -``` - -```js -{ - "name": "backstage.plugin-github-actions", - "version": "0.6.6", - "extensions": [], - "registrationMethod": "callback", // where container init is available in browser - "baseURL": "auto", - "loadScripts": [ - "backstage.plugin-github-actions.804b91040fcbca6585ce.js" - ], - "buildHash": "804b91040fcbca6585ce1bcd4b1f8aa2" -} -``` - -##### `registrationMethod` - -Refers to [webpack output.libraryTarget](https://webpack.js.org/configuration/output/#outputlibrarytarget). - -Callback refers to `jsonp` and a the `custom` is used if other available target configuration has been picked. - -It is recommended to use either `global` or `jsonp` as these are environment agnostic (browser VS node). `jsonp` requires additional configurations. The `global` is preferable due to its simplicity. - -##### `baseURL` - -The `baseURL` is derived from [webpack public path](https://webpack.js.org/configuration/output/#outputpublicpath) - -The public path can also be set to `auto` to remove the need to specify origin or pathname and resolve the pathname at runtime. - -In Scalprum, some manifest [post processing](https://github.com/janus-idp/backstage-showcase/blob/main/packages/app/src/components/DynamicRoot/DynamicRoot.tsx#L323) is required to load the initial scripts if the `auto` baseURL is chosen. +![scope sharing sample](./scope-sharing.png) ### Plugin registry @@ -290,6 +462,7 @@ Plugin registry can be fairly simplistic. It can be as simple as JSON file conta type RegistryEntry = { name: string // plugin name manifestLocation: string // path to the manifest resource + assetHost: string // host part of URL to deal with the `auto` publicPath } // object for easy access @@ -308,7 +481,8 @@ Example of such registry { "backstage.plugin-github-actions": { "name": "backstage.plugin-github-actions", - "manifestLocation": "https://foo-bar.com/api/plugin-storage/plugin-manifest.json" + "manifestLocation": "/api/plugin-storage/plugin-manifest.json", + "assetHost": "https://foo-bar.com" }, // ..rest of plugins } @@ -318,6 +492,7 @@ Example of such registry { "name": "backstage.plugin-github-actions", "manifestLocation": "https://foo-bar.com/api/plugin-storage/plugin-manifest.json" + "assetHost": "https://foo-bar.com" }, // ...rest of plugins ] @@ -353,7 +528,6 @@ Example of registry with embedded manifests "pluginManifest": { "name": "backstage.plugin-github-actions", "version": "0.6.6", - "extensions": [], "registrationMethod": "callback", "baseURL": "auto", "loadScripts": [ @@ -372,7 +546,6 @@ Example of registry with embedded manifests "pluginManifest": { "name": "backstage.plugin-github-actions", "version": "0.6.6", - "extensions": [], "registrationMethod": "callback", "baseURL": "auto", "loadScripts": [ @@ -386,155 +559,374 @@ Example of registry with embedded manifests ``` -### Webpack build configuration +### Frontend plugin build configuration -> NOTE This is a sample current configuration in the Janus project. It uses Scalprum webpack based build plugin to generate the output. It does not take the [all options](#Module-federation-implementation-experiments) in consideration. This section will likely change considerably. +#### Build tooling -Part of a Scalprum tooling is also [dynamic-plugins-sdk](https://github.com/openshift/dynamic-plugin-sdk). Right now the package is a part of a different project, but that is about to change. More details in the [Scalprum roadmap](https://github.com/scalprum/scaffolding/blob/main/ROADMAP.md). +- webpack module bundler as a base +- use `@openshift/dynamic-plugin-sdk-webpack` to build dynamic frontend output + - with `@module-federation/enhanced` plugins instead of native webpack -#### Sample plugin configuration using Scalprum SDK +#### Module sharing + +Webpack allows for dependency/module sharing across different remote modules. For performance's sake, all dependencies should be shared. The sharing is version-restricted, and there can be multiple versions of the same package at the same time. This ensures that remote modules will have the necessary dependency version available, either from the shared scope or as a fallback from the respective build. + +**Singleton sharing** + +Singleton sharing is necessary for context sharing between remote modules and between remote modules and shell application. + +Only a minimal set of dependencies should be shared as singletons as it gives access to all packages to the parent context. Also **version checking is disabled for singleton packages!** + +Singleton "must have" list: + +- @scalprum/core +- @scalprum/react-core +- @openshift/dynamic-plugin-sdk +- react +- react-dom +- react-router-dom + +Singleton "might have to" list: + +- @material-ui/core/styles +- @material-ui/styles + +**@mui/_ and @material-ui/_ like packages** + +> NOTE: Can leverage [Generate module sharing map](#generate-module-sharing-map). + +Component libraries are usually large (thousands of svg icons in @mui/icons) and it is inefficient to share them as a whole. **Tree shaking is disabled for shared modules**. That means sharing large packages in multiple versions will result in a bloated JS in browsers. + +Sharing components like these can be done on module level. Instead of sharing the entire package, share its individual components: + +```js +const shared = { + // will result in bloated bundles and degraded performance + '@mui/material': { + requiredVersion: 'x.x.x', // semver + }, + // sharing per module level, only button module is included in the output + '@mui/material/Button': { + version: 'x.x.x', // might have to specifically set the version + requiredVersion: 'x.x.x', // semver + }, +}; +``` + +Sharing dependencies on module level leads to optimal bundle size. Even if all modules from a dependency are listed, Webpack will only bundle modules that are discovered in the source files. That means the list can be generated at build time with no risk of bloating the output with unused modules. + +The module sharing "matching" is based on import paths. If relative import paths are used `import {foo} from 'bar'` it will not be matched to the absolute import path of a shared module `import foo from 'bar/foo'`. Therefore absolute import paths have to enforced or path transformation has to happen at build time. For JS builds, babel can be used, for ts builds a `ts-patch` utility with custom plugins is an option. + +#### Limitations + +A limitation of module sharing is that each module name can only appear once in each context. This means that if you're trying to build a bundle of shared modules with a deeper dependency tree, you may end up needing to resolve conflicts by renaming some modules that appear multiple times with different versions. This will in turn limit sharing of those modules with other bundles. + +There is also a conflict with the chunk splitting currently used in the Backstage CLI that means that some singleton modules need to be configured to be eagerly loaded. More broadly we may also want to re-evaluate the chunk splitting strategy in the Backstage CLI when adding support for module federation. + +#### Webpack chunk optimization + +Custom webpack chunk splitting configuration can be problematic, especially when modifying runtime and vendor chunks. Module federation creates its own chunks. Shared modules that are not set up to be eagerly loaded (using the `eager` configuration) **cannot be included inside the entry script**. With a custom chunk splitting setup, they can potentially be forced into the entry script, causing runtime errors. On the other hand, some critical runtime code that has to be in the entry script, cna be forced out of it. This is particularly problematic for the "shell" application. + +Chunk optimization should be disabled for the initial implementation. + +#### Webpack Public path option + +The `publicPath` output config in webpack is a mandatory attribute for federated modules. However, at build time, it is impossible to guess where the assets are served from. From origin to the pathname, this is specific to each installation. + +We can leverage the [auto](https://webpack.js.org/guides/public-path/#automatic-publicpath) option. However this means that some manifest transformation has to happen at runtime when entry scripts are loaded into the browser. More on that in the [Plugin manifest](#plugin-manifest), [CDN Plugin](#dynamic-assets-server-plugin), and [Plugin loading](#plugin-loading) sections. + +#### Sample webpack configuration ```TS -import { DynamicRemotePlugin } from '@openshift/dynamic-plugin-sdk-webpack'; -const sharedModules = { - /** - * Mandatory singleton packages for sharing - */ - react: { - singleton: true, - requiredVersion: '*', - }, - 'react-dom': { - singleton: true, - requiredVersion: '*', - }, - 'react-router-dom': { - singleton: true, - requiredVersion: '*', - }, - 'react-router': { - singleton: true, - requiredVersion: '*', - }, - ... - /** - * Full list of shared modules in Janus - * https://github.com/janus-idp/backstage-plugins/blob/87a6b045c7b0f301ebed8b8f99dc1741fa2b044b/packages/cli/src/lib/bundler/scalprumConfig.ts#L16 - */ +type DynamicPluginConfig = { + name: string; + version?: string; +}; +// { name: "@backstage/plugin-api-docs", version: "1.0.0" } +// generates "dynamic-backstage.plugin-api-docs" +const getName = (plugin: DynamicPluginConfig) => { + let pluginName: string; + if (plugin.name.includes('/')) { + const fragments = plugin.name.split('/'); + pluginName = `${fragments[0].replace('@', '')}.${fragments[1]}`; + } else { + pluginName = plugin.name; + } + return `dynamic-${pluginName}`; } + +// plugin = { name: "@backstage/plugin-api-docs", version: "1.0.0" } based on package.json +const pluginName = getName(plugin); + +const { ModuleFederationPlugin, ContainerPlugin } = require('@module-federation/enhanced'); + const dynamicPluginPlugin = new DynamicRemotePlugin({ extensions: [], - sharedModules, - entryScriptFilename: `${options.pluginMetadata.name}.[contenthash].js`, - pluginMetadata: { - // version cna be used from the package.json version field - version: '1.0.0', - /** - * Name can be easily derived from the plugin name - * https://github.com/janus-idp/backstage-plugins/blob/87a6b045c7b0f301ebed8b8f99dc1741fa2b044b/packages/cli/src/commands/export-dynamic-plugin/frontend.ts#L40 - */ - name: 'backstage.plugin-github-actions', - /** - * Path to the plugin entry point. - * It can default to the same entry point as in regular build. - * Plugins can expose multiple modules. We have found that one is sufficient from backstage plugins. - */ - exposedModules: { - PluginRoot: './src/index.ts' + sharedModules, // from shared config and generated from `package.json` dependencies + entryScriptFilename: `[name].[contenthash].js`, // using contenthash for cashing purposes + moduleFederationSettings: { + libraryType: 'global', // use the globalThis object rather than jsonp + // instruct the sdk plugin to use @module-federation/enhanced tooling + pluginOverride: { + ModuleFederationPlugin, + ContainerPlugin, } }, -}); -``` - -The `DynamicRemotePlugin` webpack plugin takes care of the rest, including the manifest generation. - -#### Sample plugin raw webpack configuration - -The Scalprum config translates to a following base webpack plugin configuration: - -```JS -import { container } from 'webpack'; - -const dynamicPlugin = new container.ModuleFederationPlugin({ - name: 'backstage.plugin-github-actions', - library: { - type: 'global', - /** - * Some library.type has name limitation - * for example, if "type": "var" is used, the library.name can contain the "-" character - */ - name: 'backstage.plugin-github-actions' + pluginMetadata: { + name: pluginName, + version: plugin.version || '0.0.0', + exposedModules: { + // path to the default export of the frontend plugin entry point + // the path should be sourced from the "main" attribute withing package.json + pluginEntry: './src/index.ts', + }, }, - filename: 'backstage.plugin-github-actions.[contenthash].js', - exposes: { - PluginRoot: './src/index.ts' - }, - // list of shared modules like "react", "react-dom", etc - shared: sharedModules, }); + + +const config: Configuration = { + context: pluginRoot, + output: { + chunkFilename: `${pluginName}.[contenthash].js`, + path: path.resolve(pluginRoot, 'dist'), + publicPath: 'auto', + }, + entry: {}, + resolve: { + extensions: ['.js', '.jsx', '.ts', '.tsx'], + }, + // extend existing webpack plugins that are relevant for dynamic plugins + plugins: [dynamicPluginPlugin, ...], + module: { + rules: [ + { + // needs TS config as well + test: /\.js$/, + exclude: /(node_modules)/, + use: { + loader: 'swc-loader', + }, + }, + { + test: /\.(png|svg|jpg|jpeg|gif)$/i, + type: 'asset/resource', + }, + // additional loaders for CSS if necessary, can use the same as the current backstage shell app + ], + }, + }; + return config; ``` -Additional plugin would have to be written from scratch to generate the plugin manifest file. +**Webpack plugins** -### Sample shell application webpack configuration +Existing webpack plugins can be used. Subset of shared plugins should be identified from current configurations and shared between the dynamic plugins and the shell application. -Shell application (backstage) has very simple module federation configuration. It does not require anything special to be able to inject plugins. Main requirement is to provide core shared packages like react and react-dom. +### Plugin manifest -```JS -import { container } from 'webpack'; +Plugin manifest is a simple JSON file containing critical metadata to initialize a remote plugin. -const scalprumPlugin = new container.ModuleFederationPlugin({ - name: 'backstageHost', - filename: 'backstageHost.[contenthash].js', - // same share modules list as with plugin config - shared: [sharedModules], -}); +The `@openshift/dynamic-plugin-sdk-webpack` plugin will output manifest file in the following format: + +```ts +type PluginManifest = { + name: string; + version: string; + dependencies?: Record; + customProperties?: AnyObject; + baseURL: string; + loadScripts: string[]; + registrationMethod: 'callback' | 'custom'; + buildHash?: string; +}; ``` -Nothing else is required. +This manifest is directly usable in Scalprum at runtime. -### Plugin storage +**baseURL** -Where will the dynamic plugin assets be hosted? Module federation does not strictly require the remote assets to be all hosted on the same origin. +This attribute is populated by the `output.publicPath` configuration. In this case, it will be a value of `auto`. That is not usable by the Scalprum loader. It has to be a URL. -Theoretically plugins can be hosted on some "public CDN" which is detached from individual backstage instances. +Because the origin can't be reliably "guessed" at build time, the value has to be filled by the CDN server. The attribute can be either overridden or, preferably, added to the `customProperties` attribute. -Assets can be also be hosted in the same way as they have always been. +A default`DEFAULT_API_PATH` should be used. Covering majority of the use cases. -It's important to consider old deployments as part of this storage, to make sure that dynamic chunks are still available to users who have not yet refreshed the page to load the latest version of the app. +```ts +type CustomProperties = { + assetHost?: string; // for local development should be http://localhost:PORT + // for deployment, should match the api host https://backstage.company.org +}; +``` -### Plugin discovery +Any additional metadata about plugins, can be also stored to the `customProperties`. Either at build time or runtime. That depends on the use case. The values can be read at runtime during plugin initialization. -How to notify/send data to browser +```ts +type CustomProperties = { + backstage: Record; +}; +``` -### Plugin initialization +**Exposing singleton packages config** -Currently all plugins have to be initialized at UI bootstrap (page refresh). The new UI async API can be used to initialize the remote assets. +Singleton shared packages do not follow the version matching strategy. It is a weak point in the dependency sharing strategy. Exposing the data in the manifest files provides the option to check the singleton configuration at runtime and prevent runtime crashes of plugins. -The `CreateAppFeatureLoader` can be leveraged to initialize the remote container. +```ts +type SingletonShareConfig = { + singleton: true; + version: string; + packageName: string; +}; -```TS -const allPluginManifests = {...} // get this from the config +type SingletonShareObject = { + [packageName: string]: SingletonShareConfig; +}; +``` -const asyncFeatureLoaders: CreateAppFeatureLoader[] = Object.values(allPluginManifests).map(({ manifest }) => { - return { - getLoaderName: () => manifest.name, - load: (options) => { - // initialize the remote container, depends on tooling - const plugin = initDynamicPlugin(manifest) - } +**Backstage plugin manifest** + +The plugin manifest for backstage with the additional attributes: + +```ts +type SingletonShareConfig = { + singleton: true; + version: string; + packageName: string; +}; + +type SingletonShareObject = { + [packageName: string]: SingletonShareConfig; +}; + +type CustomProperties = { + assetHost?: string; + backstage: Record; + singletonPackages: SingletonShareObject; +}; + +type PluginManifest = { + name: string; + version: string; + dependencies?: Record; + customProperties: CustomProperties; + baseURL: 'auto'; + loadScripts: string[]; + registrationMethod: 'custom'; + buildHash?: string; +}; +``` + +### Simplistic minimal example of module map generator + +```js +const path = require('path'); +const typescript = require('typescript'); +const fs = require('fs'); + +/** @type {typescript.CompilerOptions} */ +const defaultCompilerOptions = { + targe: 'es2015', + module: 'es2015', + esModuleInterop: true, + allowJs: true, + strict: false, + skipLibCheck: true, + noEmit: true, + // needs to be configured to the root directory dependency + rootDir: path.resolve(__dirname, 'dist'), + baseUrl: path.resolve(__dirname, 'dist'), +}; + +// these need to be configured, usually getting metadata from the lib package.json +const rootDit = path.resolve(__dirname, 'dist'); +const base = path.resolve(__dirname, 'dist', 'index.js'); + +function getDynamicModuleMap(libName) { + const compiler = typescript.createCompilerHost(defaultCompilerOptions, [ + rootDit, + ]); + const program = typescript.createProgram( + [base], + defaultCompilerOptions, + compiler, + ); + + const moduleResolutionCache = typescript.createModuleResolutionCache( + rootDit, + x => x, + defaultCompilerOptions, + ); + const errorDiagnostics = typescript + .getPreEmitDiagnostics(program) + .filter(d => d.category === typescript.DiagnosticCategory.Error); + if (errorDiagnostics.length > 0) { + const { getCanonicalFileName, getCurrentDirectory, getNewLine } = compiler; + + console.error( + typescript.formatDiagnostics(errorDiagnostics, { + getCanonicalFileName, + getCurrentDirectory, + getNewLine, + }), + ); + + throw new Error(`Detected TypeScript errors while parsing modules`); } -}) + const typeChecker = program.getTypeChecker(); -const app = createApp({ - features: [ - ...asyncFeatureLoaders, - // rest of classic features - ] -}) + /** @param {typescript.SourceFile} sourceFile */ + const getExportNames = sourceFile => + typeChecker + .getExportsOfModule(typeChecker.getSymbolAtLocation(sourceFile)) + .map(symbol => symbol.getName()); + + const baseExports = getExportNames(program.getSourceFile(base)); + const compilerDir = compiler.getCurrentDirectory(); + const resolvedModules = baseExports + .map(name => { + const res = typescript.resolveModuleName( + name, + base, + defaultCompilerOptions, + compiler, + moduleResolutionCache, + ); + if (res.resolvedModule?.resolvedFileName) { + return { + name, + file: + libName + + res.resolvedModule.resolvedFileName + .replace(compilerDir, '') + .replace(/\.js$/, ''), + }; + } + return undefined; + }) + .filter(x => x !== undefined); + + const moduleMapFileName = path.resolve(__dirname, 'module-map.json'); + fs.writeFileSync(moduleMapFileName, JSON.stringify(resolvedModules, null, 2)); +} + +const libName = '@mui/foo'; + +getDynamicModuleMap(libName); + +/** + * [ + * { + * "name": "foo", + * "file": "@mui/foo/dist/foo" + * }, + * { + * "name": "baz", + * "file": "@mui/foo/dist/baz" + * } + * ] + */ ``` ### Plugin declarative configuration diff --git a/beps/0002-dynamic-frontend-plugins/dependency-sharing-schema.json b/beps/0002-dynamic-frontend-plugins/dependency-sharing-schema.json new file mode 100644 index 0000000000..4777f81f78 --- /dev/null +++ b/beps/0002-dynamic-frontend-plugins/dependency-sharing-schema.json @@ -0,0 +1,43 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "type": "object", + "additionalProperties": false, + "properties": { + "shareModules": { + "type": "object", + "patternProperties": { + "^(@[^/]+/)?[^/]+$": { + "$ref": "#/definitions/sharedModule" + } + }, + "additionalProperties": false + }, + "excludeModules": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "definitions": { + "sharedModule": { + "type": "object", + "required": ["requiredVersion"], + "properties": { + "requiredVersion": { + "$ref": "#/definitions/semverString" + }, + "version": { + "$ref": "#/definitions/semverString" + }, + "singleton": { + "type": "boolean" + } + } + }, + "semverString": { + "type": "string", + "pattern": "^(\\^|\\~)?(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$" + } + } +} diff --git a/beps/0002-dynamic-frontend-plugins/share-config-sample.json b/beps/0002-dynamic-frontend-plugins/share-config-sample.json new file mode 100644 index 0000000000..fe5c9943ad --- /dev/null +++ b/beps/0002-dynamic-frontend-plugins/share-config-sample.json @@ -0,0 +1,17 @@ +{ + "$schema": "./dependency-sharing-schema.json", + "shareModules": { + "foo-bar": { + "requiredVersion": "1.0.0" + }, + "@bax/foo-bar": { + "requiredVersion": "1.0.0", + "singleton": true + }, + "@bax-baz/foo-bar2": { + "requiredVersion": "^1.2.0", + "version": "1.4.0" + } + }, + "excludeModules": ["foo-bar-baz"] +} From a0fd89c3ef77677404cfb46e973000ef4061d2b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20St=C3=B6rkle?= Date: Thu, 15 Feb 2024 14:54:48 +0100 Subject: [PATCH 014/510] fix: use correct odata type in TypeScript MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Florian Störkle --- .../src/microsoftGraph/client.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.ts index 1233b1e2f9..c190e2a959 100644 --- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.ts +++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.ts @@ -64,8 +64,8 @@ export type ODataQuery = { * @public */ export type GroupMember = - | (MicrosoftGraph.Group & { '@odata.type': '#microsoft.graph.user' }) - | (MicrosoftGraph.User & { '@odata.type': '#microsoft.graph.group' }); + | (MicrosoftGraph.Group & { '@odata.type': '#microsoft.graph.group' }) + | (MicrosoftGraph.User & { '@odata.type': '#microsoft.graph.user' }); /** * A HTTP Client that communicates with Microsoft Graph API. From da7651605a6c78e8e4a89ab89fc2d0e30291d06b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20St=C3=B6rkle?= Date: Fri, 16 Feb 2024 13:15:50 +0100 Subject: [PATCH 015/510] feat(catalog): ingest member groups if configured MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Florian Störkle --- .../config.d.ts | 5 + .../src/microsoftGraph/config.test.ts | 2 + .../src/microsoftGraph/config.ts | 10 ++ .../src/microsoftGraph/read.test.ts | 114 ++++++++++++++++++ .../src/microsoftGraph/read.ts | 28 +++++ .../MicrosoftGraphOrgEntityProvider.ts | 1 + 6 files changed, 160 insertions(+) diff --git a/plugins/catalog-backend-module-msgraph/config.d.ts b/plugins/catalog-backend-module-msgraph/config.d.ts index 5a1f56a03f..a470c075f0 100644 --- a/plugins/catalog-backend-module-msgraph/config.d.ts +++ b/plugins/catalog-backend-module-msgraph/config.d.ts @@ -192,6 +192,11 @@ export interface Config { * E.g. ["id", "displayName", "description"] */ select?: string[]; + /** + * Whether to ingest groups that are members of the found/filtered/searched groups. + * Default value is `false`. + */ + includeSubGroups?: boolean; }; userGroupMember?: { diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/config.test.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/config.test.ts index b02894dfd9..e1c81662a3 100644 --- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/config.test.ts +++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/config.test.ts @@ -175,6 +175,7 @@ describe('readProviderConfigs', () => { expand: 'member', filter: 'securityEnabled eq false', select: ['id', 'displayName', 'description'], + includeSubGroups: true, }, schedule: { frequency: 'PT30M', @@ -203,6 +204,7 @@ describe('readProviderConfigs', () => { groupExpand: 'member', groupSelect: ['id', 'displayName', 'description'], groupFilter: 'securityEnabled eq false', + groupIncludeSubGroups: true, schedule: { frequency: Duration.fromISO('PT30M'), timeout: { diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/config.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/config.ts index 1545114e45..257a7d5736 100644 --- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/config.ts +++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/config.ts @@ -116,6 +116,12 @@ export type MicrosoftGraphProviderConfig = { */ groupSelect?: string[]; + /** + * Whether to ingest groups that are members of the found/filtered/searched groups. + * Default value is `false`. + */ + groupIncludeSubGroups?: boolean; + /** * By default, the Microsoft Graph API only provides the basic feature set * for querying. Certain features are limited to advanced query capabilities @@ -292,6 +298,9 @@ export function readProviderConfig( const groupFilter = config.getOptionalString('group.filter'); const groupSearch = config.getOptionalString('group.search'); const groupSelect = config.getOptionalStringArray('group.select'); + const groupIncludeSubGroups = config.getOptionalBoolean( + 'group.includeSubGroups', + ); const queryMode = config.getOptionalString('queryMode'); if ( @@ -347,6 +356,7 @@ export function readProviderConfig( groupFilter, groupSearch, groupSelect, + groupIncludeSubGroups, queryMode, userGroupMemberFilter, userGroupMemberSearch, diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.test.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.test.ts index 8821ffd2db..b83597653f 100644 --- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.test.ts +++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.test.ts @@ -90,6 +90,9 @@ describe('read microsoft graph', () => { yield { '@odata.type': '#microsoft.graph.group', id: 'childgroupid', + displayName: 'Child Group Name', + description: 'Child Group Description', + mail: 'childgroup@example.com', }; yield { '@odata.type': '#microsoft.graph.user', @@ -770,6 +773,117 @@ describe('read microsoft graph', () => { top: 999, }); }); + + it('should read groups and their sub groups', async () => { + async function* getExampleGroupMembersForSubGroup(): AsyncIterable { + yield { + '@odata.type': '#microsoft.graph.user', + id: 'userid2', + }; + } + + client.getGroups.mockImplementation(getExampleGroups); + client.getGroupMembers.mockImplementationOnce(getExampleGroupMembers); + client.getGroupMembers.mockImplementationOnce( + getExampleGroupMembersForSubGroup, + ); + client.getOrganization.mockResolvedValue({ + id: 'tenantid', + displayName: 'Organization Name', + }); + client.getGroupPhotoWithSizeLimit.mockResolvedValue( + 'data:image/jpeg;base64,...', + ); + + const { groups, groupMember, groupMemberOf, rootGroup } = + await readMicrosoftGraphGroups(client, 'tenantid', { + groupIncludeSubGroups: true, + }); + + const expectedRootGroup = group({ + metadata: { + annotations: { + 'graph.microsoft.com/tenant-id': 'tenantid', + }, + name: 'organization_name', + description: 'Organization Name', + }, + spec: { + type: 'root', + profile: { + displayName: 'Organization Name', + }, + children: [], + }, + }); + expect(groups).toEqual([ + expectedRootGroup, + group({ + metadata: { + annotations: { + 'graph.microsoft.com/group-id': 'childgroupid', + }, + name: 'child_group_name', + description: 'Child Group Description', + }, + spec: { + type: 'team', + profile: { + displayName: 'Child Group Name', + email: 'childgroup@example.com', + // TODO: Loading groups photos doesn't work right now as Microsoft + // Graph doesn't allows this yet + /* picture: 'data:image/jpeg;base64,...',*/ + }, + children: [], + }, + }), + group({ + metadata: { + annotations: { + 'graph.microsoft.com/group-id': 'groupid', + }, + name: 'group_name', + description: 'Group Description', + }, + spec: { + type: 'team', + profile: { + displayName: 'Group Name', + email: 'group@example.com', + // TODO: Loading groups photos doesn't work right now as Microsoft + // Graph doesn't allows this yet + /* picture: 'data:image/jpeg;base64,...',*/ + }, + children: [], + }, + }), + ]); + expect(rootGroup).toEqual(expectedRootGroup); + expect(groupMember.get('groupid')).toEqual(new Set(['childgroupid'])); + expect(groupMemberOf.get('userid')).toEqual(new Set(['groupid'])); + expect(groupMemberOf.get('userid2')).toEqual(new Set(['childgroupid'])); + expect(groupMember.get('organization_name')).toEqual(new Set()); + + expect(client.getGroups).toHaveBeenCalledTimes(1); + expect(client.getGroups).toHaveBeenCalledWith( + { + top: 999, + }, + undefined, + ); + expect(client.getGroupMembers).toHaveBeenCalledTimes(2); + expect(client.getGroupMembers).toHaveBeenCalledWith('groupid', { + top: 999, + }); + expect(client.getGroupMembers).toHaveBeenCalledWith('childgroupid', { + top: 999, + }); + // TODO: Loading groups photos doesn't work right now as Microsoft Graph + // doesn't allows this yet + // expect(client.getGroupPhotoWithSizeLimit).toBeCalledTimes(1); + // expect(client.getGroupPhotoWithSizeLimit).toBeCalledWith('groupid', 120); + }); }); describe('resolveRelations', () => { diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts index 2ca21fca9c..60e5c3d79b 100644 --- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts +++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts @@ -178,6 +178,7 @@ export async function readMicrosoftGraphGroups( groupFilter?: string; groupSearch?: string; groupSelect?: string[]; + groupIncludeSubGroups?: boolean; groupTransformer?: GroupTransformer; organizationTransformer?: OrganizationTransformer; }, @@ -244,6 +245,31 @@ export async function readMicrosoftGraphGroups( if (member['@odata.type'] === '#microsoft.graph.group') { ensureItem(groupMember, group.id!, member.id); + + if (options?.groupIncludeSubGroups) { + const groupMemberEntity = await transformer(member); + + if (groupMemberEntity) { + groups.push(groupMemberEntity); + + for await (const subMember of client.getGroupMembers( + member.id!, + { top: PAGE_SIZE }, + )) { + if (!subMember.id) { + continue; + } + + if (subMember['@odata.type'] === '#microsoft.graph.user') { + ensureItem(groupMemberOf, subMember.id, member.id!); + } + + if (subMember['@odata.type'] === '#microsoft.graph.group') { + ensureItem(groupMember, member.id!, subMember.id); + } + } + } + } } } @@ -377,6 +403,7 @@ export async function readMicrosoftGraphOrg( groupSearch?: string; groupFilter?: string; groupSelect?: string[]; + groupIncludeSubGroups?: boolean; queryMode?: 'basic' | 'advanced'; userTransformer?: UserTransformer; groupTransformer?: GroupTransformer; @@ -421,6 +448,7 @@ export async function readMicrosoftGraphOrg( groupFilter: options.groupFilter, groupSearch: options.groupSearch, groupSelect: options.groupSelect, + groupIncludeSubGroups: options.groupIncludeSubGroups, groupTransformer: options.groupTransformer, organizationTransformer: options.organizationTransformer, }); diff --git a/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgEntityProvider.ts b/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgEntityProvider.ts index 3c8b903e69..c48ee18ffe 100644 --- a/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgEntityProvider.ts +++ b/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgEntityProvider.ts @@ -317,6 +317,7 @@ export class MicrosoftGraphOrgEntityProvider implements EntityProvider { groupFilter: provider.groupFilter, groupSearch: provider.groupSearch, groupSelect: provider.groupSelect, + groupIncludeSubGroups: provider.groupIncludeSubGroups, queryMode: provider.queryMode, groupTransformer: this.options.groupTransformer, userTransformer: this.options.userTransformer, From 24b3a3141b2eec8f89e4f76aa3cfc7328d28ea6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20St=C3=B6rkle?= Date: Mon, 19 Feb 2024 08:35:18 +0100 Subject: [PATCH 016/510] docs: document `includeSubGroups` config option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Florian Störkle --- docs/integrations/azure/org.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/integrations/azure/org.md b/docs/integrations/azure/org.md index 89abd4813b..b1719a63da 100644 --- a/docs/integrations/azure/org.md +++ b/docs/integrations/azure/org.md @@ -112,6 +112,17 @@ microsoftGraphOrg: search: '"description:One" AND ("displayName:Video" OR "displayName:Drive")' ``` +If you don't want to only ingest groups matching the `search` and/or `filter` query, but also the groups which are members of the matched groups, you can use the `includeSubGroups` configuration: + +```yaml +microsoftGraphOrg: + providerId: + group: + filter: securityEnabled eq false and mailEnabled eq true and groupTypes/any(c:c+eq+'Unified') + search: '"description:One" AND ("displayName:Video" OR "displayName:Drive")' + includeSubGroups: true +``` + In addition to these groups, one additional group will be created for your organization. All imported groups will be a child of this group. From d9cf697afda7543d72610e59f656ca05e2c9c3d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20St=C3=B6rkle?= Date: Mon, 19 Feb 2024 08:40:38 +0100 Subject: [PATCH 017/510] chore: generate API report MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Florian Störkle --- plugins/catalog-backend-module-msgraph/api-report.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/catalog-backend-module-msgraph/api-report.md b/plugins/catalog-backend-module-msgraph/api-report.md index 86170e2910..87402eedb1 100644 --- a/plugins/catalog-backend-module-msgraph/api-report.md +++ b/plugins/catalog-backend-module-msgraph/api-report.md @@ -39,10 +39,10 @@ export function defaultUserTransformer( // @public export type GroupMember = | (MicrosoftGraph.Group & { - '@odata.type': '#microsoft.graph.user'; + '@odata.type': '#microsoft.graph.group'; }) | (MicrosoftGraph.User & { - '@odata.type': '#microsoft.graph.group'; + '@odata.type': '#microsoft.graph.user'; }); // @public @@ -210,6 +210,7 @@ export type MicrosoftGraphProviderConfig = { groupFilter?: string; groupSearch?: string; groupSelect?: string[]; + groupIncludeSubGroups?: boolean; queryMode?: 'basic' | 'advanced'; loadUserPhotos?: boolean; schedule?: TaskScheduleDefinition; @@ -253,6 +254,7 @@ export function readMicrosoftGraphOrg( groupSearch?: string; groupFilter?: string; groupSelect?: string[]; + groupIncludeSubGroups?: boolean; queryMode?: 'basic' | 'advanced'; userTransformer?: UserTransformer; groupTransformer?: GroupTransformer; From 58dff4d5e574428090ec09a4fbc7de3e08224c4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20St=C3=B6rkle?= Date: Tue, 16 Apr 2024 10:01:13 +0200 Subject: [PATCH 018/510] chore: add changeset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Florian Störkle --- .changeset/little-suns-fly.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/little-suns-fly.md diff --git a/.changeset/little-suns-fly.md b/.changeset/little-suns-fly.md new file mode 100644 index 0000000000..887df4be6d --- /dev/null +++ b/.changeset/little-suns-fly.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-msgraph': patch +--- + +Added option to ingest groups based on their group membership in Azure Entra ID From 4e4ef2ba78a8ead2fdf3bd674ac1ef5dcf313eb0 Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Wed, 5 Jun 2024 13:33:31 +0300 Subject: [PATCH 019/510] chore: move notification processor filters to common package Signed-off-by: Heikki Hellgren --- .changeset/weak-emus-doubt.md | 7 +++ .../processor/NotificationsEmailProcessor.ts | 30 ++---------- plugins/notifications-common/api-report.md | 14 ++++++ plugins/notifications-common/package.json | 1 + plugins/notifications-common/src/filters.ts | 47 +++++++++++++++++++ plugins/notifications-common/src/index.ts | 1 + plugins/notifications-common/src/types.ts | 9 ++++ plugins/notifications-node/api-report.md | 10 ++-- plugins/notifications-node/src/extensions.ts | 9 ++-- yarn.lock | 1 + 10 files changed, 89 insertions(+), 40 deletions(-) create mode 100644 .changeset/weak-emus-doubt.md create mode 100644 plugins/notifications-common/src/filters.ts diff --git a/.changeset/weak-emus-doubt.md b/.changeset/weak-emus-doubt.md new file mode 100644 index 0000000000..cd3b4a836b --- /dev/null +++ b/.changeset/weak-emus-doubt.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-notifications-backend-module-email': patch +'@backstage/plugin-notifications-common': patch +'@backstage/plugin-notifications-node': patch +--- + +Move notification processor filter parsing to common package diff --git a/plugins/notifications-backend-module-email/src/processor/NotificationsEmailProcessor.ts b/plugins/notifications-backend-module-email/src/processor/NotificationsEmailProcessor.ts index a78ebd3260..8689afc065 100644 --- a/plugins/notifications-backend-module-email/src/processor/NotificationsEmailProcessor.ts +++ b/plugins/notifications-backend-module-email/src/processor/NotificationsEmailProcessor.ts @@ -15,7 +15,6 @@ */ import { NotificationProcessor, - NotificationProcessorFilters, NotificationSendOptions, } from '@backstage/plugin-notifications-node'; import { @@ -30,9 +29,9 @@ import { CatalogClient, } from '@backstage/catalog-client'; import { + getProcessorFiltersFromConfig, Notification, - notificationSeverities, - NotificationSeverity, + NotificationProcessorFilters, } from '@backstage/plugin-notifications-common'; import { createSendmailTransport, @@ -86,30 +85,7 @@ export class NotificationsEmailProcessor implements NotificationProcessor { ? durationToMilliseconds(readDurationFromConfig(cacheConfig)) : 3_600_000; this.frontendBaseUrl = config.getString('app.baseUrl'); - this.filter = {}; - const minSeverity = emailProcessorConfig.getOptionalString( - 'filter.minSeverity', - ) as NotificationSeverity; - if (minSeverity) { - if (notificationSeverities.includes(minSeverity)) { - this.filter.minSeverity = minSeverity; - } else { - throw new Error(`Invalid minSeverity: ${minSeverity}`); - } - } - const maxSeverity = emailProcessorConfig.getOptionalString( - 'filter.maxSeverity', - ) as NotificationSeverity; - if (maxSeverity) { - if (notificationSeverities.includes(maxSeverity)) { - this.filter.maxSeverity = maxSeverity; - } else { - throw new Error(`Invalid maxSeverity: ${maxSeverity}`); - } - } - this.filter.excludedTopics = emailProcessorConfig.getOptionalStringArray( - 'filter.excludedTopics', - ); + this.filter = getProcessorFiltersFromConfig(emailProcessorConfig); } private async getTransporter() { diff --git a/plugins/notifications-common/api-report.md b/plugins/notifications-common/api-report.md index 3ddce24393..0f59a85849 100644 --- a/plugins/notifications-common/api-report.md +++ b/plugins/notifications-common/api-report.md @@ -3,6 +3,13 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { Config } from '@backstage/config'; + +// @public (undocumented) +export const getProcessorFiltersFromConfig: ( + config: Config, +) => NotificationProcessorFilters; + // @public (undocumented) export type NewNotificationSignal = { action: 'new_notification'; @@ -33,6 +40,13 @@ export type NotificationPayload = { icon?: string; }; +// @public (undocumented) +export type NotificationProcessorFilters = { + minSeverity?: NotificationSeverity; + maxSeverity?: NotificationSeverity; + excludedTopics?: string[]; +}; + // @public (undocumented) export type NotificationReadSignal = { action: 'notification_read' | 'notification_unread'; diff --git a/plugins/notifications-common/package.json b/plugins/notifications-common/package.json index 2745230a4a..eaec75cb5e 100644 --- a/plugins/notifications-common/package.json +++ b/plugins/notifications-common/package.json @@ -32,6 +32,7 @@ "test": "backstage-cli package test" }, "dependencies": { + "@backstage/config": "workspace:^", "@material-ui/icons": "^4.9.1" }, "devDependencies": { diff --git a/plugins/notifications-common/src/filters.ts b/plugins/notifications-common/src/filters.ts new file mode 100644 index 0000000000..725cfcf714 --- /dev/null +++ b/plugins/notifications-common/src/filters.ts @@ -0,0 +1,47 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Config } from '@backstage/config'; +import { NotificationProcessorFilters, NotificationSeverity } from './types'; +import { notificationSeverities } from './constants'; + +/** @public */ +export const getProcessorFiltersFromConfig = (config: Config) => { + const filter: NotificationProcessorFilters = {}; + const minSeverity = config.getOptionalString( + 'filter.minSeverity', + ) as NotificationSeverity; + if (minSeverity) { + if (notificationSeverities.includes(minSeverity)) { + filter.minSeverity = minSeverity; + } else { + throw new Error(`Invalid minSeverity: ${minSeverity}`); + } + } + const maxSeverity = config.getOptionalString( + 'filter.maxSeverity', + ) as NotificationSeverity; + if (maxSeverity) { + if (notificationSeverities.includes(maxSeverity)) { + filter.maxSeverity = maxSeverity; + } else { + throw new Error(`Invalid maxSeverity: ${maxSeverity}`); + } + } + filter.excludedTopics = config.getOptionalStringArray( + 'filter.excludedTopics', + ); + return filter; +}; diff --git a/plugins/notifications-common/src/index.ts b/plugins/notifications-common/src/index.ts index 7d74c75be8..9fc7bde2b8 100644 --- a/plugins/notifications-common/src/index.ts +++ b/plugins/notifications-common/src/index.ts @@ -22,3 +22,4 @@ export * from './types'; export * from './constants'; +export * from './filters'; diff --git a/plugins/notifications-common/src/types.ts b/plugins/notifications-common/src/types.ts index b9c9f63489..a4be3e4255 100644 --- a/plugins/notifications-common/src/types.ts +++ b/plugins/notifications-common/src/types.ts @@ -116,3 +116,12 @@ export type NotificationReadSignal = { /** @public */ export type NotificationSignal = NewNotificationSignal | NotificationReadSignal; + +/** + * @public + */ +export type NotificationProcessorFilters = { + minSeverity?: NotificationSeverity; + maxSeverity?: NotificationSeverity; + excludedTopics?: string[]; +}; diff --git a/plugins/notifications-node/api-report.md b/plugins/notifications-node/api-report.md index 27e6422f8a..37f28fec35 100644 --- a/plugins/notifications-node/api-report.md +++ b/plugins/notifications-node/api-report.md @@ -8,7 +8,7 @@ import { DiscoveryService } from '@backstage/backend-plugin-api'; import { ExtensionPoint } from '@backstage/backend-plugin-api'; import { Notification as Notification_2 } from '@backstage/plugin-notifications-common'; import { NotificationPayload } from '@backstage/plugin-notifications-common'; -import { NotificationSeverity } from '@backstage/plugin-notifications-common'; +import { NotificationProcessorFilters as NotificationProcessorFilters_2 } from '@backstage/plugin-notifications-common'; import { ServiceRef } from '@backstage/backend-plugin-api'; // @public (undocumented) @@ -38,12 +38,8 @@ export interface NotificationProcessor { ): Promise; } -// @public (undocumented) -export type NotificationProcessorFilters = { - minSeverity?: NotificationSeverity; - maxSeverity?: NotificationSeverity; - excludedTopics?: string[]; -}; +// @public @deprecated (undocumented) +export type NotificationProcessorFilters = NotificationProcessorFilters_2; // @public (undocumented) export type NotificationRecipients = diff --git a/plugins/notifications-node/src/extensions.ts b/plugins/notifications-node/src/extensions.ts index 7adb6caf50..03ce47fea6 100644 --- a/plugins/notifications-node/src/extensions.ts +++ b/plugins/notifications-node/src/extensions.ts @@ -16,7 +16,7 @@ import { createExtensionPoint } from '@backstage/backend-plugin-api'; import { Notification, - NotificationSeverity, + NotificationProcessorFilters as NotificationProcessorFiltersCommon, } from '@backstage/plugin-notifications-common'; import { NotificationSendOptions } from './service'; @@ -119,9 +119,6 @@ export const notificationsProcessingExtensionPoint = /** * @public + * @deprecated Please import from `@backstage/plugin-notifications-common` instead */ -export type NotificationProcessorFilters = { - minSeverity?: NotificationSeverity; - maxSeverity?: NotificationSeverity; - excludedTopics?: string[]; -}; +export type NotificationProcessorFilters = NotificationProcessorFiltersCommon; diff --git a/yarn.lock b/yarn.lock index 2ad2995d52..7c2b1ac7fe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6240,6 +6240,7 @@ __metadata: resolution: "@backstage/plugin-notifications-common@workspace:plugins/notifications-common" dependencies: "@backstage/cli": "workspace:^" + "@backstage/config": "workspace:^" "@material-ui/icons": ^4.9.1 languageName: unknown linkType: soft From 3a5d011ded51423947b861f0d0b0663e34944a78 Mon Sep 17 00:00:00 2001 From: AmbrishRamachandiran Date: Fri, 7 Jun 2024 11:51:14 +0530 Subject: [PATCH 020/510] Updated docs of technical faq Signed-off-by: AmbrishRamachandiran --- docs/faq/technical.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/faq/technical.md b/docs/faq/technical.md index d64d81d499..32511351f0 100644 --- a/docs/faq/technical.md +++ b/docs/faq/technical.md @@ -116,7 +116,7 @@ This makes it easier to create, find, and update documentation. [TechDocs is now open source.](https://backstage.io/docs/features/techdocs/) (See also: "[Will Spotify's internal plugins be open sourced, too?](https://backstage.io/docs/faq/product#will-spotifys-internal-plugins-be-open-sourced-too)" -above) +above). ### Are you planning to have plugins baked into the repo? Or should they be developed in separate repos? From acf66e727a21ffce6797bb473eef7810dd863618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl?= <61149845+RaphaelSve@users.noreply.github.com> Date: Mon, 10 Jun 2024 11:29:51 +0200 Subject: [PATCH 021/510] Update check-docs-quality.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add new regex for README files Signed-off-by: Raphaël <61149845+RaphaelSve@users.noreply.github.com> --- scripts/check-docs-quality.js | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/check-docs-quality.js b/scripts/check-docs-quality.js index 9a9336b3e9..0fd374ef23 100755 --- a/scripts/check-docs-quality.js +++ b/scripts/check-docs-quality.js @@ -30,6 +30,7 @@ const IGNORED_WHEN_LISTING = [ /^.*[/\\]knip-report\.md$/, /^docs[/\\]releases[/\\].*-changelog\.md$/, /^docs[/\\]reference[/\\]/, + /^README-[a-z]{2}_[A-Z]{2}\.md$/, ]; const IGNORED_WHEN_EXPLICIT = [ From ffdfd558980f0c9ec3005e16292f03860c728cf8 Mon Sep 17 00:00:00 2001 From: Jack Green Date: Tue, 11 Jun 2024 09:43:55 +0100 Subject: [PATCH 022/510] Update `README.md` FAQ link The [FAQ link](https://backstage.io/docs/FAQ) returns 404: ``` curl -I https://backstage.io/docs/FAQ HTTP/2 404 ``` It does redirect to [a working page](https://backstage.io/docs/FAQ), but intermediately shows a `Page Not Found` error. Signed-off-by: Jack Green --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 47ae539b6b..65b9187ac7 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ 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 +- [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 From 2b8b4f115a1f3052dc5db9ff14c33b8d0afd8d20 Mon Sep 17 00:00:00 2001 From: Niall Thomson Date: Tue, 11 Jun 2024 22:19:44 -0400 Subject: [PATCH 023/510] Removed code that catches error and formatted changeset markdown Signed-off-by: Niall Thomson --- .changeset/swift-kings-sparkle.md | 2 +- .../AwsOrganizationCloudAccountProcessor.ts | 36 +++++++++---------- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/.changeset/swift-kings-sparkle.md b/.changeset/swift-kings-sparkle.md index 18a37b82f1..84ceae962b 100644 --- a/.changeset/swift-kings-sparkle.md +++ b/.changeset/swift-kings-sparkle.md @@ -2,4 +2,4 @@ '@backstage/plugin-catalog-backend-module-aws': patch --- -AwsOrganizationCloudAccountProcessor configuration field roleArn is deprecated in favor of new field accountId +`AwsOrganizationCloudAccountProcessor` configuration field `roleArn` is deprecated in favor of new field `accountId` diff --git a/plugins/catalog-backend-module-aws/src/processors/AwsOrganizationCloudAccountProcessor.ts b/plugins/catalog-backend-module-aws/src/processors/AwsOrganizationCloudAccountProcessor.ts index b843503a28..73d7a63e2b 100644 --- a/plugins/catalog-backend-module-aws/src/processors/AwsOrganizationCloudAccountProcessor.ts +++ b/plugins/catalog-backend-module-aws/src/processors/AwsOrganizationCloudAccountProcessor.ts @@ -106,27 +106,23 @@ export class AwsOrganizationCloudAccountProcessor implements CatalogProcessor { this.logger?.info('Discovering AWS Organization Account objects'); - try { - (await this.getAwsAccounts()) - .map(account => this.mapAccountToComponent(account)) - .filter(entity => { - if (location.target !== '') { - if (entity.metadata.annotations) { - return ( - entity.metadata.annotations[ORGANIZATION_ANNOTATION] === - location.target - ); - } - return false; + (await this.getAwsAccounts()) + .map(account => this.mapAccountToComponent(account)) + .filter(entity => { + if (location.target !== '') { + if (entity.metadata.annotations) { + return ( + entity.metadata.annotations[ORGANIZATION_ANNOTATION] === + location.target + ); } - return true; - }) - .forEach(entity => { - emit(processingResult.entity(location, entity)); - }); - } catch (e) { - this.logger?.error(e); - } + return false; + } + return true; + }) + .forEach(entity => { + emit(processingResult.entity(location, entity)); + }); return true; } From 0e61a3c09172129843b739ebfb5112b8b262f1d3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Jun 2024 09:47:55 +0000 Subject: [PATCH 024/510] fix(deps): update dependency core-js to v3.37.1 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 2d508b5bff..869b26ae5e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23630,9 +23630,9 @@ __metadata: linkType: hard "core-js@npm:^3.6.5": - version: 3.37.0 - resolution: "core-js@npm:3.37.0" - checksum: 212c3e9b3fc277dbb63739ef58a61c5709ccd0b36f09c3ce6946aa91fa180c60f57f976d4a5fdb9cda0c6cb55417379ba5a008fc3a1384ec94ec8ec61826469d + version: 3.37.1 + resolution: "core-js@npm:3.37.1" + checksum: 2d58a5c599f05c3e04abc8bc5e64b88eb17d914c0f552f670fb800afa74ec54b4fcc7f231ad6bd45badaf62c0fb0ce30e6fe89cedb6bb6d54e6f19115c3c17ff languageName: node linkType: hard From 6c5c94aaef0e1a668eee8acad4c17c75e671c1fb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Jun 2024 20:19:12 +0000 Subject: [PATCH 025/510] fix(deps): update material-ui monorepo to v5.15.20 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 60 +++++++++++++++++++++++++++---------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/yarn.lock b/yarn.lock index 8e35710b7f..c0caa1600a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11019,23 +11019,23 @@ __metadata: languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.15.15": - version: 5.15.15 - resolution: "@mui/core-downloads-tracker@npm:5.15.15" - checksum: 3e99a04e03f66d5fa5f0c23cdce0f9fa2331ba08c99a75dc2347ccaa1c6ed520153e04aaeb0d613c9dca099a3e6242558a6284c33d93f95cc65e3243b17860bc +"@mui/core-downloads-tracker@npm:^5.15.20": + version: 5.15.20 + resolution: "@mui/core-downloads-tracker@npm:5.15.20" + checksum: 8cc71169ce1201c5a37fad6c5c58739850694e90c7bda636c692d47a79fd4c7884eab2c24b0084d6732a3d28c9a4a6d222dd5747f9d91f5075614700a3a3282a languageName: node linkType: hard "@mui/material@npm:^5.12.2": - version: 5.15.15 - resolution: "@mui/material@npm:5.15.15" + version: 5.15.20 + resolution: "@mui/material@npm:5.15.20" dependencies: "@babel/runtime": ^7.23.9 "@mui/base": 5.0.0-beta.40 - "@mui/core-downloads-tracker": ^5.15.15 - "@mui/system": ^5.15.15 + "@mui/core-downloads-tracker": ^5.15.20 + "@mui/system": ^5.15.20 "@mui/types": ^7.2.14 - "@mui/utils": ^5.15.14 + "@mui/utils": ^5.15.20 "@types/react-transition-group": ^4.4.10 clsx: ^2.1.0 csstype: ^3.1.3 @@ -11055,16 +11055,16 @@ __metadata: optional: true "@types/react": optional: true - checksum: ee0dc22fc4d617f7cf69f2451b6d5139978e6c5319e3056e7719159aff786ee3b80abd07691e230371811d9b5b574aef4559d7855bfe2f8493d596d960a91ab7 + checksum: 0d0e29682fa8f4ff03746efabb4b480da9dfe004e68982a36662ff0d40d76f5840ebf8ef3b0f9629056afb3030145dd5eb3bd2b0ab96d201fac7a300fef155b0 languageName: node linkType: hard -"@mui/private-theming@npm:^5.15.14": - version: 5.15.14 - resolution: "@mui/private-theming@npm:5.15.14" +"@mui/private-theming@npm:^5.15.20": + version: 5.15.20 + resolution: "@mui/private-theming@npm:5.15.20" dependencies: "@babel/runtime": ^7.23.9 - "@mui/utils": ^5.15.14 + "@mui/utils": ^5.15.20 prop-types: ^15.8.1 peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 @@ -11072,7 +11072,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 1b1ef54e8281c9b13fcc58f4c39682efc610946a68402283c19fcfbce8a7d7a231d61b536d6df9bf7a59a1426591bd403a453a59eb8efb9689437fb58554dc8c + checksum: 5c70a9ebca3827cea11d67b3f8ed24d18a10c44f30f14d8d1c37b3f1e74d7a5e91cec5ffb7f24e8b2d974b38e4d046a93473c20a0cd7c7a880580e5df3d1afb7 languageName: node linkType: hard @@ -11098,14 +11098,14 @@ __metadata: linkType: hard "@mui/styles@npm:^5.14.18": - version: 5.15.15 - resolution: "@mui/styles@npm:5.15.15" + version: 5.15.20 + resolution: "@mui/styles@npm:5.15.20" dependencies: "@babel/runtime": ^7.23.9 "@emotion/hash": ^0.9.1 - "@mui/private-theming": ^5.15.14 + "@mui/private-theming": ^5.15.20 "@mui/types": ^7.2.14 - "@mui/utils": ^5.15.14 + "@mui/utils": ^5.15.20 clsx: ^2.1.0 csstype: ^3.1.3 hoist-non-react-statics: ^3.3.2 @@ -11124,19 +11124,19 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 5e436a8a22ae9a2e6fcb63ead3a6eff2092cc9731fce0b22d04ab9c67639a173a0e27fb617628e7720592862118a32248be458bedfabaf1de5448543a97b0307 + checksum: bdc19d66caf3fb3272dd1c67d6a40b0e77bca2c3c7a5b9112ebed2cf3d6795932401bcb9ddfb9daba9c3e293455cf9cb2c24975eff15c75a2ce3d40ed30d59d7 languageName: node linkType: hard -"@mui/system@npm:^5.15.15": - version: 5.15.15 - resolution: "@mui/system@npm:5.15.15" +"@mui/system@npm:^5.15.20": + version: 5.15.20 + resolution: "@mui/system@npm:5.15.20" dependencies: "@babel/runtime": ^7.23.9 - "@mui/private-theming": ^5.15.14 + "@mui/private-theming": ^5.15.20 "@mui/styled-engine": ^5.15.14 "@mui/types": ^7.2.14 - "@mui/utils": ^5.15.14 + "@mui/utils": ^5.15.20 clsx: ^2.1.0 csstype: ^3.1.3 prop-types: ^15.8.1 @@ -11152,7 +11152,7 @@ __metadata: optional: true "@types/react": optional: true - checksum: 9ca96d5f66b2a9d6471909cc98c671eea5ec0a6d58a7ec071073b9e5200b95c3f017f0ca5cc946abc7f83074bd11830ca18f5e30bc98e25cd6ca217bd1b3a26f + checksum: e9e79b6a905845aef87939de8ac7990d73a2f92bba02e41905dcb9f44e53727bdfa52a978cf59a2a2cfa73d2512df78c4351eb130d7c25af1880bb8b7ebfc686 languageName: node linkType: hard @@ -11168,9 +11168,9 @@ __metadata: languageName: node linkType: hard -"@mui/utils@npm:^5.14.15, @mui/utils@npm:^5.15.14": - version: 5.15.14 - resolution: "@mui/utils@npm:5.15.14" +"@mui/utils@npm:^5.14.15, @mui/utils@npm:^5.15.14, @mui/utils@npm:^5.15.20": + version: 5.15.20 + resolution: "@mui/utils@npm:5.15.20" dependencies: "@babel/runtime": ^7.23.9 "@types/prop-types": ^15.7.11 @@ -11182,7 +11182,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 36543ba7e3b65fb3219ed27e8f1455aff15b47a74c9b642c63e60774e22baa6492a196079e72bcfa5a570421dab32160398f892110bd444428bcf8b266b11893 + checksum: 8f8c7f9129e0eb1bf55c1d675c647da1fa4acf1c7f50e0ce2ce750cc0603e62fdc21b76e8ef8ff9bf06bce054e9cf97210ed737f55887b0ef939bd6605b4e537 languageName: node linkType: hard From 0568962439c3a91f1d1d43c53cd2302496d507a4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Jun 2024 22:50:31 +0000 Subject: [PATCH 026/510] chore(deps): update alpine docker tag to v3.20 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- plugins/scaffolder-backend/scripts/Cookiecutter.dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/scaffolder-backend/scripts/Cookiecutter.dockerfile b/plugins/scaffolder-backend/scripts/Cookiecutter.dockerfile index ecaefee183..0c8b305de5 100644 --- a/plugins/scaffolder-backend/scripts/Cookiecutter.dockerfile +++ b/plugins/scaffolder-backend/scripts/Cookiecutter.dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.19 +FROM alpine:3.20 RUN apk add --update \ git \ From 605b6916cf153ea41106e3a09ef4b33fd42abc4f Mon Sep 17 00:00:00 2001 From: "Stephen A. Wilson" Date: Thu, 13 Jun 2024 10:58:22 -0400 Subject: [PATCH 027/510] Allow for searching TechDocs by Title Signed-off-by: Stephen A. Wilson --- .changeset/fuzzy-socks-do.md | 6 + app-config.yaml | 3 + .../catalog-info.yaml | 12 ++ .../docs/code/code-sample.md | 31 +++++ .../docs/extensions.md | 112 ++++++++++++++++++ .../docs/images/backstage-logo-cncf.svg | 1 + .../docs/index.md | 55 +++++++++ .../docs/sub-page.md | 12 ++ .../mkdocs.yml | 12 ++ .../src/home/components/Tables/DocsTable.tsx | 1 + .../src/home/components/Tables/columns.tsx | 34 +++++- 11 files changed, 274 insertions(+), 5 deletions(-) create mode 100644 .changeset/fuzzy-socks-do.md create mode 100644 plugins/techdocs-backend/examples/documented-component-with-title/catalog-info.yaml create mode 100644 plugins/techdocs-backend/examples/documented-component-with-title/docs/code/code-sample.md create mode 100644 plugins/techdocs-backend/examples/documented-component-with-title/docs/extensions.md create mode 100644 plugins/techdocs-backend/examples/documented-component-with-title/docs/images/backstage-logo-cncf.svg create mode 100644 plugins/techdocs-backend/examples/documented-component-with-title/docs/index.md create mode 100644 plugins/techdocs-backend/examples/documented-component-with-title/docs/sub-page.md create mode 100644 plugins/techdocs-backend/examples/documented-component-with-title/mkdocs.yml diff --git a/.changeset/fuzzy-socks-do.md b/.changeset/fuzzy-socks-do.md new file mode 100644 index 0000000000..02d2e4dca9 --- /dev/null +++ b/.changeset/fuzzy-socks-do.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-techdocs-backend': patch +'@backstage/plugin-techdocs': patch +--- + +Allow for searching TechDocs by entity title diff --git a/app-config.yaml b/app-config.yaml index cb70170541..69145cd896 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -297,6 +297,9 @@ catalog: # Example component for TechDocs - type: file target: ../../plugins/techdocs-backend/examples/documented-component/catalog-info.yaml + # Example component for TechDocs with a title + - type: file + target: ../../plugins/techdocs-backend/examples/documented-component-with-title/catalog-info.yaml # Example component for ADRs - type: file target: ../../plugins/adr/examples/component/catalog-info.yaml diff --git a/plugins/techdocs-backend/examples/documented-component-with-title/catalog-info.yaml b/plugins/techdocs-backend/examples/documented-component-with-title/catalog-info.yaml new file mode 100644 index 0000000000..1a1d65ba39 --- /dev/null +++ b/plugins/techdocs-backend/examples/documented-component-with-title/catalog-info.yaml @@ -0,0 +1,12 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: documented-with-title + title: Fizzbuzz Docs + description: A TechDocs with a title different than it's name + annotations: + backstage.io/techdocs-ref: dir:. +spec: + type: service + lifecycle: experimental + owner: user:guest diff --git a/plugins/techdocs-backend/examples/documented-component-with-title/docs/code/code-sample.md b/plugins/techdocs-backend/examples/documented-component-with-title/docs/code/code-sample.md new file mode 100644 index 0000000000..f41ab1d506 --- /dev/null +++ b/plugins/techdocs-backend/examples/documented-component-with-title/docs/code/code-sample.md @@ -0,0 +1,31 @@ +# Sample Code + +This page provides some sample code which may be used in your example component. + +This code uses TypeScript, and the Markdown code fence to wrap the code. + +```typescript +const serviceEntityPage = ( + + + + + + + + + + + + +); +``` + +Here is an example of Python code: + +```python +def getUsersInGroup(targetGroup, secure=False): + + if __debug__: + print('targetGroup=[' + targetGroup + ']') +``` diff --git a/plugins/techdocs-backend/examples/documented-component-with-title/docs/extensions.md b/plugins/techdocs-backend/examples/documented-component-with-title/docs/extensions.md new file mode 100644 index 0000000000..eb9abca74a --- /dev/null +++ b/plugins/techdocs-backend/examples/documented-component-with-title/docs/extensions.md @@ -0,0 +1,112 @@ +# Plugins & Extensions + +Just by including the TechDocs Core Plugin to your MkDocs site included with Backstage, +you gain the immediate use of a variety of popular plugins and extensions to MkDocs. + +For more information and full details of the available features, see the +[`mkdocs-techdocs-core` repository](https://github.com/backstage/mkdocs-techdocs-core#mkdocs-plugins-and-extensions). + +This page provides a demonstration of some of the available features. + +## Admonitions + +Admonitions are call outs that help catch a users attention. + +To define an admonition simply put the following Markdown into your content: + +``` +!!! warn + Defining admonitions can be addicting. +``` + +And they end up looking like this: + + +!!! warn + Defining admonitions can be addicting. + + +!!! note + You can learn a lot about TechDocs by just visiting the Backstage web site at + https://backstage.io/docs. + + +!!! info + TechDocs is the core feature that supports documentation as code in Backstage. + + +!!! tip + Don't forget to spell check your documentation. + +## PlantUML + +You can create dynamic UML diagrams on the fly by just specifying flow via text, +using [PlantUML](https://pypi.org/project/plantuml-markdown/). + +```plantuml format="svg" classes="uml myDiagram" alt="Backstage sample PlantUML" title="Backstage sample PlantUML" width="500px" height="250px" +User -> SCMProvider: stores +TechDocs -> SCMProvider: prepares +TechDocs -> TechDocs: generates +TechDocs -> CloudStorage: publishes +CloudStorage -> Backstage: displays +``` + +## Pymdownx Extensions + +Pymdownx (Python Markdown extensions) are a variety of smaller additions. + +### Details + + +??? note "What is the answer to life, the universe, and everything? (click me for the answer)" + The answer is 42. + + +??? note "What is 4 plus 4?" + The answer is 8. + + +???+ note "How do I get support?" + You can get support by opening an issue in this repository. This detail is open by default + so it's more easily visible without requiring the user to click to open it. + +### Task Lists + +Automatic rendering of Markdown task lists. + +- [x] Phase 1 +- [x] Phase 2 +- [ ] Phase 3 + +### Emojis + +Very nice job on documentation! :thumbsup: + +I've read a lot of documentation, but I love :heart: this document. + +Weather: :sunny: :umbrella: :cloud: :snowflake: + +Animals: :tiger: :horse: :turtle: :wolf: :frog: + +### Attributes + +[A Download Link](./images/backstage-logo-cncf.svg){: download } + +![A Scaled Image](./images/backstage-logo-cncf.svg){: style="width: 100px" } + +### MDX truly sane lists + +- `attributes` + +- `customer` + - `first_name` + - `test` + - `family_name` + - `email` +- `person` + - `first_name` + - `family_name` + - `birth_date` +- `subscription_id` + +- `request` diff --git a/plugins/techdocs-backend/examples/documented-component-with-title/docs/images/backstage-logo-cncf.svg b/plugins/techdocs-backend/examples/documented-component-with-title/docs/images/backstage-logo-cncf.svg new file mode 100644 index 0000000000..b5ff591d1b --- /dev/null +++ b/plugins/techdocs-backend/examples/documented-component-with-title/docs/images/backstage-logo-cncf.svg @@ -0,0 +1 @@ +05 Logo_Black \ No newline at end of file diff --git a/plugins/techdocs-backend/examples/documented-component-with-title/docs/index.md b/plugins/techdocs-backend/examples/documented-component-with-title/docs/index.md new file mode 100644 index 0000000000..6295a69406 --- /dev/null +++ b/plugins/techdocs-backend/examples/documented-component-with-title/docs/index.md @@ -0,0 +1,55 @@ +# Welcome! + +This is a basic example of documentation. It is intended as a showcase of some of the +features that TechDocs provides out of the box. + +You can see also: + +- [A sub page](sub-page.md) +- [Inline code examples](code/code-sample.md) +- [Plugin & Extension examples](extensions.md) - Diagrams, emojis, visual formatting. + +## Basic Markdown + +Headings: + +# h1 + +## h2 + +### h3 + +#### h4 + +##### h5 + +###### h6 + +Here is a bulleted list: + +- Item one +- Item two +- Item Three + +Check out the [Markdown Guide](https://www.markdownguide.org/) to learn more about how to +simply create documentation. + +You can also learn more about how to configure and setup this documentation in Backstage, +[read up on the TechDocs Overview](https://backstage.io/docs/features/techdocs/). + +## Image Example + +This documentation is powered by Backstage's TechDocs feature: + +![Backstage Logo](images/backstage-logo-cncf.svg) + +## Table Example + +While this documentation isn't comprehensive, in the future it should cover the following +topics outlined in this example table: + +| Topic | Description | +| ------- | ------------------------------------------------------------ | +| Topic 1 | An introductory topic to help you learn about the component. | +| Topic 2 | A more detailed topic that explains more information. | +| Topic 3 | A final topic that provides conclusions and lessons learned. | diff --git a/plugins/techdocs-backend/examples/documented-component-with-title/docs/sub-page.md b/plugins/techdocs-backend/examples/documented-component-with-title/docs/sub-page.md new file mode 100644 index 0000000000..987f5e8a95 --- /dev/null +++ b/plugins/techdocs-backend/examples/documented-component-with-title/docs/sub-page.md @@ -0,0 +1,12 @@ +# Another page in our documentation + +This sub-page can be used to elaborate on a specific part of the component. + +## Details + +It is linked off the main page, and due to its inclusion in the `mkdocs.yml` file, +becomes part of the auto-generated site navigation. + +## MkDocs + +Visit https://www.mkdocs.org for more information about the MkDocs tool. diff --git a/plugins/techdocs-backend/examples/documented-component-with-title/mkdocs.yml b/plugins/techdocs-backend/examples/documented-component-with-title/mkdocs.yml new file mode 100644 index 0000000000..1a159a4d12 --- /dev/null +++ b/plugins/techdocs-backend/examples/documented-component-with-title/mkdocs.yml @@ -0,0 +1,12 @@ +site_name: 'Example Documentation' +repo_url: https://github.com/backstage/backstage +edit_uri: edit/master/plugins/techdocs-backend/examples/documented-component/docs + +nav: + - Home: index.md + - Subpage: sub-page.md + - 'Code Sample': code/code-sample.md + - Extensions: extensions.md + +plugins: + - techdocs-core diff --git a/plugins/techdocs/src/home/components/Tables/DocsTable.tsx b/plugins/techdocs/src/home/components/Tables/DocsTable.tsx index c0b39878cd..59abd9b278 100644 --- a/plugins/techdocs/src/home/components/Tables/DocsTable.tsx +++ b/plugins/techdocs/src/home/components/Tables/DocsTable.tsx @@ -85,6 +85,7 @@ export const DocsTable = (props: DocsTableProps) => { }); const defaultColumns: TableColumn[] = [ + columnFactories.createTitleColumn({ hidden: true }), columnFactories.createNameColumn(), columnFactories.createOwnerColumn(), columnFactories.createKindColumn(), diff --git a/plugins/techdocs/src/home/components/Tables/columns.tsx b/plugins/techdocs/src/home/components/Tables/columns.tsx index bc85bb7a63..3deb4d9b33 100644 --- a/plugins/techdocs/src/home/components/Tables/columns.tsx +++ b/plugins/techdocs/src/home/components/Tables/columns.tsx @@ -24,17 +24,20 @@ function customTitle(entity: Entity): string { return entity.metadata.title || entity.metadata.name; } +type ColumnOptions = Partial>; + /** * Not directly exported, but through DocsTable.columns and EntityListDocsTable.columns * * @public */ export const columnFactories = { - createNameColumn(): TableColumn { + createTitleColumn(overrides: ColumnOptions = {}): TableColumn { return { title: 'Document', - field: 'entity.metadata.name', + field: 'entity.metadata.title', highlight: true, + searchable: true, render: (row: DocsTableRow) => ( ), + ...overrides, }; }, - createOwnerColumn(): TableColumn { + createNameColumn(overrides: ColumnOptions = {}): TableColumn { + return { + title: 'Document', + field: 'entity.metadata.name', + highlight: true, + searchable: true, + render: (row: DocsTableRow) => ( + {customTitle(row.entity)} + } + subvalue={row.entity.metadata.description} + /> + ), + ...overrides, + }; + }, + createOwnerColumn(overrides: ColumnOptions = {}): TableColumn { return { title: 'Owner', field: 'resolved.ownedByRelationsTitle', @@ -55,18 +76,21 @@ export const columnFactories = { defaultKind="group" /> ), + ...overrides, }; }, - createKindColumn(): TableColumn { + createKindColumn(overrides: ColumnOptions = {}): TableColumn { return { title: 'Kind', field: 'entity.kind', + ...overrides, }; }, - createTypeColumn(): TableColumn { + createTypeColumn(overrides: ColumnOptions = {}): TableColumn { return { title: 'Type', field: 'entity.spec.type', + ...overrides, }; }, }; From edcd757d14708cb8de75278dd28a7d9c68a6dbe0 Mon Sep 17 00:00:00 2001 From: "Stephen A. Wilson" Date: Thu, 13 Jun 2024 11:13:36 -0400 Subject: [PATCH 028/510] remove techdocs-backend from changeset Signed-off-by: Stephen A. Wilson --- .changeset/fuzzy-socks-do.md | 1 - 1 file changed, 1 deletion(-) diff --git a/.changeset/fuzzy-socks-do.md b/.changeset/fuzzy-socks-do.md index 02d2e4dca9..aabc10f0cd 100644 --- a/.changeset/fuzzy-socks-do.md +++ b/.changeset/fuzzy-socks-do.md @@ -1,5 +1,4 @@ --- -'@backstage/plugin-techdocs-backend': patch '@backstage/plugin-techdocs': patch --- From e9551a759824d57c4c8a62dd832de4e65e27d253 Mon Sep 17 00:00:00 2001 From: "Stephen A. Wilson" Date: Thu, 13 Jun 2024 13:05:09 -0400 Subject: [PATCH 029/510] revert changes to match prior work in CatalogTable Signed-off-by: Stephen A. Wilson --- plugins/techdocs/api-report.md | 14 ++++++++++++++ .../src/home/components/Tables/columns.tsx | 18 ++++++------------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/plugins/techdocs/api-report.md b/plugins/techdocs/api-report.md index ebd6adcd3c..90834c6fcb 100644 --- a/plugins/techdocs/api-report.md +++ b/plugins/techdocs/api-report.md @@ -78,6 +78,13 @@ export type DocsGroupConfig = { export const DocsTable: { (props: DocsTableProps): React_2.JSX.Element | null; columns: { + createTitleColumn( + options?: + | { + hidden?: boolean | undefined; + } + | undefined, + ): TableColumn; createNameColumn(): TableColumn; createOwnerColumn(): TableColumn; createKindColumn(): TableColumn; @@ -142,6 +149,13 @@ export type EntityListDocsGridPageProps = { export const EntityListDocsTable: { (props: EntityListDocsTableProps): React_2.JSX.Element; columns: { + createTitleColumn( + options?: + | { + hidden?: boolean | undefined; + } + | undefined, + ): TableColumn; createNameColumn(): TableColumn; createOwnerColumn(): TableColumn; createKindColumn(): TableColumn; diff --git a/plugins/techdocs/src/home/components/Tables/columns.tsx b/plugins/techdocs/src/home/components/Tables/columns.tsx index 3deb4d9b33..b9d22705d3 100644 --- a/plugins/techdocs/src/home/components/Tables/columns.tsx +++ b/plugins/techdocs/src/home/components/Tables/columns.tsx @@ -24,18 +24,17 @@ function customTitle(entity: Entity): string { return entity.metadata.title || entity.metadata.name; } -type ColumnOptions = Partial>; - /** * Not directly exported, but through DocsTable.columns and EntityListDocsTable.columns * * @public */ export const columnFactories = { - createTitleColumn(overrides: ColumnOptions = {}): TableColumn { + createTitleColumn(options?: { hidden?: boolean }): TableColumn { return { title: 'Document', field: 'entity.metadata.title', + hidden: options?.hidden, highlight: true, searchable: true, render: (row: DocsTableRow) => ( @@ -46,10 +45,9 @@ export const columnFactories = { subvalue={row.entity.metadata.description} /> ), - ...overrides, }; }, - createNameColumn(overrides: ColumnOptions = {}): TableColumn { + createNameColumn(): TableColumn { return { title: 'Document', field: 'entity.metadata.name', @@ -63,10 +61,9 @@ export const columnFactories = { subvalue={row.entity.metadata.description} /> ), - ...overrides, }; }, - createOwnerColumn(overrides: ColumnOptions = {}): TableColumn { + createOwnerColumn(): TableColumn { return { title: 'Owner', field: 'resolved.ownedByRelationsTitle', @@ -76,21 +73,18 @@ export const columnFactories = { defaultKind="group" /> ), - ...overrides, }; }, - createKindColumn(overrides: ColumnOptions = {}): TableColumn { + createKindColumn(): TableColumn { return { title: 'Kind', field: 'entity.kind', - ...overrides, }; }, - createTypeColumn(overrides: ColumnOptions = {}): TableColumn { + createTypeColumn(): TableColumn { return { title: 'Type', field: 'entity.spec.type', - ...overrides, }; }, }; From cc183007ea0a2df88750d404df6c3cb6b41816b7 Mon Sep 17 00:00:00 2001 From: John Philip Date: Fri, 14 Jun 2024 17:49:47 -0400 Subject: [PATCH 030/510] Update techdocs.ts container image Signed-off-by: John Philip --- plugins/techdocs-node/src/stages/generate/techdocs.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/techdocs-node/src/stages/generate/techdocs.ts b/plugins/techdocs-node/src/stages/generate/techdocs.ts index c5130a3f8f..a5bd0fea09 100644 --- a/plugins/techdocs-node/src/stages/generate/techdocs.ts +++ b/plugins/techdocs-node/src/stages/generate/techdocs.ts @@ -53,7 +53,7 @@ export class TechdocsGenerator implements GeneratorBase { * The default docker image (and version) used to generate content. Public * and static so that techdocs-node consumers can use the same version. */ - public static readonly defaultDockerImage = 'spotify/techdocs:v1.2.3'; + public static readonly defaultDockerImage = 'spotify/techdocs:v1.2.4'; private readonly logger: Logger; private readonly containerRunner?: ContainerRunner; private readonly options: GeneratorConfig; From a5576b2f024761f714886fed15d89e07da7724ad Mon Sep 17 00:00:00 2001 From: Jente Sondervorst Date: Sat, 15 Jun 2024 22:41:39 +0200 Subject: [PATCH 031/510] Added support for only users or only groups and multiple users or multiple groups bindings Closes: #25256 Signed-off-by: Jente Sondervorst --- .changeset/friendly-bulldogs-pay.md | 5 + .../src/ldap/config.test.ts | 68 ++++++++-- .../src/ldap/config.ts | 78 +++++++++--- .../src/ldap/read.test.ts | 118 +++++++++++++++++- .../src/ldap/read.ts | 86 +++++++------ 5 files changed, 298 insertions(+), 57 deletions(-) create mode 100644 .changeset/friendly-bulldogs-pay.md diff --git a/.changeset/friendly-bulldogs-pay.md b/.changeset/friendly-bulldogs-pay.md new file mode 100644 index 0000000000..9c7ab8f9cb --- /dev/null +++ b/.changeset/friendly-bulldogs-pay.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-ldap': minor +--- + +Added support for single ldap catalog provider to provide list and undefined user and group bindings next to standard single one. diff --git a/plugins/catalog-backend-module-ldap/src/ldap/config.test.ts b/plugins/catalog-backend-module-ldap/src/ldap/config.test.ts index ddea9de03f..8cd41e0b70 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/config.test.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/config.test.ts @@ -15,7 +15,7 @@ */ import { ConfigReader } from '@backstage/config'; -import { readProviderConfigs } from './config'; +import { readProviderConfigs, UserConfig } from './config'; describe('readLdapConfig', () => { it('applies all of the defaults', () => { @@ -247,7 +247,7 @@ describe('readLdapConfig', () => { const actual = readProviderConfigs(new ConfigReader(config)); const expected = '(|(cn=foo bar)(cn=bar))'; - expect(actual[0].users.options.filter).toEqual(expected); + expect((actual[0].users!! as UserConfig).options.filter).toEqual(expected); }); it('supports a dot nested set structure', () => { @@ -284,7 +284,9 @@ describe('readLdapConfig', () => { }; const actual = readProviderConfigs(new ConfigReader(config)); - expect(actual[0].users.set).toEqual({ 'metadata.annotations': { a: 'b' } }); + expect((actual[0].users!! as UserConfig).set).toEqual({ + 'metadata.annotations': { a: 'b' }, + }); }); it('throws on attempts to modify the set structure', () => { @@ -320,25 +322,77 @@ describe('readLdapConfig', () => { const actual = readProviderConfigs(new ConfigReader(config)); expect(() => { - (actual[0].users.set as any).y = 2; + ((actual[0].users!! as UserConfig).set as any).y = 2; }).toThrowErrorMatchingInlineSnapshot( `"Cannot add property y, object is not extensible"`, ); expect(() => { - (actual[0].users.set as any).x.b = 2; + ((actual[0].users!! as UserConfig).set as any).x.b = 2; }).toThrowErrorMatchingInlineSnapshot( `"Cannot add property b, object is not extensible"`, ); expect(() => { - (actual[0].groups.set as any).y = 2; + ((actual[0].users!! as UserConfig).set as any).y = 2; }).toThrowErrorMatchingInlineSnapshot( `"Cannot add property y, object is not extensible"`, ); expect(() => { - (actual[0].groups.set as any).x.b = 2; + ((actual[0].users!! as UserConfig).set as any).x.b = 2; }).toThrowErrorMatchingInlineSnapshot( `"Cannot add property b, object is not extensible"`, ); }); + + it('supports users/groups config as list', () => { + const config = { + catalog: { + providers: { + ldapOrg: { + default: { + target: 'target', + users: [ + { + dn: 'udn1', + }, + { + dn: 'udn2', + }, + ], + groups: [ + { + dn: 'gdn1', + }, + { + dn: 'gdn2', + }, + ], + }, + }, + }, + }, + }; + const actual = readProviderConfigs(new ConfigReader(config)); + + expect(actual[0].users).toHaveLength(2); + expect(actual[0].groups).toHaveLength(2); + }); + + it('supports users/groups config as undefined', () => { + const config = { + catalog: { + providers: { + ldapOrg: { + default: { + target: 'target', + }, + }, + }, + }, + }; + const actual = readProviderConfigs(new ConfigReader(config)); + + expect(actual[0].users).toBeUndefined(); + expect(actual[0].groups).toBeUndefined(); + }); }); diff --git a/plugins/catalog-backend-module-ldap/src/ldap/config.ts b/plugins/catalog-backend-module-ldap/src/ldap/config.ts index 2bd21fd166..7a5b2828e2 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/config.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/config.ts @@ -42,9 +42,9 @@ export type LdapProviderConfig = { // command is not issued. bind?: BindConfig; // The settings that govern the reading and interpretation of users - users: UserConfig; + users: UserConfigList; // The settings that govern the reading and interpretation of groups - groups: GroupConfig; + groups: GroupConfigList; // Schedule configuration for refresh tasks. schedule?: TaskScheduleDefinition; }; @@ -81,6 +81,8 @@ export type BindConfig = { * * @public */ +export type UserConfigList = UserConfig | UserConfig[] | undefined; + export type UserConfig = { // The DN under which users are stored. dn: string; @@ -121,6 +123,8 @@ export type UserConfig = { * * @public */ +export type GroupConfigList = GroupConfig | GroupConfig[] | undefined; + export type GroupConfig = { // The DN under which groups are stored. dn: string; @@ -272,9 +276,7 @@ function readSetConfig( return c.get(); } -function readUserMapConfig( - c: Config | undefined, -): Partial { +function readUserMapConfig(c: Config | undefined): Partial { if (!c) { return {}; } @@ -292,7 +294,7 @@ function readUserMapConfig( function readGroupMapConfig( c: Config | undefined, -): Partial { +): Partial { if (!c) { return {}; } @@ -311,8 +313,21 @@ function readGroupMapConfig( } function readUserConfig( - c: Config, + c: Config | Config[] | undefined, ): RecursivePartial { + if (!c) { + return undefined; + } + if (Array.isArray(c)) { + return c.map(it => { + return { + dn: it.getString('dn'), + options: readOptionsConfig(it.getOptionalConfig('options')), + set: readSetConfig(it.getOptionalConfig('set')), + map: readUserMapConfig(it.getOptionalConfig('map')), + }; + }); + } return { dn: c.getString('dn'), options: readOptionsConfig(c.getOptionalConfig('options')), @@ -322,8 +337,21 @@ function readUserConfig( } function readGroupConfig( - c: Config, + c: Config | Config[] | undefined, ): RecursivePartial { + if (!c) { + return undefined; + } + if (Array.isArray(c)) { + return c.map(it => { + return { + dn: it.getString('dn'), + options: readOptionsConfig(it.getOptionalConfig('options')), + set: readSetConfig(it.getOptionalConfig('set')), + map: readGroupMapConfig(it.getOptionalConfig('map')), + }; + }); + } return { dn: c.getString('dn'), options: readOptionsConfig(c.getOptionalConfig('options')), @@ -383,19 +411,41 @@ export function readProviderConfigs(config: Config): LdapProviderConfig[] { ? readTaskScheduleDefinitionFromConfig(c.getConfig('schedule')) : undefined; + const isUserList = Array.isArray(c.getOptional('users')); + const isGroupList = Array.isArray(c.getOptional('groups')); + const newConfig = { id, target: trimEnd(c.getString('target'), '/'), tls: readTlsConfig(c.getOptionalConfig('tls')), bind: readBindConfig(c.getOptionalConfig('bind')), - users: readUserConfig(c.getConfig('users')), - groups: readGroupConfig(c.getConfig('groups')), + users: readUserConfig( + isUserList + ? c.getOptionalConfigArray('users') + : c.getOptionalConfig('users'), + ), + groups: readGroupConfig( + isGroupList + ? c.getOptionalConfigArray('groups') + : c.getOptionalConfig('groups'), + ), schedule, }; - const merged = mergeWith({}, defaultConfig, newConfig, (_into, from) => { - // Replace arrays instead of merging, otherwise default behavior - return Array.isArray(from) ? from : undefined; - }); + + const merged = mergeWith( + {}, + defaultConfig, + newConfig, + (_value, srcValue, key, object, _source) => { + // Remove users and groups from default if they are not set in the new config + if ((key === 'users' || key === 'groups') && !srcValue) { + return (object[key] = srcValue); + } + // Replace arrays instead of merging, otherwise default behavior + return Array.isArray(srcValue) ? srcValue : undefined; + }, + ); + return freeze(merged) as LdapProviderConfig; }); } diff --git a/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts b/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts index fc451fde97..33c52477aa 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts @@ -18,7 +18,12 @@ import { GroupEntity, UserEntity } from '@backstage/catalog-model'; import { SearchEntry } from 'ldapjs'; import merge from 'lodash/merge'; import { LdapClient } from './client'; -import { GroupConfig, UserConfig } from './config'; +import { + GroupConfig, + GroupConfigList, + UserConfig, + UserConfigList, +} from './config'; import { LDAP_DN_ANNOTATION, LDAP_RDN_ANNOTATION, @@ -255,6 +260,58 @@ describe('readLdapUsers', () => { new Map([['dn-value', new Set(['x', 'y', 'z'])]]), ); }); + it('can process a list of UserConfigs', async () => { + client.getVendor.mockResolvedValue(DefaultLdapVendor); + client.searchStreaming.mockImplementation(async (_dn, _opts, fn) => { + await fn( + searchEntry({ + uid: ['uid-value'], + description: ['description-value'], + cn: ['cn-value'], + mail: ['mail-value'], + avatarUrl: ['avatarUrl-value'], + memberOf: ['x', 'y', 'z'], + entryDN: ['dn-value'], + entryUUID: ['uuid-value'], + }), + ); + }); + const config: UserConfigList = [ + { + dn: 'ddd', + options: {}, + map: { + rdn: 'uid', + name: 'uid', + description: 'description', + displayName: 'cn', + email: 'mail', + picture: 'avatarUrl', + memberOf: 'memberOf', + }, + }, + { + dn: 'ddd', + options: {}, + map: { + rdn: 'uid', + name: 'uid', + description: 'description', + displayName: 'cn', + email: 'mail', + picture: 'avatarUrl', + memberOf: 'memberOf', + }, + }, + ]; + const { users } = await readLdapUsers(client, config); + expect(users).toHaveLength(2); + }); + it('can process no UserConfigs', async () => { + const config: UserConfigList = undefined; + const { users } = await readLdapUsers(client, config); + expect(users).toHaveLength(0); + }); }); describe('readLdapGroups', () => { @@ -401,6 +458,65 @@ describe('readLdapGroups', () => { new Map([['dn-value', new Set(['x', 'y', 'z'])]]), ); }); + + it('can process a list of GroupConfigs', async () => { + client.getVendor.mockResolvedValue(DefaultLdapVendor); + client.searchStreaming.mockImplementation(async (_dn, _opts, fn) => { + await fn( + searchEntry({ + cn: ['cn-value'], + description: ['description-value'], + tt: ['type-value'], + mail: ['mail-value'], + avatarUrl: ['avatarUrl-value'], + memberOf: ['x', 'y', 'z'], + member: ['e', 'f', 'g'], + entryDN: ['dn-value'], + entryUUID: ['uuid-value'], + }), + ); + }); + const config: GroupConfigList = [ + { + dn: 'ddd', + options: {}, + map: { + rdn: 'cn', + name: 'cn', + description: 'description', + displayName: 'cn', + email: 'mail', + picture: 'avatarUrl', + type: 'tt', + memberOf: 'memberOf', + members: 'member', + }, + }, + { + dn: 'ddd', + options: {}, + map: { + rdn: 'cn', + name: 'cn', + description: 'description', + displayName: 'cn', + email: 'mail', + picture: 'avatarUrl', + type: 'tt', + memberOf: 'memberOf', + members: 'member', + }, + }, + ]; + const { groups } = await readLdapGroups(client, config); + expect(groups).toHaveLength(2); + }); + + it('can process no GroupConfigs', async () => { + const config: GroupConfigList = undefined; + const { groups } = await readLdapGroups(client, config); + expect(groups).toHaveLength(0); + }); }); describe('resolveRelations', () => { diff --git a/plugins/catalog-backend-module-ldap/src/ldap/read.ts b/plugins/catalog-backend-module-ldap/src/ldap/read.ts index 50036b94b0..5dadcaede2 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/read.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/read.ts @@ -24,7 +24,12 @@ import lodashSet from 'lodash/set'; import cloneDeep from 'lodash/cloneDeep'; import { buildOrgHierarchy } from './org'; import { LdapClient } from './client'; -import { GroupConfig, UserConfig } from './config'; +import { + GroupConfig, + GroupConfigList, + UserConfig, + UserConfigList, +} from './config'; import { LDAP_DN_ANNOTATION, LDAP_RDN_ANNOTATION, @@ -104,32 +109,37 @@ export async function defaultUserTransformer( */ export async function readLdapUsers( client: LdapClient, - config: UserConfig, + config: UserConfigList, opts?: { transformer?: UserTransformer }, ): Promise<{ users: UserEntity[]; // With all relations empty userMemberOf: Map>; // DN -> DN or UUID of groups }> { - const { dn, options, map } = config; - const vendor = await client.getVendor(); - + if (!config) { + return { users: [], userMemberOf: new Map() }; + } + const configs = Array.isArray(config) ? config : [config]; const entities: UserEntity[] = []; const userMemberOf: Map> = new Map(); + const vendor = await client.getVendor(); const transformer = opts?.transformer ?? defaultUserTransformer; - await client.searchStreaming(dn, options, async user => { - const entity = await transformer(vendor, config, user); + for (const cfg of configs) { + const { dn, options, map } = cfg; + await client.searchStreaming(dn, options, async user => { + const entity = await transformer(vendor, cfg, user); - if (!entity) { - return; - } + if (!entity) { + return; + } - mapReferencesAttr(user, vendor, map.memberOf, (myDn, vs) => { - ensureItems(userMemberOf, myDn, vs); + mapReferencesAttr(user, vendor, map.memberOf, (myDn, vs) => { + ensureItems(userMemberOf, myDn, vs); + }); + entities.push(entity); }); - entities.push(entity); - }); + } return { users: entities, userMemberOf }; } @@ -206,7 +216,7 @@ export async function defaultGroupTransformer( */ export async function readLdapGroups( client: LdapClient, - config: GroupConfig, + config: GroupConfigList, opts?: { transformer?: GroupTransformer; }, @@ -215,35 +225,41 @@ export async function readLdapGroups( groupMemberOf: Map>; // DN -> DN or UUID of groups groupMember: Map>; // DN -> DN or UUID of groups & users }> { + if (!config) { + return { groups: [], groupMemberOf: new Map(), groupMember: new Map() }; + } + const configs = Array.isArray(config) ? config : [config]; const groups: GroupEntity[] = []; const groupMemberOf: Map> = new Map(); const groupMember: Map> = new Map(); - const { dn, map, options } = config; const vendor = await client.getVendor(); - const transformer = opts?.transformer ?? defaultGroupTransformer; - await client.searchStreaming(dn, options, async entry => { - if (!entry) { - return; - } + for (const cfg of configs) { + const { dn, map, options } = cfg; - const entity = await transformer(vendor, config, entry); + await client.searchStreaming(dn, options, async entry => { + if (!entry) { + return; + } - if (!entity) { - return; - } + const entity = await transformer(vendor, cfg, entry); - mapReferencesAttr(entry, vendor, map.memberOf, (myDn, vs) => { - ensureItems(groupMemberOf, myDn, vs); + if (!entity) { + return; + } + + mapReferencesAttr(entry, vendor, map.memberOf, (myDn, vs) => { + ensureItems(groupMemberOf, myDn, vs); + }); + mapReferencesAttr(entry, vendor, map.members, (myDn, vs) => { + ensureItems(groupMember, myDn, vs); + }); + + groups.push(entity); }); - mapReferencesAttr(entry, vendor, map.members, (myDn, vs) => { - ensureItems(groupMember, myDn, vs); - }); - - groups.push(entity); - }); + } return { groups, @@ -264,8 +280,8 @@ export async function readLdapGroups( */ export async function readLdapOrg( client: LdapClient, - userConfig: UserConfig, - groupConfig: GroupConfig, + userConfig: UserConfigList, + groupConfig: GroupConfigList, options: { groupTransformer?: GroupTransformer; userTransformer?: UserTransformer; From cb32ca7bac6a2023e34ac3c3b87071b9c587825a Mon Sep 17 00:00:00 2001 From: Jente Sondervorst Date: Sat, 15 Jun 2024 22:41:39 +0200 Subject: [PATCH 032/510] Added support for only users or only groups and multiple users or multiple groups bindings Closes: #25256 Signed-off-by: Jente Sondervorst --- .changeset/friendly-bulldogs-pay.md | 5 + docs/integrations/ldap/org.md | 8 ++ .../src/ldap/config.test.ts | 68 ++++++++-- .../src/ldap/config.ts | 78 +++++++++--- .../src/ldap/read.test.ts | 118 +++++++++++++++++- .../src/ldap/read.ts | 86 +++++++------ 6 files changed, 306 insertions(+), 57 deletions(-) create mode 100644 .changeset/friendly-bulldogs-pay.md diff --git a/.changeset/friendly-bulldogs-pay.md b/.changeset/friendly-bulldogs-pay.md new file mode 100644 index 0000000000..9c7ab8f9cb --- /dev/null +++ b/.changeset/friendly-bulldogs-pay.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-ldap': minor +--- + +Added support for single ldap catalog provider to provide list and undefined user and group bindings next to standard single one. diff --git a/docs/integrations/ldap/org.md b/docs/integrations/ldap/org.md index f70d02afed..f839516d9a 100644 --- a/docs/integrations/ldap/org.md +++ b/docs/integrations/ldap/org.md @@ -86,6 +86,14 @@ catalog: These config blocks have a lot of options in them, so we will describe each "root" key within the block separately. +> NOTE: +> +> If you want to import users and groups from different LDAP servers, you can define multiple providers with different names. +> If they should come from the same server, you can define multiple users and groups blocks within the same provider using an array of users / groups. +> Entries coming from the same block will be able to detect group memberships based on the `memberOf` attribute. +> +> If you want only to import users or groups, you can omit the groups or users block. + ### target This is the URL of the targeted server, typically on the form diff --git a/plugins/catalog-backend-module-ldap/src/ldap/config.test.ts b/plugins/catalog-backend-module-ldap/src/ldap/config.test.ts index ddea9de03f..8cd41e0b70 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/config.test.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/config.test.ts @@ -15,7 +15,7 @@ */ import { ConfigReader } from '@backstage/config'; -import { readProviderConfigs } from './config'; +import { readProviderConfigs, UserConfig } from './config'; describe('readLdapConfig', () => { it('applies all of the defaults', () => { @@ -247,7 +247,7 @@ describe('readLdapConfig', () => { const actual = readProviderConfigs(new ConfigReader(config)); const expected = '(|(cn=foo bar)(cn=bar))'; - expect(actual[0].users.options.filter).toEqual(expected); + expect((actual[0].users!! as UserConfig).options.filter).toEqual(expected); }); it('supports a dot nested set structure', () => { @@ -284,7 +284,9 @@ describe('readLdapConfig', () => { }; const actual = readProviderConfigs(new ConfigReader(config)); - expect(actual[0].users.set).toEqual({ 'metadata.annotations': { a: 'b' } }); + expect((actual[0].users!! as UserConfig).set).toEqual({ + 'metadata.annotations': { a: 'b' }, + }); }); it('throws on attempts to modify the set structure', () => { @@ -320,25 +322,77 @@ describe('readLdapConfig', () => { const actual = readProviderConfigs(new ConfigReader(config)); expect(() => { - (actual[0].users.set as any).y = 2; + ((actual[0].users!! as UserConfig).set as any).y = 2; }).toThrowErrorMatchingInlineSnapshot( `"Cannot add property y, object is not extensible"`, ); expect(() => { - (actual[0].users.set as any).x.b = 2; + ((actual[0].users!! as UserConfig).set as any).x.b = 2; }).toThrowErrorMatchingInlineSnapshot( `"Cannot add property b, object is not extensible"`, ); expect(() => { - (actual[0].groups.set as any).y = 2; + ((actual[0].users!! as UserConfig).set as any).y = 2; }).toThrowErrorMatchingInlineSnapshot( `"Cannot add property y, object is not extensible"`, ); expect(() => { - (actual[0].groups.set as any).x.b = 2; + ((actual[0].users!! as UserConfig).set as any).x.b = 2; }).toThrowErrorMatchingInlineSnapshot( `"Cannot add property b, object is not extensible"`, ); }); + + it('supports users/groups config as list', () => { + const config = { + catalog: { + providers: { + ldapOrg: { + default: { + target: 'target', + users: [ + { + dn: 'udn1', + }, + { + dn: 'udn2', + }, + ], + groups: [ + { + dn: 'gdn1', + }, + { + dn: 'gdn2', + }, + ], + }, + }, + }, + }, + }; + const actual = readProviderConfigs(new ConfigReader(config)); + + expect(actual[0].users).toHaveLength(2); + expect(actual[0].groups).toHaveLength(2); + }); + + it('supports users/groups config as undefined', () => { + const config = { + catalog: { + providers: { + ldapOrg: { + default: { + target: 'target', + }, + }, + }, + }, + }; + const actual = readProviderConfigs(new ConfigReader(config)); + + expect(actual[0].users).toBeUndefined(); + expect(actual[0].groups).toBeUndefined(); + }); }); diff --git a/plugins/catalog-backend-module-ldap/src/ldap/config.ts b/plugins/catalog-backend-module-ldap/src/ldap/config.ts index 2bd21fd166..7a5b2828e2 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/config.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/config.ts @@ -42,9 +42,9 @@ export type LdapProviderConfig = { // command is not issued. bind?: BindConfig; // The settings that govern the reading and interpretation of users - users: UserConfig; + users: UserConfigList; // The settings that govern the reading and interpretation of groups - groups: GroupConfig; + groups: GroupConfigList; // Schedule configuration for refresh tasks. schedule?: TaskScheduleDefinition; }; @@ -81,6 +81,8 @@ export type BindConfig = { * * @public */ +export type UserConfigList = UserConfig | UserConfig[] | undefined; + export type UserConfig = { // The DN under which users are stored. dn: string; @@ -121,6 +123,8 @@ export type UserConfig = { * * @public */ +export type GroupConfigList = GroupConfig | GroupConfig[] | undefined; + export type GroupConfig = { // The DN under which groups are stored. dn: string; @@ -272,9 +276,7 @@ function readSetConfig( return c.get(); } -function readUserMapConfig( - c: Config | undefined, -): Partial { +function readUserMapConfig(c: Config | undefined): Partial { if (!c) { return {}; } @@ -292,7 +294,7 @@ function readUserMapConfig( function readGroupMapConfig( c: Config | undefined, -): Partial { +): Partial { if (!c) { return {}; } @@ -311,8 +313,21 @@ function readGroupMapConfig( } function readUserConfig( - c: Config, + c: Config | Config[] | undefined, ): RecursivePartial { + if (!c) { + return undefined; + } + if (Array.isArray(c)) { + return c.map(it => { + return { + dn: it.getString('dn'), + options: readOptionsConfig(it.getOptionalConfig('options')), + set: readSetConfig(it.getOptionalConfig('set')), + map: readUserMapConfig(it.getOptionalConfig('map')), + }; + }); + } return { dn: c.getString('dn'), options: readOptionsConfig(c.getOptionalConfig('options')), @@ -322,8 +337,21 @@ function readUserConfig( } function readGroupConfig( - c: Config, + c: Config | Config[] | undefined, ): RecursivePartial { + if (!c) { + return undefined; + } + if (Array.isArray(c)) { + return c.map(it => { + return { + dn: it.getString('dn'), + options: readOptionsConfig(it.getOptionalConfig('options')), + set: readSetConfig(it.getOptionalConfig('set')), + map: readGroupMapConfig(it.getOptionalConfig('map')), + }; + }); + } return { dn: c.getString('dn'), options: readOptionsConfig(c.getOptionalConfig('options')), @@ -383,19 +411,41 @@ export function readProviderConfigs(config: Config): LdapProviderConfig[] { ? readTaskScheduleDefinitionFromConfig(c.getConfig('schedule')) : undefined; + const isUserList = Array.isArray(c.getOptional('users')); + const isGroupList = Array.isArray(c.getOptional('groups')); + const newConfig = { id, target: trimEnd(c.getString('target'), '/'), tls: readTlsConfig(c.getOptionalConfig('tls')), bind: readBindConfig(c.getOptionalConfig('bind')), - users: readUserConfig(c.getConfig('users')), - groups: readGroupConfig(c.getConfig('groups')), + users: readUserConfig( + isUserList + ? c.getOptionalConfigArray('users') + : c.getOptionalConfig('users'), + ), + groups: readGroupConfig( + isGroupList + ? c.getOptionalConfigArray('groups') + : c.getOptionalConfig('groups'), + ), schedule, }; - const merged = mergeWith({}, defaultConfig, newConfig, (_into, from) => { - // Replace arrays instead of merging, otherwise default behavior - return Array.isArray(from) ? from : undefined; - }); + + const merged = mergeWith( + {}, + defaultConfig, + newConfig, + (_value, srcValue, key, object, _source) => { + // Remove users and groups from default if they are not set in the new config + if ((key === 'users' || key === 'groups') && !srcValue) { + return (object[key] = srcValue); + } + // Replace arrays instead of merging, otherwise default behavior + return Array.isArray(srcValue) ? srcValue : undefined; + }, + ); + return freeze(merged) as LdapProviderConfig; }); } diff --git a/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts b/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts index fc451fde97..33c52477aa 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts @@ -18,7 +18,12 @@ import { GroupEntity, UserEntity } from '@backstage/catalog-model'; import { SearchEntry } from 'ldapjs'; import merge from 'lodash/merge'; import { LdapClient } from './client'; -import { GroupConfig, UserConfig } from './config'; +import { + GroupConfig, + GroupConfigList, + UserConfig, + UserConfigList, +} from './config'; import { LDAP_DN_ANNOTATION, LDAP_RDN_ANNOTATION, @@ -255,6 +260,58 @@ describe('readLdapUsers', () => { new Map([['dn-value', new Set(['x', 'y', 'z'])]]), ); }); + it('can process a list of UserConfigs', async () => { + client.getVendor.mockResolvedValue(DefaultLdapVendor); + client.searchStreaming.mockImplementation(async (_dn, _opts, fn) => { + await fn( + searchEntry({ + uid: ['uid-value'], + description: ['description-value'], + cn: ['cn-value'], + mail: ['mail-value'], + avatarUrl: ['avatarUrl-value'], + memberOf: ['x', 'y', 'z'], + entryDN: ['dn-value'], + entryUUID: ['uuid-value'], + }), + ); + }); + const config: UserConfigList = [ + { + dn: 'ddd', + options: {}, + map: { + rdn: 'uid', + name: 'uid', + description: 'description', + displayName: 'cn', + email: 'mail', + picture: 'avatarUrl', + memberOf: 'memberOf', + }, + }, + { + dn: 'ddd', + options: {}, + map: { + rdn: 'uid', + name: 'uid', + description: 'description', + displayName: 'cn', + email: 'mail', + picture: 'avatarUrl', + memberOf: 'memberOf', + }, + }, + ]; + const { users } = await readLdapUsers(client, config); + expect(users).toHaveLength(2); + }); + it('can process no UserConfigs', async () => { + const config: UserConfigList = undefined; + const { users } = await readLdapUsers(client, config); + expect(users).toHaveLength(0); + }); }); describe('readLdapGroups', () => { @@ -401,6 +458,65 @@ describe('readLdapGroups', () => { new Map([['dn-value', new Set(['x', 'y', 'z'])]]), ); }); + + it('can process a list of GroupConfigs', async () => { + client.getVendor.mockResolvedValue(DefaultLdapVendor); + client.searchStreaming.mockImplementation(async (_dn, _opts, fn) => { + await fn( + searchEntry({ + cn: ['cn-value'], + description: ['description-value'], + tt: ['type-value'], + mail: ['mail-value'], + avatarUrl: ['avatarUrl-value'], + memberOf: ['x', 'y', 'z'], + member: ['e', 'f', 'g'], + entryDN: ['dn-value'], + entryUUID: ['uuid-value'], + }), + ); + }); + const config: GroupConfigList = [ + { + dn: 'ddd', + options: {}, + map: { + rdn: 'cn', + name: 'cn', + description: 'description', + displayName: 'cn', + email: 'mail', + picture: 'avatarUrl', + type: 'tt', + memberOf: 'memberOf', + members: 'member', + }, + }, + { + dn: 'ddd', + options: {}, + map: { + rdn: 'cn', + name: 'cn', + description: 'description', + displayName: 'cn', + email: 'mail', + picture: 'avatarUrl', + type: 'tt', + memberOf: 'memberOf', + members: 'member', + }, + }, + ]; + const { groups } = await readLdapGroups(client, config); + expect(groups).toHaveLength(2); + }); + + it('can process no GroupConfigs', async () => { + const config: GroupConfigList = undefined; + const { groups } = await readLdapGroups(client, config); + expect(groups).toHaveLength(0); + }); }); describe('resolveRelations', () => { diff --git a/plugins/catalog-backend-module-ldap/src/ldap/read.ts b/plugins/catalog-backend-module-ldap/src/ldap/read.ts index 50036b94b0..5dadcaede2 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/read.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/read.ts @@ -24,7 +24,12 @@ import lodashSet from 'lodash/set'; import cloneDeep from 'lodash/cloneDeep'; import { buildOrgHierarchy } from './org'; import { LdapClient } from './client'; -import { GroupConfig, UserConfig } from './config'; +import { + GroupConfig, + GroupConfigList, + UserConfig, + UserConfigList, +} from './config'; import { LDAP_DN_ANNOTATION, LDAP_RDN_ANNOTATION, @@ -104,32 +109,37 @@ export async function defaultUserTransformer( */ export async function readLdapUsers( client: LdapClient, - config: UserConfig, + config: UserConfigList, opts?: { transformer?: UserTransformer }, ): Promise<{ users: UserEntity[]; // With all relations empty userMemberOf: Map>; // DN -> DN or UUID of groups }> { - const { dn, options, map } = config; - const vendor = await client.getVendor(); - + if (!config) { + return { users: [], userMemberOf: new Map() }; + } + const configs = Array.isArray(config) ? config : [config]; const entities: UserEntity[] = []; const userMemberOf: Map> = new Map(); + const vendor = await client.getVendor(); const transformer = opts?.transformer ?? defaultUserTransformer; - await client.searchStreaming(dn, options, async user => { - const entity = await transformer(vendor, config, user); + for (const cfg of configs) { + const { dn, options, map } = cfg; + await client.searchStreaming(dn, options, async user => { + const entity = await transformer(vendor, cfg, user); - if (!entity) { - return; - } + if (!entity) { + return; + } - mapReferencesAttr(user, vendor, map.memberOf, (myDn, vs) => { - ensureItems(userMemberOf, myDn, vs); + mapReferencesAttr(user, vendor, map.memberOf, (myDn, vs) => { + ensureItems(userMemberOf, myDn, vs); + }); + entities.push(entity); }); - entities.push(entity); - }); + } return { users: entities, userMemberOf }; } @@ -206,7 +216,7 @@ export async function defaultGroupTransformer( */ export async function readLdapGroups( client: LdapClient, - config: GroupConfig, + config: GroupConfigList, opts?: { transformer?: GroupTransformer; }, @@ -215,35 +225,41 @@ export async function readLdapGroups( groupMemberOf: Map>; // DN -> DN or UUID of groups groupMember: Map>; // DN -> DN or UUID of groups & users }> { + if (!config) { + return { groups: [], groupMemberOf: new Map(), groupMember: new Map() }; + } + const configs = Array.isArray(config) ? config : [config]; const groups: GroupEntity[] = []; const groupMemberOf: Map> = new Map(); const groupMember: Map> = new Map(); - const { dn, map, options } = config; const vendor = await client.getVendor(); - const transformer = opts?.transformer ?? defaultGroupTransformer; - await client.searchStreaming(dn, options, async entry => { - if (!entry) { - return; - } + for (const cfg of configs) { + const { dn, map, options } = cfg; - const entity = await transformer(vendor, config, entry); + await client.searchStreaming(dn, options, async entry => { + if (!entry) { + return; + } - if (!entity) { - return; - } + const entity = await transformer(vendor, cfg, entry); - mapReferencesAttr(entry, vendor, map.memberOf, (myDn, vs) => { - ensureItems(groupMemberOf, myDn, vs); + if (!entity) { + return; + } + + mapReferencesAttr(entry, vendor, map.memberOf, (myDn, vs) => { + ensureItems(groupMemberOf, myDn, vs); + }); + mapReferencesAttr(entry, vendor, map.members, (myDn, vs) => { + ensureItems(groupMember, myDn, vs); + }); + + groups.push(entity); }); - mapReferencesAttr(entry, vendor, map.members, (myDn, vs) => { - ensureItems(groupMember, myDn, vs); - }); - - groups.push(entity); - }); + } return { groups, @@ -264,8 +280,8 @@ export async function readLdapGroups( */ export async function readLdapOrg( client: LdapClient, - userConfig: UserConfig, - groupConfig: GroupConfig, + userConfig: UserConfigList, + groupConfig: GroupConfigList, options: { groupTransformer?: GroupTransformer; userTransformer?: UserTransformer; From 66d852407e16bab4cdf3fff171e9f50171d02acc Mon Sep 17 00:00:00 2001 From: Jente Sondervorst Date: Sun, 16 Jun 2024 14:08:57 +0200 Subject: [PATCH 033/510] Added api-reports Closes: #25256 Signed-off-by: Jente Sondervorst --- plugins/catalog-backend-module-ldap/api-report.md | 14 ++++++++++---- .../catalog-backend-module-ldap/src/ldap/config.ts | 10 ++++++++++ .../catalog-backend-module-ldap/src/ldap/index.ts | 2 ++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/plugins/catalog-backend-module-ldap/api-report.md b/plugins/catalog-backend-module-ldap/api-report.md index 5fcbbc3091..7bc53eb7b2 100644 --- a/plugins/catalog-backend-module-ldap/api-report.md +++ b/plugins/catalog-backend-module-ldap/api-report.md @@ -68,6 +68,9 @@ export type GroupConfig = { }; }; +// @public +export type GroupConfigList = GroupConfig | GroupConfig[] | undefined; + // @public export type GroupTransformer = ( vendor: LdapVendor, @@ -197,8 +200,8 @@ export type LdapProviderConfig = { target: string; tls?: TLSConfig; bind?: BindConfig; - users: UserConfig; - groups: GroupConfig; + users: UserConfigList; + groups: GroupConfigList; schedule?: TaskScheduleDefinition; }; @@ -223,8 +226,8 @@ export function readLdapLegacyConfig(config: Config): LdapProviderConfig[]; // @public export function readLdapOrg( client: LdapClient, - userConfig: UserConfig, - groupConfig: GroupConfig, + userConfig: UserConfigList, + groupConfig: GroupConfigList, options: { groupTransformer?: GroupTransformer; userTransformer?: UserTransformer; @@ -263,6 +266,9 @@ export type UserConfig = { }; }; +// @public +export type UserConfigList = UserConfig | UserConfig[] | undefined; + // @public export type UserTransformer = ( vendor: LdapVendor, diff --git a/plugins/catalog-backend-module-ldap/src/ldap/config.ts b/plugins/catalog-backend-module-ldap/src/ldap/config.ts index 7a5b2828e2..d31de61605 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/config.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/config.ts @@ -83,6 +83,11 @@ export type BindConfig = { */ export type UserConfigList = UserConfig | UserConfig[] | undefined; +/** + * The settings that govern the reading and interpretation of users. + * + * @public + */ export type UserConfig = { // The DN under which users are stored. dn: string; @@ -125,6 +130,11 @@ export type UserConfig = { */ export type GroupConfigList = GroupConfig | GroupConfig[] | undefined; +/** + * The settings that govern the reading and interpretation of groups. + * + * @public + */ export type GroupConfig = { // The DN under which groups are stored. dn: string; diff --git a/plugins/catalog-backend-module-ldap/src/ldap/index.ts b/plugins/catalog-backend-module-ldap/src/ldap/index.ts index cfab5a4444..81cab40b75 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/index.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/index.ts @@ -20,7 +20,9 @@ export { readProviderConfigs, readLdapLegacyConfig } from './config'; export type { LdapProviderConfig, GroupConfig, + GroupConfigList, UserConfig, + UserConfigList, BindConfig, TLSConfig, } from './config'; From 561083b716ea71f8387dc00345e30fc15052a1b5 Mon Sep 17 00:00:00 2001 From: David Weber Date: Wed, 15 May 2024 22:09:21 +0200 Subject: [PATCH 034/510] chore: add relations plugin to plugin page Signed-off-by: David Weber Signed-off-by: David Weber --- microsite/data/plugins/relations.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 microsite/data/plugins/relations.yaml diff --git a/microsite/data/plugins/relations.yaml b/microsite/data/plugins/relations.yaml new file mode 100644 index 0000000000..61ce052453 --- /dev/null +++ b/microsite/data/plugins/relations.yaml @@ -0,0 +1,10 @@ +--- +title: Relations +author: dweber019 +authorUrl: https://github.com/dweber019 +category: Catalog +description: This plugin enables you to configure additional relations between entities, which aren't supported out of box. +documentation: https://github.com/dweber019/backstage-plugins/tree/main/plugins/relations +iconUrl: https://raw.githubusercontent.com/dweber019/backstage-plugins/main/plugins/relations-backend/docs/pluginIcon.png +npmPackageName: '@dweber019/backstage-plugin-relations' +addedDate: '2024-05-15' From 82434ee7b5f8fdd414c8ed7e624f52ee4d43b5f7 Mon Sep 17 00:00:00 2001 From: Jente Sondervorst Date: Mon, 17 Jun 2024 22:37:31 +0200 Subject: [PATCH 035/510] Review comments Closes: #25256 Signed-off-by: Jente Sondervorst --- .../catalog-backend-module-ldap/api-report.md | 14 +- .../catalog-backend-module-ldap/config.d.ts | 512 ++++++++++++------ .../src/ldap/config.test.ts | 182 ++++--- .../src/ldap/config.ts | 145 ++--- .../src/ldap/index.ts | 2 - .../src/ldap/read.test.ts | 153 +++--- .../src/ldap/read.ts | 25 +- 7 files changed, 589 insertions(+), 444 deletions(-) diff --git a/plugins/catalog-backend-module-ldap/api-report.md b/plugins/catalog-backend-module-ldap/api-report.md index 7bc53eb7b2..9013f75450 100644 --- a/plugins/catalog-backend-module-ldap/api-report.md +++ b/plugins/catalog-backend-module-ldap/api-report.md @@ -68,9 +68,6 @@ export type GroupConfig = { }; }; -// @public -export type GroupConfigList = GroupConfig | GroupConfig[] | undefined; - // @public export type GroupTransformer = ( vendor: LdapVendor, @@ -200,8 +197,8 @@ export type LdapProviderConfig = { target: string; tls?: TLSConfig; bind?: BindConfig; - users: UserConfigList; - groups: GroupConfigList; + users: UserConfig[]; + groups: GroupConfig[]; schedule?: TaskScheduleDefinition; }; @@ -226,8 +223,8 @@ export function readLdapLegacyConfig(config: Config): LdapProviderConfig[]; // @public export function readLdapOrg( client: LdapClient, - userConfig: UserConfigList, - groupConfig: GroupConfigList, + userConfig: UserConfig[], + groupConfig: GroupConfig[], options: { groupTransformer?: GroupTransformer; userTransformer?: UserTransformer; @@ -266,9 +263,6 @@ export type UserConfig = { }; }; -// @public -export type UserConfigList = UserConfig | UserConfig[] | undefined; - // @public export type UserTransformer = ( vendor: LdapVendor, diff --git a/plugins/catalog-backend-module-ldap/config.d.ts b/plugins/catalog-backend-module-ldap/config.d.ts index a585471033..65914fdf74 100644 --- a/plugins/catalog-backend-module-ldap/config.d.ts +++ b/plugins/catalog-backend-module-ldap/config.d.ts @@ -63,180 +63,352 @@ export interface Config { /** * The settings that govern the reading and interpretation of users. */ - users: { - /** - * The DN under which users are stored. - * - * E.g. "ou=people,ou=example,dc=example,dc=net" - */ - dn: string; - /** - * The search options to use. The default is scope "one" and - * attributes "*" and "+". - * - * It is common to want to specify a filter, to narrow down the set - * of matching items. - */ - options: { - scope?: 'base' | 'one' | 'sub'; - filter?: string; - attributes?: string | string[]; - sizeLimit?: number; - timeLimit?: number; - derefAliases?: number; - typesOnly?: boolean; - paged?: - | boolean - | { - pageSize?: number; - pagePause?: boolean; - }; - }; - /** - * JSON paths (on a.b.c form) and hard coded values to set on those - * paths. - * - * This can be useful for example if you want to hard code a - * namespace or similar on the generated entities. - */ - set?: { [key: string]: JsonValue }; - /** - * Mappings from well known entity fields, to LDAP attribute names - */ - map?: { - /** - * The name of the attribute that holds the relative - * distinguished name of each entry. Defaults to "uid". - */ - rdn?: string; - /** - * The name of the attribute that shall be used for the value of - * the metadata.name field of the entity. Defaults to "uid". - */ - name?: string; - /** - * The name of the attribute that shall be used for the value of - * the metadata.description field of the entity. - */ - description?: string; - /** - * The name of the attribute that shall be used for the value of - * the spec.profile.displayName field of the entity. Defaults to - * "cn". - */ - displayName?: string; - /** - * The name of the attribute that shall be used for the value of - * the spec.profile.email field of the entity. Defaults to - * "mail". - */ - email?: string; - /** - * The name of the attribute that shall be used for the value of - * the spec.profile.picture field of the entity. - */ - picture?: string; - /** - * The name of the attribute that shall be used for the values of - * the spec.memberOf field of the entity. Defaults to "memberOf". - */ - memberOf?: string; - }; - }; + users?: + | { + /** + * The DN under which users are stored. + * + * E.g. "ou=people,ou=example,dc=example,dc=net" + */ + dn: string; + /** + * The search options to use. The default is scope "one" and + * attributes "*" and "+". + * + * It is common to want to specify a filter, to narrow down the set + * of matching items. + */ + options: { + scope?: 'base' | 'one' | 'sub'; + filter?: string; + attributes?: string | string[]; + sizeLimit?: number; + timeLimit?: number; + derefAliases?: number; + typesOnly?: boolean; + paged?: + | boolean + | { + pageSize?: number; + pagePause?: boolean; + }; + }; + /** + * JSON paths (on a.b.c form) and hard coded values to set on those + * paths. + * + * This can be useful for example if you want to hard code a + * namespace or similar on the generated entities. + */ + set?: { [key: string]: JsonValue }; + /** + * Mappings from well known entity fields, to LDAP attribute names + */ + map?: { + /** + * The name of the attribute that holds the relative + * distinguished name of each entry. Defaults to "uid". + */ + rdn?: string; + /** + * The name of the attribute that shall be used for the value of + * the metadata.name field of the entity. Defaults to "uid". + */ + name?: string; + /** + * The name of the attribute that shall be used for the value of + * the metadata.description field of the entity. + */ + description?: string; + /** + * The name of the attribute that shall be used for the value of + * the spec.profile.displayName field of the entity. Defaults to + * "cn". + */ + displayName?: string; + /** + * The name of the attribute that shall be used for the value of + * the spec.profile.email field of the entity. Defaults to + * "mail". + */ + email?: string; + /** + * The name of the attribute that shall be used for the value of + * the spec.profile.picture field of the entity. + */ + picture?: string; + /** + * The name of the attribute that shall be used for the values of + * the spec.memberOf field of the entity. Defaults to "memberOf". + */ + memberOf?: string; + }; + } + | Array<{ + /** + * The DN under which users are stored. + * + * E.g. "ou=people,ou=example,dc=example,dc=net" + */ + dn: string; + /** + * The search options to use. The default is scope "one" and + * attributes "*" and "+". + * + * It is common to want to specify a filter, to narrow down the set + * of matching items. + */ + options: { + scope?: 'base' | 'one' | 'sub'; + filter?: string; + attributes?: string | string[]; + sizeLimit?: number; + timeLimit?: number; + derefAliases?: number; + typesOnly?: boolean; + paged?: + | boolean + | { + pageSize?: number; + pagePause?: boolean; + }; + }; + /** + * JSON paths (on a.b.c form) and hard coded values to set on those + * paths. + * + * This can be useful for example if you want to hard code a + * namespace or similar on the generated entities. + */ + set?: { [key: string]: JsonValue }; + /** + * Mappings from well known entity fields, to LDAP attribute names + */ + map?: { + /** + * The name of the attribute that holds the relative + * distinguished name of each entry. Defaults to "uid". + */ + rdn?: string; + /** + * The name of the attribute that shall be used for the value of + * the metadata.name field of the entity. Defaults to "uid". + */ + name?: string; + /** + * The name of the attribute that shall be used for the value of + * the metadata.description field of the entity. + */ + description?: string; + /** + * The name of the attribute that shall be used for the value of + * the spec.profile.displayName field of the entity. Defaults to + * "cn". + */ + displayName?: string; + /** + * The name of the attribute that shall be used for the value of + * the spec.profile.email field of the entity. Defaults to + * "mail". + */ + email?: string; + /** + * The name of the attribute that shall be used for the value of + * the spec.profile.picture field of the entity. + */ + picture?: string; + /** + * The name of the attribute that shall be used for the values of + * the spec.memberOf field of the entity. Defaults to "memberOf". + */ + memberOf?: string; + }; + }>; /** * The settings that govern the reading and interpretation of groups. */ - groups: { - /** - * The DN under which groups are stored. - * - * E.g. "ou=people,ou=example,dc=example,dc=net" - */ - dn: string; - /** - * The search options to use. The default is scope "one" and - * attributes "*" and "+". - * - * It is common to want to specify a filter, to narrow down the set - * of matching items. - */ - options: { - scope?: 'base' | 'one' | 'sub'; - filter?: string; - attributes?: string | string[]; - sizeLimit?: number; - timeLimit?: number; - derefAliases?: number; - typesOnly?: boolean; - paged?: - | boolean - | { - pageSize?: number; - pagePause?: boolean; - }; - }; - /** - * JSON paths (on a.b.c form) and hard coded values to set on those - * paths. - * - * This can be useful for example if you want to hard code a - * namespace or similar on the generated entities. - */ - set?: { [key: string]: JsonValue }; - /** - * Mappings from well known entity fields, to LDAP attribute names - */ - map?: { - /** - * The name of the attribute that holds the relative - * distinguished name of each entry. Defaults to "cn". - */ - rdn?: string; - /** - * The name of the attribute that shall be used for the value of - * the metadata.name field of the entity. Defaults to "cn". - */ - name?: string; - /** - * The name of the attribute that shall be used for the value of - * the metadata.description field of the entity. Defaults to - * "description". - */ - description?: string; - /** - * The name of the attribute that shall be used for the value of - * the spec.type field of the entity. Defaults to "groupType". - */ - type?: string; - /** - * The name of the attribute that shall be used for the value of - * the spec.profile.displayName field of the entity. Defaults to - * "cn". - */ - displayName?: string; - /** - * The name of the attribute that shall be used for the value of - * the spec.profile.email field of the entity. - */ - email?: string; - /** - * The name of the attribute that shall be used for the value of - * the spec.profile.picture field of the entity. - */ - picture?: string; - /** - * The name of the attribute that shall be used for the values of - * the spec.parent field of the entity. Defaults to "memberOf". - */ - memberOf?: string; - /** - * The name of the attribute that shall be used for the values of - * the spec.children field of the entity. Defaults to "member". - */ - members?: string; - }; - }; + groups?: + | { + /** + * The DN under which groups are stored. + * + * E.g. "ou=people,ou=example,dc=example,dc=net" + */ + dn: string; + /** + * The search options to use. The default is scope "one" and + * attributes "*" and "+". + * + * It is common to want to specify a filter, to narrow down the set + * of matching items. + */ + options: { + scope?: 'base' | 'one' | 'sub'; + filter?: string; + attributes?: string | string[]; + sizeLimit?: number; + timeLimit?: number; + derefAliases?: number; + typesOnly?: boolean; + paged?: + | boolean + | { + pageSize?: number; + pagePause?: boolean; + }; + }; + /** + * JSON paths (on a.b.c form) and hard coded values to set on those + * paths. + * + * This can be useful for example if you want to hard code a + * namespace or similar on the generated entities. + */ + set?: { [key: string]: JsonValue }; + /** + * Mappings from well known entity fields, to LDAP attribute names + */ + map?: { + /** + * The name of the attribute that holds the relative + * distinguished name of each entry. Defaults to "cn". + */ + rdn?: string; + /** + * The name of the attribute that shall be used for the value of + * the metadata.name field of the entity. Defaults to "cn". + */ + name?: string; + /** + * The name of the attribute that shall be used for the value of + * the metadata.description field of the entity. Defaults to + * "description". + */ + description?: string; + /** + * The name of the attribute that shall be used for the value of + * the spec.type field of the entity. Defaults to "groupType". + */ + type?: string; + /** + * The name of the attribute that shall be used for the value of + * the spec.profile.displayName field of the entity. Defaults to + * "cn". + */ + displayName?: string; + /** + * The name of the attribute that shall be used for the value of + * the spec.profile.email field of the entity. + */ + email?: string; + /** + * The name of the attribute that shall be used for the value of + * the spec.profile.picture field of the entity. + */ + picture?: string; + /** + * The name of the attribute that shall be used for the values of + * the spec.parent field of the entity. Defaults to "memberOf". + */ + memberOf?: string; + /** + * The name of the attribute that shall be used for the values of + * the spec.children field of the entity. Defaults to "member". + */ + members?: string; + }; + } + | Array<{ + /** + * The DN under which groups are stored. + * + * E.g. "ou=people,ou=example,dc=example,dc=net" + */ + dn: string; + /** + * The search options to use. The default is scope "one" and + * attributes "*" and "+". + * + * It is common to want to specify a filter, to narrow down the set + * of matching items. + */ + options: { + scope?: 'base' | 'one' | 'sub'; + filter?: string; + attributes?: string | string[]; + sizeLimit?: number; + timeLimit?: number; + derefAliases?: number; + typesOnly?: boolean; + paged?: + | boolean + | { + pageSize?: number; + pagePause?: boolean; + }; + }; + /** + * JSON paths (on a.b.c form) and hard coded values to set on those + * paths. + * + * This can be useful for example if you want to hard code a + * namespace or similar on the generated entities. + */ + set?: { [key: string]: JsonValue }; + /** + * Mappings from well known entity fields, to LDAP attribute names + */ + map?: { + /** + * The name of the attribute that holds the relative + * distinguished name of each entry. Defaults to "cn". + */ + rdn?: string; + /** + * The name of the attribute that shall be used for the value of + * the metadata.name field of the entity. Defaults to "cn". + */ + name?: string; + /** + * The name of the attribute that shall be used for the value of + * the metadata.description field of the entity. Defaults to + * "description". + */ + description?: string; + /** + * The name of the attribute that shall be used for the value of + * the spec.type field of the entity. Defaults to "groupType". + */ + type?: string; + /** + * The name of the attribute that shall be used for the value of + * the spec.profile.displayName field of the entity. Defaults to + * "cn". + */ + displayName?: string; + /** + * The name of the attribute that shall be used for the value of + * the spec.profile.email field of the entity. + */ + email?: string; + /** + * The name of the attribute that shall be used for the value of + * the spec.profile.picture field of the entity. + */ + picture?: string; + /** + * The name of the attribute that shall be used for the values of + * the spec.parent field of the entity. Defaults to "memberOf". + */ + memberOf?: string; + /** + * The name of the attribute that shall be used for the values of + * the spec.children field of the entity. Defaults to "member". + */ + members?: string; + }; + }>; }>; }; diff --git a/plugins/catalog-backend-module-ldap/src/ldap/config.test.ts b/plugins/catalog-backend-module-ldap/src/ldap/config.test.ts index 8cd41e0b70..553bf3c525 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/config.test.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/config.test.ts @@ -15,7 +15,7 @@ */ import { ConfigReader } from '@backstage/config'; -import { readProviderConfigs, UserConfig } from './config'; +import { readProviderConfigs } from './config'; describe('readLdapConfig', () => { it('applies all of the defaults', () => { @@ -42,38 +42,42 @@ describe('readLdapConfig', () => { id: 'default', target: 'target', bind: undefined, - users: { - dn: 'udn', - options: { - scope: 'one', - attributes: ['*', '+'], + users: [ + { + dn: 'udn', + options: { + scope: 'one', + attributes: ['*', '+'], + }, + set: undefined, + map: { + rdn: 'uid', + name: 'uid', + displayName: 'cn', + email: 'mail', + memberOf: 'memberOf', + }, }, - set: undefined, - map: { - rdn: 'uid', - name: 'uid', - displayName: 'cn', - email: 'mail', - memberOf: 'memberOf', + ], + groups: [ + { + dn: 'gdn', + options: { + scope: 'one', + attributes: ['*', '+'], + }, + set: undefined, + map: { + rdn: 'cn', + name: 'cn', + description: 'description', + type: 'groupType', + displayName: 'cn', + memberOf: 'memberOf', + members: 'member', + }, }, - }, - groups: { - dn: 'gdn', - options: { - scope: 'one', - attributes: ['*', '+'], - }, - set: undefined, - map: { - rdn: 'cn', - name: 'cn', - description: 'description', - type: 'groupType', - displayName: 'cn', - memberOf: 'memberOf', - members: 'member', - }, - }, + ], }, ]; expect(actual).toEqual(expected); @@ -159,57 +163,61 @@ describe('readLdapConfig', () => { keys: '/tmp/keys.pem', certs: '/tmp/certs.pem', }, - users: { - dn: 'udn', - options: { - scope: 'base', - attributes: ['*'], - filter: 'f', - paged: true, - timeLimit: 42, - sizeLimit: 100, - derefAliases: 0, - typesOnly: false, - }, - set: { p: 'v' }, - map: { - rdn: 'u', - name: 'v', - description: 'd', - displayName: 'c', - email: 'm', - picture: 'p', - memberOf: 'm', - }, - }, - groups: { - dn: 'gdn', - options: { - scope: 'base', - attributes: ['*'], - filter: 'f', - paged: { - pageSize: 7, - pagePause: true, + users: [ + { + dn: 'udn', + options: { + scope: 'base', + attributes: ['*'], + filter: 'f', + paged: true, + timeLimit: 42, + sizeLimit: 100, + derefAliases: 0, + typesOnly: false, + }, + set: { p: 'v' }, + map: { + rdn: 'u', + name: 'v', + description: 'd', + displayName: 'c', + email: 'm', + picture: 'p', + memberOf: 'm', }, - timeLimit: 42, - sizeLimit: 100, - derefAliases: 1, - typesOnly: true, }, - set: { p: 'v' }, - map: { - rdn: 'u', - name: 'v', - description: 'd', - type: 't', - displayName: 'c', - email: 'm', - picture: 'p', - memberOf: 'm', - members: 'n', + ], + groups: [ + { + dn: 'gdn', + options: { + scope: 'base', + attributes: ['*'], + filter: 'f', + paged: { + pageSize: 7, + pagePause: true, + }, + timeLimit: 42, + sizeLimit: 100, + derefAliases: 1, + typesOnly: true, + }, + set: { p: 'v' }, + map: { + rdn: 'u', + name: 'v', + description: 'd', + type: 't', + displayName: 'c', + email: 'm', + picture: 'p', + memberOf: 'm', + members: 'n', + }, }, - }, + ], }, ]; expect(actual).toEqual(expected); @@ -247,7 +255,7 @@ describe('readLdapConfig', () => { const actual = readProviderConfigs(new ConfigReader(config)); const expected = '(|(cn=foo bar)(cn=bar))'; - expect((actual[0].users!! as UserConfig).options.filter).toEqual(expected); + expect(actual[0].users[0].options.filter).toEqual(expected); }); it('supports a dot nested set structure', () => { @@ -284,7 +292,7 @@ describe('readLdapConfig', () => { }; const actual = readProviderConfigs(new ConfigReader(config)); - expect((actual[0].users!! as UserConfig).set).toEqual({ + expect(actual[0].users[0].set).toEqual({ 'metadata.annotations': { a: 'b' }, }); }); @@ -322,23 +330,23 @@ describe('readLdapConfig', () => { const actual = readProviderConfigs(new ConfigReader(config)); expect(() => { - ((actual[0].users!! as UserConfig).set as any).y = 2; + (actual[0].users[0].set as any).y = 2; }).toThrowErrorMatchingInlineSnapshot( `"Cannot add property y, object is not extensible"`, ); expect(() => { - ((actual[0].users!! as UserConfig).set as any).x.b = 2; + (actual[0].users[0].set as any).x.b = 2; }).toThrowErrorMatchingInlineSnapshot( `"Cannot add property b, object is not extensible"`, ); expect(() => { - ((actual[0].users!! as UserConfig).set as any).y = 2; + (actual[0].users[0].set as any).y = 2; }).toThrowErrorMatchingInlineSnapshot( `"Cannot add property y, object is not extensible"`, ); expect(() => { - ((actual[0].users!! as UserConfig).set as any).x.b = 2; + (actual[0].users[0].set as any).x.b = 2; }).toThrowErrorMatchingInlineSnapshot( `"Cannot add property b, object is not extensible"`, ); @@ -392,7 +400,7 @@ describe('readLdapConfig', () => { }; const actual = readProviderConfigs(new ConfigReader(config)); - expect(actual[0].users).toBeUndefined(); - expect(actual[0].groups).toBeUndefined(); + expect(actual[0].users).toHaveLength(0); + expect(actual[0].groups).toHaveLength(0); }); }); diff --git a/plugins/catalog-backend-module-ldap/src/ldap/config.ts b/plugins/catalog-backend-module-ldap/src/ldap/config.ts index d31de61605..9295639cae 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/config.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/config.ts @@ -42,9 +42,9 @@ export type LdapProviderConfig = { // command is not issued. bind?: BindConfig; // The settings that govern the reading and interpretation of users - users: UserConfigList; + users: UserConfig[]; // The settings that govern the reading and interpretation of groups - groups: GroupConfigList; + groups: GroupConfig[]; // Schedule configuration for refresh tasks. schedule?: TaskScheduleDefinition; }; @@ -76,13 +76,6 @@ export type BindConfig = { secret: string; }; -/** - * The settings that govern the reading and interpretation of users. - * - * @public - */ -export type UserConfigList = UserConfig | UserConfig[] | undefined; - /** * The settings that govern the reading and interpretation of users. * @@ -123,13 +116,6 @@ export type UserConfig = { }; }; -/** - * The settings that govern the reading and interpretation of groups. - * - * @public - */ -export type GroupConfigList = GroupConfig | GroupConfig[] | undefined; - /** * The settings that govern the reading and interpretation of groups. * @@ -175,34 +161,33 @@ export type GroupConfig = { }; }; -const defaultConfig = { - users: { - options: { - scope: 'one', - attributes: ['*', '+'], - }, - map: { - rdn: 'uid', - name: 'uid', - displayName: 'cn', - email: 'mail', - memberOf: 'memberOf', - }, +const defaultUserConfig = { + options: { + scope: 'one', + attributes: ['*', '+'], }, - groups: { - options: { - scope: 'one', - attributes: ['*', '+'], - }, - map: { - rdn: 'cn', - name: 'cn', - description: 'description', - displayName: 'cn', - type: 'groupType', - memberOf: 'memberOf', - members: 'member', - }, + map: { + rdn: 'uid', + name: 'uid', + displayName: 'cn', + email: 'mail', + memberOf: 'memberOf', + }, +}; + +const defaultGroupConfig = { + options: { + scope: 'one', + attributes: ['*', '+'], + }, + map: { + rdn: 'cn', + name: 'cn', + description: 'description', + displayName: 'cn', + type: 'groupType', + memberOf: 'memberOf', + members: 'member', }, }; @@ -326,18 +311,15 @@ function readUserConfig( c: Config | Config[] | undefined, ): RecursivePartial { if (!c) { - return undefined; + return []; } if (Array.isArray(c)) { - return c.map(it => { - return { - dn: it.getString('dn'), - options: readOptionsConfig(it.getOptionalConfig('options')), - set: readSetConfig(it.getOptionalConfig('set')), - map: readUserMapConfig(it.getOptionalConfig('map')), - }; - }); + return c.map(it => readSingleUserConfig(it)); } + return [readSingleUserConfig(c)]; +} + +function readSingleUserConfig(c: Config): RecursivePartial { return { dn: c.getString('dn'), options: readOptionsConfig(c.getOptionalConfig('options')), @@ -350,18 +332,15 @@ function readGroupConfig( c: Config | Config[] | undefined, ): RecursivePartial { if (!c) { - return undefined; + return []; } if (Array.isArray(c)) { - return c.map(it => { - return { - dn: it.getString('dn'), - options: readOptionsConfig(it.getOptionalConfig('options')), - set: readSetConfig(it.getOptionalConfig('set')), - map: readGroupMapConfig(it.getOptionalConfig('map')), - }; - }); + return c.map(it => readSingleGroupConfig(it)); } + return [readSingleGroupConfig(c)]; +} + +function readSingleGroupConfig(c: Config): RecursivePartial { return { dn: c.getString('dn'), options: readOptionsConfig(c.getOptionalConfig('options')), @@ -390,14 +369,15 @@ export function readLdapLegacyConfig(config: Config): LdapProviderConfig[] { target: trimEnd(c.getString('target'), '/'), tls: readTlsConfig(c.getOptionalConfig('tls')), bind: readBindConfig(c.getOptionalConfig('bind')), - users: readUserConfig(c.getConfig('users')), - groups: readGroupConfig(c.getConfig('groups')), + users: readUserConfig(c.getConfig('users')).map(it => { + return mergeWith({}, defaultUserConfig, it, replaceArraysIfPresent); + }), + groups: readGroupConfig(c.getConfig('groups')).map(it => { + return mergeWith({}, defaultGroupConfig, it, replaceArraysIfPresent); + }), }; - const merged = mergeWith({}, defaultConfig, newConfig, (_into, from) => { - // Replace arrays instead of merging, otherwise default behavior - return Array.isArray(from) ? from : undefined; - }); - return freeze(merged) as LdapProviderConfig; + + return freeze(newConfig) as LdapProviderConfig; }); } @@ -433,29 +413,24 @@ export function readProviderConfigs(config: Config): LdapProviderConfig[] { isUserList ? c.getOptionalConfigArray('users') : c.getOptionalConfig('users'), - ), + ).map(it => { + return mergeWith({}, defaultUserConfig, it, replaceArraysIfPresent); + }), groups: readGroupConfig( isGroupList ? c.getOptionalConfigArray('groups') : c.getOptionalConfig('groups'), - ), + ).map(it => { + return mergeWith({}, defaultGroupConfig, it, replaceArraysIfPresent); + }), schedule, }; - const merged = mergeWith( - {}, - defaultConfig, - newConfig, - (_value, srcValue, key, object, _source) => { - // Remove users and groups from default if they are not set in the new config - if ((key === 'users' || key === 'groups') && !srcValue) { - return (object[key] = srcValue); - } - // Replace arrays instead of merging, otherwise default behavior - return Array.isArray(srcValue) ? srcValue : undefined; - }, - ); - - return freeze(merged) as LdapProviderConfig; + return freeze(newConfig) as LdapProviderConfig; }); } + +function replaceArraysIfPresent(_into: any, from: any) { + // Replace arrays instead of merging, otherwise default behavior + return Array.isArray(from) ? from : undefined; +} diff --git a/plugins/catalog-backend-module-ldap/src/ldap/index.ts b/plugins/catalog-backend-module-ldap/src/ldap/index.ts index 81cab40b75..cfab5a4444 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/index.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/index.ts @@ -20,9 +20,7 @@ export { readProviderConfigs, readLdapLegacyConfig } from './config'; export type { LdapProviderConfig, GroupConfig, - GroupConfigList, UserConfig, - UserConfigList, BindConfig, TLSConfig, } from './config'; diff --git a/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts b/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts index 33c52477aa..1c3dfb179a 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts @@ -18,12 +18,7 @@ import { GroupEntity, UserEntity } from '@backstage/catalog-model'; import { SearchEntry } from 'ldapjs'; import merge from 'lodash/merge'; import { LdapClient } from './client'; -import { - GroupConfig, - GroupConfigList, - UserConfig, - UserConfigList, -} from './config'; +import { GroupConfig, UserConfig } from './config'; import { LDAP_DN_ANNOTATION, LDAP_RDN_ANNOTATION, @@ -104,19 +99,21 @@ describe('readLdapUsers', () => { }), ); }); - const config: UserConfig = { - dn: 'ddd', - options: {}, - map: { - rdn: 'uid', - name: 'uid', - description: 'description', - displayName: 'cn', - email: 'mail', - picture: 'avatarUrl', - memberOf: 'memberOf', + const config: UserConfig[] = [ + { + dn: 'ddd', + options: {}, + map: { + rdn: 'uid', + name: 'uid', + description: 'description', + displayName: 'cn', + email: 'mail', + picture: 'avatarUrl', + memberOf: 'memberOf', + }, }, - }; + ]; const { users, userMemberOf } = await readLdapUsers(client, config); expect(users).toEqual([ expect.objectContaining({ @@ -165,19 +162,21 @@ describe('readLdapUsers', () => { }), ); }); - const config: UserConfig = { - dn: 'ddd', - options: {}, - map: { - rdn: 'uid', - name: 'uid', - description: 'description', - displayName: 'cn', - email: 'mail', - picture: 'avatarUrl', - memberOf: 'memberOf', + const config: UserConfig[] = [ + { + dn: 'ddd', + options: {}, + map: { + rdn: 'uid', + name: 'uid', + description: 'description', + displayName: 'cn', + email: 'mail', + picture: 'avatarUrl', + memberOf: 'memberOf', + }, }, - }; + ]; const { users, userMemberOf } = await readLdapUsers(client, config); expect(users).toEqual([ expect.objectContaining({ @@ -221,19 +220,21 @@ describe('readLdapUsers', () => { }), ); }); - const config: UserConfig = { - dn: 'ddd', - options: {}, - map: { - rdn: 'uid', - name: 'uid', - description: 'description', - displayName: 'cn', - email: 'mail', - picture: 'avatarUrl', - memberOf: 'memberOf', + const config: UserConfig[] = [ + { + dn: 'ddd', + options: {}, + map: { + rdn: 'uid', + name: 'uid', + description: 'description', + displayName: 'cn', + email: 'mail', + picture: 'avatarUrl', + memberOf: 'memberOf', + }, }, - }; + ]; const { users, userMemberOf } = await readLdapUsers(client, config); expect(users).toEqual([ expect.objectContaining({ @@ -276,7 +277,7 @@ describe('readLdapUsers', () => { }), ); }); - const config: UserConfigList = [ + const config: UserConfig[] = [ { dn: 'ddd', options: {}, @@ -308,7 +309,7 @@ describe('readLdapUsers', () => { expect(users).toHaveLength(2); }); it('can process no UserConfigs', async () => { - const config: UserConfigList = undefined; + const config: UserConfig[] = []; const { users } = await readLdapUsers(client, config); expect(users).toHaveLength(0); }); @@ -339,21 +340,23 @@ describe('readLdapGroups', () => { }), ); }); - const config: GroupConfig = { - dn: 'ddd', - options: {}, - map: { - rdn: 'cn', - name: 'cn', - description: 'description', - displayName: 'cn', - email: 'mail', - picture: 'avatarUrl', - type: 'tt', - memberOf: 'memberOf', - members: 'member', + const config: GroupConfig[] = [ + { + dn: 'ddd', + options: {}, + map: { + rdn: 'cn', + name: 'cn', + description: 'description', + displayName: 'cn', + email: 'mail', + picture: 'avatarUrl', + type: 'tt', + memberOf: 'memberOf', + members: 'member', + }, }, - }; + ]; const { groups, groupMember, groupMemberOf } = await readLdapGroups( client, config, @@ -410,21 +413,23 @@ describe('readLdapGroups', () => { }), ); }); - const config: GroupConfig = { - dn: 'ddd', - options: {}, - map: { - rdn: 'cn', - name: 'cn', - description: 'description', - displayName: 'cn', - email: 'mail', - picture: 'avatarUrl', - type: 'tt', - memberOf: 'memberOf', - members: 'member', + const config: GroupConfig[] = [ + { + dn: 'ddd', + options: {}, + map: { + rdn: 'cn', + name: 'cn', + description: 'description', + displayName: 'cn', + email: 'mail', + picture: 'avatarUrl', + type: 'tt', + memberOf: 'memberOf', + members: 'member', + }, }, - }; + ]; const { groups, groupMember, groupMemberOf } = await readLdapGroups( client, config, @@ -476,7 +481,7 @@ describe('readLdapGroups', () => { }), ); }); - const config: GroupConfigList = [ + const config: GroupConfig[] = [ { dn: 'ddd', options: {}, @@ -513,7 +518,7 @@ describe('readLdapGroups', () => { }); it('can process no GroupConfigs', async () => { - const config: GroupConfigList = undefined; + const config: GroupConfig[] = []; const { groups } = await readLdapGroups(client, config); expect(groups).toHaveLength(0); }); diff --git a/plugins/catalog-backend-module-ldap/src/ldap/read.ts b/plugins/catalog-backend-module-ldap/src/ldap/read.ts index 5dadcaede2..9e6e11a0bc 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/read.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/read.ts @@ -24,12 +24,7 @@ import lodashSet from 'lodash/set'; import cloneDeep from 'lodash/cloneDeep'; import { buildOrgHierarchy } from './org'; import { LdapClient } from './client'; -import { - GroupConfig, - GroupConfigList, - UserConfig, - UserConfigList, -} from './config'; +import { GroupConfig, UserConfig } from './config'; import { LDAP_DN_ANNOTATION, LDAP_RDN_ANNOTATION, @@ -109,23 +104,22 @@ export async function defaultUserTransformer( */ export async function readLdapUsers( client: LdapClient, - config: UserConfigList, + config: UserConfig[], opts?: { transformer?: UserTransformer }, ): Promise<{ users: UserEntity[]; // With all relations empty userMemberOf: Map>; // DN -> DN or UUID of groups }> { - if (!config) { + if (config.length === 0) { return { users: [], userMemberOf: new Map() }; } - const configs = Array.isArray(config) ? config : [config]; const entities: UserEntity[] = []; const userMemberOf: Map> = new Map(); const vendor = await client.getVendor(); const transformer = opts?.transformer ?? defaultUserTransformer; - for (const cfg of configs) { + for (const cfg of config) { const { dn, options, map } = cfg; await client.searchStreaming(dn, options, async user => { const entity = await transformer(vendor, cfg, user); @@ -216,7 +210,7 @@ export async function defaultGroupTransformer( */ export async function readLdapGroups( client: LdapClient, - config: GroupConfigList, + config: GroupConfig[], opts?: { transformer?: GroupTransformer; }, @@ -225,10 +219,9 @@ export async function readLdapGroups( groupMemberOf: Map>; // DN -> DN or UUID of groups groupMember: Map>; // DN -> DN or UUID of groups & users }> { - if (!config) { + if (config.length === 0) { return { groups: [], groupMemberOf: new Map(), groupMember: new Map() }; } - const configs = Array.isArray(config) ? config : [config]; const groups: GroupEntity[] = []; const groupMemberOf: Map> = new Map(); const groupMember: Map> = new Map(); @@ -236,7 +229,7 @@ export async function readLdapGroups( const vendor = await client.getVendor(); const transformer = opts?.transformer ?? defaultGroupTransformer; - for (const cfg of configs) { + for (const cfg of config) { const { dn, map, options } = cfg; await client.searchStreaming(dn, options, async entry => { @@ -280,8 +273,8 @@ export async function readLdapGroups( */ export async function readLdapOrg( client: LdapClient, - userConfig: UserConfigList, - groupConfig: GroupConfigList, + userConfig: UserConfig[], + groupConfig: GroupConfig[], options: { groupTransformer?: GroupTransformer; userTransformer?: UserTransformer; From 427ae454727b9d16de844166838564527ee5bfcd Mon Sep 17 00:00:00 2001 From: Jente Sondervorst Date: Mon, 17 Jun 2024 22:45:18 +0200 Subject: [PATCH 036/510] adapt test Closes: #25256 Signed-off-by: Jente Sondervorst --- plugins/catalog-backend-module-ldap/src/ldap/config.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/catalog-backend-module-ldap/src/ldap/config.test.ts b/plugins/catalog-backend-module-ldap/src/ldap/config.test.ts index 553bf3c525..b81339c325 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/config.test.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/config.test.ts @@ -341,12 +341,12 @@ describe('readLdapConfig', () => { ); expect(() => { - (actual[0].users[0].set as any).y = 2; + (actual[0].groups[0].set as any).y = 2; }).toThrowErrorMatchingInlineSnapshot( `"Cannot add property y, object is not extensible"`, ); expect(() => { - (actual[0].users[0].set as any).x.b = 2; + (actual[0].groups[0].set as any).x.b = 2; }).toThrowErrorMatchingInlineSnapshot( `"Cannot add property b, object is not extensible"`, ); From c324de8ccd2fcf63da0049c0643b9850dffa91e8 Mon Sep 17 00:00:00 2001 From: mario ma Date: Mon, 4 Mar 2024 20:07:29 +0800 Subject: [PATCH 037/510] feat: add i18n to plugin-catalog Signed-off-by: mario ma --- .../src/components/AboutCard/AboutCard.tsx | 21 +-- .../src/components/AboutCard/AboutContent.tsx | 47 +++--- .../CatalogPage/DefaultCatalogPage.tsx | 2 +- .../CatalogSearchResultListItem.tsx | 13 +- .../components/CatalogTable/CatalogTable.tsx | 13 +- .../DependencyOfComponentsCard.tsx | 10 +- .../DependsOnComponentsCard.tsx | 7 +- .../DependsOnResourcesCard.tsx | 7 +- .../EntityContextMenu/EntityContextMenu.tsx | 13 +- .../EntityContextMenu/UnregisterEntity.tsx | 5 +- .../EntityLabelsCard/EntityLabelsCard.tsx | 5 +- .../EntityLabelsEmptyState.tsx | 8 +- .../components/EntityLayout/EntityLayout.tsx | 10 +- .../EntityLinksCard/EntityLinksCard.tsx | 5 +- .../EntityLinksCard/EntityLinksEmptyState.tsx | 8 +- .../EntityNotFound/EntityNotFound.tsx | 10 +- .../DeleteEntityDialog.tsx | 9 +- .../EntityOrphanWarning.tsx | 6 +- .../EntityProcessingErrorsPanel.tsx | 5 +- .../EntityRelationWarning.tsx | 9 +- .../HasComponentsCard/HasComponentsCard.tsx | 7 +- .../HasResourcesCard/HasResourcesCard.tsx | 7 +- .../HasSubcomponentsCard.tsx | 7 +- .../HasSystemsCard/HasSystemsCard.tsx | 7 +- .../RelatedEntitiesCard.tsx | 7 +- .../SystemDiagramCard/SystemDiagramCard.tsx | 17 ++- plugins/catalog/src/translation.ts | 135 ++++++++++++++++++ 27 files changed, 314 insertions(+), 86 deletions(-) diff --git a/plugins/catalog/src/components/AboutCard/AboutCard.tsx b/plugins/catalog/src/components/AboutCard/AboutCard.tsx index ee6147c54e..ed196fe3e0 100644 --- a/plugins/catalog/src/components/AboutCard/AboutCard.tsx +++ b/plugins/catalog/src/components/AboutCard/AboutCard.tsx @@ -64,6 +64,8 @@ import { catalogEntityRefreshPermission } from '@backstage/plugin-catalog-common import { useSourceTemplateCompoundEntityRef } from './hooks'; import { taskCreatePermission } from '@backstage/plugin-scaffolder-common/alpha'; import { usePermission } from '@backstage/plugin-permission-react'; +import { catalogTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; const TECHDOCS_ANNOTATION = 'backstage.io/techdocs-ref'; @@ -116,6 +118,7 @@ export function AboutCard(props: AboutCardProps) { const { allowed: canRefresh } = useEntityPermission( catalogEntityRefreshPermission, ); + const { t } = useTranslationRef(catalogTranslationRef); const { allowed: canCreateTemplateTask } = usePermission({ permission: taskCreatePermission, @@ -142,13 +145,13 @@ export function AboutCard(props: AboutCardProps) { } const viewInSource: IconLinkVerticalProps = { - label: 'View Source', + label: t('aboutCard.viewSource'), disabled: !entitySourceLocation, icon: , href: entitySourceLocation?.locationTargetUrl, }; const viewInTechDocs: IconLinkVerticalProps = { - label: 'View TechDocs', + label: t('aboutCard.viewTechdocs'), disabled: !( entity.metadata.annotations?.[TECHDOCS_ANNOTATION] || @@ -176,7 +179,7 @@ export function AboutCard(props: AboutCardProps) { const Icon = app.getSystemIcon('scaffolder') ?? CreateComponentIcon; const launchTemplate: IconLinkVerticalProps = { - label: 'Launch Template', + label: t('aboutCard.launchTemplate'), icon: , disabled: !templateRoute || !canCreateTemplateTask, href: @@ -212,25 +215,25 @@ export function AboutCard(props: AboutCardProps) { try { await catalogApi.refreshEntity(stringifyEntityRef(entity)); alertApi.post({ - message: 'Refresh scheduled', + message: t('aboutCard.refreshScheduledMessage'), severity: 'info', display: 'transient', }); } catch (e) { errorApi.post(e); } - }, [catalogApi, alertApi, errorApi, entity]); + }, [catalogApi, entity, alertApi, t, errorApi]); return ( {allowRefresh && canRefresh && ( @@ -240,7 +243,7 @@ export function AboutCard(props: AboutCardProps) { component={Link} aria-label="Edit" disabled={!entityMetadataEditUrl} - title="Edit Metadata" + title={t('aboutCard.editButtonTitle')} to={entityMetadataEditUrl ?? '#'} > @@ -248,7 +251,7 @@ export function AboutCard(props: AboutCardProps) { {sourceTemplateRef && templateRoute && ( - + {ownedByRelations.length > 0 && ( @@ -130,8 +140,8 @@ export function AboutContent(props: AboutContentProps) { {(isSystem || partOfDomainRelations.length > 0) && ( {partOfDomainRelations.length > 0 && ( @@ -147,8 +157,8 @@ export function AboutContent(props: AboutContentProps) { isResource || partOfSystemRelations.length > 0) && ( {partOfSystemRelations.length > 0 && ( @@ -161,8 +171,8 @@ export function AboutContent(props: AboutContentProps) { )} {isComponent && partOfComponentRelations.length > 0 && ( @@ -188,22 +198,25 @@ export function AboutContent(props: AboutContentProps) { isComponent || typeof entity?.spec?.lifecycle === 'string') && ( )} - {(entity?.metadata?.tags || []).map(t => ( - + {(entity?.metadata?.tags || []).map(tag => ( + ))} {isLocation && (entity?.spec?.targets || entity?.spec?.target) && ( - + )} - All your software catalog entities + {t('indexPage.supportButtonContent')} diff --git a/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx b/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx index 32c86f38b7..1a596f8b9b 100644 --- a/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx +++ b/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx @@ -27,6 +27,8 @@ import { ResultHighlight, } from '@backstage/plugin-search-common'; import { HighlightedSearchResultText } from '@backstage/plugin-search-react'; +import { catalogTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/frontend-plugin-api'; const useStyles = makeStyles( { @@ -66,6 +68,7 @@ export function CatalogSearchResultListItem( const highlight = props.highlight as ResultHighlight; const classes = useStyles(); + const { t } = useTranslationRef(catalogTranslationRef); if (!result) return null; @@ -121,10 +124,16 @@ export function CatalogSearchResultListItem( {result.kind && } {result.type && } {result.lifecycle && ( - + )} {result.owner && ( - + )} diff --git a/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx b/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx index b1590bdff3..e18467249a 100644 --- a/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx +++ b/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx @@ -48,6 +48,8 @@ import { columnFactories } from './columns'; import { CatalogTableColumnsFunc, CatalogTableRow } from './types'; import { PaginatedCatalogTable } from './PaginatedCatalogTable'; import { defaultCatalogTableColumnsFunc } from './defaultCatalogTableColumnsFunc'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; +import { catalogTranslationRef } from '../../translation'; /** * Props for {@link CatalogTable}. @@ -96,13 +98,14 @@ export const CatalogTable = (props: CatalogTableProps) => { typeof columns === 'function' ? columns(entityListContext) : columns, [columns, entityListContext], ); + const { t } = useTranslationRef(catalogTranslationRef); if (error) { return (
@@ -113,7 +116,7 @@ export const CatalogTable = (props: CatalogTableProps) => { const defaultActions: TableProps['actions'] = [ ({ entity }) => { const url = entity.metadata.annotations?.[ANNOTATION_VIEW_URL]; - const title = 'View'; + const title = t('catalogTable.viewActionTitle'); return { icon: () => ( @@ -132,7 +135,7 @@ export const CatalogTable = (props: CatalogTableProps) => { }, ({ entity }) => { const url = entity.metadata.annotations?.[ANNOTATION_EDIT_URL]; - const title = 'Edit'; + const title = t('catalogTable.editActionTitle'); return { icon: () => ( @@ -151,7 +154,9 @@ export const CatalogTable = (props: CatalogTableProps) => { }, ({ entity }) => { const isStarred = isStarredEntity(entity); - const title = isStarred ? 'Remove from favorites' : 'Add to favorites'; + const title = isStarred + ? t('catalogTable.unStarActionTitle') + : t('catalogTable.starActionTitle'); return { cellStyle: { paddingLeft: '1em' }, diff --git a/plugins/catalog/src/components/DependencyOfComponentsCard/DependencyOfComponentsCard.tsx b/plugins/catalog/src/components/DependencyOfComponentsCard/DependencyOfComponentsCard.tsx index d87b558048..617d009d4f 100644 --- a/plugins/catalog/src/components/DependencyOfComponentsCard/DependencyOfComponentsCard.tsx +++ b/plugins/catalog/src/components/DependencyOfComponentsCard/DependencyOfComponentsCard.tsx @@ -23,6 +23,8 @@ import { componentEntityHelpLink, RelatedEntitiesCard, } from '../RelatedEntitiesCard'; +import { catalogTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; /** @public */ export interface DependencyOfComponentsCardProps { @@ -33,7 +35,11 @@ export interface DependencyOfComponentsCardProps { export function DependencyOfComponentsCard( props: DependencyOfComponentsCardProps, ) { - const { variant = 'gridItem', title = 'Dependency of components' } = props; + const { t } = useTranslationRef(catalogTranslationRef); + const { + variant = 'gridItem', + title = t('dependencyOfComponentsCard.title'), + } = props; return ( diff --git a/plugins/catalog/src/components/DependsOnComponentsCard/DependsOnComponentsCard.tsx b/plugins/catalog/src/components/DependsOnComponentsCard/DependsOnComponentsCard.tsx index f4ea850b9b..fe56ea582b 100644 --- a/plugins/catalog/src/components/DependsOnComponentsCard/DependsOnComponentsCard.tsx +++ b/plugins/catalog/src/components/DependsOnComponentsCard/DependsOnComponentsCard.tsx @@ -27,6 +27,8 @@ import { componentEntityHelpLink, RelatedEntitiesCard, } from '../RelatedEntitiesCard'; +import { catalogTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; /** @public */ export interface DependsOnComponentsCardProps { @@ -37,9 +39,10 @@ export interface DependsOnComponentsCardProps { } export function DependsOnComponentsCard(props: DependsOnComponentsCardProps) { + const { t } = useTranslationRef(catalogTranslationRef); const { variant = 'gridItem', - title = 'Depends on components', + title = t('dependsOnComponentsCard.title'), columns = componentEntityColumns, tableOptions = {}, } = props; @@ -50,7 +53,7 @@ export function DependsOnComponentsCard(props: DependsOnComponentsCardProps) { entityKind="Component" relationType={RELATION_DEPENDS_ON} columns={columns} - emptyMessage="No component is a dependency of this component" + emptyMessage={t('dependsOnComponentsCard.emptyMessage')} emptyHelpLink={componentEntityHelpLink} asRenderableEntities={asComponentEntities} tableOptions={tableOptions} diff --git a/plugins/catalog/src/components/DependsOnResourcesCard/DependsOnResourcesCard.tsx b/plugins/catalog/src/components/DependsOnResourcesCard/DependsOnResourcesCard.tsx index d99a9df387..281bfd8766 100644 --- a/plugins/catalog/src/components/DependsOnResourcesCard/DependsOnResourcesCard.tsx +++ b/plugins/catalog/src/components/DependsOnResourcesCard/DependsOnResourcesCard.tsx @@ -27,6 +27,8 @@ import { RelatedEntitiesCard, resourceEntityColumns, } from '../RelatedEntitiesCard'; +import { catalogTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; /** @public */ export interface DependsOnResourcesCardProps { @@ -37,9 +39,10 @@ export interface DependsOnResourcesCardProps { } export function DependsOnResourcesCard(props: DependsOnResourcesCardProps) { + const { t } = useTranslationRef(catalogTranslationRef); const { variant = 'gridItem', - title = 'Depends on resources', + title = t('dependsOnResourcesCard.title'), columns = resourceEntityColumns, tableOptions = {}, } = props; @@ -50,7 +53,7 @@ export function DependsOnResourcesCard(props: DependsOnResourcesCardProps) { entityKind="Resource" relationType={RELATION_DEPENDS_ON} columns={columns} - emptyMessage="No resource is a dependency of this component" + emptyMessage={t('dependsOnResourcesCard.emptyMessage')} emptyHelpLink={componentEntityHelpLink} asRenderableEntities={asResourceEntities} tableOptions={tableOptions} diff --git a/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.tsx b/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.tsx index a173773e35..5b740038a1 100644 --- a/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.tsx +++ b/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.tsx @@ -33,6 +33,8 @@ import { catalogEntityDeletePermission } from '@backstage/plugin-catalog-common/ import { UnregisterEntity, UnregisterEntityOptions } from './UnregisterEntity'; import { useApi, alertApiRef } from '@backstage/core-plugin-api'; import useCopyToClipboard from 'react-use/esm/useCopyToClipboard'; +import { catalogTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; /** @public */ export type EntityContextMenuClassKey = 'button'; @@ -70,6 +72,7 @@ export function EntityContextMenu(props: EntityContextMenuProps) { onUnregisterEntity, onInspectEntity, } = props; + const { t } = useTranslationRef(catalogTranslationRef); const [anchorEl, setAnchorEl] = useState(); const classes = useStyles(); const unregisterPermission = useEntityPermission( @@ -90,12 +93,12 @@ export function EntityContextMenu(props: EntityContextMenuProps) { useEffect(() => { if (!copyState.error && copyState.value) { alertApi.post({ - message: 'Copied!', + message: t('entityContextMenu.copiedMessage'), severity: 'info', display: 'transient', }); } - }, [copyState, alertApi]); + }, [copyState, alertApi, t]); const extraItems = UNSTABLE_extraContextMenuItems && [ ...UNSTABLE_extraContextMenuItems.map(item => ( @@ -117,7 +120,7 @@ export function EntityContextMenu(props: EntityContextMenuProps) { return ( <> - + - + { @@ -168,7 +171,7 @@ export function EntityContextMenu(props: EntityContextMenuProps) { - + diff --git a/plugins/catalog/src/components/EntityContextMenu/UnregisterEntity.tsx b/plugins/catalog/src/components/EntityContextMenu/UnregisterEntity.tsx index 3de890097b..08496d4819 100644 --- a/plugins/catalog/src/components/EntityContextMenu/UnregisterEntity.tsx +++ b/plugins/catalog/src/components/EntityContextMenu/UnregisterEntity.tsx @@ -19,6 +19,8 @@ import ListItemIcon from '@material-ui/core/ListItemIcon'; import ListItemText from '@material-ui/core/ListItemText'; import MenuItem from '@material-ui/core/MenuItem'; import CancelIcon from '@material-ui/icons/Cancel'; +import { catalogTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; type VisibleType = 'visible' | 'hidden' | 'disable'; @@ -40,6 +42,7 @@ export function UnregisterEntity(props: UnregisterEntityProps) { onUnregisterEntity, onClose, } = props; + const { t } = useTranslationRef(catalogTranslationRef); const isBoolean = typeof unregisterEntityOptions?.disableUnregister === 'boolean'; @@ -65,7 +68,7 @@ export function UnregisterEntity(props: UnregisterEntityProps) { - + ); } diff --git a/plugins/catalog/src/components/EntityLabelsCard/EntityLabelsCard.tsx b/plugins/catalog/src/components/EntityLabelsCard/EntityLabelsCard.tsx index 0b1448bb1f..d48b45f054 100644 --- a/plugins/catalog/src/components/EntityLabelsCard/EntityLabelsCard.tsx +++ b/plugins/catalog/src/components/EntityLabelsCard/EntityLabelsCard.tsx @@ -25,6 +25,8 @@ import { import { EntityLabelsEmptyState } from './EntityLabelsEmptyState'; import Typography from '@material-ui/core/Typography'; import { makeStyles } from '@material-ui/core/styles'; +import { catalogTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; /** @public */ export interface EntityLabelsCardProps { @@ -42,6 +44,7 @@ export const EntityLabelsCard = (props: EntityLabelsCardProps) => { const { variant, title } = props; const { entity } = useEntity(); const classes = useStyles(); + const { t } = useTranslationRef(catalogTranslationRef); const columns: TableColumn<{ key: string; value: string }>[] = [ { @@ -61,7 +64,7 @@ export const EntityLabelsCard = (props: EntityLabelsCardProps) => { const labels = entity?.metadata?.labels; return ( - + {!labels || Object.keys(labels).length === 0 ? ( ) : ( diff --git a/plugins/catalog/src/components/EntityLabelsCard/EntityLabelsEmptyState.tsx b/plugins/catalog/src/components/EntityLabelsCard/EntityLabelsEmptyState.tsx index 5f5db0baa5..16d0a3a897 100644 --- a/plugins/catalog/src/components/EntityLabelsCard/EntityLabelsEmptyState.tsx +++ b/plugins/catalog/src/components/EntityLabelsCard/EntityLabelsEmptyState.tsx @@ -19,6 +19,8 @@ import Typography from '@material-ui/core/Typography'; import { makeStyles } from '@material-ui/core/styles'; import React from 'react'; import { CodeSnippet } from '@backstage/core-components'; +import { catalogTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; const ENTITY_YAML = `metadata: name: example @@ -39,12 +41,12 @@ const useStyles = makeStyles( export function EntityLabelsEmptyState() { const classes = useStyles(); + const { t } = useTranslationRef(catalogTranslationRef); return ( <> - No labels defined for this entity. You can add labels to your entity - YAML as shown in the highlighted example below: + {t('entityLabelsCard.emptyDescription')}
- Read more + {t('entityLabelsCard.readMoreButtonTitle')} ); diff --git a/plugins/catalog/src/components/EntityLayout/EntityLayout.tsx b/plugins/catalog/src/components/EntityLayout/EntityLayout.tsx index 274972283f..bbc7792acb 100644 --- a/plugins/catalog/src/components/EntityLayout/EntityLayout.tsx +++ b/plugins/catalog/src/components/EntityLayout/EntityLayout.tsx @@ -53,6 +53,8 @@ import React, { useEffect, useState } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; import { EntityContextMenu } from '../EntityContextMenu/EntityContextMenu'; import { rootRouteRef, unregisterRedirectRouteRef } from '../../routes'; +import { catalogTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; /** @public */ export type EntityLayoutRouteProps = { @@ -117,11 +119,12 @@ function headerProps( function EntityLabels(props: { entity: Entity }) { const { entity } = props; const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY); + const { t } = useTranslationRef(catalogTranslationRef); return ( <> {ownedByRelations.length > 0 && ( )} @@ -234,6 +237,7 @@ export const EntityLayout = (props: EntityLayoutProps) => { const navigate = useNavigate(); const catalogRoute = useRouteRef(rootRouteRef); const unregisterRedirectRoute = useRouteRef(unregisterRedirectRouteRef); + const { t } = useTranslationRef(catalogTranslationRef); const cleanUpAfterRemoval = async () => { setConfirmationDialogOpen(false); @@ -286,7 +290,7 @@ export const EntityLayout = (props: EntityLayoutProps) => { {NotFoundComponent ? ( NotFoundComponent ) : ( - + There is no {kind} with the requested{' '} kind, namespace, and name diff --git a/plugins/catalog/src/components/EntityLinksCard/EntityLinksCard.tsx b/plugins/catalog/src/components/EntityLinksCard/EntityLinksCard.tsx index ebc551c29f..b5d8269a0b 100644 --- a/plugins/catalog/src/components/EntityLinksCard/EntityLinksCard.tsx +++ b/plugins/catalog/src/components/EntityLinksCard/EntityLinksCard.tsx @@ -22,6 +22,8 @@ import { LinksGridList } from './LinksGridList'; import { ColumnBreakpoints } from './types'; import { IconComponent, useApp } from '@backstage/core-plugin-api'; import { InfoCard, InfoCardVariants } from '@backstage/core-components'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; +import { catalogTranslationRef } from '../../translation'; /** @public */ export interface EntityLinksCardProps { @@ -33,6 +35,7 @@ export const EntityLinksCard = (props: EntityLinksCardProps) => { const { cols = undefined, variant } = props; const { entity } = useEntity(); const app = useApp(); + const { t } = useTranslationRef(catalogTranslationRef); const iconResolver = (key?: string): IconComponent => key ? app.getSystemIcon(key) ?? LanguageIcon : LanguageIcon; @@ -40,7 +43,7 @@ export const EntityLinksCard = (props: EntityLinksCardProps) => { const links = entity?.metadata?.links; return ( - + {!links || links.length === 0 ? ( ) : ( diff --git a/plugins/catalog/src/components/EntityLinksCard/EntityLinksEmptyState.tsx b/plugins/catalog/src/components/EntityLinksCard/EntityLinksEmptyState.tsx index 81009c5393..09362385f9 100644 --- a/plugins/catalog/src/components/EntityLinksCard/EntityLinksEmptyState.tsx +++ b/plugins/catalog/src/components/EntityLinksCard/EntityLinksEmptyState.tsx @@ -19,6 +19,8 @@ import Typography from '@material-ui/core/Typography'; import { makeStyles } from '@material-ui/core/styles'; import React from 'react'; import { CodeSnippet } from '@backstage/core-components'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; +import { catalogTranslationRef } from '../../translation'; const ENTITY_YAML = `metadata: name: example @@ -44,12 +46,12 @@ const useStyles = makeStyles( export function EntityLinksEmptyState() { const classes = useStyles(); + const { t } = useTranslationRef(catalogTranslationRef); return ( <> - No links defined for this entity. You can add links to your entity YAML - as shown in the highlighted example below: + {t('entityLinksCard.emptyDescription')}
- Read more + {t('entityLinksCard.readMoreButtonTitle')} ); diff --git a/plugins/catalog/src/components/EntityNotFound/EntityNotFound.tsx b/plugins/catalog/src/components/EntityNotFound/EntityNotFound.tsx index 479edf3984..252005dff5 100644 --- a/plugins/catalog/src/components/EntityNotFound/EntityNotFound.tsx +++ b/plugins/catalog/src/components/EntityNotFound/EntityNotFound.tsx @@ -20,6 +20,8 @@ import Button from '@material-ui/core/Button'; import Typography from '@material-ui/core/Typography'; import { makeStyles } from '@material-ui/core/styles'; import { Illo } from './Illo'; +import { catalogTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; const useStyles = makeStyles(theme => ({ container: { @@ -45,24 +47,24 @@ const useStyles = makeStyles(theme => ({ export function EntityNotFound() { const classes = useStyles(); + const { t } = useTranslationRef(catalogTranslationRef); return ( - Entity was not found + {t('entityNotFound.title')} - Want to help us build this? Check out our Getting Started - documentation. + {t('entityNotFound.description')} diff --git a/plugins/catalog/src/components/EntityOrphanWarning/DeleteEntityDialog.tsx b/plugins/catalog/src/components/EntityOrphanWarning/DeleteEntityDialog.tsx index 603f2040d9..c9c24a14a1 100644 --- a/plugins/catalog/src/components/EntityOrphanWarning/DeleteEntityDialog.tsx +++ b/plugins/catalog/src/components/EntityOrphanWarning/DeleteEntityDialog.tsx @@ -23,6 +23,8 @@ import DialogTitle from '@material-ui/core/DialogTitle'; import React, { useState } from 'react'; import { alertApiRef, useApi } from '@backstage/core-plugin-api'; import { assertError } from '@backstage/errors'; +import { catalogTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; interface DeleteEntityDialogProps { open: boolean; @@ -36,6 +38,7 @@ export function DeleteEntityDialog(props: DeleteEntityDialogProps) { const [busy, setBusy] = useState(false); const catalogApi = useApi(catalogApiRef); const alertApi = useApi(alertApiRef); + const { t } = useTranslationRef(catalogTranslationRef); const onDelete = async () => { setBusy(true); @@ -54,7 +57,7 @@ export function DeleteEntityDialog(props: DeleteEntityDialogProps) { return ( - Are you sure you want to delete this entity? + {t('deleteEntity.dialogTitle')} diff --git a/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx index 8a17559681..10a10e54fd 100644 --- a/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx +++ b/plugins/catalog/src/components/EntityOrphanWarning/EntityOrphanWarning.tsx @@ -22,6 +22,8 @@ import { useNavigate } from 'react-router-dom'; import { DeleteEntityDialog } from './DeleteEntityDialog'; import { useRouteRef } from '@backstage/core-plugin-api'; import { rootRouteRef } from '../../routes'; +import { catalogTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; /** * Returns true if the given entity has the orphan annotation given by the @@ -44,6 +46,7 @@ export function EntityOrphanWarning() { const catalogLink = useRouteRef(rootRouteRef); const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false); const { entity } = useEntity(); + const { t } = useTranslationRef(catalogTranslationRef); const cleanUpAfterRemoval = async () => { setConfirmationDialogOpen(false); @@ -53,8 +56,7 @@ export function EntityOrphanWarning() { return ( <> setConfirmationDialogOpen(true)}> - This entity is not referenced by any location and is therefore not - receiving updates. Click here to delete. + {t('deleteEntity.description')} i.error && @@ -95,6 +97,7 @@ export function EntityProcessingErrorsPanel() { const { loading, error, value } = useAsync(async () => { return getOwnAndAncestorsErrors(entityRef, catalogApi); }, [entityRef, catalogApi]); + const { t } = useTranslationRef(catalogTranslationRef); if (error) { return ( @@ -115,7 +118,7 @@ export function EntityProcessingErrorsPanel() { {stringifyEntityRef(entity) !== stringifyEntityRef(ancestorError.entity) && ( - The error below originates from{' '} + {t('entityProcessingErrorsDescription')}{' '} )} diff --git a/plugins/catalog/src/components/EntityRelationWarning/EntityRelationWarning.tsx b/plugins/catalog/src/components/EntityRelationWarning/EntityRelationWarning.tsx index 13542a32b4..2ce9120bf0 100644 --- a/plugins/catalog/src/components/EntityRelationWarning/EntityRelationWarning.tsx +++ b/plugins/catalog/src/components/EntityRelationWarning/EntityRelationWarning.tsx @@ -26,6 +26,8 @@ import useAsync from 'react-use/esm/useAsync'; import Box from '@material-ui/core/Box'; import { ResponseErrorPanel } from '@backstage/core-components'; import { useApi, ApiHolder } from '@backstage/core-plugin-api'; +import { catalogTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; async function getRelationWarnings(entity: Entity, catalogApi: CatalogApi) { const entityRefRelations = entity.relations?.map( @@ -80,6 +82,7 @@ export function EntityRelationWarning() { const { loading, error, value } = useAsync(async () => { return getRelationWarnings(entity, catalogApi); }, [entity, catalogApi]); + const { t } = useTranslationRef(catalogTranslationRef); if (error) { return ( @@ -95,10 +98,8 @@ export function EntityRelationWarning() { return ( <> - - This entity has relations to other entities, which can't be found in the - catalog.
- Entities not found are: {value.join(', ')} + + {t('entityRelationWarningDescription')} {value.join(', ')} ); diff --git a/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.tsx b/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.tsx index 9071dac030..917543dd12 100644 --- a/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.tsx +++ b/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.tsx @@ -23,6 +23,8 @@ import { componentEntityHelpLink, RelatedEntitiesCard, } from '../RelatedEntitiesCard'; +import { catalogTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; /** @public */ export interface HasComponentsCardProps { @@ -31,7 +33,8 @@ export interface HasComponentsCardProps { } export function HasComponentsCard(props: HasComponentsCardProps) { - const { variant = 'gridItem', title = 'Has components' } = props; + const { t } = useTranslationRef(catalogTranslationRef); + const { variant = 'gridItem', title = t('hasComponentsCard.title') } = props; return ( diff --git a/plugins/catalog/src/components/HasResourcesCard/HasResourcesCard.tsx b/plugins/catalog/src/components/HasResourcesCard/HasResourcesCard.tsx index 5af7eec258..d11f10c882 100644 --- a/plugins/catalog/src/components/HasResourcesCard/HasResourcesCard.tsx +++ b/plugins/catalog/src/components/HasResourcesCard/HasResourcesCard.tsx @@ -23,6 +23,8 @@ import { resourceEntityColumns, resourceEntityHelpLink, } from '../RelatedEntitiesCard'; +import { catalogTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; /** @public */ export interface HasResourcesCardProps { @@ -31,7 +33,8 @@ export interface HasResourcesCardProps { } export function HasResourcesCard(props: HasResourcesCardProps) { - const { variant = 'gridItem', title = 'Has resources' } = props; + const { t } = useTranslationRef(catalogTranslationRef); + const { variant = 'gridItem', title = t('hasResourcesCard.title') } = props; return ( ); diff --git a/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.tsx b/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.tsx index ac40c82435..d81349794a 100644 --- a/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.tsx +++ b/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.tsx @@ -22,6 +22,8 @@ import { componentEntityColumns, RelatedEntitiesCard, } from '../RelatedEntitiesCard'; +import { catalogTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; /** @public */ export interface HasSubcomponentsCardProps { @@ -31,10 +33,11 @@ export interface HasSubcomponentsCardProps { } export function HasSubcomponentsCard(props: HasSubcomponentsCardProps) { + const { t } = useTranslationRef(catalogTranslationRef); const { variant = 'gridItem', tableOptions = {}, - title = 'Has subcomponents', + title = t('hasSubcomponentsCard.title'), } = props; return ( diff --git a/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.tsx b/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.tsx index d6da465ffa..cee45a95c5 100644 --- a/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.tsx +++ b/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.tsx @@ -23,6 +23,8 @@ import { systemEntityColumns, systemEntityHelpLink, } from '../RelatedEntitiesCard'; +import { catalogTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; /** @public */ export interface HasSystemsCardProps { @@ -31,7 +33,8 @@ export interface HasSystemsCardProps { } export function HasSystemsCard(props: HasSystemsCardProps) { - const { variant = 'gridItem', title = 'Has systems' } = props; + const { t } = useTranslationRef(catalogTranslationRef); + const { variant = 'gridItem', title = t('hasSystemsCard.title') } = props; return ( ); diff --git a/plugins/catalog/src/components/RelatedEntitiesCard/RelatedEntitiesCard.tsx b/plugins/catalog/src/components/RelatedEntitiesCard/RelatedEntitiesCard.tsx index eb37973c27..dd1359482d 100644 --- a/plugins/catalog/src/components/RelatedEntitiesCard/RelatedEntitiesCard.tsx +++ b/plugins/catalog/src/components/RelatedEntitiesCard/RelatedEntitiesCard.tsx @@ -31,6 +31,8 @@ import { TableColumn, TableOptions, } from '@backstage/core-components'; +import { catalogTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; /** @public */ export type RelatedEntitiesCardProps = { @@ -72,6 +74,7 @@ export function RelatedEntitiesCard( tableOptions = {}, } = props; + const { t } = useTranslationRef(catalogTranslationRef); const { entity } = useEntity(); const { entities, loading, error } = useRelatedEntities(entity, { type: relationType, @@ -102,7 +105,9 @@ export function RelatedEntitiesCard(
{emptyMessage} - Learn how to change this. + + {t('relatedEntitiesCard.emptyHelpLinkTitle')} +
} diff --git a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.tsx b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.tsx index 22466b1464..5e485d672b 100644 --- a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.tsx +++ b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.tsx @@ -46,6 +46,8 @@ import { } from '@backstage/core-components'; import { useApi, useRouteRef } from '@backstage/core-plugin-api'; +import { catalogTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; /** @public */ export type SystemDiagramCardClassKey = @@ -164,6 +166,7 @@ function RenderNode(props: DependencyGraphTypes.RenderNodeProps) { export function SystemDiagramCard() { const { entity } = useEntity(); const theme = useTheme(); + const { t } = useTranslationRef(catalogTranslationRef); const currentSystemName = entity.metadata.name; const currentSystemNode = stringifyEntityRef(entity); const systemNodes = new Array<{ id: string; kind: string; name: string }>(); @@ -211,7 +214,7 @@ export function SystemDiagramCard() { systemEdges.push({ from: currentSystemNode, to: stringifyEntityRef(foundDomain), - label: 'part of', + label: t('systemDiagramCard.edgeLabels.partOf'), }), ); @@ -235,7 +238,7 @@ export function SystemDiagramCard() { systemEdges.push({ from: stringifyEntityRef(catalogItem), to: stringifyEntityRef(foundRelation), - label: 'part of', + label: t('systemDiagramCard.edgeLabels.partOf'), }), ); @@ -247,7 +250,7 @@ export function SystemDiagramCard() { systemEdges.push({ from: stringifyEntityRef(catalogItem), to: stringifyEntityRef(foundRelation), - label: 'provides', + label: t('systemDiagramCard.edgeLabels.provides'), }), ); @@ -259,7 +262,7 @@ export function SystemDiagramCard() { systemEdges.push({ from: stringifyEntityRef(catalogItem), to: stringifyEntityRef(foundRelation), - label: 'depends on', + label: t('systemDiagramCard.edgeLabels.dependsOn'), }), ); } @@ -272,7 +275,7 @@ export function SystemDiagramCard() { } return ( - + - Use pinch & zoom - to move around the diagram. + + {t('systemDiagramCard.description')} ); diff --git a/plugins/catalog/src/translation.ts b/plugins/catalog/src/translation.ts index bd27069fde..2699b58542 100644 --- a/plugins/catalog/src/translation.ts +++ b/plugins/catalog/src/translation.ts @@ -23,6 +23,141 @@ export const catalogTranslationRef = createTranslationRef({ indexPage: { title: `{{orgName}} Catalog`, createButtonTitle: 'Create', + supportButtonContent: 'All your software catalog entities', + }, + aboutCard: { + title: 'About', + refreshButtonTitle: 'Schedule entity refresh', + editButtonTitle: 'Edit Metadata', + createSimilarButtonTitle: 'Create something similar', + refreshScheduledMessage: 'Refresh scheduled', + launchTemplate: 'Launch Template', + viewTechdocs: 'View TechDocs', + viewSource: 'View Source', + descriptionField: { + label: 'Description', + value: 'No description', + }, + ownerField: { + label: 'Owner', + value: 'No Owner', + }, + domainField: { + label: 'Domain', + value: 'No Domain', + }, + systemField: { + label: 'System', + value: 'No System', + }, + parentComponentField: { + label: 'Parent Component', + value: 'No Parent Component', + }, + typeField: { + label: 'Type', + }, + lifecycleField: { + label: 'Lifecycle', + }, + tagsField: { + label: 'Tags', + value: 'No Tags', + }, + targetsField: { + label: 'Targets', + }, + }, + searchResultItem: { + lifecycle: 'Lifecycle', + Owner: 'Owner', + }, + catalogTable: { + warningPanelTitle: 'Could not fetch catalog entities.', + viewActionTitle: 'View', + editActionTitle: 'Edit', + starActionTitle: 'Add to favorites', + unStarActionTitle: 'Remove from favorites', + }, + dependencyOfComponentsCard: { + title: 'Dependency of components', + emptyMessage: 'No component depends on this component', + }, + dependsOnComponentsCard: { + title: 'Depends on components', + emptyMessage: 'No component is a dependency of this component', + }, + dependsOnResourcesCard: { + title: 'Depends on resources', + emptyMessage: 'No resource is a dependency of this component', + }, + entityContextMenu: { + copiedMessage: 'Copied!', + moreButtonTitle: 'More', + inspectMenuTitle: 'Inspect entity', + copyURLMenuTitle: 'Copy entity URL', + unregisterMenuTitle: 'Unregister entity', + }, + entityLabelsCard: { + title: 'Labels', + emptyDescription: + 'No labels defined for this entity. You can add labels to your entity YAML as shown in the highlighted example below:', + readMoreButtonTitle: 'Read more', + }, + entityLabels: { + warningPanelTitle: 'Entity not found', + ownerLabel: 'Owner', + lifecycleLabel: 'Lifecycle', + }, + entityLinksCard: { + title: 'Links', + emptyDescription: + 'No links defined for this entity. You can add links to your entity YAML as shown in the highlighted example below:', + readMoreButtonTitle: 'Read more', + }, + entityNotFound: { + title: 'Entity was not found', + description: + 'Want to help us build this? Check out our Getting Started documentation.', + docButtonTitle: 'DOCS', + }, + deleteEntity: { + dialogTitle: 'Are you sure you want to delete this entity?', + deleteButtonTitle: 'Delete', + cancelButtonTitle: 'Cancel', + description: + 'This entity is not referenced by any location and is therefore not receiving updates. Click here to delete.', + }, + entityProcessingErrorsDescription: 'The error below originates from', + entityRelationWarningDescription: + "This entity has relations to other entities, which can't be found in the catalog.\n Entities not found are: ", + hasComponentsCard: { + title: 'Has components', + emptyMessage: 'No component is part of this system', + }, + hasResourcesCard: { + title: 'Has resources', + emptyMessage: 'No resource is part of this system', + }, + hasSubcomponentsCard: { + title: 'Has subcomponents', + emptyMessage: 'No subcomponent is part of this component', + }, + hasSystemsCard: { + title: 'Has systems', + emptyMessage: 'No system is part of this domain', + }, + relatedEntitiesCard: { + emptyHelpLinkTitle: 'Learn how to change this.', + }, + systemDiagramCard: { + title: 'System Diagram', + description: 'Use pinch & zoo to move around the diagram.', + edgeLabels: { + partOf: 'part of', + provides: 'provides', + dependsOn: 'depends on', + }, }, }, }); From 06c09562079e9d1b31c6af4b85ba5991301f675b Mon Sep 17 00:00:00 2001 From: mario ma Date: Tue, 5 Mar 2024 17:24:27 +0800 Subject: [PATCH 038/510] feat: add i18n to plugin-catalog-react Signed-off-by: mario ma --- .changeset/friendly-oranges-greet.md | 7 ++ plugins/catalog-react/api-report-alpha.md | 59 +++++++++ plugins/catalog-react/src/alpha.tsx | 1 + .../CatalogFilterLayout.tsx | 7 +- .../EntityKindPicker.test.tsx | 14 +-- .../EntityKindPicker/EntityKindPicker.tsx | 9 +- .../EntityLifecyclePicker.test.tsx | 18 +-- .../EntityLifecyclePicker.tsx | 5 +- .../EntityNamespacePicker.test.tsx | 20 +-- .../EntityNamespacePicker.tsx | 6 +- .../EntityOwnerPicker.test.tsx | 24 ++-- .../EntityOwnerPicker/EntityOwnerPicker.tsx | 5 +- .../CardActionComponents/EmailCardAction.tsx | 11 +- .../EntityCardActions.tsx | 5 +- .../EntityPeekAheadPopover.tsx | 6 +- .../EntityProcessingStatusPicker.test.tsx | 23 ++-- .../EntityProcessingStatusPicker.tsx | 5 +- .../EntitySearchBar/EntitySearchBar.test.tsx | 7 +- .../EntitySearchBar/EntitySearchBar.tsx | 5 +- .../src/components/EntityTable/columns.tsx | 2 + .../EntityTagPicker/EntityTagPicker.test.tsx | 28 ++--- .../EntityTagPicker/EntityTagPicker.tsx | 5 +- .../EntityTypePicker.test.tsx | 10 +- .../EntityTypePicker/EntityTypePicker.tsx | 11 +- .../FavoriteEntity/FavoriteEntity.tsx | 9 +- .../InspectEntityDialog.tsx | 7 +- .../components/AncestryPage.tsx | 7 +- .../components/ColocatedPage.tsx | 18 ++- .../components/JsonPage.tsx | 9 +- .../components/OverviewPage.tsx | 7 +- .../components/YamlPage.tsx | 9 +- .../UnregisterEntityDialog.tsx | 63 +++++----- .../UserListPicker/UserListPicker.test.tsx | 44 ++++--- .../UserListPicker/UserListPicker.tsx | 27 ++-- .../src/hooks/useEntityListProvider.test.tsx | 5 + plugins/catalog-react/src/translation.ts | 116 ++++++++++++++++++ plugins/catalog/api-report-alpha.md | 75 +++++++++++ plugins/catalog/src/alpha.ts | 1 + .../TemplateCard/CardHeader.test.tsx | 6 +- 39 files changed, 526 insertions(+), 170 deletions(-) create mode 100644 .changeset/friendly-oranges-greet.md create mode 100644 plugins/catalog-react/src/translation.ts diff --git a/.changeset/friendly-oranges-greet.md b/.changeset/friendly-oranges-greet.md new file mode 100644 index 0000000000..4fbabf76f5 --- /dev/null +++ b/.changeset/friendly-oranges-greet.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-scaffolder-react': patch +'@backstage/plugin-catalog-react': patch +'@backstage/plugin-catalog': patch +--- + +Support i18n for catalog and catalog-react plugins diff --git a/plugins/catalog-react/api-report-alpha.md b/plugins/catalog-react/api-report-alpha.md index fb807d947d..ea01122ccc 100644 --- a/plugins/catalog-react/api-report-alpha.md +++ b/plugins/catalog-react/api-report-alpha.md @@ -13,6 +13,7 @@ import { PortableSchema } from '@backstage/frontend-plugin-api'; import { ResolvedExtensionInputs } from '@backstage/frontend-plugin-api'; import { ResourcePermission } from '@backstage/plugin-permission-common'; import { RouteRef } from '@backstage/frontend-plugin-api'; +import { TranslationRef } from '@backstage/core-plugin-api/alpha'; // @alpha (undocumented) export const catalogExtensionData: { @@ -24,6 +25,64 @@ export const catalogExtensionData: { entityFilterExpression: ConfigurableExtensionDataRef; }; +// @alpha (undocumented) +export const catalogReactTranslationRef: TranslationRef< + 'catalog-react', + { + readonly 'catalogFilter.title': 'Filters'; + readonly 'catalogFilter.buttonTitle': 'Filters'; + readonly 'entityKindPicker.title': 'Kind'; + readonly 'entityKindPicker.errorMessage': 'Failed to load entity kinds'; + readonly entityLifecyclePickerTitle: 'Lifecycle'; + readonly entityNamespacePickerTitle: 'Namespace'; + readonly entityOwnerPickerTitle: 'Owner'; + readonly 'entityPeekAheadPopover.title': 'Drill into the entity to see all of the tags.'; + readonly 'entityPeekAheadPopover.entityCardActionsTitle': 'Show details'; + readonly 'entityPeekAheadPopover.emailCardAction.title': 'Email {{email}}'; + readonly 'entityPeekAheadPopover.emailCardAction.subTitle': 'mailto {{email}}'; + readonly entityProcessingStatusPickerTitle: 'Processing Status'; + readonly entitySearchBarPlaceholder: 'Search'; + readonly entityTagPickerTitle: 'Tags'; + readonly 'entityTypePicker.title': 'Type'; + readonly 'entityTypePicker.errorMessage': 'Failed to load entity types'; + readonly 'entityTypePicker.optionAllTitle': 'all'; + readonly 'favoriteEntity.addToFavorites': 'Add to favorites'; + readonly 'favoriteEntity.RemoveFromFavorites': 'Remove from favorites'; + readonly 'inspectEntityDialog.title': 'Entity Inspector'; + readonly 'inspectEntityDialog.closeButtonTitle': 'Close'; + readonly 'inspectEntityDialog.ancestryPage.title': 'Ancestry'; + readonly 'inspectEntityDialog.colocatedPage.title': 'Colocated'; + readonly 'inspectEntityDialog.colocatedPage.description': 'These are the entities that are colocated with this entity - as in, they originated from the same data source (e.g. came from the same YAML file), or from the same origin (e.g. the originally registered URL).'; + readonly 'inspectEntityDialog.colocatedPage.alertNoLocation': 'Entity had no location information.'; + readonly 'inspectEntityDialog.colocatedPage.alertNoEntity': 'There were no other entities on this location.'; + readonly 'inspectEntityDialog.jsonPage.title': 'Entity as JSON'; + readonly 'inspectEntityDialog.jsonPage.description': 'This is the raw entity data as received from the catalog, on JSON form.'; + readonly 'inspectEntityDialog.overviewPage.title': 'Overview'; + readonly 'inspectEntityDialog.yamlPage.title': 'Entity as YAML'; + readonly 'inspectEntityDialog.yamlPage.description': 'This is the raw entity data as received from the catalog, on YAML form.'; + readonly 'unregisterEntityDialog.title': 'Are you sure you want to unregister this entity?'; + readonly 'unregisterEntityDialog.cancelButtonTitle': 'Cancel'; + readonly 'unregisterEntityDialog.deleteButtonTitle': 'Delete Entity'; + readonly 'unregisterEntityDialog.deleteEntitySuccessMessage': 'Removed entity {{entityName}}'; + readonly 'unregisterEntityDialog.onlyDeleteStateTitle': 'This entity does not seem to originate from a registered location. You therefore only have the option to delete it outright from the catalog.'; + readonly 'unregisterEntityDialog.errorStateTitle': 'Internal error: Unknown state'; + readonly 'unregisterEntityDialog.bootstrapState.title': 'You cannot unregister this entity, since it originates from a protected Backstage configuration (location "{{location}}"). If you believe this is in error, please contact the {{appTitle}} integrator.'; + readonly 'unregisterEntityDialog.bootstrapState.advancedDescription': 'You have the option to delete the entity itself from the catalog. Note that this should only be done if you know that the catalog file has been deleted at, or moved from, its origin location. If that is not the case, the entity will reappear shortly as the next refresh round is performed by the catalog.'; + readonly 'unregisterEntityDialog.bootstrapState.advancedOptions': 'Advanced Options'; + readonly 'unregisterEntityDialog.unregisterState.title': 'This action will unregister the following entities:'; + readonly 'unregisterEntityDialog.unregisterState.description': 'To undo, just re-register the entity in {{appTitle}}.'; + readonly 'unregisterEntityDialog.unregisterState.subTitle': 'Located at the following location:'; + readonly 'unregisterEntityDialog.unregisterState.advancedDescription': 'You also have the option to delete the entity itself from the catalog. Note that this should only be done if you know that the catalog file has been deleted at, or moved from, its origin location. If that is not the case, the entity will reappear shortly as the next refresh round is performed by the catalog.'; + readonly 'unregisterEntityDialog.unregisterState.advancedOptions': 'Advanced Options'; + readonly 'unregisterEntityDialog.unregisterState.unregisterButtonTitle': 'Unregister Location'; + readonly 'userListPicker.defaultOrgName': 'Company'; + readonly 'userListPicker.orgFilterAllLabel': 'All'; + readonly 'userListPicker.personalFilter.title': 'Personal'; + readonly 'userListPicker.personalFilter.ownedLabel': 'Owned'; + readonly 'userListPicker.personalFilter.starredLabel': 'Starred'; + } +>; + // @alpha (undocumented) export function createEntityCardExtension< TConfig extends { diff --git a/plugins/catalog-react/src/alpha.tsx b/plugins/catalog-react/src/alpha.tsx index f5f4dfdb74..b1650d1f5b 100644 --- a/plugins/catalog-react/src/alpha.tsx +++ b/plugins/catalog-react/src/alpha.tsx @@ -32,6 +32,7 @@ import { Expand } from '../../../packages/frontend-plugin-api/src/types'; export { useEntityPermission } from './hooks/useEntityPermission'; export { isOwnerOf } from './utils'; +export * from './translation'; /** @alpha */ export const catalogExtensionData = { diff --git a/plugins/catalog-react/src/components/CatalogFilterLayout/CatalogFilterLayout.tsx b/plugins/catalog-react/src/components/CatalogFilterLayout/CatalogFilterLayout.tsx index 7583520412..ee51020cbb 100644 --- a/plugins/catalog-react/src/components/CatalogFilterLayout/CatalogFilterLayout.tsx +++ b/plugins/catalog-react/src/components/CatalogFilterLayout/CatalogFilterLayout.tsx @@ -23,6 +23,8 @@ import Typography from '@material-ui/core/Typography'; import useMediaQuery from '@material-ui/core/useMediaQuery'; import { Theme, useTheme } from '@material-ui/core/styles'; import FilterListIcon from '@material-ui/icons/FilterList'; +import { catalogReactTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; /** @public */ export const Filters = (props: { @@ -37,6 +39,7 @@ export const Filters = (props: { ); const theme = useTheme(); const [filterDrawerOpen, setFilterDrawerOpen] = useState(false); + const { t } = useTranslationRef(catalogReactTranslationRef); return isScreenSmallerThanBreakpoint ? ( <> @@ -45,7 +48,7 @@ export const Filters = (props: { onClick={() => setFilterDrawerOpen(true)} startIcon={} > - Filters + {t('catalogFilter.buttonTitle')} - Filters + {t('catalogFilter.title')} {props.children} diff --git a/plugins/catalog-react/src/components/EntityKindPicker/EntityKindPicker.test.tsx b/plugins/catalog-react/src/components/EntityKindPicker/EntityKindPicker.test.tsx index 2513f8dca9..612c515d28 100644 --- a/plugins/catalog-react/src/components/EntityKindPicker/EntityKindPicker.test.tsx +++ b/plugins/catalog-react/src/components/EntityKindPicker/EntityKindPicker.test.tsx @@ -18,7 +18,7 @@ import { GetEntityFacetsResponse } from '@backstage/catalog-client'; import { Entity } from '@backstage/catalog-model'; import { ApiProvider } from '@backstage/core-app-api'; import { alertApiRef } from '@backstage/core-plugin-api'; -import { renderWithEffects, TestApiRegistry } from '@backstage/test-utils'; +import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils'; import { fireEvent, waitFor, screen, within } from '@testing-library/react'; import { capitalize } from 'lodash'; import { default as React } from 'react'; @@ -75,7 +75,7 @@ describe('', () => { ); it('renders available entity kinds', async () => { - await renderWithEffects( + await renderInTestApp( ', () => { it('sets the selected kind filter', async () => { const updateFilters = jest.fn(); - await renderWithEffects( + await renderInTestApp( ', () => { it('respects the query parameter filter value', async () => { const updateFilters = jest.fn(); const queryParameters = { kind: 'group' }; - await renderWithEffects( + await renderInTestApp( ', () => { }); it('renders unknown kinds provided in query parameters', async () => { - await renderWithEffects( + await renderInTestApp( ', () => { }); it('limits kinds when allowedKinds is set', async () => { - await renderWithEffects( + await renderInTestApp( @@ -183,7 +183,7 @@ describe('', () => { }); it('renders kind from the query parameter even when not in allowedKinds', async () => { - await renderWithEffects( + await renderInTestApp( { const { allowedKinds, hidden, initialFilter = 'component' } = props; + const { t } = useTranslationRef(catalogReactTranslationRef); const alertApi = useApi(alertApiRef); @@ -106,11 +109,11 @@ export const EntityKindPicker = (props: EntityKindPickerProps) => { useEffect(() => { if (error) { alertApi.post({ - message: `Failed to load entity kinds`, + message: t('entityKindPicker.errorMessage'), severity: 'error', }); } - }, [error, alertApi]); + }, [error, alertApi, t]); if (error) return null; @@ -124,7 +127,7 @@ export const EntityKindPicker = (props: EntityKindPickerProps) => { return hidden ? null : ( 1 ? selectedTypes[0] : undefined) ?? 'all'} onChange={value => diff --git a/plugins/catalog-react/src/components/FavoriteEntity/FavoriteEntity.tsx b/plugins/catalog-react/src/components/FavoriteEntity/FavoriteEntity.tsx index fd0a656317..b788579e41 100644 --- a/plugins/catalog-react/src/components/FavoriteEntity/FavoriteEntity.tsx +++ b/plugins/catalog-react/src/components/FavoriteEntity/FavoriteEntity.tsx @@ -22,6 +22,8 @@ import Star from '@material-ui/icons/Star'; import StarBorder from '@material-ui/icons/StarBorder'; import React, { ComponentProps } from 'react'; import { useStarredEntity } from '../../hooks/useStarredEntity'; +import { catalogReactTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; /** @public */ export type FavoriteEntityProps = ComponentProps & { @@ -43,6 +45,7 @@ export const FavoriteEntity = (props: FavoriteEntityProps) => { const { toggleStarredEntity, isStarredEntity } = useStarredEntity( props.entity, ); + const { t } = useTranslationRef(catalogReactTranslationRef); return ( { onClick={() => toggleStarredEntity()} > {isStarredEntity ? : } diff --git a/plugins/catalog-react/src/components/InspectEntityDialog/InspectEntityDialog.tsx b/plugins/catalog-react/src/components/InspectEntityDialog/InspectEntityDialog.tsx index f155c3f164..644167acbb 100644 --- a/plugins/catalog-react/src/components/InspectEntityDialog/InspectEntityDialog.tsx +++ b/plugins/catalog-react/src/components/InspectEntityDialog/InspectEntityDialog.tsx @@ -30,6 +30,8 @@ import { ColocatedPage } from './components/ColocatedPage'; import { JsonPage } from './components/JsonPage'; import { OverviewPage } from './components/OverviewPage'; import { YamlPage } from './components/YamlPage'; +import { catalogReactTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; const useStyles = makeStyles(theme => ({ fullHeightDialog: { @@ -95,6 +97,7 @@ export function InspectEntityDialog(props: { }) { const classes = useStyles(); const [activeTab, setActiveTab] = React.useState(0); + const { t } = useTranslationRef(catalogReactTranslationRef); useEffect(() => { setActiveTab(0); @@ -114,7 +117,7 @@ export function InspectEntityDialog(props: { PaperProps={{ className: classes.fullHeightDialog }} > - Entity Inspector + {t('inspectEntityDialog.title')}
@@ -152,7 +155,7 @@ export function InspectEntityDialog(props: { diff --git a/plugins/catalog-react/src/components/InspectEntityDialog/components/AncestryPage.tsx b/plugins/catalog-react/src/components/InspectEntityDialog/components/AncestryPage.tsx index e08bac06e8..98bd27bd77 100644 --- a/plugins/catalog-react/src/components/InspectEntityDialog/components/AncestryPage.tsx +++ b/plugins/catalog-react/src/components/InspectEntityDialog/components/AncestryPage.tsx @@ -38,6 +38,8 @@ import { catalogApiRef } from '../../../api'; import { humanizeEntityRef } from '../../EntityRefLink'; import { entityRouteRef } from '../../../routes'; import { EntityKindIcon } from './EntityKindIcon'; +import { catalogReactTranslationRef } from '../../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; const useStyles = makeStyles(theme => ({ node: { @@ -198,6 +200,7 @@ function CustomNode({ node }: DependencyGraphTypes.RenderNodeProps) { export function AncestryPage(props: { entity: Entity }) { const { loading, error, nodes, edges } = useAncestry(props.entity); + const { t } = useTranslationRef(catalogReactTranslationRef); if (loading) { return ; } else if (error) { @@ -206,7 +209,9 @@ export function AncestryPage(props: { entity: Entity }) { return ( <> - Ancestry + + {t('inspectEntityDialog.ancestryPage.title')} + This is the ancestry of entities above the current one - as in, the chain(s) of entities down to the current one, where{' '} diff --git a/plugins/catalog-react/src/components/InspectEntityDialog/components/ColocatedPage.tsx b/plugins/catalog-react/src/components/InspectEntityDialog/components/ColocatedPage.tsx index 97bf0f3cb8..6f89ff2c9f 100644 --- a/plugins/catalog-react/src/components/InspectEntityDialog/components/ColocatedPage.tsx +++ b/plugins/catalog-react/src/components/InspectEntityDialog/components/ColocatedPage.tsx @@ -32,6 +32,8 @@ import useAsync from 'react-use/esm/useAsync'; import { catalogApiRef } from '../../../api'; import { EntityRefLink } from '../../EntityRefLink'; import { KeyValueListItem, ListItemText } from './common'; +import { catalogReactTranslationRef } from '../../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; const useStyles = makeStyles({ root: { @@ -95,6 +97,7 @@ function EntityList(props: { entities: Entity[]; header?: [string, string] }) { function Contents(props: { entity: Entity }) { const { entity } = props; + const { t } = useTranslationRef(catalogReactTranslationRef); const { loading, error, location, originLocation, colocatedEntities } = useColocated(entity); @@ -106,12 +109,14 @@ function Contents(props: { entity: Entity }) { if (!location && !originLocation) { return ( - Entity had no location information. + + {t('inspectEntityDialog.colocatedPage.alertNoLocation')} + ); } else if (!colocatedEntities?.length) { return ( - There were no other entities on this location. + {t('inspectEntityDialog.colocatedPage.alertNoEntity')} ); } @@ -148,13 +153,14 @@ function Contents(props: { entity: Entity }) { export function ColocatedPage(props: { entity: Entity }) { const classes = useStyles(); + const { t } = useTranslationRef(catalogReactTranslationRef); return ( <> - Colocated + + {t('inspectEntityDialog.colocatedPage.title')} + - These are the entities that are colocated with this entity - as in, they - originated from the same data source (e.g. came from the same YAML - file), or from the same origin (e.g. the originally registered URL). + {t('inspectEntityDialog.colocatedPage.description')}
diff --git a/plugins/catalog-react/src/components/InspectEntityDialog/components/JsonPage.tsx b/plugins/catalog-react/src/components/InspectEntityDialog/components/JsonPage.tsx index b6bda65229..af8a724729 100644 --- a/plugins/catalog-react/src/components/InspectEntityDialog/components/JsonPage.tsx +++ b/plugins/catalog-react/src/components/InspectEntityDialog/components/JsonPage.tsx @@ -19,13 +19,18 @@ import { CodeSnippet } from '@backstage/core-components'; import DialogContentText from '@material-ui/core/DialogContentText'; import React from 'react'; import { sortKeys } from './util'; +import { catalogReactTranslationRef } from '../../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; export function JsonPage(props: { entity: Entity }) { + const { t } = useTranslationRef(catalogReactTranslationRef); return ( <> - Entity as JSON + + {t('inspectEntityDialog.jsonPage.title')} + - This is the raw entity data as received from the catalog, on JSON form. + {t('inspectEntityDialog.jsonPage.description')}
diff --git a/plugins/catalog-react/src/components/InspectEntityDialog/components/OverviewPage.tsx b/plugins/catalog-react/src/components/InspectEntityDialog/components/OverviewPage.tsx index ad742459de..361910b2cd 100644 --- a/plugins/catalog-react/src/components/InspectEntityDialog/components/OverviewPage.tsx +++ b/plugins/catalog-react/src/components/InspectEntityDialog/components/OverviewPage.tsx @@ -36,6 +36,8 @@ import { } from './common'; import { stringifyEntityRef } from '@backstage/catalog-model'; import { CopyTextButton } from '@backstage/core-components'; +import { catalogReactTranslationRef } from '../../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; const useStyles = makeStyles({ root: { @@ -59,11 +61,14 @@ export function OverviewPage(props: { entity: AlphaEntity }) { sortBy(relations, r => r.targetRef), 'type', ); + const { t } = useTranslationRef(catalogReactTranslationRef); const entityRef = stringifyEntityRef(props.entity); return ( <> - Overview + + {t('inspectEntityDialog.overviewPage.title')} +
diff --git a/plugins/catalog-react/src/components/InspectEntityDialog/components/YamlPage.tsx b/plugins/catalog-react/src/components/InspectEntityDialog/components/YamlPage.tsx index ad74611ec5..4e56b9b42a 100644 --- a/plugins/catalog-react/src/components/InspectEntityDialog/components/YamlPage.tsx +++ b/plugins/catalog-react/src/components/InspectEntityDialog/components/YamlPage.tsx @@ -20,13 +20,18 @@ import DialogContentText from '@material-ui/core/DialogContentText'; import React from 'react'; import YAML from 'yaml'; import { sortKeys } from './util'; +import { catalogReactTranslationRef } from '../../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; export function YamlPage(props: { entity: Entity }) { + const { t } = useTranslationRef(catalogReactTranslationRef); return ( <> - Entity as YAML + + {t('inspectEntityDialog.yamlPage.title')} + - This is the raw entity data as received from the catalog, on YAML form. + {t('inspectEntityDialog.yamlPage.description')}
diff --git a/plugins/catalog-react/src/components/UnregisterEntityDialog/UnregisterEntityDialog.tsx b/plugins/catalog-react/src/components/UnregisterEntityDialog/UnregisterEntityDialog.tsx index 7f41badca5..e2ed9387e1 100644 --- a/plugins/catalog-react/src/components/UnregisterEntityDialog/UnregisterEntityDialog.tsx +++ b/plugins/catalog-react/src/components/UnregisterEntityDialog/UnregisterEntityDialog.tsx @@ -32,6 +32,8 @@ import { useUnregisterEntityDialogState } from './useUnregisterEntityDialogState import { alertApiRef, configApiRef, useApi } from '@backstage/core-plugin-api'; import { Progress, ResponseErrorPanel } from '@backstage/core-components'; import { assertError } from '@backstage/errors'; +import { catalogReactTranslationRef } from '../../translation'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; const useStyles = makeStyles({ advancedButton: { @@ -58,6 +60,7 @@ const Contents = ({ const [showDelete, setShowDelete] = useState(false); const [busy, setBusy] = useState(false); const appTitle = configApi.getOptionalString('app.title') ?? 'Backstage'; + const { t } = useTranslationRef(catalogReactTranslationRef); const onUnregister = useCallback( async function onUnregisterFn() { @@ -86,7 +89,9 @@ const Contents = ({ const entityName = entity.metadata.title ?? entity.metadata.name; onConfirm(); alertApi.post({ - message: `Removed entity ${entityName}`, + message: t('unregisterEntityDialog.deleteEntitySuccessMessage', { + entityName, + }), severity: 'success', display: 'transient', }); @@ -98,13 +103,13 @@ const Contents = ({ } } }, - [alertApi, onConfirm, state, entity], + [alertApi, onConfirm, state, entity, t], ); const DialogActionsPanel = () => ( ); @@ -121,10 +126,10 @@ const Contents = ({ return ( <> - You cannot unregister this entity, since it originates from a - protected Backstage configuration (location "{state.location}"). If - you believe this is in error, please contact the {appTitle}{' '} - integrator. + {t('unregisterEntityDialog.bootstrapState.title', { + appTitle, + location: state.location, + })} @@ -137,7 +142,7 @@ const Contents = ({ className={classes.advancedButton} onClick={() => setShowDelete(true)} > - Advanced Options + {t('unregisterEntityDialog.bootstrapState.advancedOptions')} @@ -146,11 +151,7 @@ const Contents = ({ {showDelete && ( <> - You have the option to delete the entity itself from the - catalog. Note that this should only be done if you know that the - catalog file has been deleted at, or moved from, its origin - location. If that is not the case, the entity will reappear - shortly as the next refresh round is performed by the catalog. + {t('unregisterEntityDialog.bootstrapState.advancedDescription')} @@ -172,8 +173,7 @@ const Contents = ({ return ( <> - This entity does not seem to originate from a registered location. You - therefore only have the option to delete it outright from the catalog. + {t('unregisterEntityDialog.onlyDeleteStateTitle')} @@ -192,7 +192,7 @@ const Contents = ({ return ( <> - This action will unregister the following entities: + {t('unregisterEntityDialog.unregisterState.title')} {state.colocatedEntities.map(e => ( @@ -202,13 +202,15 @@ const Contents = ({ ))} - Located at the following location: + {t('unregisterEntityDialog.unregisterState.subTitle')}
  • {state.location}
  • - To undo, just re-register the entity in {appTitle}. + {t('unregisterEntityDialog.unregisterState.description', { + appTitle, + })} {!showDelete && ( @@ -228,7 +230,7 @@ const Contents = ({ className={classes.advancedButton} onClick={() => setShowDelete(true)} > - Advanced Options + {t('unregisterEntityDialog.unregisterState.advancedOptions')} )} @@ -240,11 +242,7 @@ const Contents = ({ - You also have the option to delete the entity itself from the - catalog. Note that this should only be done if you know that the - catalog file has been deleted at, or moved from, its origin - location. If that is not the case, the entity will reappear - shortly as the next refresh round is performed by the catalog. + {t('unregisterEntityDialog.unregisterState.advancedDescription')} )} @@ -260,7 +258,11 @@ const Contents = ({ ); } - return Internal error: Unknown state; + return ( + + {t('unregisterEntityDialog.errorStateTitle')} + + ); }; /** @public */ @@ -274,10 +276,11 @@ export type UnregisterEntityDialogProps = { /** @public */ export const UnregisterEntityDialog = (props: UnregisterEntityDialogProps) => { const { open, onConfirm, onClose, entity } = props; + const { t } = useTranslationRef(catalogReactTranslationRef); return ( - Are you sure you want to unregister this entity? + {t('unregisterEntityDialog.title')} diff --git a/plugins/catalog-react/src/components/UserListPicker/UserListPicker.test.tsx b/plugins/catalog-react/src/components/UserListPicker/UserListPicker.test.tsx index 5667447503..0b101e8174 100644 --- a/plugins/catalog-react/src/components/UserListPicker/UserListPicker.test.tsx +++ b/plugins/catalog-react/src/components/UserListPicker/UserListPicker.test.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; -import { fireEvent, render, waitFor, screen } from '@testing-library/react'; +import { fireEvent, waitFor, screen } from '@testing-library/react'; import { UserEntity } from '@backstage/catalog-model'; import { UserListPicker, UserListPickerProps } from './UserListPicker'; import { MockEntityListContextProvider } from '../../testUtils/providers'; @@ -30,7 +30,11 @@ import { QueryEntitiesInitialRequest, } from '@backstage/catalog-client'; import { catalogApiRef } from '../../api'; -import { MockStorageApi, TestApiRegistry } from '@backstage/test-utils'; +import { + MockStorageApi, + TestApiRegistry, + renderInTestApp, +} from '@backstage/test-utils'; import { ApiProvider } from '@backstage/core-app-api'; import { ConfigApi, @@ -145,7 +149,7 @@ describe('', () => { }); it('renders filter groups', async () => { - render( + await renderInTestApp( @@ -164,7 +168,7 @@ describe('', () => { }); it('renders filters', async () => { - render( + await renderInTestApp( ', () => { }); it('respects other frontend filters in counts', async () => { - render( + await renderInTestApp( ', () => { it('respects the query parameter filter value', async () => { const updateFilters = jest.fn(); const queryParameters = { user: 'owned', kind: 'component' }; - render( + await renderInTestApp( ', () => { it('updates user filter when a menuitem is selected', async () => { const updateFilters = jest.fn(); - render( + await renderInTestApp( ', () => { it('responds to external queryParameters changes', async () => { const updateFilters = jest.fn(); - const rendered = render( + const rendered = await renderInTestApp( ', () => { it('does not reset the filter while entities are loading', async () => { mockCatalogApi.queryEntities?.mockReturnValue(new Promise(() => {})); - render(); + await renderInTestApp(); await waitFor(() => expect(mockCatalogApi.queryEntities).toHaveBeenCalled(), @@ -433,7 +437,7 @@ describe('', () => { return mockQueryEntitiesImplementation(request); }); - render(); + await renderInTestApp(); await waitFor(() => expect(mockCatalogApi.queryEntities).toHaveBeenCalledTimes(3), @@ -444,7 +448,7 @@ describe('', () => { }); it('does not reset the filter when request is empty', async () => { - render(); + await renderInTestApp(); await waitFor(() => { expect(mockCatalogApi.queryEntities).toHaveBeenCalledTimes(1); @@ -473,7 +477,7 @@ describe('', () => { return mockQueryEntitiesImplementation(request); }); - render(); + await renderInTestApp(); await waitFor(() => expect(updateFilters).toHaveBeenLastCalledWith({ @@ -489,7 +493,7 @@ describe('', () => { () => new Promise(() => {}), ); - render(); + await renderInTestApp(); await waitFor(() => expect(mockCatalogApi.queryEntities).toHaveBeenCalled(), @@ -512,7 +516,7 @@ describe('', () => { return mockQueryEntitiesImplementation(request); }); - render(); + await renderInTestApp(); await waitFor(() => expect(mockCatalogApi.queryEntities).toHaveBeenCalledTimes(3), @@ -537,7 +541,7 @@ describe('', () => { return mockQueryEntitiesImplementation(request); }); - render(); + await renderInTestApp(); await waitFor(() => expect(updateFilters).toHaveBeenLastCalledWith({ @@ -563,7 +567,7 @@ describe('', () => { return mockQueryEntitiesImplementation(request); }); - render(); + await renderInTestApp(); await waitFor(() => expect(mockCatalogApi.queryEntities).toHaveBeenCalledTimes(3), @@ -574,7 +578,7 @@ describe('', () => { }); it('does not reset the filter when entities are loaded', async () => { - render(); + await renderInTestApp(); await waitFor(() => expect(mockCatalogApi.queryEntities).toHaveBeenCalledTimes(3), @@ -588,7 +592,7 @@ describe('', () => { }); it('does not reset the filter when request is empty xxxx', async () => { - render(); + await renderInTestApp(); await waitFor(() => { expect(mockCatalogApi.queryEntities).toHaveBeenCalledTimes(1); @@ -619,7 +623,7 @@ describe('', () => { return mockQueryEntitiesImplementation(request); }); - render(); + await renderInTestApp(); await waitFor(() => expect(mockCatalogApi.queryEntities).toHaveBeenCalledTimes(3), @@ -630,7 +634,7 @@ describe('', () => { }); it('does not reset the filter when entities are loaded', async () => { - render(); + await renderInTestApp(); await waitFor(() => expect(mockCatalogApi.queryEntities).toHaveBeenCalledTimes(3), diff --git a/plugins/catalog-react/src/components/UserListPicker/UserListPicker.tsx b/plugins/catalog-react/src/components/UserListPicker/UserListPicker.tsx index 1e46258885..7f0ff8be74 100644 --- a/plugins/catalog-react/src/components/UserListPicker/UserListPicker.tsx +++ b/plugins/catalog-react/src/components/UserListPicker/UserListPicker.tsx @@ -36,6 +36,11 @@ import { UserListFilterKind } from '../../types'; import { useOwnedEntitiesCount } from './useOwnedEntitiesCount'; import { useAllEntitiesCount } from './useAllEntitiesCount'; import { useStarredEntitiesCount } from './useStarredEntitiesCount'; +import { + TranslationFunction, + useTranslationRef, +} from '@backstage/core-plugin-api/alpha'; +import { catalogReactTranslationRef } from '../../translation'; /** @public */ export type CatalogReactUserListPickerClassKey = @@ -83,29 +88,32 @@ export type ButtonGroup = { }[]; }; -function getFilterGroups(orgName: string | undefined): ButtonGroup[] { +function getFilterGroups( + orgName: string, + t: TranslationFunction, +): ButtonGroup[] { return [ { - name: 'Personal', + name: t('userListPicker.personalFilter.title'), items: [ { id: 'owned', - label: 'Owned', + label: t('userListPicker.personalFilter.ownedLabel'), icon: SettingsIcon, }, { id: 'starred', - label: 'Starred', + label: t('userListPicker.personalFilter.starredLabel'), icon: StarIcon, }, ], }, { - name: orgName ?? 'Company', + name: orgName, items: [ { id: 'all', - label: 'All', + label: t('userListPicker.orgFilterAllLabel'), }, ], }, @@ -123,7 +131,10 @@ export const UserListPicker = (props: UserListPickerProps) => { const { initialFilter, availableFilters } = props; const classes = useStyles(); const configApi = useApi(configApiRef); - const orgName = configApi.getOptionalString('organization.name') ?? 'Company'; + const { t } = useTranslationRef(catalogReactTranslationRef); + const orgName = + configApi.getOptionalString('organization.name') ?? + t('userListPicker.defaultOrgName'); const { filters, updateFilters, @@ -133,7 +144,7 @@ export const UserListPicker = (props: UserListPickerProps) => { // Remove group items that aren't in availableFilters and exclude // any now-empty groups. const userAndGroupFilterIds = ['starred', 'all']; - const filterGroups = getFilterGroups(orgName) + const filterGroups = getFilterGroups(orgName, t) .map(filterGroup => ({ ...filterGroup, items: filterGroup.items.filter(({ id }) => diff --git a/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx b/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx index bc8e6b6038..9afa81e2dd 100644 --- a/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx +++ b/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx @@ -20,6 +20,7 @@ import { alertApiRef, ConfigApi, configApiRef, + errorApiRef, IdentityApi, identityApiRef, storageApiRef, @@ -39,6 +40,8 @@ import { } from '../filters'; import { EntityListProvider, useEntityList } from './useEntityListProvider'; import { useMountEffect } from '@react-hookz/web'; +import { translationApiRef } from '@backstage/core-plugin-api/alpha'; +import { MockTranslationApi } from '@backstage/test-utils/alpha'; const entities: Entity[] = [ { @@ -110,6 +113,8 @@ const createWrapper = [storageApiRef, MockStorageApi.create()], [starredEntitiesApiRef, new MockStarredEntitiesApi()], [alertApiRef, { post: jest.fn() }], + [translationApiRef, MockTranslationApi.create()], + [errorApiRef, { error$: jest.fn(), post: jest.fn() }], ]} > diff --git a/plugins/catalog-react/src/translation.ts b/plugins/catalog-react/src/translation.ts new file mode 100644 index 0000000000..685bf1fd00 --- /dev/null +++ b/plugins/catalog-react/src/translation.ts @@ -0,0 +1,116 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createTranslationRef } from '@backstage/core-plugin-api/alpha'; + +/** @alpha */ +export const catalogReactTranslationRef = createTranslationRef({ + id: 'catalog-react', + messages: { + catalogFilter: { + title: 'Filters', + buttonTitle: 'Filters', + }, + entityKindPicker: { + title: 'Kind', + errorMessage: 'Failed to load entity kinds', + }, + entityLifecyclePickerTitle: 'Lifecycle', + entityNamespacePickerTitle: 'Namespace', + entityOwnerPickerTitle: 'Owner', + entityPeekAheadPopover: { + title: 'Drill into the entity to see all of the tags.', + emailCardAction: { + title: 'Email {{email}}', + subTitle: 'mailto {{email}}', + }, + entityCardActionsTitle: 'Show details', + }, + entityProcessingStatusPickerTitle: 'Processing Status', + entitySearchBarPlaceholder: 'Search', + entityTagPickerTitle: 'Tags', + entityTypePicker: { + title: 'Type', + errorMessage: 'Failed to load entity types', + optionAllTitle: 'all', + }, + favoriteEntity: { + addToFavorites: 'Add to favorites', + RemoveFromFavorites: 'Remove from favorites', + }, + inspectEntityDialog: { + title: 'Entity Inspector', + closeButtonTitle: 'Close', + ancestryPage: { + title: 'Ancestry', + }, + colocatedPage: { + title: 'Colocated', + description: + 'These are the entities that are colocated with this entity - as in, they originated from the same data source (e.g. came from the same YAML file), or from the same origin (e.g. the originally registered URL).', + alertNoLocation: 'Entity had no location information.', + alertNoEntity: 'There were no other entities on this location.', + }, + jsonPage: { + title: 'Entity as JSON', + description: + 'This is the raw entity data as received from the catalog, on JSON form.', + }, + overviewPage: { + title: 'Overview', + }, + yamlPage: { + title: 'Entity as YAML', + description: + 'This is the raw entity data as received from the catalog, on YAML form.', + }, + }, + unregisterEntityDialog: { + title: 'Are you sure you want to unregister this entity?', + cancelButtonTitle: 'Cancel', + deleteButtonTitle: 'Delete Entity', + deleteEntitySuccessMessage: 'Removed entity {{entityName}}', + bootstrapState: { + title: + 'You cannot unregister this entity, since it originates from a protected Backstage configuration (location "{{location}}"). If you believe this is in error, please contact the {{appTitle}} integrator.', + advancedDescription: + 'You have the option to delete the entity itself from the catalog. Note that this should only be done if you know that the catalog file has been deleted at, or moved from, its origin location. If that is not the case, the entity will reappear shortly as the next refresh round is performed by the catalog.', + advancedOptions: 'Advanced Options', + }, + onlyDeleteStateTitle: + 'This entity does not seem to originate from a registered location. You therefore only have the option to delete it outright from the catalog.', + unregisterState: { + title: 'This action will unregister the following entities:', + subTitle: 'Located at the following location:', + description: 'To undo, just re-register the entity in {{appTitle}}.', + unregisterButtonTitle: 'Unregister Location', + advancedOptions: 'Advanced Options', + advancedDescription: + 'You also have the option to delete the entity itself from the catalog. Note that this should only be done if you know that the catalog file has been deleted at, or moved from, its origin location. If that is not the case, the entity will reappear shortly as the next refresh round is performed by the catalog.', + }, + errorStateTitle: 'Internal error: Unknown state', + }, + userListPicker: { + defaultOrgName: 'Company', + personalFilter: { + title: 'Personal', + ownedLabel: 'Owned', + starredLabel: 'Starred', + }, + orgFilterAllLabel: 'All', + }, + }, +}); diff --git a/plugins/catalog/api-report-alpha.md b/plugins/catalog/api-report-alpha.md index 75d7e53873..642eeb3225 100644 --- a/plugins/catalog/api-report-alpha.md +++ b/plugins/catalog/api-report-alpha.md @@ -19,6 +19,81 @@ export const catalogTranslationRef: TranslationRef< { readonly 'indexPage.title': '{{orgName}} Catalog'; readonly 'indexPage.createButtonTitle': 'Create'; + readonly 'deleteEntity.description': 'This entity is not referenced by any location and is therefore not receiving updates. Click here to delete.'; + readonly 'deleteEntity.cancelButtonTitle': 'Cancel'; + readonly 'deleteEntity.deleteButtonTitle': 'Delete'; + readonly 'deleteEntity.dialogTitle': 'Are you sure you want to delete this entity?'; + readonly 'indexPage.title': '{{orgName}} Catalog'; + readonly 'indexPage.createButtonTitle': 'Create'; + readonly 'indexPage.supportButtonContent': 'All your software catalog entities'; + readonly 'aboutCard.title': 'About'; + readonly 'aboutCard.refreshButtonTitle': 'Schedule entity refresh'; + readonly 'aboutCard.editButtonTitle': 'Edit Metadata'; + readonly 'aboutCard.refreshScheduledMessage': 'Refresh scheduled'; + readonly 'aboutCard.launchTemplate': 'Launch Template'; + readonly 'aboutCard.viewTechdocs': 'View TechDocs'; + readonly 'aboutCard.viewSource': 'View Source'; + readonly 'aboutCard.descriptionField.value': 'No description'; + readonly 'aboutCard.descriptionField.label': 'Description'; + readonly 'aboutCard.ownerField.value': 'No Owner'; + readonly 'aboutCard.ownerField.label': 'Owner'; + readonly 'aboutCard.domainField.value': 'No Domain'; + readonly 'aboutCard.domainField.label': 'Domain'; + readonly 'aboutCard.systemField.value': 'No System'; + readonly 'aboutCard.systemField.label': 'System'; + readonly 'aboutCard.parentComponentField.value': 'No Parent Component'; + readonly 'aboutCard.parentComponentField.label': 'Parent Component'; + readonly 'aboutCard.typeField.label': 'Type'; + readonly 'aboutCard.lifecycleField.label': 'Lifecycle'; + readonly 'aboutCard.tagsField.value': 'No Tags'; + readonly 'aboutCard.tagsField.label': 'Tags'; + readonly 'aboutCard.targetsField.label': 'Targets'; + readonly 'searchResultItem.lifecycle': 'Lifecycle'; + readonly 'searchResultItem.Owner': 'Owner'; + readonly 'catalogTable.warningPanelTitle': 'Could not fetch catalog entities.'; + readonly 'catalogTable.viewActionTitle': 'View'; + readonly 'catalogTable.editActionTitle': 'Edit'; + readonly 'catalogTable.starActionTitle': 'Add to favorites'; + readonly 'catalogTable.unStarActionTitle': 'Remove from favorites'; + readonly 'dependencyOfComponentsCard.title': 'Dependency of components'; + readonly 'dependencyOfComponentsCard.emptyMessage': 'No component depends on this component'; + readonly 'dependsOnComponentsCard.title': 'Depends on components'; + readonly 'dependsOnComponentsCard.emptyMessage': 'No component is a dependency of this component'; + readonly 'dependsOnResourcesCard.title': 'Depends on resources'; + readonly 'dependsOnResourcesCard.emptyMessage': 'No resource is a dependency of this component'; + readonly 'entityContextMenu.copiedMessage': 'Copied!'; + readonly 'entityContextMenu.moreButtonTitle': 'More'; + readonly 'entityContextMenu.inspectMenuTitle': 'Inspect entity'; + readonly 'entityContextMenu.copyURLMenuTitle': 'Copy entity URL'; + readonly 'entityContextMenu.unregisterMenuTitle': 'Unregister entity'; + readonly 'entityLabelsCard.title': 'Labels'; + readonly 'entityLabelsCard.emptyDescription': 'No labels defined for this entity. You can add labels to your entity YAML as shown in the highlighted example below:'; + readonly 'entityLabelsCard.readMoreButtonTitle': 'Read more'; + readonly 'entityLabels.warningPanelTitle': 'Entity not found'; + readonly 'entityLabels.ownerLabel': 'Owner'; + readonly 'entityLabels.lifecycleLabel': 'Lifecycle'; + readonly 'entityLinksCard.title': 'Links'; + readonly 'entityLinksCard.emptyDescription': 'No links defined for this entity. You can add links to your entity YAML as shown in the highlighted example below:'; + readonly 'entityLinksCard.readMoreButtonTitle': 'Read more'; + readonly 'entityNotFound.title': 'Entity was not found'; + readonly 'entityNotFound.description': 'Want to help us build this? Check out our Getting Started documentation.'; + readonly 'entityNotFound.docButtonTitle': 'DOCS'; + readonly entityProcessingErrorsDescription: 'The error below originates from'; + readonly entityRelationWarningDescription: "This entity has relations to other entities, which can't be found in the catalog.\n Entities not found are: "; + readonly 'hasComponentsCard.title': 'Has components'; + readonly 'hasComponentsCard.emptyMessage': 'No component is part of this system'; + readonly 'hasResourcesCard.title': 'Has resources'; + readonly 'hasResourcesCard.emptyMessage': 'No resource is part of this system'; + readonly 'hasSubcomponentsCard.title': 'Has subcomponents'; + readonly 'hasSubcomponentsCard.emptyMessage': 'No subcomponent is part of this component'; + readonly 'hasSystemsCard.title': 'Has systems'; + readonly 'hasSystemsCard.emptyMessage': 'No system is part of this domain'; + readonly 'relatedEntitiesCard.emptyHelpLinkTitle': 'Learn how to change this.'; + readonly 'systemDiagramCard.title': 'System Diagram'; + readonly 'systemDiagramCard.description': 'Use pinch & zoo to move around the diagram.'; + readonly 'systemDiagramCard.edgeLabels.dependsOn': 'depends on'; + readonly 'systemDiagramCard.edgeLabels.partOf': 'part of'; + readonly 'systemDiagramCard.edgeLabels.provides': 'provides'; } >; diff --git a/plugins/catalog/src/alpha.ts b/plugins/catalog/src/alpha.ts index 927d5362b4..b78a5e6225 100644 --- a/plugins/catalog/src/alpha.ts +++ b/plugins/catalog/src/alpha.ts @@ -17,3 +17,4 @@ export * from './alpha/index'; export { default } from './alpha/index'; export { catalogTranslationRef } from './translation'; +export * from './translation'; diff --git a/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.test.tsx b/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.test.tsx index 5aa138340e..90157c3226 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.test.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.test.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ import React from 'react'; -import { fireEvent, render } from '@testing-library/react'; +import { fireEvent } from '@testing-library/react'; import { CardHeader } from './CardHeader'; import { ThemeProvider } from '@material-ui/core/styles'; import { lightTheme } from '@backstage/theme'; @@ -30,7 +30,7 @@ import { stringifyEntityRef } from '@backstage/catalog-model'; import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; describe('CardHeader', () => { - it('should select the correct theme from the theme provider from the header', () => { + it('should select the correct theme from the theme provider from the header', async () => { // Can't really test what we want here. // But we can check that we call the getPage theme with the right type of template at least. const mockTheme = { @@ -38,7 +38,7 @@ describe('CardHeader', () => { getPageTheme: jest.fn(lightTheme.getPageTheme), }; - render( + await renderInTestApp( Date: Tue, 5 Mar 2024 17:27:16 +0800 Subject: [PATCH 039/510] chore: update changelog Signed-off-by: mario ma --- .changeset/friendly-oranges-greet.md | 1 - 1 file changed, 1 deletion(-) diff --git a/.changeset/friendly-oranges-greet.md b/.changeset/friendly-oranges-greet.md index 4fbabf76f5..d327c40640 100644 --- a/.changeset/friendly-oranges-greet.md +++ b/.changeset/friendly-oranges-greet.md @@ -1,5 +1,4 @@ --- -'@backstage/plugin-scaffolder-react': patch '@backstage/plugin-catalog-react': patch '@backstage/plugin-catalog': patch --- From 951e2daf16df181a6e9f70fa861e068e2d6a0338 Mon Sep 17 00:00:00 2001 From: mario ma Date: Thu, 28 Mar 2024 21:39:24 +0800 Subject: [PATCH 040/510] fix: unit test Signed-off-by: mario ma --- .../EntityNamespacePicker/EntityNamespacePicker.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog-react/src/components/EntityNamespacePicker/EntityNamespacePicker.test.tsx b/plugins/catalog-react/src/components/EntityNamespacePicker/EntityNamespacePicker.test.tsx index aa9c794f3b..05fa1dc07f 100644 --- a/plugins/catalog-react/src/components/EntityNamespacePicker/EntityNamespacePicker.test.tsx +++ b/plugins/catalog-react/src/components/EntityNamespacePicker/EntityNamespacePicker.test.tsx @@ -241,7 +241,7 @@ describe('', () => { ); }); it('renders initially selected namespaces', async () => { - render( + renderInTestApp( Date: Tue, 9 Apr 2024 21:10:24 +0800 Subject: [PATCH 041/510] fix: ci pipeline prettier:check error Signed-off-by: mario ma --- .../src/components/EntitySearchBar/EntitySearchBar.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog-react/src/components/EntitySearchBar/EntitySearchBar.test.tsx b/plugins/catalog-react/src/components/EntitySearchBar/EntitySearchBar.test.tsx index 89a486bfa3..736c0678f8 100644 --- a/plugins/catalog-react/src/components/EntitySearchBar/EntitySearchBar.test.tsx +++ b/plugins/catalog-react/src/components/EntitySearchBar/EntitySearchBar.test.tsx @@ -53,4 +53,4 @@ describe('EntitySearchBar', () => { text: undefined, }); }); -}); \ No newline at end of file +}); From 430c8fbcfc79a5e121dfec06a095758a98268824 Mon Sep 17 00:00:00 2001 From: mario ma Date: Tue, 9 Apr 2024 21:54:53 +0800 Subject: [PATCH 042/510] fix: update api report Signed-off-by: mario ma --- plugins/catalog/api-report-alpha.md | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/catalog/api-report-alpha.md b/plugins/catalog/api-report-alpha.md index 642eeb3225..14d62d53bf 100644 --- a/plugins/catalog/api-report-alpha.md +++ b/plugins/catalog/api-report-alpha.md @@ -29,6 +29,7 @@ export const catalogTranslationRef: TranslationRef< readonly 'aboutCard.title': 'About'; readonly 'aboutCard.refreshButtonTitle': 'Schedule entity refresh'; readonly 'aboutCard.editButtonTitle': 'Edit Metadata'; + readonly 'aboutCard.createSimilarButtonTitle': 'Create something similar'; readonly 'aboutCard.refreshScheduledMessage': 'Refresh scheduled'; readonly 'aboutCard.launchTemplate': 'Launch Template'; readonly 'aboutCard.viewTechdocs': 'View TechDocs'; From 24208fce4e26cb708ce94bdedf23a5d45124287e Mon Sep 17 00:00:00 2001 From: mario ma Date: Tue, 9 Apr 2024 22:29:10 +0800 Subject: [PATCH 043/510] fix: unit test Signed-off-by: mario ma --- .../EntitySearchBar/EntitySearchBar.test.tsx | 2 +- .../CatalogTable/PaginatedCatalogTable.test.tsx | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/catalog-react/src/components/EntitySearchBar/EntitySearchBar.test.tsx b/plugins/catalog-react/src/components/EntitySearchBar/EntitySearchBar.test.tsx index 736c0678f8..cbfeffa009 100644 --- a/plugins/catalog-react/src/components/EntitySearchBar/EntitySearchBar.test.tsx +++ b/plugins/catalog-react/src/components/EntitySearchBar/EntitySearchBar.test.tsx @@ -25,7 +25,7 @@ describe('EntitySearchBar', () => { it('should display search value and execute set callback', async () => { const updateFilters = jest.fn(); - renderInTestApp( + await renderInTestApp( { ); }; - it('should display all the items', () => { - render( + it('should display all the items', async () => { + await renderInTestApp( wrapInContext(), ); @@ -74,7 +74,7 @@ describe('PaginatedCatalogTable', () => { }); it('should display and invoke the next button', async () => { - const { rerender } = render( + const { rerender } = await renderInTestApp( wrapInContext( { }); it('should display and invoke the prev button', async () => { - const { rerender } = render( + const { rerender } = await renderInTestApp( wrapInContext( Date: Tue, 18 Jun 2024 16:27:59 +0800 Subject: [PATCH 044/510] fix: rebase conficts Signed-off-by: mario ma --- plugins/catalog/api-report-alpha.md | 2 -- plugins/scaffolder/api-report.md | 26 +++++++++++++------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/plugins/catalog/api-report-alpha.md b/plugins/catalog/api-report-alpha.md index 14d62d53bf..102e2a7aa3 100644 --- a/plugins/catalog/api-report-alpha.md +++ b/plugins/catalog/api-report-alpha.md @@ -17,8 +17,6 @@ import { TranslationRef } from '@backstage/core-plugin-api/alpha'; export const catalogTranslationRef: TranslationRef< 'catalog', { - readonly 'indexPage.title': '{{orgName}} Catalog'; - readonly 'indexPage.createButtonTitle': 'Create'; readonly 'deleteEntity.description': 'This entity is not referenced by any location and is therefore not receiving updates. Click here to delete.'; readonly 'deleteEntity.cancelButtonTitle': 'Cancel'; readonly 'deleteEntity.deleteButtonTitle': 'Delete'; diff --git a/plugins/scaffolder/api-report.md b/plugins/scaffolder/api-report.md index 5c766af890..7f16d4c787 100644 --- a/plugins/scaffolder/api-report.md +++ b/plugins/scaffolder/api-report.md @@ -81,8 +81,6 @@ export const EntityPickerFieldExtension: FieldExtensionComponent_2< { defaultKind?: string | undefined; defaultNamespace?: string | false | undefined; - allowedKinds?: string[] | undefined; - allowArbitraryValues?: boolean | undefined; catalogFilter?: | Record< string, @@ -101,6 +99,8 @@ export const EntityPickerFieldExtension: FieldExtensionComponent_2< } >[] | undefined; + allowedKinds?: string[] | undefined; + allowArbitraryValues?: boolean | undefined; } >; @@ -110,8 +110,6 @@ export const EntityPickerFieldSchema: FieldSchema< { defaultKind?: string | undefined; defaultNamespace?: string | false | undefined; - allowedKinds?: string[] | undefined; - allowArbitraryValues?: boolean | undefined; catalogFilter?: | Record< string, @@ -130,6 +128,8 @@ export const EntityPickerFieldSchema: FieldSchema< } >[] | undefined; + allowedKinds?: string[] | undefined; + allowArbitraryValues?: boolean | undefined; } >; @@ -216,7 +216,6 @@ export const MultiEntityPickerFieldExtension: FieldExtensionComponent_2< { defaultKind?: string | undefined; defaultNamespace?: string | false | undefined; - allowArbitraryValues?: boolean | undefined; catalogFilter?: | Record< string, @@ -235,6 +234,7 @@ export const MultiEntityPickerFieldExtension: FieldExtensionComponent_2< } >[] | undefined; + allowArbitraryValues?: boolean | undefined; } >; @@ -269,8 +269,6 @@ export const OwnedEntityPickerFieldExtension: FieldExtensionComponent_2< { defaultKind?: string | undefined; defaultNamespace?: string | false | undefined; - allowedKinds?: string[] | undefined; - allowArbitraryValues?: boolean | undefined; catalogFilter?: | Record< string, @@ -289,6 +287,8 @@ export const OwnedEntityPickerFieldExtension: FieldExtensionComponent_2< } >[] | undefined; + allowedKinds?: string[] | undefined; + allowArbitraryValues?: boolean | undefined; } >; @@ -298,8 +298,6 @@ export const OwnedEntityPickerFieldSchema: FieldSchema< { defaultKind?: string | undefined; defaultNamespace?: string | false | undefined; - allowedKinds?: string[] | undefined; - allowArbitraryValues?: boolean | undefined; catalogFilter?: | Record< string, @@ -318,6 +316,8 @@ export const OwnedEntityPickerFieldSchema: FieldSchema< } >[] | undefined; + allowedKinds?: string[] | undefined; + allowArbitraryValues?: boolean | undefined; } >; @@ -330,8 +330,6 @@ export const OwnerPickerFieldExtension: FieldExtensionComponent_2< string, { defaultNamespace?: string | false | undefined; - allowedKinds?: string[] | undefined; - allowArbitraryValues?: boolean | undefined; catalogFilter?: | Record< string, @@ -350,6 +348,8 @@ export const OwnerPickerFieldExtension: FieldExtensionComponent_2< } >[] | undefined; + allowedKinds?: string[] | undefined; + allowArbitraryValues?: boolean | undefined; } >; @@ -358,8 +358,6 @@ export const OwnerPickerFieldSchema: FieldSchema< string, { defaultNamespace?: string | false | undefined; - allowedKinds?: string[] | undefined; - allowArbitraryValues?: boolean | undefined; catalogFilter?: | Record< string, @@ -378,6 +376,8 @@ export const OwnerPickerFieldSchema: FieldSchema< } >[] | undefined; + allowedKinds?: string[] | undefined; + allowArbitraryValues?: boolean | undefined; } >; From d42b410050645dcac54a3bbefa6f20e219b7a807 Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 18 Jun 2024 11:53:20 +0200 Subject: [PATCH 045/510] chore: initial pass at implementation from mob with simple test Signed-off-by: blam --- .../src/wiring/createExtensionKind.test.tsx | 44 +++++ .../src/wiring/createExtensionKind.ts | 164 ++++++++++++++++++ 2 files changed, 208 insertions(+) create mode 100644 packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx create mode 100644 packages/frontend-plugin-api/src/wiring/createExtensionKind.ts diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx b/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx new file mode 100644 index 0000000000..d841ea2c62 --- /dev/null +++ b/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx @@ -0,0 +1,44 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { coreExtensionData } from './coreExtensionData'; +import { createExtensionKind } from './createExtensionKind'; + +describe('createExtensionKind', () => { + it('should allow creation of extension kinds', () => { + const TestExtension = createExtensionKind({ + kind: 'test-extension', + attachTo: { id: 'test', input: 'default' }, + output: { + element: coreExtensionData.reactElement, + }, + factory(_, props: { text: string }) { + return { + element:

    {props.text}

    , + }; + }, + }); + + const extension = TestExtension.new({ + name: 'my-extension', + props: { + text: 'Hello, world!', + }, + }); + + expect(extension).toBeDefined(); + }); +}); diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts b/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts new file mode 100644 index 0000000000..31a8e5da64 --- /dev/null +++ b/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts @@ -0,0 +1,164 @@ +import { AppNode } from '../apis'; +import { PortableSchema } from '../schema'; +import { Expand } from '../types'; +import { + AnyExtensionDataMap, + AnyExtensionInputMap, + ExtensionDataValues, + ResolvedExtensionInputs, + createExtension, +} from './createExtension'; + +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +interface ExtensionKindOptions< + TProps, + TInputs extends AnyExtensionInputMap, + TOutput extends AnyExtensionDataMap, + TConfig, +> { + kind: string; + namespace?: string; + name?: string; + attachTo: { id: string; input: string }; + disabled?: boolean; + inputs?: TInputs; + output: TOutput; + configSchema?: PortableSchema; + factory( + options: { + node: AppNode; + config: TConfig; + inputs: Expand>; + }, + props: TProps, + ): Expand>; +} + +class ExtensionKind< + TProps, + TInputs extends AnyExtensionInputMap, + TOutput extends AnyExtensionDataMap, + TConfig, +> { + static create< + TProps, + TInputs extends AnyExtensionInputMap, + TOutput extends AnyExtensionDataMap, + TConfig, + >( + options: ExtensionKindOptions, + ): ExtensionKind { + return new ExtensionKind(options); + } + + private constructor( + private readonly options: ExtensionKindOptions< + TProps, + TInputs, + TOutput, + TConfig + >, + ) {} + + public new(options: { + namespace?: string; + name?: string; + attachTo?: { id: string; input: string }; + disabled?: boolean; + inputs?: TInputs; + output?: TOutput; + configSchema?: PortableSchema; + props: TProps; + factory?( + options: { + node: AppNode; + config: TConfig; + inputs: Expand>; + orignalFactory( + options?: { + node?: AppNode; + config?: TConfig; + inputs?: Expand>; + }, + props?: TProps, + ): Expand>; + }, + props: TProps, + ): Expand>; + }) { + return createExtension({ + kind: this.options.kind, + namespace: options.namespace ?? this.options.namespace, + name: options.name ?? this.options.name, + attachTo: options.attachTo ?? this.options.attachTo, + disabled: options.disabled ?? this.options.disabled, + inputs: options.inputs ?? this.options.inputs, + output: options.output ?? this.options.output, + configSchema: options.configSchema ?? this.options.configSchema, // TODO: some config merging or smth + factory: ({ node, config, inputs }) => { + if (options.factory) { + return options.factory( + { + node, + config, + inputs, + orignalFactory: ( + innerOptions?: { + node?: AppNode; + config?: TConfig; + inputs?: Expand>; + }, + innerProps?: TProps, + ) => + this.options.factory( + { + node: innerOptions?.node ?? node, + config: innerOptions?.config ?? config, + inputs: innerOptions?.inputs ?? inputs, + }, + innerProps ?? options.props, + ), + }, + options.props, + ); + } + + return this.options.factory( + { + node, + config, + inputs, + }, + options.props, + ); + }, + }); + } +} + +/** + * A simpler replacement for wrapping up `createExtension` inside a kind or type. This allows for a cleaner API for creating + * types and instances of those types. + */ +export function createExtensionKind< + TProps, + TInputs extends AnyExtensionInputMap, + TOutput extends AnyExtensionDataMap, + TConfig, +>(options: ExtensionKindOptions) { + return ExtensionKind.create(options); +} From d6c9f12ab3bc54f077e1d2baac8396c61c1c9cbf Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 18 Jun 2024 13:27:31 +0200 Subject: [PATCH 046/510] chore: add some simple tests Signed-off-by: blam --- .../src/wiring/createExtensionKind.test.tsx | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx b/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx index d841ea2c62..ea9459f3f6 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx +++ b/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx @@ -16,6 +16,7 @@ import React from 'react'; import { coreExtensionData } from './coreExtensionData'; import { createExtensionKind } from './createExtensionKind'; +import { createExtensionTester } from '@backstage/frontend-test-utils'; describe('createExtensionKind', () => { it('should allow creation of extension kinds', () => { @@ -40,5 +41,40 @@ describe('createExtensionKind', () => { }); expect(extension).toBeDefined(); + + const { container } = createExtensionTester(extension).render(); + expect(container.querySelector('h1')).toHaveTextContent('Hello, world!'); + }); + + it('should allow overriding of the default factory', () => { + const TestExtension = createExtensionKind({ + kind: 'test-extension', + attachTo: { id: 'test', input: 'default' }, + output: { + element: coreExtensionData.reactElement, + }, + factory(_, props: { text: string }) { + return { + element:

    {props.text}

    , + }; + }, + }); + + const extension = TestExtension.new({ + name: 'my-extension', + props: { + text: 'Hello, world!', + }, + factory(_, props: { text: string }) { + return { + element:

    {props.text}

    , + }; + }, + }); + + expect(extension).toBeDefined(); + + const { container } = createExtensionTester(extension).render(); + expect(container.querySelector('h2')).toHaveTextContent('Hello, world!'); }); }); From ad4591af6615ac1e6281e424ea3b7ec90e9ca4f9 Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 18 Jun 2024 13:29:57 +0200 Subject: [PATCH 047/510] chore: test creted extension Signed-off-by: blam --- .../src/wiring/createExtensionKind.test.tsx | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx b/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx index ea9459f3f6..2d5b218082 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx +++ b/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx @@ -40,7 +40,31 @@ describe('createExtensionKind', () => { }, }); - expect(extension).toBeDefined(); + expect(extension).toEqual({ + $$type: '@backstage/ExtensionDefinition', + attachTo: { + id: 'test', + input: 'default', + }, + configSchema: undefined, + disabled: false, + inputs: {}, + kind: 'test-extension', + name: 'my-extension', + namespace: undefined, + output: { + element: { + $$type: '@backstage/ExtensionDataRef', + config: {}, + id: 'core.reactElement', + optional: expect.any(Function), + toString: expect.any(Function), + }, + }, + factory: expect.any(Function), + toString: expect.any(Function), + version: 'v1', + }); const { container } = createExtensionTester(extension).render(); expect(container.querySelector('h1')).toHaveTextContent('Hello, world!'); From 582dfb5359009e74913b0466976a6ee77a29a822 Mon Sep 17 00:00:00 2001 From: mario ma Date: Tue, 18 Jun 2024 19:54:41 +0800 Subject: [PATCH 048/510] fix: EntityNamespacePicker test Signed-off-by: mario ma --- .../EntityNamespacePicker.test.tsx | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/plugins/catalog-react/src/components/EntityNamespacePicker/EntityNamespacePicker.test.tsx b/plugins/catalog-react/src/components/EntityNamespacePicker/EntityNamespacePicker.test.tsx index 05fa1dc07f..0fd336da42 100644 --- a/plugins/catalog-react/src/components/EntityNamespacePicker/EntityNamespacePicker.test.tsx +++ b/plugins/catalog-react/src/components/EntityNamespacePicker/EntityNamespacePicker.test.tsx @@ -215,7 +215,7 @@ describe('', () => { }), ); }); - it('namespace picker is invisible if there are only 1 available option', async () => { + it('namespace picker is visible if there are only 1 available option', async () => { const defaultNamespaces = ['default', 'default', 'default']; const mockCatalogApiRefDefaultNamespace = { getEntityFacets: async () => ({ @@ -236,6 +236,27 @@ describe('', () => {
    , ); + await waitFor(() => + expect(screen.queryByText('Namespace')).toBeInTheDocument(), + ); + }); + it('namespace picker is invisible if there is zero available option', async () => { + const mockCatalogApiRefDefaultNamespace = { + getEntityFacets: async () => ({ + facets: { + 'metadata.namespace': [], + }, + }), + } as unknown as CatalogApi; + await renderInTestApp( + + + + + , + ); await waitFor(() => expect(screen.queryByText('Namespace')).not.toBeInTheDocument(), ); From 71172a4caf3044b5379bd956c64d3535e1bc6528 Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 18 Jun 2024 14:13:34 +0200 Subject: [PATCH 049/510] chore: added api-reports Signed-off-by: blam --- packages/frontend-plugin-api/api-report.md | 95 +++++++++++++++++++ .../src/wiring/createExtensionKind.ts | 13 ++- .../frontend-plugin-api/src/wiring/index.ts | 5 + 3 files changed, 111 insertions(+), 2 deletions(-) diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index 3e19573d95..b4c761ec05 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -522,6 +522,16 @@ export function createExtensionInput< } >; +// @public +export function createExtensionKind< + TProps, + TInputs extends AnyExtensionInputMap, + TOutput extends AnyExtensionDataMap, + TConfig, +>( + options: ExtensionKindOptions, +): ExtensionKind; + // @public (undocumented) export interface CreateExtensionOptions< TOutput extends AnyExtensionDataMap, @@ -913,6 +923,91 @@ export interface ExtensionInput< extensionData: TExtensionData; } +// @public (undocumented) +export class ExtensionKind< + TProps, + TInputs extends AnyExtensionInputMap, + TOutput extends AnyExtensionDataMap, + TConfig, +> { + // (undocumented) + static create< + TProps, + TInputs extends AnyExtensionInputMap, + TOutput extends AnyExtensionDataMap, + TConfig, + >( + options: ExtensionKindOptions, + ): ExtensionKind; + // (undocumented) + new(options: { + namespace?: string; + name?: string; + attachTo?: { + id: string; + input: string; + }; + disabled?: boolean; + inputs?: TInputs; + output?: TOutput; + configSchema?: PortableSchema; + props: TProps; + factory?( + options: { + node: AppNode; + config: TConfig; + inputs: Expand>; + orignalFactory( + options?: { + node?: AppNode; + config?: TConfig; + inputs?: Expand>; + }, + props?: TProps, + ): Expand>; + }, + props: TProps, + ): Expand>; + }): ExtensionDefinition; +} + +// @public (undocumented) +export interface ExtensionKindOptions< + TProps, + TInputs extends AnyExtensionInputMap, + TOutput extends AnyExtensionDataMap, + TConfig, +> { + // (undocumented) + attachTo: { + id: string; + input: string; + }; + // (undocumented) + configSchema?: PortableSchema; + // (undocumented) + disabled?: boolean; + // (undocumented) + factory( + options: { + node: AppNode; + config: TConfig; + inputs: Expand>; + }, + props: TProps, + ): Expand>; + // (undocumented) + inputs?: TInputs; + // (undocumented) + kind: string; + // (undocumented) + name?: string; + // (undocumented) + namespace?: string; + // (undocumented) + output: TOutput; +} + // @public (undocumented) export interface ExtensionOverrides { // (undocumented) diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts b/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts index 31a8e5da64..2067d18c04 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts @@ -24,7 +24,11 @@ import { * See the License for the specific language governing permissions and * limitations under the License. */ -interface ExtensionKindOptions< + +/** + * @public + */ +export interface ExtensionKindOptions< TProps, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, @@ -48,7 +52,10 @@ interface ExtensionKindOptions< ): Expand>; } -class ExtensionKind< +/** + * @public + */ +export class ExtensionKind< TProps, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, @@ -153,6 +160,8 @@ class ExtensionKind< /** * A simpler replacement for wrapping up `createExtension` inside a kind or type. This allows for a cleaner API for creating * types and instances of those types. + * + * @public */ export function createExtensionKind< TProps, diff --git a/packages/frontend-plugin-api/src/wiring/index.ts b/packages/frontend-plugin-api/src/wiring/index.ts index 61f821c7ce..e8c9afbaae 100644 --- a/packages/frontend-plugin-api/src/wiring/index.ts +++ b/packages/frontend-plugin-api/src/wiring/index.ts @@ -48,3 +48,8 @@ export { type FeatureFlagConfig, type FrontendFeature, } from './types'; +export { + type ExtensionKindOptions, + ExtensionKind, + createExtensionKind, +} from './createExtensionKind'; From 4e53ad666d3c39d53ad4b81d7b6869a23dc1d5fa Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 18 Jun 2024 14:15:39 +0200 Subject: [PATCH 050/510] chore: add changeset Signed-off-by: blam --- .changeset/dry-squids-tap.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .changeset/dry-squids-tap.md diff --git a/.changeset/dry-squids-tap.md b/.changeset/dry-squids-tap.md new file mode 100644 index 0000000000..a9eb7efb3b --- /dev/null +++ b/.changeset/dry-squids-tap.md @@ -0,0 +1,26 @@ +--- +'@backstage/frontend-plugin-api': patch +--- + +Introduce a new way to create extension types and kinds, with `createExtensionKind`. + +This allows the creation of extension with the following pattern: + +```tsx +// create the extension kind +const TestExtension = createExtensionKind({ + kind: 'test-extension', + attachTo: { id: 'test', input: 'default' }, + output: { + element: coreExtensionData.reactElement, + }, + factory(_, props: { text: string }) { + return { + element:

    {props.text}

    , + }; + }, +}); + +// create an instance of the extension kind with props +const testExtension = TestExtension.create({ text: 'Hello World' }); +``` From dfaa28db0711ffe942da9fc5ddb6e3a7a45d0ecb Mon Sep 17 00:00:00 2001 From: Adam Letizia Date: Tue, 18 Jun 2024 09:23:41 -0500 Subject: [PATCH 051/510] fix(scaffolder-backend-module-github): adds requireLastPushApproval input Signed-off-by: Adam Letizia --- .changeset/ten-nails-hear.md | 5 + .../api-report.md | 2 + .../src/actions/gitHelpers.ts | 3 + .../src/actions/github.test.ts | 651 ++++-------------- .../src/actions/github.ts | 4 + .../src/actions/githubRepoPush.test.ts | 102 ++- .../src/actions/githubRepoPush.ts | 4 + .../src/actions/helpers.ts | 2 + .../src/actions/inputProperties.ts | 6 + 9 files changed, 277 insertions(+), 502 deletions(-) create mode 100644 .changeset/ten-nails-hear.md diff --git a/.changeset/ten-nails-hear.md b/.changeset/ten-nails-hear.md new file mode 100644 index 0000000000..363b028372 --- /dev/null +++ b/.changeset/ten-nails-hear.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-github': patch +--- + +Adds requireLastPushApproval input property to configure Branch Protection Settings diff --git a/plugins/scaffolder-backend-module-github/api-report.md b/plugins/scaffolder-backend-module-github/api-report.md index beabdfaaf6..78b1daf65d 100644 --- a/plugins/scaffolder-backend-module-github/api-report.md +++ b/plugins/scaffolder-backend-module-github/api-report.md @@ -256,6 +256,7 @@ export function createGithubRepoPushAction(options: { sourcePath?: string | undefined; token?: string | undefined; requiredCommitSigning?: boolean | undefined; + requireLastPushApproval?: boolean | undefined; }, JsonObject >; @@ -328,6 +329,7 @@ export function createPublishGithubAction(options: { requiredStatusCheckContexts?: string[] | undefined; requireBranchesToBeUpToDate?: boolean | undefined; requiredConversationResolution?: boolean | undefined; + requireLastPushApproval?: boolean | undefined; repoVisibility?: 'internal' | 'private' | 'public' | undefined; collaborators?: | ( diff --git a/plugins/scaffolder-backend-module-github/src/actions/gitHelpers.ts b/plugins/scaffolder-backend-module-github/src/actions/gitHelpers.ts index ea92201eec..9989a80724 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/gitHelpers.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/gitHelpers.ts @@ -38,6 +38,7 @@ type BranchProtectionOptions = { }; requireBranchesToBeUpToDate?: boolean; requiredConversationResolution?: boolean; + requireLastPushApproval: boolean; defaultBranch?: string; enforceAdmins?: boolean; dismissStaleReviews?: boolean; @@ -56,6 +57,7 @@ export const enableBranchProtectionOnDefaultRepoBranch = async ({ requiredStatusCheckContexts = [], requireBranchesToBeUpToDate = true, requiredConversationResolution = false, + requireLastPushApproval = false, defaultBranch = 'master', enforceAdmins = true, dismissStaleReviews = false, @@ -88,6 +90,7 @@ export const enableBranchProtectionOnDefaultRepoBranch = async ({ require_code_owner_reviews: requireCodeOwnerReviews, bypass_pull_request_allowances: bypassPullRequestAllowances, dismiss_stale_reviews: dismissStaleReviews, + require_last_push_approval: requireLastPushApproval, }, required_conversation_resolution: requiredConversationResolution, }); 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 9eda9a2eb0..31ec7ecc90 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/github.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/github.test.ts @@ -1010,174 +1010,6 @@ describe('publish:github', () => { ); }); - it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of requireCodeOwnerReviews', async () => { - mockOctokit.rest.users.getByUsername.mockResolvedValue({ - data: { type: 'User' }, - }); - - mockOctokit.rest.repos.createForAuthenticatedUser.mockResolvedValue({ - data: { - name: 'repo', - }, - }); - - await action.handler(mockContext); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repo', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - restrictions: undefined, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - enforceAdmins: true, - dismissStaleReviews: false, - requiredCommitSigning: false, - }); - - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, - requireCodeOwnerReviews: true, - }, - }); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repo', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: true, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - restrictions: undefined, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - enforceAdmins: true, - dismissStaleReviews: false, - requiredCommitSigning: false, - }); - - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, - requireCodeOwnerReviews: false, - }, - }); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repo', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - restrictions: undefined, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - enforceAdmins: true, - dismissStaleReviews: false, - requiredCommitSigning: false, - }); - }); - - it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of enforceAdmins', async () => { - mockOctokit.rest.users.getByUsername.mockResolvedValue({ - data: { type: 'User' }, - }); - - mockOctokit.rest.repos.createForAuthenticatedUser.mockResolvedValue({ - data: { - name: 'repo', - }, - }); - - await action.handler(mockContext); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repo', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - restrictions: undefined, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - enforceAdmins: true, - dismissStaleReviews: false, - requiredCommitSigning: false, - }); - - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, - protectEnforceAdmins: false, - }, - }); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repo', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - restrictions: undefined, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - enforceAdmins: false, - dismissStaleReviews: false, - requiredCommitSigning: false, - }); - - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, - protectEnforceAdmins: true, - }, - }); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repo', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - restrictions: undefined, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - enforceAdmins: true, - dismissStaleReviews: false, - requiredCommitSigning: false, - }); - }); - it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of requiredStatusCheckContexts and requireBranchesToBeUpToDate', async () => { mockOctokit.rest.users.getByUsername.mockResolvedValue({ data: { type: 'User' }, @@ -1204,6 +1036,7 @@ describe('publish:github', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, requiredCommitSigning: false, @@ -1232,6 +1065,7 @@ describe('publish:github', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, requiredCommitSigning: false, @@ -1259,6 +1093,7 @@ describe('publish:github', () => { requiredStatusCheckContexts: ['statusCheck'], requireBranchesToBeUpToDate: false, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, requiredCommitSigning: false, @@ -1285,6 +1120,7 @@ describe('publish:github', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, requiredCommitSigning: false, @@ -1346,255 +1182,6 @@ describe('publish:github', () => { }); }); - it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of dismissStaleReviews', async () => { - mockOctokit.rest.users.getByUsername.mockResolvedValue({ - data: { type: 'User' }, - }); - - mockOctokit.rest.repos.createForAuthenticatedUser.mockResolvedValue({ - data: { - name: 'repo', - }, - }); - - await action.handler(mockContext); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repo', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - restrictions: undefined, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - enforceAdmins: true, - dismissStaleReviews: false, - requiredCommitSigning: false, - }); - - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, - dismissStaleReviews: true, - }, - }); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repo', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - restrictions: undefined, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - enforceAdmins: true, - dismissStaleReviews: true, - requiredCommitSigning: false, - }); - - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, - dismissStaleReviews: false, - }, - }); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repo', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - restrictions: undefined, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - enforceAdmins: true, - dismissStaleReviews: false, - requiredCommitSigning: false, - }); - }); - it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of requiredConversationResolution', async () => { - mockOctokit.rest.users.getByUsername.mockResolvedValue({ - data: { type: 'User' }, - }); - - mockOctokit.rest.repos.createForAuthenticatedUser.mockResolvedValue({ - data: { - name: 'repo', - }, - }); - - await action.handler(mockContext); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repo', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - restrictions: undefined, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - enforceAdmins: true, - dismissStaleReviews: false, - requiredCommitSigning: false, - }); - - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, - requiredConversationResolution: true, - }, - }); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repo', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - restrictions: undefined, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: true, - enforceAdmins: true, - dismissStaleReviews: false, - requiredCommitSigning: false, - }); - - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, - requiredConversationResolution: false, - }, - }); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repo', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - restrictions: undefined, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - enforceAdmins: true, - dismissStaleReviews: false, - requiredCommitSigning: false, - }); - }); - it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of requiredApprovingReviewCount', async () => { - mockOctokit.rest.users.getByUsername.mockResolvedValue({ - data: { type: 'User' }, - }); - - mockOctokit.rest.repos.createForAuthenticatedUser.mockResolvedValue({ - data: { - name: 'repo', - }, - }); - - await action.handler(mockContext); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repo', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - restrictions: undefined, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - enforceAdmins: true, - dismissStaleReviews: false, - requiredCommitSigning: false, - }); - - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, - requiredApprovingReviewCount: 2, - }, - }); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repo', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 2, - restrictions: undefined, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - enforceAdmins: true, - dismissStaleReviews: false, - requiredCommitSigning: false, - }); - - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, - requiredApprovingReviewCount: 0, - }, - }); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repo', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 0, - restrictions: undefined, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - enforceAdmins: true, - dismissStaleReviews: false, - requiredCommitSigning: false, - }); - }); it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of restrictions', async () => { mockOctokit.rest.users.getByUsername.mockResolvedValue({ data: { type: 'User' }, @@ -1621,6 +1208,7 @@ describe('publish:github', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, requiredCommitSigning: false, @@ -1653,6 +1241,7 @@ describe('publish:github', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, requiredCommitSigning: false, @@ -1685,6 +1274,7 @@ describe('publish:github', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, requiredCommitSigning: false, @@ -1719,6 +1309,7 @@ describe('publish:github', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, requiredCommitSigning: false, @@ -1753,6 +1344,7 @@ describe('publish:github', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, requiredCommitSigning: false, @@ -1787,94 +1379,12 @@ describe('publish:github', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, requiredCommitSigning: false, }); }); - it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of requiredCommitSigning', async () => { - mockOctokit.rest.users.getByUsername.mockResolvedValue({ - data: { type: 'User' }, - }); - - mockOctokit.rest.repos.createForAuthenticatedUser.mockResolvedValue({ - data: { - name: 'repo', - }, - }); - - await action.handler(mockContext); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repo', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - restrictions: undefined, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - enforceAdmins: true, - dismissStaleReviews: false, - requiredCommitSigning: false, - }); - - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, - requiredCommitSigning: false, - }, - }); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repo', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - restrictions: undefined, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - enforceAdmins: true, - dismissStaleReviews: false, - requiredCommitSigning: false, - }); - - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, - requiredCommitSigning: true, - }, - }); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repo', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - restrictions: undefined, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - enforceAdmins: true, - dismissStaleReviews: false, - requiredCommitSigning: true, - }); - }); it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of bypassPullRequestAllowances', async () => { mockOctokit.rest.users.getByUsername.mockResolvedValue({ data: { type: 'User' }, @@ -1901,6 +1411,7 @@ describe('publish:github', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, requiredCommitSigning: false, @@ -1931,6 +1442,7 @@ describe('publish:github', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, requiredCommitSigning: false, @@ -1961,6 +1473,7 @@ describe('publish:github', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, requiredCommitSigning: false, @@ -1991,6 +1504,7 @@ describe('publish:github', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, requiredCommitSigning: false, @@ -2025,6 +1539,7 @@ describe('publish:github', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, requiredCommitSigning: false, @@ -2059,9 +1574,145 @@ describe('publish:github', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, requiredCommitSigning: false, }); }); + + it.each([ + { + inputProperty: 'dismissStaleReviews', + defaultValue: false, + overrideValue: true, + }, + { + inputProperty: 'requiredConversationResolution', + defaultValue: false, + overrideValue: true, + }, + { + inputProperty: 'requireLastPushApproval', + defaultValue: false, + overrideValue: true, + }, + { + inputProperty: 'requiredApprovingReviewCount', + defaultValue: 1, + overrideValue: 2, + }, + { + inputProperty: 'requiredCommitSigning', + defaultValue: false, + overrideValue: true, + }, + { + inputProperty: 'protectEnforceAdmins', + defaultValue: true, + overrideValue: false, + octokitParameter: 'enforceAdmins', + }, + { + inputProperty: 'requireCodeOwnerReviews', + defaultValue: false, + overrideValue: true, + }, + ])( + 'should call enableBranchProtectionOnDefaultRepoBranch with the correct values of $inputProperty', + async ({ + inputProperty, + defaultValue, + overrideValue, + octokitParameter, + }) => { + mockOctokit.rest.users.getByUsername.mockResolvedValue({ + data: { type: 'User' }, + }); + + mockOctokit.rest.repos.createForAuthenticatedUser.mockResolvedValue({ + data: { + name: 'repo', + }, + }); + + await action.handler(mockContext); + + expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ + owner: 'owner', + client: mockOctokit, + repoName: 'repo', + logger: mockContext.logger, + defaultBranch: 'master', + requireCodeOwnerReviews: false, + bypassPullRequestAllowances: undefined, + requiredApprovingReviewCount: 1, + restrictions: undefined, + requiredStatusCheckContexts: [], + requireBranchesToBeUpToDate: true, + requiredConversationResolution: false, + requireLastPushApproval: false, + enforceAdmins: true, + dismissStaleReviews: false, + requiredCommitSigning: false, + [octokitParameter || inputProperty]: defaultValue, + }); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + [inputProperty]: overrideValue, + }, + }); + + expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ + owner: 'owner', + client: mockOctokit, + repoName: 'repo', + logger: mockContext.logger, + defaultBranch: 'master', + requireCodeOwnerReviews: false, + bypassPullRequestAllowances: undefined, + requiredApprovingReviewCount: 1, + restrictions: undefined, + requiredStatusCheckContexts: [], + requireBranchesToBeUpToDate: true, + requiredConversationResolution: false, + requireLastPushApproval: false, + enforceAdmins: true, + dismissStaleReviews: false, + requiredCommitSigning: false, + [octokitParameter || inputProperty]: overrideValue, + }); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + [inputProperty]: defaultValue, + }, + }); + + expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ + owner: 'owner', + client: mockOctokit, + repoName: 'repo', + logger: mockContext.logger, + defaultBranch: 'master', + requireCodeOwnerReviews: false, + bypassPullRequestAllowances: undefined, + requiredApprovingReviewCount: 1, + restrictions: undefined, + requiredStatusCheckContexts: [], + requireBranchesToBeUpToDate: true, + requiredConversationResolution: false, + requireLastPushApproval: false, + enforceAdmins: true, + dismissStaleReviews: false, + requiredCommitSigning: false, + [octokitParameter || inputProperty]: defaultValue, + }); + }, + ); }); diff --git a/plugins/scaffolder-backend-module-github/src/actions/github.ts b/plugins/scaffolder-backend-module-github/src/actions/github.ts index f32b65bc9a..c8b22de7e7 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/github.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/github.ts @@ -86,6 +86,7 @@ export function createPublishGithubAction(options: { requiredStatusCheckContexts?: string[]; requireBranchesToBeUpToDate?: boolean; requiredConversationResolution?: boolean; + requireLastPushApproval?: boolean; repoVisibility?: 'private' | 'internal' | 'public'; collaborators?: Array< | { @@ -137,6 +138,7 @@ export function createPublishGithubAction(options: { requireBranchesToBeUpToDate: inputProps.requireBranchesToBeUpToDate, requiredConversationResolution: inputProps.requiredConversationResolution, + requireLastPushApproval: inputProps.requireLastPushApproval, repoVisibility: inputProps.repoVisibility, defaultBranch: inputProps.defaultBranch, protectDefaultBranch: inputProps.protectDefaultBranch, @@ -187,6 +189,7 @@ export function createPublishGithubAction(options: { requiredStatusCheckContexts = [], requireBranchesToBeUpToDate = true, requiredConversationResolution = false, + requireLastPushApproval = false, repoVisibility = 'private', defaultBranch = 'master', protectDefaultBranch = true, @@ -274,6 +277,7 @@ export function createPublishGithubAction(options: { requiredStatusCheckContexts, requireBranchesToBeUpToDate, requiredConversationResolution, + requireLastPushApproval, config, ctx.logger, gitCommitMessage, diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.test.ts index 4d16a25774..257220134f 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.test.ts @@ -325,6 +325,7 @@ describe('github:repo:push', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, bypassPullRequestAllowances: undefined, @@ -351,6 +352,7 @@ describe('github:repo:push', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, bypassPullRequestAllowances: undefined, @@ -377,6 +379,7 @@ describe('github:repo:push', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, bypassPullRequestAllowances: undefined, @@ -406,6 +409,7 @@ describe('github:repo:push', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, bypassPullRequestAllowances: undefined, @@ -432,6 +436,7 @@ describe('github:repo:push', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, bypassPullRequestAllowances: undefined, @@ -458,6 +463,7 @@ describe('github:repo:push', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: false, dismissStaleReviews: false, bypassPullRequestAllowances: undefined, @@ -487,6 +493,7 @@ describe('github:repo:push', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, bypassPullRequestAllowances: undefined, @@ -501,7 +508,6 @@ describe('github:repo:push', () => { ...mockContext.input, requiredStatusCheckContexts: ['statusCheck'], requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, }, }); @@ -515,6 +521,7 @@ describe('github:repo:push', () => { requiredStatusCheckContexts: ['statusCheck'], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, bypassPullRequestAllowances: undefined, @@ -542,6 +549,7 @@ describe('github:repo:push', () => { requiredStatusCheckContexts: ['statusCheck'], requireBranchesToBeUpToDate: false, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, bypassPullRequestAllowances: undefined, @@ -556,7 +564,6 @@ describe('github:repo:push', () => { ...mockContext.input, requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, }, }); @@ -570,6 +577,7 @@ describe('github:repo:push', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, bypassPullRequestAllowances: undefined, @@ -618,6 +626,7 @@ describe('github:repo:push', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, bypassPullRequestAllowances: undefined, @@ -644,6 +653,7 @@ describe('github:repo:push', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: true, bypassPullRequestAllowances: undefined, @@ -670,6 +680,7 @@ describe('github:repo:push', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, bypassPullRequestAllowances: undefined, @@ -699,6 +710,7 @@ describe('github:repo:push', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, bypassPullRequestAllowances: undefined, @@ -725,6 +737,7 @@ describe('github:repo:push', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: true, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, bypassPullRequestAllowances: undefined, @@ -751,6 +764,91 @@ describe('github:repo:push', () => { requiredStatusCheckContexts: [], requireBranchesToBeUpToDate: true, requiredConversationResolution: false, + requireLastPushApproval: false, + enforceAdmins: true, + dismissStaleReviews: false, + bypassPullRequestAllowances: undefined, + requiredApprovingReviewCount: 1, + requiredCommitSigning: false, + restrictions: undefined, + }); + }); + + it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of requireLastPushApproval', async () => { + mockOctokit.rest.repos.get.mockResolvedValue({ + data: { + clone_url: 'https://github.com/clone/url.git', + html_url: 'https://github.com/html/url', + }, + }); + + await action.handler(mockContext); + + expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ + owner: 'owner', + client: mockOctokit, + repoName: 'repository', + logger: mockContext.logger, + defaultBranch: 'master', + requireCodeOwnerReviews: false, + requiredStatusCheckContexts: [], + requireBranchesToBeUpToDate: true, + requiredConversationResolution: false, + requireLastPushApproval: false, + enforceAdmins: true, + dismissStaleReviews: false, + bypassPullRequestAllowances: undefined, + requiredApprovingReviewCount: 1, + requiredCommitSigning: false, + restrictions: undefined, + }); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + requireLastPushApproval: true, + }, + }); + + expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ + owner: 'owner', + client: mockOctokit, + repoName: 'repository', + logger: mockContext.logger, + defaultBranch: 'master', + requireCodeOwnerReviews: false, + requiredStatusCheckContexts: [], + requireBranchesToBeUpToDate: true, + requiredConversationResolution: false, + requireLastPushApproval: true, + enforceAdmins: true, + dismissStaleReviews: false, + bypassPullRequestAllowances: undefined, + requiredApprovingReviewCount: 1, + requiredCommitSigning: false, + restrictions: undefined, + }); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + requireLastPushApproval: false, + }, + }); + + expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ + owner: 'owner', + client: mockOctokit, + repoName: 'repository', + logger: mockContext.logger, + defaultBranch: 'master', + requireCodeOwnerReviews: false, + requiredStatusCheckContexts: [], + requireBranchesToBeUpToDate: true, + requiredConversationResolution: false, + requireLastPushApproval: false, enforceAdmins: true, dismissStaleReviews: false, bypassPullRequestAllowances: undefined, diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.ts b/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.ts index 5b9db78f48..a4fa7673c6 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.ts @@ -75,6 +75,7 @@ export function createGithubRepoPushAction(options: { sourcePath?: string; token?: string; requiredCommitSigning?: boolean; + requireLastPushApproval?: boolean; }>({ id: 'github:repo:push', description: @@ -95,6 +96,7 @@ export function createGithubRepoPushAction(options: { requireBranchesToBeUpToDate: inputProps.requireBranchesToBeUpToDate, requiredConversationResolution: inputProps.requiredConversationResolution, + requireLastPushApproval: inputProps.requireLastPushApproval, defaultBranch: inputProps.defaultBranch, protectDefaultBranch: inputProps.protectDefaultBranch, protectEnforceAdmins: inputProps.protectEnforceAdmins, @@ -132,6 +134,7 @@ export function createGithubRepoPushAction(options: { requiredStatusCheckContexts = [], requireBranchesToBeUpToDate = true, requiredConversationResolution = false, + requireLastPushApproval = false, token: providedToken, requiredCommitSigning = false, } = ctx.input; @@ -174,6 +177,7 @@ export function createGithubRepoPushAction(options: { requiredStatusCheckContexts, requireBranchesToBeUpToDate, requiredConversationResolution, + requireLastPushApproval, config, ctx.logger, gitCommitMessage, diff --git a/plugins/scaffolder-backend-module-github/src/actions/helpers.ts b/plugins/scaffolder-backend-module-github/src/actions/helpers.ts index dd2f4a9f76..eec6f73f92 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/helpers.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/helpers.ts @@ -360,6 +360,7 @@ export async function initRepoPushAndProtect( requiredStatusCheckContexts: string[], requireBranchesToBeUpToDate: boolean, requiredConversationResolution: boolean, + requireLastPushApproval: boolean, config: Config, logger: any, gitCommitMessage?: string, @@ -408,6 +409,7 @@ export async function initRepoPushAndProtect( requiredStatusCheckContexts, requireBranchesToBeUpToDate, requiredConversationResolution, + requireLastPushApproval, enforceAdmins: protectEnforceAdmins, dismissStaleReviews: dismissStaleReviews, requiredCommitSigning: requiredCommitSigning, diff --git a/plugins/scaffolder-backend-module-github/src/actions/inputProperties.ts b/plugins/scaffolder-backend-module-github/src/actions/inputProperties.ts index 585526fe94..f6fc592b72 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/inputProperties.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/inputProperties.ts @@ -64,6 +64,11 @@ const requiredConversationResolution = { 'Requires all conversations on code to be resolved before a pull request can be merged into this branch', type: 'boolean', }; +const requireLastPushApproval = { + title: 'Require last push approval', + type: 'boolean', + description: `Whether the most recent push to a PR must be approved by someone other than the person who pushed it. The default value is 'false'`, +}; const repoVisibility = { title: 'Repository Visibility', type: 'string', @@ -326,6 +331,7 @@ export { dismissStaleReviews }; export { requiredStatusCheckContexts }; export { requireBranchesToBeUpToDate }; export { requiredConversationResolution }; +export { requireLastPushApproval }; export { hasProjects }; export { hasIssues }; export { hasWiki }; From 3008b637979478fa4c7e68f8cc2caa2fbc7044e5 Mon Sep 17 00:00:00 2001 From: Adam Letizia Date: Tue, 18 Jun 2024 10:04:33 -0500 Subject: [PATCH 052/510] chore(test): extract test case scenarios for branch protection settings Signed-off-by: Adam Letizia --- .../src/actions/githubRepoPush.test.ts | 540 ++++-------------- 1 file changed, 126 insertions(+), 414 deletions(-) diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.test.ts index 257220134f..d0ee4bfa12 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.test.ts @@ -305,174 +305,6 @@ describe('github:repo:push', () => { ); }); - it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of requireCodeOwnerReviews', async () => { - mockOctokit.rest.repos.get.mockResolvedValue({ - data: { - clone_url: 'https://github.com/clone/url.git', - html_url: 'https://github.com/html/url', - }, - }); - - await action.handler(mockContext); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repository', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - requireLastPushApproval: false, - enforceAdmins: true, - dismissStaleReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - requiredCommitSigning: false, - restrictions: undefined, - }); - - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, - requireCodeOwnerReviews: true, - }, - }); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repository', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: true, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - requireLastPushApproval: false, - enforceAdmins: true, - dismissStaleReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - requiredCommitSigning: false, - restrictions: undefined, - }); - - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, - requireCodeOwnerReviews: false, - }, - }); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repository', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - requireLastPushApproval: false, - enforceAdmins: true, - dismissStaleReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - requiredCommitSigning: false, - restrictions: undefined, - }); - }); - - it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of enforceAdmins', async () => { - mockOctokit.rest.repos.get.mockResolvedValue({ - data: { - clone_url: 'https://github.com/clone/url.git', - html_url: 'https://github.com/html/url', - }, - }); - - await action.handler(mockContext); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repository', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - requireLastPushApproval: false, - enforceAdmins: true, - dismissStaleReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - requiredCommitSigning: false, - restrictions: undefined, - }); - - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, - protectEnforceAdmins: true, - }, - }); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repository', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - requireLastPushApproval: false, - enforceAdmins: true, - dismissStaleReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - requiredCommitSigning: false, - restrictions: undefined, - }); - - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, - protectEnforceAdmins: false, - }, - }); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repository', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - requireLastPushApproval: false, - enforceAdmins: false, - dismissStaleReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - requiredCommitSigning: false, - restrictions: undefined, - }); - }); - it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of requiredStatusCheckContexts and requireBranchesToBeUpToDate', async () => { mockOctokit.rest.repos.get.mockResolvedValue({ data: { @@ -606,255 +438,135 @@ describe('github:repo:push', () => { expect(enableBranchProtectionOnDefaultRepoBranch).not.toHaveBeenCalled(); }); - it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of dismissStaleReviews', async () => { - mockOctokit.rest.repos.get.mockResolvedValue({ - data: { - clone_url: 'https://github.com/clone/url.git', - html_url: 'https://github.com/html/url', - }, - }); + it.each([ + { + inputProperty: 'dismissStaleReviews', + defaultValue: false, + overrideValue: true, + }, + { + inputProperty: 'requiredConversationResolution', + defaultValue: false, + overrideValue: true, + }, + { + inputProperty: 'requireLastPushApproval', + defaultValue: false, + overrideValue: true, + }, + { + inputProperty: 'requiredApprovingReviewCount', + defaultValue: 1, + overrideValue: 2, + }, + { + inputProperty: 'requiredCommitSigning', + defaultValue: false, + overrideValue: true, + }, + { + inputProperty: 'protectEnforceAdmins', + defaultValue: true, + overrideValue: false, + octokitParameter: 'enforceAdmins', + }, + { + inputProperty: 'requireCodeOwnerReviews', + defaultValue: false, + overrideValue: true, + }, + ])( + 'should call enableBranchProtectionOnDefaultRepoBranch with the correct values of $inputProperty', + async ({ + inputProperty, + defaultValue, + overrideValue, + octokitParameter, + }) => { + mockOctokit.rest.repos.get.mockResolvedValue({ + data: { + clone_url: 'https://github.com/clone/url.git', + html_url: 'https://github.com/html/url', + }, + }); - await action.handler(mockContext); + await action.handler(mockContext); - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repository', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - requireLastPushApproval: false, - enforceAdmins: true, - dismissStaleReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - requiredCommitSigning: false, - restrictions: undefined, - }); - - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, - dismissStaleReviews: true, - }, - }); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repository', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - requireLastPushApproval: false, - enforceAdmins: true, - dismissStaleReviews: true, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - requiredCommitSigning: false, - restrictions: undefined, - }); - - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, - dismissStaleReviews: false, - }, - }); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repository', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - requireLastPushApproval: false, - enforceAdmins: true, - dismissStaleReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - requiredCommitSigning: false, - restrictions: undefined, - }); - }); - - it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of requiredConversationResolution', async () => { - mockOctokit.rest.repos.get.mockResolvedValue({ - data: { - clone_url: 'https://github.com/clone/url.git', - html_url: 'https://github.com/html/url', - }, - }); - - await action.handler(mockContext); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repository', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - requireLastPushApproval: false, - enforceAdmins: true, - dismissStaleReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - requiredCommitSigning: false, - restrictions: undefined, - }); - - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, - requiredConversationResolution: true, - }, - }); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repository', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: true, - requireLastPushApproval: false, - enforceAdmins: true, - dismissStaleReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - requiredCommitSigning: false, - restrictions: undefined, - }); - - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, + expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ + owner: 'owner', + client: mockOctokit, + repoName: 'repository', + logger: mockContext.logger, + defaultBranch: 'master', + requireCodeOwnerReviews: false, + requiredStatusCheckContexts: [], + requireBranchesToBeUpToDate: true, requiredConversationResolution: false, - }, - }); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repository', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - requireLastPushApproval: false, - enforceAdmins: true, - dismissStaleReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - requiredCommitSigning: false, - restrictions: undefined, - }); - }); - - it('should call enableBranchProtectionOnDefaultRepoBranch with the correct values of requireLastPushApproval', async () => { - mockOctokit.rest.repos.get.mockResolvedValue({ - data: { - clone_url: 'https://github.com/clone/url.git', - html_url: 'https://github.com/html/url', - }, - }); - - await action.handler(mockContext); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repository', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - requireLastPushApproval: false, - enforceAdmins: true, - dismissStaleReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - requiredCommitSigning: false, - restrictions: undefined, - }); - - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, - requireLastPushApproval: true, - }, - }); - - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repository', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - requireLastPushApproval: true, - enforceAdmins: true, - dismissStaleReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - requiredCommitSigning: false, - restrictions: undefined, - }); - - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, requireLastPushApproval: false, - }, - }); + enforceAdmins: true, + dismissStaleReviews: false, + bypassPullRequestAllowances: undefined, + requiredApprovingReviewCount: 1, + requiredCommitSigning: false, + restrictions: undefined, + [octokitParameter || inputProperty]: defaultValue, + }); - expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ - owner: 'owner', - client: mockOctokit, - repoName: 'repository', - logger: mockContext.logger, - defaultBranch: 'master', - requireCodeOwnerReviews: false, - requiredStatusCheckContexts: [], - requireBranchesToBeUpToDate: true, - requiredConversationResolution: false, - requireLastPushApproval: false, - enforceAdmins: true, - dismissStaleReviews: false, - bypassPullRequestAllowances: undefined, - requiredApprovingReviewCount: 1, - requiredCommitSigning: false, - restrictions: undefined, - }); - }); + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + [inputProperty]: overrideValue, + }, + }); + + expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ + owner: 'owner', + client: mockOctokit, + repoName: 'repository', + logger: mockContext.logger, + defaultBranch: 'master', + requireCodeOwnerReviews: false, + requiredStatusCheckContexts: [], + requireBranchesToBeUpToDate: true, + requiredConversationResolution: false, + requireLastPushApproval: false, + enforceAdmins: true, + dismissStaleReviews: false, + bypassPullRequestAllowances: undefined, + requiredApprovingReviewCount: 1, + requiredCommitSigning: false, + restrictions: undefined, + [octokitParameter || inputProperty]: overrideValue, + }); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + [inputProperty]: defaultValue, + }, + }); + + expect(enableBranchProtectionOnDefaultRepoBranch).toHaveBeenCalledWith({ + owner: 'owner', + client: mockOctokit, + repoName: 'repository', + logger: mockContext.logger, + defaultBranch: 'master', + requireCodeOwnerReviews: false, + requiredStatusCheckContexts: [], + requireBranchesToBeUpToDate: true, + requiredConversationResolution: false, + requireLastPushApproval: false, + enforceAdmins: true, + dismissStaleReviews: false, + bypassPullRequestAllowances: undefined, + requiredApprovingReviewCount: 1, + requiredCommitSigning: false, + restrictions: undefined, + [octokitParameter || inputProperty]: defaultValue, + }); + }, + ); }); From 6caac4ef072448c81b29c2765ceeca4f64bdbb37 Mon Sep 17 00:00:00 2001 From: Adam Letizia Date: Tue, 18 Jun 2024 10:22:59 -0500 Subject: [PATCH 053/510] chore(changeset): update changeset description for each action Signed-off-by: Adam Letizia --- .changeset/ten-nails-hear.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.changeset/ten-nails-hear.md b/.changeset/ten-nails-hear.md index 363b028372..8d3c4d59c3 100644 --- a/.changeset/ten-nails-hear.md +++ b/.changeset/ten-nails-hear.md @@ -2,4 +2,6 @@ '@backstage/plugin-scaffolder-backend-module-github': patch --- -Adds requireLastPushApproval input property to configure Branch Protection Settings +Adds `requireLastPushApproval` input property to configure Branch Protection Settings in `github:publish` action + +Adds `requireLastPushApproval` input property to configure Branch Protection Settings in `github:repo:push` action From 3bf0697eb80eb0a78c654c896587e03e678e510e Mon Sep 17 00:00:00 2001 From: Marek Libra Date: Thu, 20 Jun 2024 10:23:18 +0200 Subject: [PATCH 054/510] Hide NotificationsPage toolbar for empty list Signed-off-by: Marek Libra --- .changeset/metal-suits-drum.md | 5 +++ .../NotificationsTable/NotificationsTable.tsx | 41 ++++++++++--------- 2 files changed, 26 insertions(+), 20 deletions(-) create mode 100644 .changeset/metal-suits-drum.md diff --git a/.changeset/metal-suits-drum.md b/.changeset/metal-suits-drum.md new file mode 100644 index 0000000000..4cc7e18ced --- /dev/null +++ b/.changeset/metal-suits-drum.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-notifications': patch +--- + +The toolbar on the Notifications page is hidden when there are no listed notifications. diff --git a/plugins/notifications/src/components/NotificationsTable/NotificationsTable.tsx b/plugins/notifications/src/components/NotificationsTable/NotificationsTable.tsx index 72a27975f6..d7c4c40781 100644 --- a/plugins/notifications/src/components/NotificationsTable/NotificationsTable.tsx +++ b/plugins/notifications/src/components/NotificationsTable/NotificationsTable.tsx @@ -173,12 +173,14 @@ export const NotificationsTable = ({ } }, [notifications, selectedNotifications]); - const compactColumns = React.useMemo( - (): TableColumn[] => [ + const compactColumns = React.useMemo((): TableColumn[] => { + const showToolbar = notifications.length > 0; + + return [ { /* selection column */ width: '1rem', - title: ( + title: showToolbar ? ( - ), + ) : undefined, render: (notification: Notification) => ( - ), + ) : undefined, render: (notification: Notification) => ( ), }, - ], - [ - markAsReadOnLinkOpen, - selectedNotifications, - notifications, - isUnread, - onSwitchReadStatus, - onSwitchSavedStatus, - onMarkAllRead, - onNotificationsSelectChange, - classes.severityItem, - classes.description, - ], - ); + ]; + }, [ + markAsReadOnLinkOpen, + selectedNotifications, + notifications, + isUnread, + onSwitchReadStatus, + onSwitchSavedStatus, + onMarkAllRead, + onNotificationsSelectChange, + classes.severityItem, + classes.description, + ]); return ( From 9a86dc124f64668ff0a2c7f9dcdbe50a1604f1c4 Mon Sep 17 00:00:00 2001 From: Caio Augusto Date: Thu, 20 Jun 2024 10:07:56 -0300 Subject: [PATCH 055/510] fix(docs): update extension for jsx code snippets file Signed-off-by: Caio Augusto --- docs/frontend-system/architecture/07-routes.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 99cfbae937..9c6617a06f 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -359,7 +359,7 @@ export const detailsSubRouteRef = createSubRouteRef({ Using subroutes in a page extension is as simple as this: -```tsx title="plugins/catalog/src/components/IndexPage.ts" +```tsx title="plugins/catalog/src/components/IndexPage.tsx" import React from 'react'; import { Routes, Route, useLocation } from 'react-router-dom'; import { useRouteRef } from '@backstage/frontend-plugin-api'; @@ -402,7 +402,7 @@ export const IndexPage = () => { This is how you can get the parameters of a sub route URL: -```tsx title="plugins/catalog/src/components/DetailsPage.ts" +```tsx title="plugins/catalog/src/components/DetailsPage.tsx" import React from 'react'; import { useParams } from 'react-router-dom'; @@ -426,7 +426,7 @@ export const DetailsPage = () => { Finally, see how a plugin can provide subroutes: -```tsx title="plugins/catalog/src/plugin.ts" +```tsx title="plugins/catalog/src/plugin.tsx" import React from 'react'; import { createPlugin, From 8839381d6a0980df52604bc6fd8cca5a44931afc Mon Sep 17 00:00:00 2001 From: Stephen Glass Date: Fri, 21 Jun 2024 00:41:13 -0400 Subject: [PATCH 056/510] Add scaffolder option to display object items in separate rows Signed-off-by: Stephen Glass --- .changeset/late-games-protect.md | 5 + .../ReviewState/ReviewState.test.tsx | 173 ++++++++++++++++++ .../components/ReviewState/ReviewState.tsx | 63 ++++++- 3 files changed, 232 insertions(+), 9 deletions(-) create mode 100644 .changeset/late-games-protect.md diff --git a/.changeset/late-games-protect.md b/.changeset/late-games-protect.md new file mode 100644 index 0000000000..584780f836 --- /dev/null +++ b/.changeset/late-games-protect.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-react': minor +--- + +Add scaffolder option to display object items in separate rows on review page diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.test.tsx b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.test.tsx index e9277b2230..dfa1c9c097 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.test.tsx +++ b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.test.tsx @@ -202,4 +202,177 @@ describe('ReviewState', () => { expect(queryByRole('row', { name: 'Name type4' })).toBeInTheDocument(); }); + + it('should display exploded object in separate rows', async () => { + const formState = { + name: { + foo: 'type3', + bar: 'type4', + }, + }; + + const schemas: ParsedTemplateSchema[] = [ + { + mergedSchema: { + type: 'object', + properties: { + name: { + type: 'object', + 'ui:backstage': { + review: { + explode: true, + }, + }, + properties: { + foo: { + type: 'string', + default: 'type1', + }, + bar: { + type: 'string', + default: 'type2', + }, + }, + }, + }, + }, + schema: {}, + title: 'test', + uiSchema: {}, + description: 'asd', + }, + ]; + + const { queryByRole } = render( + , + ); + + expect(queryByRole('row', { name: 'Foo type3' })).toBeInTheDocument(); + expect(queryByRole('row', { name: 'Bar type4' })).toBeInTheDocument(); + }); + + it('should display exploded nested objects', async () => { + const formState = { + name: { + foo: 'type3', + bar: 'type4', + example: { + test: 'type6', + }, + }, + }; + + const schemas: ParsedTemplateSchema[] = [ + { + mergedSchema: { + type: 'object', + properties: { + name: { + type: 'object', + 'ui:backstage': { + review: { + explode: true, + }, + }, + properties: { + foo: { + type: 'string', + default: 'type1', + }, + bar: { + type: 'string', + default: 'type2', + }, + example: { + type: 'object', + 'ui:backstage': { + review: { + explode: true, + }, + }, + properties: { + test: { + type: 'string', + }, + }, + }, + }, + }, + }, + }, + schema: {}, + title: 'test', + uiSchema: {}, + description: 'asd', + }, + ]; + + const { queryByRole } = render( + , + ); + + expect(queryByRole('row', { name: 'Foo type3' })).toBeInTheDocument(); + expect(queryByRole('row', { name: 'Bar type4' })).toBeInTheDocument(); + expect(queryByRole('row', { name: 'Test type6' })).toBeInTheDocument(); + }); + + it('should display partially exploded nested objects', async () => { + const formState = { + name: { + foo: 'type3', + bar: 'type4', + example: { + test: 'type6', + }, + }, + }; + + const schemas: ParsedTemplateSchema[] = [ + { + mergedSchema: { + type: 'object', + properties: { + name: { + type: 'object', + 'ui:backstage': { + review: { + explode: true, + }, + }, + properties: { + foo: { + type: 'string', + default: 'type1', + }, + bar: { + type: 'string', + default: 'type2', + }, + example: { + type: 'object', + properties: { + test: { + type: 'string', + }, + }, + }, + }, + }, + }, + }, + schema: {}, + title: 'test', + uiSchema: {}, + description: 'asd', + }, + ]; + + const { queryByRole } = render( + , + ); + + expect(queryByRole('row', { name: 'Foo type3' })).toBeInTheDocument(); + expect(queryByRole('row', { name: 'Bar type4' })).toBeInTheDocument(); + expect(queryByRole('row', { name: 'Test type6' })).not.toBeInTheDocument(); + }); }); diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx index e3c7bc303e..ac7ac989e3 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx +++ b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; import { StructuredMetadataTable } from '@backstage/core-components'; -import { JsonObject } from '@backstage/types'; +import { JsonObject, JsonValue } from '@backstage/types'; import { Draft07 as JSONSchema } from 'json-schema-library'; import { ParsedTemplateSchema } from '../../hooks/useTemplateSchema'; @@ -28,6 +28,39 @@ export type ReviewStateProps = { formState: JsonObject; }; +function flattenObject( + obj: JsonObject, + prefix: string, + schema: JSONSchema, + formState: JsonObject, +): [string, JsonValue | undefined][] { + return Object.entries(obj).flatMap(([key, value]) => { + const prefixedKey = prefix ? `${prefix}/${key}` : key; + + const definitionInSchema = schema.getSchema({ + pointer: `#/${prefixedKey}`, + data: formState, + }); + + if (definitionInSchema) { + const backstageReviewOptions = definitionInSchema['ui:backstage']?.review; + + // Recurse into nested objects + if ( + backstageReviewOptions && + backstageReviewOptions.explode && + typeof value === 'object' && + value !== null && + !Array.isArray(value) + ) { + return flattenObject(value, prefixedKey, schema, formState); + } + } + + return [[key, value]]; + }); +} + /** * The component used by the {@link Stepper} to render the review step. * @alpha @@ -35,7 +68,7 @@ export type ReviewStateProps = { export const ReviewState = (props: ReviewStateProps) => { const reviewData = Object.fromEntries( Object.entries(props.formState) - .map(([key, value]) => { + .flatMap(([key, value]) => { for (const step of props.schemas) { const parsedSchema = new JSONSchema(step.mergedSchema); const definitionInSchema = parsedSchema.getSchema({ @@ -49,30 +82,42 @@ export const ReviewState = (props: ReviewStateProps) => { if (backstageReviewOptions) { if (backstageReviewOptions.mask) { - return [key, backstageReviewOptions.mask]; + return [[key, backstageReviewOptions.mask]]; } if (backstageReviewOptions.show === false) { return []; } + if ( + backstageReviewOptions.explode && + typeof value === 'object' && + value !== null && + !Array.isArray(value) + ) { + return flattenObject(value, key, parsedSchema, props.formState); + } } if (definitionInSchema['ui:widget'] === 'password') { - return [key, '******']; + return [[key, '******']]; } if (definitionInSchema.enum && definitionInSchema.enumNames) { return [ - key, - definitionInSchema.enumNames[ - definitionInSchema.enum.indexOf(value) - ] || value, + [ + key, + definitionInSchema.enumNames[ + definitionInSchema.enum.indexOf(value) + ] || value, + ], ]; } } } - return [key, value]; + + return [[key, value]]; }) .filter(prop => prop.length > 0), ); + return ; }; From 6f8e1176d858545ade3340a656bd098f25113c10 Mon Sep 17 00:00:00 2001 From: Tavi Nolan Date: Fri, 21 Jun 2024 12:30:17 +0100 Subject: [PATCH 057/510] Updating documents Signed-off-by: Tavi Nolan --- docs/features/software-catalog/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/software-catalog/configuration.md b/docs/features/software-catalog/configuration.md index 61366a91f7..d0206172e5 100644 --- a/docs/features/software-catalog/configuration.md +++ b/docs/features/software-catalog/configuration.md @@ -47,7 +47,7 @@ action is logged for further investigation. ### Local File (`type: file`) Configurations In addition to url locations, you can use the `file` location type to bring in content from the local file system. You should only use this for local development, test setups, and example data, not for production data. -You are also not able to use placeholders in them like `$text`. You can however reference other files relative to the current file. See the full [catalog example data set here](https://github.com/backstage/backstage/tree/master/packages/catalog-model/examples) for an extensive example. +You are also not able to use placeholders in them like `$text`. `$json` or `$yaml`. You can however reference other files relative to the current file. See the full [catalog example data set here](https://github.com/backstage/backstage/blob/master/packages/create-app/templates/default-app/app-config.yaml.hbs) for an extensive example. Here is an example pulling in the `all.yaml` file from the examples folder. Note the use of `../../` to go up two levels from the current execution path of the backend. This is typically `packages/backend/`. From 1ba64786fa522e00f4c65868b8ae0d9e6d4db43f Mon Sep 17 00:00:00 2001 From: Tavi Nolan Date: Fri, 21 Jun 2024 13:04:30 +0100 Subject: [PATCH 058/510] Minor updates to testing documentation Signed-off-by: Tavi Nolan --- docs/plugins/testing.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/plugins/testing.md b/docs/plugins/testing.md index a97b3d8166..7292ac9754 100644 --- a/docs/plugins/testing.md +++ b/docs/plugins/testing.md @@ -24,7 +24,7 @@ Running an individual test (e.g. `MyComponent.test.tsx`): To run both `MyComponent.test.tsx` and `MyControl.test.tsx` suite of tests: - yarn test MyCo + yarn test MyComponent MyControl :::note Note @@ -52,10 +52,6 @@ We use the light-weight [react-testing-library](https://github.com/kentcdodds/react-testing-library) to render React components. -## Testing Utilities - -TODO. - ## Writing Unit Tests The following principles are good guides for determining if you are writing high From d7773d174b3b4fab95db812d6a65cb7bff064139 Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Fri, 21 Jun 2024 22:30:44 +0200 Subject: [PATCH 059/510] refactor(catalog,github): reduce code duplication Signed-off-by: Patrick Jungermann --- .../providers/GithubEntityProvider.test.ts | 810 +++++------------- 1 file changed, 200 insertions(+), 610 deletions(-) diff --git a/plugins/catalog-backend-module-github/src/providers/GithubEntityProvider.test.ts b/plugins/catalog-backend-module-github/src/providers/GithubEntityProvider.test.ts index 42e49c2f72..4ee90d5395 100644 --- a/plugins/catalog-backend-module-github/src/providers/GithubEntityProvider.test.ts +++ b/plugins/catalog-backend-module-github/src/providers/GithubEntityProvider.test.ts @@ -19,12 +19,17 @@ import { TaskInvocationDefinition, TaskRunner, } from '@backstage/backend-tasks'; -import { ConfigReader } from '@backstage/config'; -import { EntityProviderConnection } from '@backstage/plugin-catalog-node'; +import { Config, ConfigReader } from '@backstage/config'; +import { + DeferredEntity, + EntityProviderConnection, + locationSpecToMetadataName, +} from '@backstage/plugin-catalog-node'; import { GithubEntityProvider } from './GithubEntityProvider'; import * as helpers from '../lib/github'; import { EventParams } from '@backstage/plugin-events-node'; import { mockServices } from '@backstage/backend-test-utils'; +import { Commit, PushEvent } from '@octokit/webhooks-types'; jest.mock('../lib/github', () => { return { @@ -47,62 +52,147 @@ class PersistingTaskRunner implements TaskRunner { const logger = mockServices.logger.mock(); describe('GithubEntityProvider', () => { - afterEach(() => jest.clearAllMocks()); + const createSingleProviderConfig = (options?: { + providerConfig?: object; + unwrapped?: boolean; + }): Config => { + const providerConfig = { + organization: 'test-org', + ...options?.providerConfig, + }; - it('no provider config', () => { + return new ConfigReader({ + catalog: { + providers: { + github: options?.unwrapped + ? providerConfig + : { myProvider: providerConfig }, + }, + }, + }); + }; + + const createProviders = (config: Config) => { const schedule = new PersistingTaskRunner(); - const config = new ConfigReader({}); - const providers = GithubEntityProvider.fromConfig(config, { + return GithubEntityProvider.fromConfig(config, { logger, schedule, }); + }; + + const createPushEvent = (options?: { + catalogFile?: { action?: 'added' | 'removed' | 'modified'; path?: string }; + org?: string; + ref?: string; + }): EventParams => { + const organization = options?.org ?? 'test-org'; + const repo = { + default_branch: 'main', + master_branch: 'main', + name: 'test-repo', + organization, + topics: [], + url: `https://github.com/${organization}/test-repo`, + } as Partial; + + const catalogCommit = { + added: [] as string[], + modified: [] as string[], + removed: [] as string[], + }; + catalogCommit[options?.catalogFile?.action ?? 'modified'] = [ + options?.catalogFile?.path ?? 'catalog-info.yaml', + ]; + + const event = { + ref: options?.ref ?? 'refs/heads/main', + repository: repo as PushEvent['repository'], + created: true, + deleted: false, + forced: false, + commits: [ + { + added: ['new-file.yaml'], + removed: [], + modified: [], + }, + catalogCommit, + ] as Partial[], + } as PushEvent; + + return { + topic: 'github.push', + metadata: { + 'x-github-event': 'push', + }, + eventPayload: event, + }; + }; + + const createExpectedEntitiesForUrl = (url: string): DeferredEntity[] => { + return [ + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Location', + metadata: { + annotations: { + 'backstage.io/managed-by-location': `url:${url}`, + 'backstage.io/managed-by-origin-location': `url:${url}`, + }, + name: locationSpecToMetadataName({ type: 'url', target: url }), + }, + spec: { + presence: 'optional', + target: url, + type: 'url', + }, + }, + locationKey: 'github-provider:myProvider', + }, + ]; + }; + + const createExpectedEntitiesForEvent = ( + event: EventParams, + options?: { branch?: string; catalogFilePath?: string }, + ): DeferredEntity[] => { + const url = `${event.eventPayload.repository.url}/blob/${ + options?.branch ?? 'main' + }/${options?.catalogFilePath ?? 'catalog-info.yaml'}`; + return createExpectedEntitiesForUrl(url); + }; + + afterEach(() => jest.clearAllMocks()); + + it('no provider config', () => { + const config = new ConfigReader({}); + const providers = createProviders(config); expect(providers).toHaveLength(0); }); it('single simple provider config', () => { - const schedule = new PersistingTaskRunner(); - const config = new ConfigReader({ - catalog: { - providers: { - github: { - organization: 'test-org', - }, - }, - }, - }); - const providers = GithubEntityProvider.fromConfig(config, { - logger, - schedule, - }); + const config = createSingleProviderConfig({ unwrapped: true }); + const providers = createProviders(config); expect(providers).toHaveLength(1); expect(providers[0].getProviderName()).toEqual('github-provider:default'); }); it('throws when the integration config does not exist', () => { - const schedule = new PersistingTaskRunner(); - const config = new ConfigReader({ - catalog: { - providers: { - github: { - organization: 'test-org', - host: 'ghe.internal.com', - }, - }, + const config = createSingleProviderConfig({ + providerConfig: { + host: 'ghe.internal.com', }, }); - expect(() => - GithubEntityProvider.fromConfig(config, { - logger, - schedule, - }), - ).toThrow(/There is no GitHub config that matches host ghe.internal.com/); + expect(() => createProviders(config)).toThrow( + /There is no GitHub config that matches host ghe.internal.com/, + ); }); it('multiple provider configs', () => { - const schedule = new PersistingTaskRunner(); const config = new ConfigReader({ catalog: { providers: { @@ -117,10 +207,7 @@ describe('GithubEntityProvider', () => { }, }, }); - const providers = GithubEntityProvider.fromConfig(config, { - logger, - schedule, - }); + const providers = createProviders(config); expect(providers).toHaveLength(2); expect(providers[0].getProviderName()).toEqual( @@ -132,19 +219,12 @@ describe('GithubEntityProvider', () => { }); it('apply full update on scheduled execution with basic filters', async () => { - const config = new ConfigReader({ - catalog: { - providers: { - github: { - myProvider: { - organization: 'test-org', - catalogPath: 'custom/path/catalog-custom.yaml', - filters: { - branch: 'main', - repository: 'test-.*', - }, - }, - }, + const config = createSingleProviderConfig({ + providerConfig: { + catalogPath: 'custom/path/catalog-custom.yaml', + filters: { + branch: 'main', + repository: 'test-.*', }, }, }); @@ -194,27 +274,7 @@ describe('GithubEntityProvider', () => { await (taskDef.fn as () => Promise)(); const url = `https://github.com/test-org/test-repo/blob/main/custom/path/catalog-custom.yaml`; - const expectedEntities = [ - { - entity: { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Location', - metadata: { - annotations: { - 'backstage.io/managed-by-location': `url:${url}`, - 'backstage.io/managed-by-origin-location': `url:${url}`, - }, - name: 'generated-5e4b9498097f15434e88c477cfba6c079aa8ca7f', - }, - spec: { - presence: 'optional', - target: `${url}`, - type: 'url', - }, - }, - locationKey: 'github-provider:myProvider', - }, - ]; + const expectedEntities = createExpectedEntitiesForUrl(url); expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1); expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ @@ -379,27 +439,7 @@ describe('GithubEntityProvider', () => { await (taskDef.fn as () => Promise)(); const url = `https://github.com/test-org/test-repo/blob/main/custom/path/catalog-custom.yaml`; - const expectedEntities = [ - { - entity: { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Location', - metadata: { - annotations: { - 'backstage.io/managed-by-location': `url:${url}`, - 'backstage.io/managed-by-origin-location': `url:${url}`, - }, - name: 'generated-5e4b9498097f15434e88c477cfba6c079aa8ca7f', - }, - spec: { - presence: 'optional', - target: `${url}`, - type: 'url', - }, - }, - locationKey: 'github-provider:myProvider', - }, - ]; + const expectedEntities = createExpectedEntitiesForUrl(url); expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1); expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ @@ -487,27 +527,7 @@ describe('GithubEntityProvider', () => { await (taskDef.fn as () => Promise)(); const url = `https://github.com/test-org/another-repo/blob/main/catalog-custom.yaml`; - const expectedEntities = [ - { - entity: { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Location', - metadata: { - annotations: { - 'backstage.io/managed-by-location': `url:${url}`, - 'backstage.io/managed-by-origin-location': `url:${url}`, - }, - name: 'generated-934f500db2ba2e8ea3524567926f45a73bb0b532', - }, - spec: { - presence: 'optional', - target: `${url}`, - type: 'url', - }, - }, - locationKey: 'github-provider:myProvider', - }, - ]; + const expectedEntities = createExpectedEntitiesForUrl(url); expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1); expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ @@ -636,27 +656,7 @@ describe('GithubEntityProvider', () => { await (taskDef.fn as () => Promise)(); const url = `https://github.com/test-org/test-repo/blob/main/custom/path/catalog-custom.yaml`; - const expectedEntities = [ - { - entity: { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Location', - metadata: { - annotations: { - 'backstage.io/managed-by-location': `url:${url}`, - 'backstage.io/managed-by-origin-location': `url:${url}`, - }, - name: 'generated-5e4b9498097f15434e88c477cfba6c079aa8ca7f', - }, - spec: { - presence: 'optional', - target: `${url}`, - type: 'url', - }, - }, - locationKey: 'github-provider:myProvider', - }, - ]; + const expectedEntities = createExpectedEntitiesForUrl(url); expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1); expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ @@ -666,15 +666,7 @@ describe('GithubEntityProvider', () => { }); it('fail without schedule and scheduler', () => { - const config = new ConfigReader({ - catalog: { - providers: { - github: { - organization: 'test-org', - }, - }, - }, - }); + const config = createSingleProviderConfig(); expect(() => GithubEntityProvider.fromConfig(config, { @@ -687,15 +679,7 @@ describe('GithubEntityProvider', () => { const scheduler = { createScheduledTaskRunner: (_: any) => jest.fn(), } as unknown as PluginTaskScheduler; - const config = new ConfigReader({ - catalog: { - providers: { - github: { - organization: 'test-org', - }, - }, - }, - }); + const config = createSingleProviderConfig(); expect(() => GithubEntityProvider.fromConfig(config, { @@ -703,7 +687,7 @@ describe('GithubEntityProvider', () => { scheduler, }), ).toThrow( - 'No schedule provided neither via code nor config for github-provider:default', + 'No schedule provided neither via code nor config for github-provider:myProvider', ); }); @@ -712,18 +696,14 @@ describe('GithubEntityProvider', () => { const scheduler = { createScheduledTaskRunner: (_: any) => schedule, } as unknown as PluginTaskScheduler; - const config = new ConfigReader({ - catalog: { - providers: { - github: { - organization: 'test-org', - schedule: { - frequency: 'P1M', - timeout: 'PT3M', - }, - }, + const config = createSingleProviderConfig({ + providerConfig: { + schedule: { + frequency: 'P1M', + timeout: 'PT3M', }, }, + unwrapped: true, }); const providers = GithubEntityProvider.fromConfig(config, { logger, @@ -735,22 +715,12 @@ describe('GithubEntityProvider', () => { }); it('apply delta update on added files from push event with glob catalog path', async () => { - const schedule = new PersistingTaskRunner(); - const config = new ConfigReader({ - catalog: { - providers: { - github: { - organization: 'test-org', - catalogPath: '**/catalog-info.yaml', - }, - }, + const config = createSingleProviderConfig({ + providerConfig: { + catalogPath: '**/catalog-info.yaml', }, }); - - const provider = GithubEntityProvider.fromConfig(config, { - logger, - schedule, - })[0]; + const provider = createProviders(config)[0]; const entityProviderConnection: EntityProviderConnection = { applyMutation: jest.fn(), @@ -758,62 +728,15 @@ describe('GithubEntityProvider', () => { }; await provider.connect(entityProviderConnection); - const event: EventParams = { - topic: 'github.push', - metadata: { - 'x-github-event': 'push', + const event = createPushEvent({ + catalogFile: { + action: 'added', + path: 'folder1/folder2/folder3/catalog-info.yaml', }, - eventPayload: { - ref: 'refs/heads/main', - repository: { - name: 'teste-1', - url: 'https://github.com/test-org/test-repo', - default_branch: 'main', - stargazers: 0, - master_branch: 'main', - organization: 'test-org', - topics: [], - }, - created: true, - deleted: false, - forced: false, - commits: [ - { - added: ['new-file.yaml'], - removed: [], - modified: [], - }, - { - added: ['folder1/folder2/folder3/catalog-info.yaml'], - removed: [], - modified: [], - }, - ], - }, - }; - const url = - 'https://github.com/test-org/test-repo/blob/main/folder1/folder2/folder3/catalog-info.yaml'; - const expectedEntities = [ - { - entity: { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Location', - metadata: { - annotations: { - 'backstage.io/managed-by-location': `url:${url}`, - 'backstage.io/managed-by-origin-location': `url:${url}`, - }, - name: 'generated-c499bfb5e3f159d2bfefe26cac86a8a0b95b47f0', - }, - spec: { - presence: 'optional', - target: `${url}`, - type: 'url', - }, - }, - locationKey: 'github-provider:default', - }, - ]; + }); + const expectedEntities = createExpectedEntitiesForEvent(event, { + catalogFilePath: 'folder1/folder2/folder3/catalog-info.yaml', + }); await provider.onEvent(event); @@ -826,21 +749,8 @@ describe('GithubEntityProvider', () => { }); it('apply delta update on added files from push event', async () => { - const schedule = new PersistingTaskRunner(); - const config = new ConfigReader({ - catalog: { - providers: { - github: { - organization: 'test-org', - }, - }, - }, - }); - - const provider = GithubEntityProvider.fromConfig(config, { - logger, - schedule, - })[0]; + const config = createSingleProviderConfig(); + const provider = createProviders(config)[0]; const entityProviderConnection: EntityProviderConnection = { applyMutation: jest.fn(), @@ -848,62 +758,12 @@ describe('GithubEntityProvider', () => { }; await provider.connect(entityProviderConnection); - const event: EventParams = { - topic: 'github.push', - metadata: { - 'x-github-event': 'push', + const event = createPushEvent({ + catalogFile: { + action: 'added', }, - eventPayload: { - ref: 'refs/heads/main', - repository: { - name: 'teste-1', - url: 'https://github.com/test-org/test-repo', - default_branch: 'main', - stargazers: 0, - master_branch: 'main', - organization: 'test-org', - topics: [], - }, - created: true, - deleted: false, - forced: false, - commits: [ - { - added: ['new-file.yaml'], - removed: [], - modified: [], - }, - { - added: ['catalog-info.yaml'], - removed: [], - modified: [], - }, - ], - }, - }; - const url = - 'https://github.com/test-org/test-repo/blob/main/catalog-info.yaml'; - const expectedEntities = [ - { - entity: { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Location', - metadata: { - annotations: { - 'backstage.io/managed-by-location': `url:${url}`, - 'backstage.io/managed-by-origin-location': `url:${url}`, - }, - name: 'generated-8688630f57e421bc85f12b9828ed7dad6aff3bb3', - }, - spec: { - presence: 'optional', - target: `${url}`, - type: 'url', - }, - }, - locationKey: 'github-provider:default', - }, - ]; + }); + const expectedEntities = createExpectedEntitiesForEvent(event); await provider.onEvent(event); @@ -916,21 +776,8 @@ describe('GithubEntityProvider', () => { }); it('apply delta update on removed files from push event', async () => { - const schedule = new PersistingTaskRunner(); - const config = new ConfigReader({ - catalog: { - providers: { - github: { - organization: 'test-org', - }, - }, - }, - }); - - const provider = GithubEntityProvider.fromConfig(config, { - logger, - schedule, - })[0]; + const config = createSingleProviderConfig(); + const provider = createProviders(config)[0]; const entityProviderConnection: EntityProviderConnection = { applyMutation: jest.fn(), @@ -938,62 +785,12 @@ describe('GithubEntityProvider', () => { }; await provider.connect(entityProviderConnection); - const event: EventParams = { - topic: 'github.push', - metadata: { - 'x-github-event': 'push', + const event = createPushEvent({ + catalogFile: { + action: 'removed', }, - eventPayload: { - ref: 'refs/heads/main', - repository: { - name: 'teste-1', - url: 'https://github.com/test-org/test-repo', - default_branch: 'main', - stargazers: 0, - master_branch: 'main', - organization: 'test-org', - topics: [], - }, - created: true, - deleted: false, - forced: false, - commits: [ - { - added: ['new-file.yaml'], - removed: [], - modified: [], - }, - { - added: [], - removed: ['catalog-info.yaml'], - modified: [], - }, - ], - }, - }; - const url = - 'https://github.com/test-org/test-repo/blob/main/catalog-info.yaml'; - const expectedEntities = [ - { - entity: { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Location', - metadata: { - annotations: { - 'backstage.io/managed-by-location': `url:${url}`, - 'backstage.io/managed-by-origin-location': `url:${url}`, - }, - name: 'generated-8688630f57e421bc85f12b9828ed7dad6aff3bb3', - }, - spec: { - presence: 'optional', - target: `${url}`, - type: 'url', - }, - }, - locationKey: 'github-provider:default', - }, - ]; + }); + const expectedEntities = createExpectedEntitiesForEvent(event); await provider.onEvent(event); @@ -1006,21 +803,8 @@ describe('GithubEntityProvider', () => { }); it('apply refresh call on modified files from push event', async () => { - const schedule = new PersistingTaskRunner(); - const config = new ConfigReader({ - catalog: { - providers: { - github: { - organization: 'test-org', - }, - }, - }, - }); - - const provider = GithubEntityProvider.fromConfig(config, { - logger, - schedule, - })[0]; + const config = createSingleProviderConfig(); + const provider = createProviders(config)[0]; const entityProviderConnection: EntityProviderConnection = { applyMutation: jest.fn(), @@ -1028,39 +812,7 @@ describe('GithubEntityProvider', () => { }; await provider.connect(entityProviderConnection); - const event: EventParams = { - topic: 'github.push', - metadata: { - 'x-github-event': 'push', - }, - eventPayload: { - ref: 'refs/heads/main', - repository: { - name: 'teste-1', - url: 'https://github.com/test-org/test-repo', - default_branch: 'main', - stargazers: 0, - master_branch: 'main', - organization: 'test-org', - topics: [], - }, - created: true, - deleted: false, - forced: false, - commits: [ - { - added: ['new-file.yaml'], - removed: [], - modified: [], - }, - { - added: [], - removed: [], - modified: ['catalog-info.yaml'], - }, - ], - }, - }; + const event = createPushEvent(); await provider.onEvent(event); @@ -1075,7 +827,6 @@ describe('GithubEntityProvider', () => { }); it('apply refresh call on modified files from push event when catalogPath contains a glob pattern', async () => { - const schedule = new PersistingTaskRunner(); const config = new ConfigReader({ catalog: { providers: { @@ -1086,11 +837,7 @@ describe('GithubEntityProvider', () => { }, }, }); - - const provider = GithubEntityProvider.fromConfig(config, { - logger, - schedule, - })[0]; + const provider = createProviders(config)[0]; const entityProviderConnection: EntityProviderConnection = { applyMutation: jest.fn(), @@ -1098,39 +845,7 @@ describe('GithubEntityProvider', () => { }; await provider.connect(entityProviderConnection); - const event: EventParams = { - topic: 'github.push', - metadata: { - 'x-github-event': 'push', - }, - eventPayload: { - ref: 'refs/heads/main', - repository: { - name: 'teste-1', - url: 'https://github.com/test-org/test-repo', - default_branch: 'main', - stargazers: 0, - master_branch: 'main', - organization: 'test-org', - topics: [], - }, - created: true, - deleted: false, - forced: false, - commits: [ - { - added: ['new-file.yaml'], - removed: [], - modified: [], - }, - { - added: [], - removed: [], - modified: ['catalog-info.yaml'], - }, - ], - }, - }; + const event = createPushEvent(); await provider.onEvent(event); @@ -1146,25 +861,15 @@ describe('GithubEntityProvider', () => { }); it('should process repository when match filters from push event', async () => { - const schedule = new PersistingTaskRunner(); - const config = new ConfigReader({ - catalog: { - providers: { - github: { - organization: 'test-org', - filters: { - branch: 'my-special-branch', - repository: 'test-repo', - }, - }, + const config = createSingleProviderConfig({ + providerConfig: { + filters: { + branch: 'my-special-branch', + repository: 'test-repo', }, }, }); - - const provider = GithubEntityProvider.fromConfig(config, { - logger, - schedule, - })[0]; + const provider = createProviders(config)[0]; const entityProviderConnection: EntityProviderConnection = { applyMutation: jest.fn(), @@ -1172,39 +877,7 @@ describe('GithubEntityProvider', () => { }; await provider.connect(entityProviderConnection); - const event: EventParams = { - topic: 'github.push', - metadata: { - 'x-github-event': 'push', - }, - eventPayload: { - ref: 'refs/heads/my-special-branch', - repository: { - name: 'test-repo', - url: 'https://github.com/test-org/test-repo', - default_branch: 'main', - stargazers: 0, - master_branch: 'main', - organization: 'test-org', - topics: [], - }, - created: true, - deleted: false, - forced: false, - commits: [ - { - added: ['new-file.yaml'], - removed: [], - modified: [], - }, - { - added: [], - removed: [], - modified: ['catalog-info.yaml'], - }, - ], - }, - }; + const event = createPushEvent({ ref: 'refs/heads/my-special-branch' }); await provider.onEvent(event); @@ -1219,24 +892,14 @@ describe('GithubEntityProvider', () => { }); it("should skip process when didn't match filters from push event", async () => { - const schedule = new PersistingTaskRunner(); - const config = new ConfigReader({ - catalog: { - providers: { - github: { - organization: 'test-org', - filters: { - repository: 'only-special-repository', - }, - }, + const config = createSingleProviderConfig({ + providerConfig: { + filters: { + repository: 'only-special-repository', }, }, }); - - const provider = GithubEntityProvider.fromConfig(config, { - logger, - schedule, - })[0]; + const provider = createProviders(config)[0]; const entityProviderConnection: EntityProviderConnection = { applyMutation: jest.fn(), @@ -1244,39 +907,7 @@ describe('GithubEntityProvider', () => { }; await provider.connect(entityProviderConnection); - const event: EventParams = { - topic: 'github.push', - metadata: { - 'x-github-event': 'push', - }, - eventPayload: { - ref: 'refs/heads/main', - repository: { - name: 'teste-1', - url: 'https://github.com/test-org/test-repo', - default_branch: 'main', - stargazers: 0, - master_branch: 'main', - organization: 'test-org', - topics: [], - }, - created: true, - deleted: false, - forced: false, - commits: [ - { - added: ['new-file.yaml'], - removed: [], - modified: [], - }, - { - added: [], - removed: [], - modified: ['catalog-info.yaml'], - }, - ], - }, - }; + const event = createPushEvent(); await provider.onEvent(event); @@ -1285,25 +916,15 @@ describe('GithubEntityProvider', () => { }); it("should skip process when didn't match org from push event", async () => { - const schedule = new PersistingTaskRunner(); - const config = new ConfigReader({ - catalog: { - providers: { - github: { - organization: 'test-org', - filters: { - branch: 'my-special-branch', - repository: 'test-repo', - }, - }, + const config = createSingleProviderConfig({ + providerConfig: { + filters: { + branch: 'my-special-branch', + repository: 'test-repo', }, }, }); - - const provider = GithubEntityProvider.fromConfig(config, { - logger, - schedule, - })[0]; + const provider = createProviders(config)[0]; const entityProviderConnection: EntityProviderConnection = { applyMutation: jest.fn(), @@ -1311,41 +932,10 @@ describe('GithubEntityProvider', () => { }; await provider.connect(entityProviderConnection); - const event: EventParams = { - topic: 'github.push', - metadata: { - 'x-github-event': 'push', - }, - eventPayload: { - ref: 'refs/heads/my-special-branch', - repository: { - name: 'test-repo', - url: 'https://github.com/test-org/test-repo', - default_branch: 'main', - stargazers: 0, - master_branch: 'main', - organization: 'other-org', - topics: [], - }, - created: true, - deleted: false, - forced: false, - commits: [ - { - added: ['new-file.yaml'], - removed: [], - modified: [], - }, - { - added: [], - removed: [], - modified: ['catalog-info.yaml'], - }, - ], - }, - }; - - await provider.onEvent(event); + const event = createPushEvent({ + ref: 'refs/heads/my-special-branch', + org: 'other-org', + }); await provider.onEvent(event); From 89145d7efc44264c35d9327edd51d322db18abce Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Sat, 22 Jun 2024 01:13:42 +0200 Subject: [PATCH 060/510] refactor(catalog,github): group event-related tests Signed-off-by: Patrick Jungermann --- .../providers/GithubEntityProvider.test.ts | 561 +++++++++--------- 1 file changed, 284 insertions(+), 277 deletions(-) diff --git a/plugins/catalog-backend-module-github/src/providers/GithubEntityProvider.test.ts b/plugins/catalog-backend-module-github/src/providers/GithubEntityProvider.test.ts index 4ee90d5395..a28d216053 100644 --- a/plugins/catalog-backend-module-github/src/providers/GithubEntityProvider.test.ts +++ b/plugins/catalog-backend-module-github/src/providers/GithubEntityProvider.test.ts @@ -80,55 +80,6 @@ describe('GithubEntityProvider', () => { }); }; - const createPushEvent = (options?: { - catalogFile?: { action?: 'added' | 'removed' | 'modified'; path?: string }; - org?: string; - ref?: string; - }): EventParams => { - const organization = options?.org ?? 'test-org'; - const repo = { - default_branch: 'main', - master_branch: 'main', - name: 'test-repo', - organization, - topics: [], - url: `https://github.com/${organization}/test-repo`, - } as Partial; - - const catalogCommit = { - added: [] as string[], - modified: [] as string[], - removed: [] as string[], - }; - catalogCommit[options?.catalogFile?.action ?? 'modified'] = [ - options?.catalogFile?.path ?? 'catalog-info.yaml', - ]; - - const event = { - ref: options?.ref ?? 'refs/heads/main', - repository: repo as PushEvent['repository'], - created: true, - deleted: false, - forced: false, - commits: [ - { - added: ['new-file.yaml'], - removed: [], - modified: [], - }, - catalogCommit, - ] as Partial[], - } as PushEvent; - - return { - topic: 'github.push', - metadata: { - 'x-github-event': 'push', - }, - eventPayload: event, - }; - }; - const createExpectedEntitiesForUrl = (url: string): DeferredEntity[] => { return [ { @@ -153,16 +104,6 @@ describe('GithubEntityProvider', () => { ]; }; - const createExpectedEntitiesForEvent = ( - event: EventParams, - options?: { branch?: string; catalogFilePath?: string }, - ): DeferredEntity[] => { - const url = `${event.eventPayload.repository.url}/blob/${ - options?.branch ?? 'main' - }/${options?.catalogFilePath ?? 'catalog-info.yaml'}`; - return createExpectedEntitiesForUrl(url); - }; - afterEach(() => jest.clearAllMocks()); it('no provider config', () => { @@ -714,232 +655,298 @@ describe('GithubEntityProvider', () => { expect(providers[0].getProviderName()).toEqual('github-provider:default'); }); - it('apply delta update on added files from push event with glob catalog path', async () => { - const config = createSingleProviderConfig({ - providerConfig: { - catalogPath: '**/catalog-info.yaml', - }, - }); - const provider = createProviders(config)[0]; - - const entityProviderConnection: EntityProviderConnection = { - applyMutation: jest.fn(), - refresh: jest.fn(), + describe('on event', () => { + const createExpectedEntitiesForEvent = ( + event: EventParams, + options?: { branch?: string; catalogFilePath?: string }, + ): DeferredEntity[] => { + const url = `${event.eventPayload.repository.url}/blob/${ + options?.branch ?? 'main' + }/${options?.catalogFilePath ?? 'catalog-info.yaml'}`; + return createExpectedEntitiesForUrl(url); }; - await provider.connect(entityProviderConnection); - const event = createPushEvent({ - catalogFile: { - action: 'added', - path: 'folder1/folder2/folder3/catalog-info.yaml', - }, - }); - const expectedEntities = createExpectedEntitiesForEvent(event, { - catalogFilePath: 'folder1/folder2/folder3/catalog-info.yaml', - }); + describe('on push event', () => { + const createPushEvent = (options?: { + catalogFile?: { + action?: 'added' | 'removed' | 'modified'; + path?: string; + }; + org?: string; + ref?: string; + }): EventParams => { + const organization = options?.org ?? 'test-org'; + const repo = { + default_branch: 'main', + master_branch: 'main', + name: 'test-repo', + organization, + topics: [], + url: `https://github.com/${organization}/test-repo`, + } as Partial; - await provider.onEvent(event); + const catalogCommit = { + added: [] as string[], + modified: [] as string[], + removed: [] as string[], + }; + catalogCommit[options?.catalogFile?.action ?? 'modified'] = [ + options?.catalogFile?.path ?? 'catalog-info.yaml', + ]; - expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1); - expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ - type: 'delta', - added: expectedEntities, - removed: [], - }); - }); + const event = { + ref: options?.ref ?? 'refs/heads/main', + repository: repo as PushEvent['repository'], + created: true, + deleted: false, + forced: false, + commits: [ + { + added: ['new-file.yaml'], + removed: [], + modified: [], + }, + catalogCommit, + ] as Partial[], + } as PushEvent; - it('apply delta update on added files from push event', async () => { - const config = createSingleProviderConfig(); - const provider = createProviders(config)[0]; + return { + topic: 'github.push', + metadata: { + 'x-github-event': 'push', + }, + eventPayload: event, + }; + }; - const entityProviderConnection: EntityProviderConnection = { - applyMutation: jest.fn(), - refresh: jest.fn(), - }; - await provider.connect(entityProviderConnection); - - const event = createPushEvent({ - catalogFile: { - action: 'added', - }, - }); - const expectedEntities = createExpectedEntitiesForEvent(event); - - await provider.onEvent(event); - - expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1); - expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ - type: 'delta', - added: expectedEntities, - removed: [], - }); - }); - - it('apply delta update on removed files from push event', async () => { - const config = createSingleProviderConfig(); - const provider = createProviders(config)[0]; - - const entityProviderConnection: EntityProviderConnection = { - applyMutation: jest.fn(), - refresh: jest.fn(), - }; - await provider.connect(entityProviderConnection); - - const event = createPushEvent({ - catalogFile: { - action: 'removed', - }, - }); - const expectedEntities = createExpectedEntitiesForEvent(event); - - await provider.onEvent(event); - - expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1); - expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ - type: 'delta', - added: [], - removed: expectedEntities, - }); - }); - - it('apply refresh call on modified files from push event', async () => { - const config = createSingleProviderConfig(); - const provider = createProviders(config)[0]; - - const entityProviderConnection: EntityProviderConnection = { - applyMutation: jest.fn(), - refresh: jest.fn(), - }; - await provider.connect(entityProviderConnection); - - const event = createPushEvent(); - - await provider.onEvent(event); - - expect(entityProviderConnection.refresh).toHaveBeenCalledTimes(1); - expect(entityProviderConnection.refresh).toHaveBeenCalledWith({ - keys: [ - 'url:https://github.com/test-org/test-repo/tree/main/catalog-info.yaml', - 'url:https://github.com/test-org/test-repo/blob/main/catalog-info.yaml', - ], - }); - expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(0); - }); - - it('apply refresh call on modified files from push event when catalogPath contains a glob pattern', async () => { - const config = new ConfigReader({ - catalog: { - providers: { - github: { - organization: 'test-org', + it('apply delta update on added files with glob catalog path', async () => { + const config = createSingleProviderConfig({ + providerConfig: { catalogPath: '**/catalog-info.yaml', }, - }, - }, + }); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createPushEvent({ + catalogFile: { + action: 'added', + path: 'folder1/folder2/folder3/catalog-info.yaml', + }, + }); + const expectedEntities = createExpectedEntitiesForEvent(event, { + catalogFilePath: 'folder1/folder2/folder3/catalog-info.yaml', + }); + + await provider.onEvent(event); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: expectedEntities, + removed: [], + }); + }); + + it('apply delta update on added files', async () => { + const config = createSingleProviderConfig(); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createPushEvent({ + catalogFile: { + action: 'added', + }, + }); + const expectedEntities = createExpectedEntitiesForEvent(event); + + await provider.onEvent(event); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: expectedEntities, + removed: [], + }); + }); + + it('apply delta update on removed files', async () => { + const config = createSingleProviderConfig(); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createPushEvent({ + catalogFile: { + action: 'removed', + }, + }); + const expectedEntities = createExpectedEntitiesForEvent(event); + + await provider.onEvent(event); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: [], + removed: expectedEntities, + }); + }); + + it('apply refresh call on modified files', async () => { + const config = createSingleProviderConfig(); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createPushEvent(); + + await provider.onEvent(event); + + expect(entityProviderConnection.refresh).toHaveBeenCalledTimes(1); + expect(entityProviderConnection.refresh).toHaveBeenCalledWith({ + keys: [ + 'url:https://github.com/test-org/test-repo/tree/main/catalog-info.yaml', + 'url:https://github.com/test-org/test-repo/blob/main/catalog-info.yaml', + ], + }); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(0); + }); + + it('apply refresh call on modified files with glob catalog path', async () => { + const config = new ConfigReader({ + catalog: { + providers: { + github: { + organization: 'test-org', + catalogPath: '**/catalog-info.yaml', + }, + }, + }, + }); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createPushEvent(); + + await provider.onEvent(event); + + expect(entityProviderConnection.refresh).toHaveBeenCalledTimes(1); + expect(entityProviderConnection.refresh).toHaveBeenCalledWith({ + keys: [ + 'url:https://github.com/test-org/test-repo/tree/main/catalog-info.yaml', + 'url:https://github.com/test-org/test-repo/blob/main/catalog-info.yaml', + 'url:https://github.com/test-org/test-repo/tree/main/**/catalog-info.yaml', + ], + }); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(0); + }); + + it('should process repository when match filters', async () => { + const config = createSingleProviderConfig({ + providerConfig: { + filters: { + branch: 'my-special-branch', + repository: 'test-repo', + }, + }, + }); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createPushEvent({ ref: 'refs/heads/my-special-branch' }); + + await provider.onEvent(event); + + expect(entityProviderConnection.refresh).toHaveBeenCalledTimes(1); + expect(entityProviderConnection.refresh).toHaveBeenCalledWith({ + keys: [ + 'url:https://github.com/test-org/test-repo/tree/my-special-branch/catalog-info.yaml', + 'url:https://github.com/test-org/test-repo/blob/my-special-branch/catalog-info.yaml', + ], + }); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(0); + }); + + it("should skip process when didn't match filters", async () => { + const config = createSingleProviderConfig({ + providerConfig: { + filters: { + repository: 'only-special-repository', + }, + }, + }); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createPushEvent(); + + await provider.onEvent(event); + + expect(entityProviderConnection.refresh).toHaveBeenCalledTimes(0); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(0); + }); + + it("should skip process when didn't match org", async () => { + const config = createSingleProviderConfig({ + providerConfig: { + filters: { + branch: 'my-special-branch', + repository: 'test-repo', + }, + }, + }); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createPushEvent({ + ref: 'refs/heads/my-special-branch', + org: 'other-org', + }); + + await provider.onEvent(event); + + expect(entityProviderConnection.refresh).toHaveBeenCalledTimes(0); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(0); + }); }); - const provider = createProviders(config)[0]; - - const entityProviderConnection: EntityProviderConnection = { - applyMutation: jest.fn(), - refresh: jest.fn(), - }; - await provider.connect(entityProviderConnection); - - const event = createPushEvent(); - - await provider.onEvent(event); - - expect(entityProviderConnection.refresh).toHaveBeenCalledTimes(1); - expect(entityProviderConnection.refresh).toHaveBeenCalledWith({ - keys: [ - 'url:https://github.com/test-org/test-repo/tree/main/catalog-info.yaml', - 'url:https://github.com/test-org/test-repo/blob/main/catalog-info.yaml', - 'url:https://github.com/test-org/test-repo/tree/main/**/catalog-info.yaml', - ], - }); - expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(0); - }); - - it('should process repository when match filters from push event', async () => { - const config = createSingleProviderConfig({ - providerConfig: { - filters: { - branch: 'my-special-branch', - repository: 'test-repo', - }, - }, - }); - const provider = createProviders(config)[0]; - - const entityProviderConnection: EntityProviderConnection = { - applyMutation: jest.fn(), - refresh: jest.fn(), - }; - await provider.connect(entityProviderConnection); - - const event = createPushEvent({ ref: 'refs/heads/my-special-branch' }); - - await provider.onEvent(event); - - expect(entityProviderConnection.refresh).toHaveBeenCalledTimes(1); - expect(entityProviderConnection.refresh).toHaveBeenCalledWith({ - keys: [ - 'url:https://github.com/test-org/test-repo/tree/my-special-branch/catalog-info.yaml', - 'url:https://github.com/test-org/test-repo/blob/my-special-branch/catalog-info.yaml', - ], - }); - expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(0); - }); - - it("should skip process when didn't match filters from push event", async () => { - const config = createSingleProviderConfig({ - providerConfig: { - filters: { - repository: 'only-special-repository', - }, - }, - }); - const provider = createProviders(config)[0]; - - const entityProviderConnection: EntityProviderConnection = { - applyMutation: jest.fn(), - refresh: jest.fn(), - }; - await provider.connect(entityProviderConnection); - - const event = createPushEvent(); - - await provider.onEvent(event); - - expect(entityProviderConnection.refresh).toHaveBeenCalledTimes(0); - expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(0); - }); - - it("should skip process when didn't match org from push event", async () => { - const config = createSingleProviderConfig({ - providerConfig: { - filters: { - branch: 'my-special-branch', - repository: 'test-repo', - }, - }, - }); - const provider = createProviders(config)[0]; - - const entityProviderConnection: EntityProviderConnection = { - applyMutation: jest.fn(), - refresh: jest.fn(), - }; - await provider.connect(entityProviderConnection); - - const event = createPushEvent({ - ref: 'refs/heads/my-special-branch', - org: 'other-org', - }); - - await provider.onEvent(event); - - expect(entityProviderConnection.refresh).toHaveBeenCalledTimes(0); - expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(0); }); }); From c17cf4fd23556921f54afe9738162e5750bbfa86 Mon Sep 17 00:00:00 2001 From: John Philip Date: Sat, 22 Jun 2024 13:00:35 -0400 Subject: [PATCH 061/510] add publisher extension point Signed-off-by: John Philip --- plugins/techdocs-backend/src/plugin.ts | 14 ++++ plugins/techdocs-node/src/extensions.ts | 27 +++++- plugins/techdocs-node/src/index.ts | 2 + .../src/stages/publish/publish.test.ts | 17 ++++ .../src/stages/publish/publish.ts | 83 +++++++++++++++++-- .../techdocs-node/src/stages/publish/types.ts | 11 +++ 6 files changed, 144 insertions(+), 10 deletions(-) diff --git a/plugins/techdocs-backend/src/plugin.ts b/plugins/techdocs-backend/src/plugin.ts index 094335a0f0..1b495bafee 100644 --- a/plugins/techdocs-backend/src/plugin.ts +++ b/plugins/techdocs-backend/src/plugin.ts @@ -30,11 +30,14 @@ import { PreparerBase, Preparers, Publisher, + PublisherBase, + PublisherType, RemoteProtocol, techdocsBuildsExtensionPoint, TechdocsGenerator, techdocsGeneratorExtensionPoint, techdocsPreparerExtensionPoint, + techdocsPublisherExtensionPoint, } from '@backstage/plugin-techdocs-node'; import Docker from 'dockerode'; import { createRouter } from '@backstage/plugin-techdocs-backend'; @@ -87,6 +90,16 @@ export const techdocsPlugin = createBackendPlugin({ }, }); + let customTechdocsPublisher: PublisherBase | undefined; + env.registerExtensionPoint(techdocsPublisherExtensionPoint, { + registerPublisher(type: PublisherType, publisher: PublisherBase) { + if (customTechdocsPublisher) { + throw new Error(`Publisher for type ${type} is already registered`); + } + customTechdocsPublisher = publisher; + }, + }); + env.registerInit({ deps: { config: coreServices.rootConfig, @@ -135,6 +148,7 @@ export const techdocsPlugin = createBackendPlugin({ const publisher = await Publisher.fromConfig(config, { logger: winstonLogger, discovery: discovery, + customPublisher: customTechdocsPublisher, }); // checks if the publisher is working and logs the result diff --git a/plugins/techdocs-node/src/extensions.ts b/plugins/techdocs-node/src/extensions.ts index 8e7c9ef244..c32a0d2db5 100644 --- a/plugins/techdocs-node/src/extensions.ts +++ b/plugins/techdocs-node/src/extensions.ts @@ -15,7 +15,13 @@ */ import { createExtensionPoint } from '@backstage/backend-plugin-api'; import { DocsBuildStrategy } from './techdocsTypes'; -import { PreparerBase, RemoteProtocol, TechdocsGenerator } from './stages'; +import { + PreparerBase, + PublisherBase, + PublisherType, + RemoteProtocol, + TechdocsGenerator, +} from './stages'; import * as winston from 'winston'; /** @@ -75,3 +81,22 @@ export const techdocsPreparerExtensionPoint = createExtensionPoint({ id: 'techdocs.preparer', }); + +/** + * Extension point type for configuring a custom Techdocs publisher + * + * @public + */ +export interface TechdocsPublisherExtensionPoint { + registerPublisher(type: PublisherType, publisher: PublisherBase): void; +} + +/** + * Extension point for configuring a custom Techdocs publisher + * + * @public + */ +export const techdocsPublisherExtensionPoint = + createExtensionPoint({ + id: 'techdocs.publisher', + }); diff --git a/plugins/techdocs-node/src/index.ts b/plugins/techdocs-node/src/index.ts index b2efadf423..18f15f39ce 100644 --- a/plugins/techdocs-node/src/index.ts +++ b/plugins/techdocs-node/src/index.ts @@ -27,7 +27,9 @@ export { techdocsBuildsExtensionPoint, techdocsGeneratorExtensionPoint, techdocsPreparerExtensionPoint, + techdocsPublisherExtensionPoint, type TechdocsBuildsExtensionPoint, type TechdocsGeneratorExtensionPoint, type TechdocsPreparerExtensionPoint, + type TechdocsPublisherExtensionPoint, } from './extensions'; diff --git a/plugins/techdocs-node/src/stages/publish/publish.test.ts b/plugins/techdocs-node/src/stages/publish/publish.test.ts index 4059eccfeb..0063839e2f 100644 --- a/plugins/techdocs-node/src/stages/publish/publish.test.ts +++ b/plugins/techdocs-node/src/stages/publish/publish.test.ts @@ -25,6 +25,7 @@ import { AwsS3Publish } from './awsS3'; import { AzureBlobStoragePublish } from './azureBlobStorage'; import { OpenStackSwiftPublish } from './openStackSwift'; import { mockServices } from '@backstage/backend-test-utils'; +import { PublisherBase } from './types'; const logger = loggerToWinstonLogger(mockServices.logger.mock()); const discovery: jest.Mocked = { @@ -184,4 +185,20 @@ describe('Publisher', () => { }); expect(publisher).toBeInstanceOf(OpenStackSwiftPublish); }); + + it('registers a custom publisher if provided', async () => { + const mockConfig = new ConfigReader({}); + + const customPublisher = { + publish: jest.fn(), + } as unknown as PublisherBase; + + const publisher = await Publisher.fromConfig(mockConfig, { + logger, + discovery, + customPublisher, + }); + + expect(publisher).toBe(customPublisher); + }); }); diff --git a/plugins/techdocs-node/src/stages/publish/publish.ts b/plugins/techdocs-node/src/stages/publish/publish.ts index 732b161b42..4fb731a0ba 100644 --- a/plugins/techdocs-node/src/stages/publish/publish.ts +++ b/plugins/techdocs-node/src/stages/publish/publish.ts @@ -20,14 +20,47 @@ import { AzureBlobStoragePublish } from './azureBlobStorage'; import { GoogleGCSPublish } from './googleStorage'; import { LocalPublish } from './local'; import { OpenStackSwiftPublish } from './openStackSwift'; -import { PublisherFactory, PublisherBase, PublisherType } from './types'; +import { + PublisherFactory, + PublisherBase, + PublisherType, + PublisherBuilder, +} from './types'; /** * Factory class to create a TechDocs publisher based on defined publisher type in app config. * Uses `techdocs.publisher.type`. * @public */ -export class Publisher { + +type CustomPublisherType = PublisherType | 'techdocs'; + +export class Publisher implements PublisherBuilder { + private publishers: Map = new Map(); + + register(type: CustomPublisherType, publisher: PublisherBase): void { + this.publishers.set(type, publisher); + } + + get(config: Config): PublisherBase { + const publisherType = (config.getOptionalString( + 'techdocs.publisher.type', + ) ?? 'local') as PublisherType; + + if (!publisherType) { + throw new Error('TechDocs publisher type not specified for the entity'); + } + + const publisher = this.publishers.get(publisherType); + if (!publisher) { + throw new Error( + `TechDocs publisher '${publisherType}' is not registered`, + ); + } + + return publisher; + } + /** * Returns a instance of TechDocs publisher * @param config - A Backstage configuration @@ -37,7 +70,14 @@ export class Publisher { config: Config, options: PublisherFactory, ): Promise { - const { logger, discovery } = options; + const { logger, discovery, customPublisher } = options; + + const publishers = new Publisher(); + + if (customPublisher) { + publishers.register('techdocs', customPublisher); + return customPublisher; + } const publisherType = (config.getOptionalString( 'techdocs.publisher.type', @@ -46,26 +86,51 @@ export class Publisher { switch (publisherType) { case 'googleGcs': logger.info('Creating Google Storage Bucket publisher for TechDocs'); - return GoogleGCSPublish.fromConfig(config, logger); + publishers.register( + publisherType, + GoogleGCSPublish.fromConfig(config, logger), + ); + break; case 'awsS3': logger.info('Creating AWS S3 Bucket publisher for TechDocs'); - return await AwsS3Publish.fromConfig(config, logger); + publishers.register( + publisherType, + await AwsS3Publish.fromConfig(config, logger), + ); + break; case 'azureBlobStorage': logger.info( 'Creating Azure Blob Storage Container publisher for TechDocs', ); - return AzureBlobStoragePublish.fromConfig(config, logger); + publishers.register( + publisherType, + AzureBlobStoragePublish.fromConfig(config, logger), + ); + break; case 'openStackSwift': logger.info( 'Creating OpenStack Swift Container publisher for TechDocs', ); - return OpenStackSwiftPublish.fromConfig(config, logger); + publishers.register( + publisherType, + OpenStackSwiftPublish.fromConfig(config, logger), + ); + break; case 'local': logger.info('Creating Local publisher for TechDocs'); - return LocalPublish.fromConfig(config, logger, discovery); + publishers.register( + publisherType, + LocalPublish.fromConfig(config, logger, discovery), + ); + break; default: logger.info('Creating Local publisher for TechDocs'); - return LocalPublish.fromConfig(config, logger, discovery); + publishers.register( + publisherType, + LocalPublish.fromConfig(config, logger, discovery), + ); } + + return publishers.get(config); } } diff --git a/plugins/techdocs-node/src/stages/publish/types.ts b/plugins/techdocs-node/src/stages/publish/types.ts index ff5b9acade..3acd48a468 100644 --- a/plugins/techdocs-node/src/stages/publish/types.ts +++ b/plugins/techdocs-node/src/stages/publish/types.ts @@ -17,6 +17,7 @@ import { Entity, CompoundEntityRef } from '@backstage/catalog-model'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { Logger } from 'winston'; import express from 'express'; +import { Config } from '@backstage/config'; /** * Options for building publishers @@ -25,6 +26,7 @@ import express from 'express'; export type PublisherFactory = { logger: Logger; discovery: PluginEndpointDiscovery; + customPublisher?: PublisherBase | undefined; }; /** @@ -157,3 +159,12 @@ export interface PublisherBase { */ migrateDocsCase?(migrateRequest: MigrateRequest): Promise; } + +/** + * Definition for a TechDocs publisher builder + * @public + */ +export type PublisherBuilder = { + register(type: PublisherType, publisher: PublisherBase): void; + get(config: Config): PublisherBase; +}; From 9ecf5fdcb9b66b97b0cb8604b7358eaf6a2bb18c Mon Sep 17 00:00:00 2001 From: John Philip Date: Sat, 22 Jun 2024 13:04:19 -0400 Subject: [PATCH 062/510] add changeset Signed-off-by: John Philip --- .changeset/fair-fans-flow.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/fair-fans-flow.md diff --git a/.changeset/fair-fans-flow.md b/.changeset/fair-fans-flow.md new file mode 100644 index 0000000000..abdc22440b --- /dev/null +++ b/.changeset/fair-fans-flow.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-techdocs-backend': patch +'@backstage/plugin-techdocs-node': patch +--- + +Adds extension point for publishers to the techdocs backend From 4c4d077b9abb1fa2840768072f7a291340bc2dd9 Mon Sep 17 00:00:00 2001 From: John Philip Date: Sat, 22 Jun 2024 13:10:45 -0400 Subject: [PATCH 063/510] add changeset Signed-off-by: John Philip --- .changeset/neat-dingos-tickle.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/neat-dingos-tickle.md diff --git a/.changeset/neat-dingos-tickle.md b/.changeset/neat-dingos-tickle.md new file mode 100644 index 0000000000..43929e532f --- /dev/null +++ b/.changeset/neat-dingos-tickle.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs-node': patch +--- + +Bumps default version of techdocs docker image to latest From e10c75aebfdc030ea3dac888ac165d93cd75d032 Mon Sep 17 00:00:00 2001 From: "Stephen A. Wilson" Date: Sat, 22 Jun 2024 15:52:58 -0400 Subject: [PATCH 064/510] Remove duplicated docs Signed-off-by: Stephen A. Wilson --- .../catalog-info.yaml | 12 -- .../docs/code/code-sample.md | 31 ----- .../docs/extensions.md | 112 ------------------ .../docs/images/backstage-logo-cncf.svg | 1 - .../docs/index.md | 55 --------- .../docs/sub-page.md | 12 -- .../mkdocs.yml | 12 -- .../documented-component/catalog-info.yaml | 2 +- 8 files changed, 1 insertion(+), 236 deletions(-) delete mode 100644 plugins/techdocs-backend/examples/documented-component-with-title/catalog-info.yaml delete mode 100644 plugins/techdocs-backend/examples/documented-component-with-title/docs/code/code-sample.md delete mode 100644 plugins/techdocs-backend/examples/documented-component-with-title/docs/extensions.md delete mode 100644 plugins/techdocs-backend/examples/documented-component-with-title/docs/images/backstage-logo-cncf.svg delete mode 100644 plugins/techdocs-backend/examples/documented-component-with-title/docs/index.md delete mode 100644 plugins/techdocs-backend/examples/documented-component-with-title/docs/sub-page.md delete mode 100644 plugins/techdocs-backend/examples/documented-component-with-title/mkdocs.yml diff --git a/plugins/techdocs-backend/examples/documented-component-with-title/catalog-info.yaml b/plugins/techdocs-backend/examples/documented-component-with-title/catalog-info.yaml deleted file mode 100644 index 1a1d65ba39..0000000000 --- a/plugins/techdocs-backend/examples/documented-component-with-title/catalog-info.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: documented-with-title - title: Fizzbuzz Docs - description: A TechDocs with a title different than it's name - annotations: - backstage.io/techdocs-ref: dir:. -spec: - type: service - lifecycle: experimental - owner: user:guest diff --git a/plugins/techdocs-backend/examples/documented-component-with-title/docs/code/code-sample.md b/plugins/techdocs-backend/examples/documented-component-with-title/docs/code/code-sample.md deleted file mode 100644 index f41ab1d506..0000000000 --- a/plugins/techdocs-backend/examples/documented-component-with-title/docs/code/code-sample.md +++ /dev/null @@ -1,31 +0,0 @@ -# Sample Code - -This page provides some sample code which may be used in your example component. - -This code uses TypeScript, and the Markdown code fence to wrap the code. - -```typescript -const serviceEntityPage = ( - - - - - - - - - - - - -); -``` - -Here is an example of Python code: - -```python -def getUsersInGroup(targetGroup, secure=False): - - if __debug__: - print('targetGroup=[' + targetGroup + ']') -``` diff --git a/plugins/techdocs-backend/examples/documented-component-with-title/docs/extensions.md b/plugins/techdocs-backend/examples/documented-component-with-title/docs/extensions.md deleted file mode 100644 index eb9abca74a..0000000000 --- a/plugins/techdocs-backend/examples/documented-component-with-title/docs/extensions.md +++ /dev/null @@ -1,112 +0,0 @@ -# Plugins & Extensions - -Just by including the TechDocs Core Plugin to your MkDocs site included with Backstage, -you gain the immediate use of a variety of popular plugins and extensions to MkDocs. - -For more information and full details of the available features, see the -[`mkdocs-techdocs-core` repository](https://github.com/backstage/mkdocs-techdocs-core#mkdocs-plugins-and-extensions). - -This page provides a demonstration of some of the available features. - -## Admonitions - -Admonitions are call outs that help catch a users attention. - -To define an admonition simply put the following Markdown into your content: - -``` -!!! warn - Defining admonitions can be addicting. -``` - -And they end up looking like this: - - -!!! warn - Defining admonitions can be addicting. - - -!!! note - You can learn a lot about TechDocs by just visiting the Backstage web site at - https://backstage.io/docs. - - -!!! info - TechDocs is the core feature that supports documentation as code in Backstage. - - -!!! tip - Don't forget to spell check your documentation. - -## PlantUML - -You can create dynamic UML diagrams on the fly by just specifying flow via text, -using [PlantUML](https://pypi.org/project/plantuml-markdown/). - -```plantuml format="svg" classes="uml myDiagram" alt="Backstage sample PlantUML" title="Backstage sample PlantUML" width="500px" height="250px" -User -> SCMProvider: stores -TechDocs -> SCMProvider: prepares -TechDocs -> TechDocs: generates -TechDocs -> CloudStorage: publishes -CloudStorage -> Backstage: displays -``` - -## Pymdownx Extensions - -Pymdownx (Python Markdown extensions) are a variety of smaller additions. - -### Details - - -??? note "What is the answer to life, the universe, and everything? (click me for the answer)" - The answer is 42. - - -??? note "What is 4 plus 4?" - The answer is 8. - - -???+ note "How do I get support?" - You can get support by opening an issue in this repository. This detail is open by default - so it's more easily visible without requiring the user to click to open it. - -### Task Lists - -Automatic rendering of Markdown task lists. - -- [x] Phase 1 -- [x] Phase 2 -- [ ] Phase 3 - -### Emojis - -Very nice job on documentation! :thumbsup: - -I've read a lot of documentation, but I love :heart: this document. - -Weather: :sunny: :umbrella: :cloud: :snowflake: - -Animals: :tiger: :horse: :turtle: :wolf: :frog: - -### Attributes - -[A Download Link](./images/backstage-logo-cncf.svg){: download } - -![A Scaled Image](./images/backstage-logo-cncf.svg){: style="width: 100px" } - -### MDX truly sane lists - -- `attributes` - -- `customer` - - `first_name` - - `test` - - `family_name` - - `email` -- `person` - - `first_name` - - `family_name` - - `birth_date` -- `subscription_id` - -- `request` diff --git a/plugins/techdocs-backend/examples/documented-component-with-title/docs/images/backstage-logo-cncf.svg b/plugins/techdocs-backend/examples/documented-component-with-title/docs/images/backstage-logo-cncf.svg deleted file mode 100644 index b5ff591d1b..0000000000 --- a/plugins/techdocs-backend/examples/documented-component-with-title/docs/images/backstage-logo-cncf.svg +++ /dev/null @@ -1 +0,0 @@ -05 Logo_Black \ No newline at end of file diff --git a/plugins/techdocs-backend/examples/documented-component-with-title/docs/index.md b/plugins/techdocs-backend/examples/documented-component-with-title/docs/index.md deleted file mode 100644 index 6295a69406..0000000000 --- a/plugins/techdocs-backend/examples/documented-component-with-title/docs/index.md +++ /dev/null @@ -1,55 +0,0 @@ -# Welcome! - -This is a basic example of documentation. It is intended as a showcase of some of the -features that TechDocs provides out of the box. - -You can see also: - -- [A sub page](sub-page.md) -- [Inline code examples](code/code-sample.md) -- [Plugin & Extension examples](extensions.md) - Diagrams, emojis, visual formatting. - -## Basic Markdown - -Headings: - -# h1 - -## h2 - -### h3 - -#### h4 - -##### h5 - -###### h6 - -Here is a bulleted list: - -- Item one -- Item two -- Item Three - -Check out the [Markdown Guide](https://www.markdownguide.org/) to learn more about how to -simply create documentation. - -You can also learn more about how to configure and setup this documentation in Backstage, -[read up on the TechDocs Overview](https://backstage.io/docs/features/techdocs/). - -## Image Example - -This documentation is powered by Backstage's TechDocs feature: - -![Backstage Logo](images/backstage-logo-cncf.svg) - -## Table Example - -While this documentation isn't comprehensive, in the future it should cover the following -topics outlined in this example table: - -| Topic | Description | -| ------- | ------------------------------------------------------------ | -| Topic 1 | An introductory topic to help you learn about the component. | -| Topic 2 | A more detailed topic that explains more information. | -| Topic 3 | A final topic that provides conclusions and lessons learned. | diff --git a/plugins/techdocs-backend/examples/documented-component-with-title/docs/sub-page.md b/plugins/techdocs-backend/examples/documented-component-with-title/docs/sub-page.md deleted file mode 100644 index 987f5e8a95..0000000000 --- a/plugins/techdocs-backend/examples/documented-component-with-title/docs/sub-page.md +++ /dev/null @@ -1,12 +0,0 @@ -# Another page in our documentation - -This sub-page can be used to elaborate on a specific part of the component. - -## Details - -It is linked off the main page, and due to its inclusion in the `mkdocs.yml` file, -becomes part of the auto-generated site navigation. - -## MkDocs - -Visit https://www.mkdocs.org for more information about the MkDocs tool. diff --git a/plugins/techdocs-backend/examples/documented-component-with-title/mkdocs.yml b/plugins/techdocs-backend/examples/documented-component-with-title/mkdocs.yml deleted file mode 100644 index 1a159a4d12..0000000000 --- a/plugins/techdocs-backend/examples/documented-component-with-title/mkdocs.yml +++ /dev/null @@ -1,12 +0,0 @@ -site_name: 'Example Documentation' -repo_url: https://github.com/backstage/backstage -edit_uri: edit/master/plugins/techdocs-backend/examples/documented-component/docs - -nav: - - Home: index.md - - Subpage: sub-page.md - - 'Code Sample': code/code-sample.md - - Extensions: extensions.md - -plugins: - - techdocs-core diff --git a/plugins/techdocs-backend/examples/documented-component/catalog-info.yaml b/plugins/techdocs-backend/examples/documented-component/catalog-info.yaml index e6d14025e1..6b30213a60 100644 --- a/plugins/techdocs-backend/examples/documented-component/catalog-info.yaml +++ b/plugins/techdocs-backend/examples/documented-component/catalog-info.yaml @@ -2,7 +2,7 @@ apiVersion: backstage.io/v1alpha1 kind: Component metadata: name: documented-component - title: Documented Component + title: Example Docs description: A Service with TechDocs documentation annotations: backstage.io/techdocs-ref: dir:. From fea739f1caa1987c9edce53bd6398a6da1504dd0 Mon Sep 17 00:00:00 2001 From: John Philip Date: Sat, 22 Jun 2024 21:14:24 -0400 Subject: [PATCH 065/510] fix api reports Signed-off-by: John Philip --- plugins/techdocs-node/api-report.md | 22 ++++++++++++++++++- .../techdocs-node/src/stages/publish/index.ts | 1 + .../src/stages/publish/publish.ts | 8 +++---- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/plugins/techdocs-node/api-report.md b/plugins/techdocs-node/api-report.md index 2d3ca90983..364c6dade0 100644 --- a/plugins/techdocs-node/api-report.md +++ b/plugins/techdocs-node/api-report.md @@ -183,11 +183,15 @@ export class Preparers implements PreparerBuilder { } // @public -export class Publisher { +export class Publisher implements PublisherBuilder { static fromConfig( config: Config, options: PublisherFactory, ): Promise; + // (undocumented) + get(config: Config): PublisherBase; + // (undocumented) + register(type: PublisherType | 'techdocs', publisher: PublisherBase): void; } // @public @@ -202,10 +206,17 @@ export interface PublisherBase { publish(request: PublishRequest): Promise; } +// @public +export type PublisherBuilder = { + register(type: PublisherType, publisher: PublisherBase): void; + get(config: Config): PublisherBase; +}; + // @public export type PublisherFactory = { logger: Logger; discovery: PluginEndpointDiscovery; + customPublisher?: PublisherBase | undefined; }; // @public @@ -303,6 +314,15 @@ export interface TechdocsPreparerExtensionPoint { // @public export const techdocsPreparerExtensionPoint: ExtensionPoint; +// @public +export interface TechdocsPublisherExtensionPoint { + // (undocumented) + registerPublisher(type: PublisherType, publisher: PublisherBase): void; +} + +// @public +export const techdocsPublisherExtensionPoint: ExtensionPoint; + // @public export const transformDirLocation: ( entity: Entity, diff --git a/plugins/techdocs-node/src/stages/publish/index.ts b/plugins/techdocs-node/src/stages/publish/index.ts index c6f86f6bc1..f342ccf0ae 100644 --- a/plugins/techdocs-node/src/stages/publish/index.ts +++ b/plugins/techdocs-node/src/stages/publish/index.ts @@ -23,4 +23,5 @@ export type { MigrateRequest, ReadinessResponse, TechDocsMetadata, + PublisherBuilder, } from './types'; diff --git a/plugins/techdocs-node/src/stages/publish/publish.ts b/plugins/techdocs-node/src/stages/publish/publish.ts index 4fb731a0ba..09a6d9b375 100644 --- a/plugins/techdocs-node/src/stages/publish/publish.ts +++ b/plugins/techdocs-node/src/stages/publish/publish.ts @@ -32,13 +32,11 @@ import { * Uses `techdocs.publisher.type`. * @public */ - -type CustomPublisherType = PublisherType | 'techdocs'; - export class Publisher implements PublisherBuilder { - private publishers: Map = new Map(); + private publishers: Map = + new Map(); - register(type: CustomPublisherType, publisher: PublisherBase): void { + register(type: PublisherType | 'techdocs', publisher: PublisherBase): void { this.publishers.set(type, publisher); } From 897afcc4d560d08d9001e0413c4dd49134cfdcfc Mon Sep 17 00:00:00 2001 From: John Philip Date: Sat, 22 Jun 2024 22:45:29 -0400 Subject: [PATCH 066/510] fix api reports Signed-off-by: John Philip --- plugins/techdocs-node/api-report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/techdocs-node/api-report.md b/plugins/techdocs-node/api-report.md index 3966b7d2d8..0b30170006 100644 --- a/plugins/techdocs-node/api-report.md +++ b/plugins/techdocs-node/api-report.md @@ -268,7 +268,7 @@ export class TechdocsGenerator implements GeneratorBase { config: Config; scmIntegrations: ScmIntegrationRegistry; }); - static readonly defaultDockerImage = 'spotify/techdocs:v1.2.3'; + static readonly defaultDockerImage = 'spotify/techdocs:v1.2.4'; static fromConfig( config: Config, options: GeneratorOptions, From f229d94b8abd8a79f651266705740e7b8ec8cd17 Mon Sep 17 00:00:00 2001 From: Tavi Nolan Date: Mon, 24 Jun 2024 13:29:53 +0100 Subject: [PATCH 067/510] changing period to comma Signed-off-by: Tavi Nolan --- docs/features/software-catalog/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/software-catalog/configuration.md b/docs/features/software-catalog/configuration.md index d0206172e5..9524886a49 100644 --- a/docs/features/software-catalog/configuration.md +++ b/docs/features/software-catalog/configuration.md @@ -47,7 +47,7 @@ action is logged for further investigation. ### Local File (`type: file`) Configurations In addition to url locations, you can use the `file` location type to bring in content from the local file system. You should only use this for local development, test setups, and example data, not for production data. -You are also not able to use placeholders in them like `$text`. `$json` or `$yaml`. You can however reference other files relative to the current file. See the full [catalog example data set here](https://github.com/backstage/backstage/blob/master/packages/create-app/templates/default-app/app-config.yaml.hbs) for an extensive example. +You are also not able to use placeholders in them like `$text`, `$json` or `$yaml`. You can however reference other files relative to the current file. See the full [catalog example data set here](https://github.com/backstage/backstage/blob/master/packages/create-app/templates/default-app/app-config.yaml.hbs) for an extensive example. Here is an example pulling in the `all.yaml` file from the examples folder. Note the use of `../../` to go up two levels from the current execution path of the backend. This is typically `packages/backend/`. From d1488caaa309df834095bde5a48bf9f99ad797af Mon Sep 17 00:00:00 2001 From: Stephen Date: Mon, 24 Jun 2024 08:52:29 -0400 Subject: [PATCH 068/510] Revert change to app-config.yaml Signed-off-by: Stephen --- app-config.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/app-config.yaml b/app-config.yaml index 69145cd896..cb70170541 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -297,9 +297,6 @@ catalog: # Example component for TechDocs - type: file target: ../../plugins/techdocs-backend/examples/documented-component/catalog-info.yaml - # Example component for TechDocs with a title - - type: file - target: ../../plugins/techdocs-backend/examples/documented-component-with-title/catalog-info.yaml # Example component for ADRs - type: file target: ../../plugins/adr/examples/component/catalog-info.yaml From 589860ec27f7fbe2cb96e5266737850a6c2c5ead Mon Sep 17 00:00:00 2001 From: Alper Altay Date: Mon, 24 Jun 2024 15:26:53 +0200 Subject: [PATCH 069/510] feat: add plugin to backend index.ts Signed-off-by: Alper Altay --- .../lib/new/factories/backendPlugin.test.ts | 88 ++++++++++++++++++- .../src/lib/new/factories/backendPlugin.ts | 34 +++++++ 2 files changed, 119 insertions(+), 3 deletions(-) diff --git a/packages/cli/src/lib/new/factories/backendPlugin.test.ts b/packages/cli/src/lib/new/factories/backendPlugin.test.ts index c5930592a3..c6196d8690 100644 --- a/packages/cli/src/lib/new/factories/backendPlugin.test.ts +++ b/packages/cli/src/lib/new/factories/backendPlugin.test.ts @@ -26,13 +26,19 @@ import { import { backendPlugin } from './backendPlugin'; import { createMockDirectory } from '@backstage/backend-test-utils'; +const backendIndexTsContent = ` +import { createBackend } from '@backstage/backend-defaults'; + +const backend = createBackend(); + +backend.start(); +`; + describe('backendPlugin factory', () => { const mockDir = createMockDirectory(); beforeEach(() => { - mockPaths({ - targetRoot: mockDir.path, - }); + mockPaths({ targetRoot: mockDir.path }); }); afterEach(() => { @@ -44,6 +50,9 @@ describe('backendPlugin factory', () => { packages: { backend: { 'package.json': JSON.stringify({}), + src: { + 'index.ts': backendIndexTsContent, + }, }, }, plugins: {}, @@ -89,6 +98,7 @@ describe('backendPlugin factory', () => { 'Installing:', `moving plugins${sep}test-backend`, 'backend adding dependency', + 'backend adding import and plugin', ]); await expect( @@ -99,6 +109,78 @@ describe('backendPlugin factory', () => { }, }); + await expect( + fs.readFile(mockDir.resolve('packages/backend/src/index.ts'), 'utf8'), + ).resolves.toBe(` +import { createBackend } from '@backstage/backend-defaults'; + +const backend = createBackend(); + +backend.add(import("backstage-plugin-test-backend")); +backend.start(); +`); + + expect(Task.forCommand).toHaveBeenCalledTimes(2); + expect(Task.forCommand).toHaveBeenCalledWith('yarn install', { + cwd: mockDir.resolve('plugins/test-backend'), + optional: true, + }); + expect(Task.forCommand).toHaveBeenCalledWith('yarn lint --fix', { + cwd: mockDir.resolve('plugins/test-backend'), + optional: true, + }); + }); + + it('should create a backend plugin with more options and codeowners', async () => { + mockDir.setContent({ + CODEOWNERS: '', + packages: { + backend: { + 'package.json': JSON.stringify({}), + src: { + 'index.ts': backendIndexTsContent, + }, + }, + }, + plugins: {}, + }); + + const options = await FactoryRegistry.populateOptions(backendPlugin, { + id: 'test', + owner: '@test-user', + }); + + const [, mockStream] = createMockOutputStream(); + jest.spyOn(process, 'stderr', 'get').mockReturnValue(mockStream); + jest.spyOn(Task, 'forCommand').mockResolvedValue(); + + await backendPlugin.create(options, { + scope: 'internal', + private: true, + isMonoRepo: true, + defaultVersion: '1.0.0', + markAsModified: () => {}, + createTemporaryDirectory: () => fs.mkdtemp('test'), + }); + + await expect( + fs.readJson(mockDir.resolve('packages/backend/package.json')), + ).resolves.toEqual({ + dependencies: { + '@internal/backstage-plugin-test-backend': '^1.0.0', + }, + }); + + await expect( + fs.readFile(mockDir.resolve('packages/backend/src/index.ts'), 'utf8'), + ).resolves.toBe(` +import { createBackend } from '@backstage/backend-defaults'; + +const backend = createBackend(); + +backend.add(import("@internal/backstage-plugin-test-backend")); +backend.start();`); + expect(Task.forCommand).toHaveBeenCalledTimes(2); expect(Task.forCommand).toHaveBeenCalledWith('yarn install', { cwd: mockDir.resolve('plugins/test-backend'), diff --git a/packages/cli/src/lib/new/factories/backendPlugin.ts b/packages/cli/src/lib/new/factories/backendPlugin.ts index 09ea98fbe7..06bc6bd366 100644 --- a/packages/cli/src/lib/new/factories/backendPlugin.ts +++ b/packages/cli/src/lib/new/factories/backendPlugin.ts @@ -78,6 +78,40 @@ export const backendPlugin = createFactory({ }, ); }); + + await Task.forItem('backend', 'adding import and plugin', async () => { + const backendFilePath = paths.resolveTargetRoot( + 'packages/backend/src/index.ts', + ); + if (!(await fs.pathExists(backendFilePath))) { + return; + } + const content = await fs.readFile(backendFilePath, 'utf8'); + const revLines = content.split('\n').reverse(); + + const lastImportIndex = revLines.findIndex(line => + line.match(/ from ("|').*("|')/), + ); + const lastBackendAddIndex = revLines.findIndex(line => + line.match(/backend.add/), + ); + + const backendAddLine = `backend.add(import("${name}"));`; + + if (lastImportIndex !== -1 && lastBackendAddIndex !== -1) { + if (!content.includes(backendAddLine)) { + const [indentation] = + revLines[lastBackendAddIndex + 1].match(/^\s*/) ?? []; + revLines.splice( + lastBackendAddIndex + 1, + 0, + indentation + backendAddLine, + ); + } + const newContent = revLines.reverse().join('\n'); + await fs.writeFile(backendFilePath, newContent, 'utf8'); + } + }); } if (options.owner) { From 4baac0c5a54cdc9ee1bfe1a16fd75743d38855e9 Mon Sep 17 00:00:00 2001 From: Alper Altay Date: Mon, 24 Jun 2024 15:30:13 +0200 Subject: [PATCH 070/510] feat: changeset Signed-off-by: Alper Altay --- .changeset/silent-lobsters-tease.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/silent-lobsters-tease.md diff --git a/.changeset/silent-lobsters-tease.md b/.changeset/silent-lobsters-tease.md new file mode 100644 index 0000000000..e116818b7c --- /dev/null +++ b/.changeset/silent-lobsters-tease.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +The backendPlugin factory now includes a step for automatically adding the new backend plugin to the `index.ts` file of the backend. From e09456b71141085d2f00971bf9d12cecc0bd9a33 Mon Sep 17 00:00:00 2001 From: Alper Altay Date: Mon, 24 Jun 2024 15:32:05 +0200 Subject: [PATCH 071/510] chore: remove "import" Signed-off-by: Alper Altay --- packages/cli/src/lib/new/factories/backendPlugin.test.ts | 2 +- packages/cli/src/lib/new/factories/backendPlugin.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/lib/new/factories/backendPlugin.test.ts b/packages/cli/src/lib/new/factories/backendPlugin.test.ts index c6196d8690..98d0fcba21 100644 --- a/packages/cli/src/lib/new/factories/backendPlugin.test.ts +++ b/packages/cli/src/lib/new/factories/backendPlugin.test.ts @@ -98,7 +98,7 @@ describe('backendPlugin factory', () => { 'Installing:', `moving plugins${sep}test-backend`, 'backend adding dependency', - 'backend adding import and plugin', + 'backend adding plugin', ]); await expect( diff --git a/packages/cli/src/lib/new/factories/backendPlugin.ts b/packages/cli/src/lib/new/factories/backendPlugin.ts index 06bc6bd366..39d6af39a2 100644 --- a/packages/cli/src/lib/new/factories/backendPlugin.ts +++ b/packages/cli/src/lib/new/factories/backendPlugin.ts @@ -79,7 +79,7 @@ export const backendPlugin = createFactory({ ); }); - await Task.forItem('backend', 'adding import and plugin', async () => { + await Task.forItem('backend', 'adding plugin', async () => { const backendFilePath = paths.resolveTargetRoot( 'packages/backend/src/index.ts', ); From f6581944cc17da9780c01d36c2c3166212bc67bd Mon Sep 17 00:00:00 2001 From: Alper Altay Date: Mon, 24 Jun 2024 17:23:28 +0200 Subject: [PATCH 072/510] feat: adjust the test Signed-off-by: Alper Altay --- .../lib/new/factories/backendPlugin.test.ts | 29 ++++++++++--------- .../src/lib/new/factories/backendPlugin.ts | 27 ++++++----------- 2 files changed, 24 insertions(+), 32 deletions(-) diff --git a/packages/cli/src/lib/new/factories/backendPlugin.test.ts b/packages/cli/src/lib/new/factories/backendPlugin.test.ts index 98d0fcba21..425e0c5bd5 100644 --- a/packages/cli/src/lib/new/factories/backendPlugin.test.ts +++ b/packages/cli/src/lib/new/factories/backendPlugin.test.ts @@ -27,10 +27,10 @@ import { backendPlugin } from './backendPlugin'; import { createMockDirectory } from '@backstage/backend-test-utils'; const backendIndexTsContent = ` -import { createBackend } from '@backstage/backend-defaults'; - -const backend = createBackend(); - +import { createBackend } from '@backstage/backend-defaults'; + +const backend = createBackend(); + backend.start(); `; @@ -112,11 +112,11 @@ describe('backendPlugin factory', () => { await expect( fs.readFile(mockDir.resolve('packages/backend/src/index.ts'), 'utf8'), ).resolves.toBe(` -import { createBackend } from '@backstage/backend-defaults'; +import { createBackend } from '@backstage/backend-defaults'; -const backend = createBackend(); - -backend.add(import("backstage-plugin-test-backend")); +const backend = createBackend(); + +backend.add(import('backstage-plugin-test-backend')); backend.start(); `); @@ -174,12 +174,13 @@ backend.start(); await expect( fs.readFile(mockDir.resolve('packages/backend/src/index.ts'), 'utf8'), ).resolves.toBe(` -import { createBackend } from '@backstage/backend-defaults'; - -const backend = createBackend(); - -backend.add(import("@internal/backstage-plugin-test-backend")); -backend.start();`); +import { createBackend } from '@backstage/backend-defaults'; + +const backend = createBackend(); + +backend.add(import('@internal/backstage-plugin-test-backend')); +backend.start(); +`); expect(Task.forCommand).toHaveBeenCalledTimes(2); expect(Task.forCommand).toHaveBeenCalledWith('yarn install', { diff --git a/packages/cli/src/lib/new/factories/backendPlugin.ts b/packages/cli/src/lib/new/factories/backendPlugin.ts index 39d6af39a2..5848a72047 100644 --- a/packages/cli/src/lib/new/factories/backendPlugin.ts +++ b/packages/cli/src/lib/new/factories/backendPlugin.ts @@ -86,29 +86,20 @@ export const backendPlugin = createFactory({ if (!(await fs.pathExists(backendFilePath))) { return; } + const content = await fs.readFile(backendFilePath, 'utf8'); - const revLines = content.split('\n').reverse(); + const lines = content.split('\n'); + const backendAddLine = `backend.add(import('${name}'));`; - const lastImportIndex = revLines.findIndex(line => - line.match(/ from ("|').*("|')/), - ); - const lastBackendAddIndex = revLines.findIndex(line => - line.match(/backend.add/), + const backendStartIndex = lines.findIndex(line => + line.match(/backend.start/), ); - const backendAddLine = `backend.add(import("${name}"));`; + if (backendStartIndex !== -1) { + const [indentation] = lines[backendStartIndex].match(/^\s*/) ?? []; + lines.splice(backendStartIndex, 0, indentation + backendAddLine); - if (lastImportIndex !== -1 && lastBackendAddIndex !== -1) { - if (!content.includes(backendAddLine)) { - const [indentation] = - revLines[lastBackendAddIndex + 1].match(/^\s*/) ?? []; - revLines.splice( - lastBackendAddIndex + 1, - 0, - indentation + backendAddLine, - ); - } - const newContent = revLines.reverse().join('\n'); + const newContent = lines.join('\n'); await fs.writeFile(backendFilePath, newContent, 'utf8'); } }); From 23fc071b000e960a82f2e5904434c45952b97d8c Mon Sep 17 00:00:00 2001 From: Alper Altay Date: Mon, 24 Jun 2024 17:31:34 +0200 Subject: [PATCH 073/510] feat: auto add modules to index.ts Signed-off-by: Alper Altay --- .../lib/new/factories/backendModule.test.ts | 23 +++++++++++++++++ .../src/lib/new/factories/backendModule.ts | 25 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/packages/cli/src/lib/new/factories/backendModule.test.ts b/packages/cli/src/lib/new/factories/backendModule.test.ts index 78ef5f96bb..2d6a4c9c83 100644 --- a/packages/cli/src/lib/new/factories/backendModule.test.ts +++ b/packages/cli/src/lib/new/factories/backendModule.test.ts @@ -26,6 +26,14 @@ import { import { backendModule } from './backendModule'; import { createMockDirectory } from '@backstage/backend-test-utils'; +const backendIndexTsContent = ` +import { createBackend } from '@backstage/backend-defaults'; + +const backend = createBackend(); + +backend.start(); +`; + describe('backendModule factory', () => { const mockDir = createMockDirectory(); @@ -44,6 +52,9 @@ describe('backendModule factory', () => { packages: { backend: { 'package.json': JSON.stringify({}), + src: { + 'index.ts': backendIndexTsContent, + }, }, }, plugins: {}, @@ -86,8 +97,20 @@ describe('backendModule factory', () => { 'Installing:', `moving plugins${sep}test-backend-module-tester-two`, 'backend adding dependency', + 'backend adding module', ]); + await expect( + fs.readFile(mockDir.resolve('packages/backend/src/index.ts'), 'utf8'), + ).resolves.toBe(` +import { createBackend } from '@backstage/backend-defaults'; + +const backend = createBackend(); + +backend.add(import('backstage-plugin-test-backend-module-tester-two')); +backend.start(); +`); + await expect( fs.readJson(mockDir.resolve('packages/backend/package.json')), ).resolves.toEqual({ diff --git a/packages/cli/src/lib/new/factories/backendModule.ts b/packages/cli/src/lib/new/factories/backendModule.ts index 698146a229..e0c56b34ae 100644 --- a/packages/cli/src/lib/new/factories/backendModule.ts +++ b/packages/cli/src/lib/new/factories/backendModule.ts @@ -91,6 +91,31 @@ export const backendModule = createFactory({ }); } + await Task.forItem('backend', 'adding module', async () => { + const backendFilePath = paths.resolveTargetRoot( + 'packages/backend/src/index.ts', + ); + if (!(await fs.pathExists(backendFilePath))) { + return; + } + + const content = await fs.readFile(backendFilePath, 'utf8'); + const lines = content.split('\n'); + const backendAddLine = `backend.add(import('${name}'));`; + + const backendStartIndex = lines.findIndex(line => + line.match(/backend.start/), + ); + + if (backendStartIndex !== -1) { + const [indentation] = lines[backendStartIndex].match(/^\s*/) ?? []; + lines.splice(backendStartIndex, 0, indentation + backendAddLine); + + const newContent = lines.join('\n'); + await fs.writeFile(backendFilePath, newContent, 'utf8'); + } + }); + if (options.owner) { await addCodeownersEntry(`/plugins/${dirName}`, options.owner); } From 983d616d678e34e836be0cfbe0d7a92cab4eff4a Mon Sep 17 00:00:00 2001 From: Alper Altay Date: Mon, 24 Jun 2024 17:32:39 +0200 Subject: [PATCH 074/510] feat: changeset Signed-off-by: Alper Altay --- .changeset/silent-lobsters-tease.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/silent-lobsters-tease.md b/.changeset/silent-lobsters-tease.md index e116818b7c..61a965236c 100644 --- a/.changeset/silent-lobsters-tease.md +++ b/.changeset/silent-lobsters-tease.md @@ -2,4 +2,4 @@ '@backstage/cli': patch --- -The backendPlugin factory now includes a step for automatically adding the new backend plugin to the `index.ts` file of the backend. +The backendPlugin and backendModule factory now includes a step for automatically adding the new backend plugin/module to the `index.ts` file of the backend. From 812afee13103aa1789b5a10c107950e9f49d4b02 Mon Sep 17 00:00:00 2001 From: Alper Altay Date: Mon, 24 Jun 2024 17:35:14 +0200 Subject: [PATCH 075/510] feat: simplify test Signed-off-by: Alper Altay --- .../lib/new/factories/backendPlugin.test.ts | 66 +------------------ 1 file changed, 3 insertions(+), 63 deletions(-) diff --git a/packages/cli/src/lib/new/factories/backendPlugin.test.ts b/packages/cli/src/lib/new/factories/backendPlugin.test.ts index 425e0c5bd5..f6eeb8cf33 100644 --- a/packages/cli/src/lib/new/factories/backendPlugin.test.ts +++ b/packages/cli/src/lib/new/factories/backendPlugin.test.ts @@ -38,7 +38,9 @@ describe('backendPlugin factory', () => { const mockDir = createMockDirectory(); beforeEach(() => { - mockPaths({ targetRoot: mockDir.path }); + mockPaths({ + targetRoot: mockDir.path, + }); }); afterEach(() => { @@ -118,68 +120,6 @@ const backend = createBackend(); backend.add(import('backstage-plugin-test-backend')); backend.start(); -`); - - expect(Task.forCommand).toHaveBeenCalledTimes(2); - expect(Task.forCommand).toHaveBeenCalledWith('yarn install', { - cwd: mockDir.resolve('plugins/test-backend'), - optional: true, - }); - expect(Task.forCommand).toHaveBeenCalledWith('yarn lint --fix', { - cwd: mockDir.resolve('plugins/test-backend'), - optional: true, - }); - }); - - it('should create a backend plugin with more options and codeowners', async () => { - mockDir.setContent({ - CODEOWNERS: '', - packages: { - backend: { - 'package.json': JSON.stringify({}), - src: { - 'index.ts': backendIndexTsContent, - }, - }, - }, - plugins: {}, - }); - - const options = await FactoryRegistry.populateOptions(backendPlugin, { - id: 'test', - owner: '@test-user', - }); - - const [, mockStream] = createMockOutputStream(); - jest.spyOn(process, 'stderr', 'get').mockReturnValue(mockStream); - jest.spyOn(Task, 'forCommand').mockResolvedValue(); - - await backendPlugin.create(options, { - scope: 'internal', - private: true, - isMonoRepo: true, - defaultVersion: '1.0.0', - markAsModified: () => {}, - createTemporaryDirectory: () => fs.mkdtemp('test'), - }); - - await expect( - fs.readJson(mockDir.resolve('packages/backend/package.json')), - ).resolves.toEqual({ - dependencies: { - '@internal/backstage-plugin-test-backend': '^1.0.0', - }, - }); - - await expect( - fs.readFile(mockDir.resolve('packages/backend/src/index.ts'), 'utf8'), - ).resolves.toBe(` -import { createBackend } from '@backstage/backend-defaults'; - -const backend = createBackend(); - -backend.add(import('@internal/backstage-plugin-test-backend')); -backend.start(); `); expect(Task.forCommand).toHaveBeenCalledTimes(2); From 42227da4acd71ec360c0eb96bbd9aa077d2e83e4 Mon Sep 17 00:00:00 2001 From: Alper Altay Date: Mon, 24 Jun 2024 17:55:48 +0200 Subject: [PATCH 076/510] chore: spelling Signed-off-by: Alper Altay --- .changeset/silent-lobsters-tease.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/silent-lobsters-tease.md b/.changeset/silent-lobsters-tease.md index 61a965236c..2dea26d8ff 100644 --- a/.changeset/silent-lobsters-tease.md +++ b/.changeset/silent-lobsters-tease.md @@ -2,4 +2,4 @@ '@backstage/cli': patch --- -The backendPlugin and backendModule factory now includes a step for automatically adding the new backend plugin/module to the `index.ts` file of the backend. +The `backendPlugin` and `backendModule` factory now includes a step for automatically adding the new backend plugin/module to the `index.ts` file of the backend. From d99fd81a7465dc68b41c9ff102e15c5c126f05ac Mon Sep 17 00:00:00 2001 From: Tavi Nolan Date: Mon, 24 Jun 2024 18:41:08 +0100 Subject: [PATCH 077/510] Adding note detailing functionality re local files and nesting Signed-off-by: Tavi Nolan --- docs/features/software-templates/input-examples.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/features/software-templates/input-examples.md b/docs/features/software-templates/input-examples.md index 32d37ae17c..5769c9976e 100644 --- a/docs/features/software-templates/input-examples.md +++ b/docs/features/software-templates/input-examples.md @@ -241,7 +241,11 @@ spec: ## Use placeholders to reference remote files -#### Note: testing of this functionality is not yet supported using _create/edit_ +:::note + +Testing of this functionality is not yet supported using _create/edit_. In addition, this functionality only works for remote files and not local files. You also cannot nest files. + +::: ### template.yaml From 8fadb84aa406b9a0d75f2bdb68c4d396b9b864c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Edstr=C3=B6m?= Date: Mon, 24 Jun 2024 22:03:10 +0200 Subject: [PATCH 078/510] Modified Select component to take in a testid parameter that sets the data-testid of the material ui Select component, ensuring backwards compatibility with default value corresponding to previously hardcoded parameter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Simon Edström --- packages/core-components/src/components/Select/Select.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/core-components/src/components/Select/Select.tsx b/packages/core-components/src/components/Select/Select.tsx index 924b49f640..5a758e6ca6 100644 --- a/packages/core-components/src/components/Select/Select.tsx +++ b/packages/core-components/src/components/Select/Select.tsx @@ -32,6 +32,7 @@ import React, { useEffect, useState } from 'react'; import ClosedDropdown from './static/ClosedDropdown'; import OpenedDropdown from './static/OpenedDropdown'; +import { string } from 'zod'; /** @public */ export type SelectInputBaseClassKey = 'root' | 'input'; @@ -136,6 +137,7 @@ export type SelectProps = { native?: boolean; disabled?: boolean; margin?: 'dense' | 'none'; + testid?: string; }; /** @public */ @@ -151,6 +153,7 @@ export function SelectComponent(props: SelectProps) { native = false, disabled = false, margin, + testid = 'select', } = props; const classes = useStyles(); const [value, setValue] = useState( @@ -203,7 +206,7 @@ export function SelectComponent(props: SelectProps) { value={value} native={native} disabled={disabled} - data-testid="select" + data-testid={testid} displayEmpty multiple={multiple} margin={margin} From 99d672dee67e9434c21b6544ef1319ed853ac57a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Edstr=C3=B6m?= Date: Mon, 24 Jun 2024 22:19:19 +0200 Subject: [PATCH 079/510] Added changeset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Simon Edström --- .changeset/new-sheep-arrive.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/new-sheep-arrive.md diff --git a/.changeset/new-sheep-arrive.md b/.changeset/new-sheep-arrive.md new file mode 100644 index 0000000000..9ae0af93aa --- /dev/null +++ b/.changeset/new-sheep-arrive.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Modified the Select component to take in a testid parameter that sets the data-testid of the material ui Select sub-component, ensuring backwards compatibility with default value corresponding to previously hardcoded data-testid of "select". From 73e43d29339a2a331716e921731a582b9f81e7cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Edstr=C3=B6m?= Date: Mon, 24 Jun 2024 22:26:33 +0200 Subject: [PATCH 080/510] Removed accidental import MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Simon Edström --- packages/core-components/src/components/Select/Select.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core-components/src/components/Select/Select.tsx b/packages/core-components/src/components/Select/Select.tsx index 5a758e6ca6..9c0d4e4dfe 100644 --- a/packages/core-components/src/components/Select/Select.tsx +++ b/packages/core-components/src/components/Select/Select.tsx @@ -32,7 +32,6 @@ import React, { useEffect, useState } from 'react'; import ClosedDropdown from './static/ClosedDropdown'; import OpenedDropdown from './static/OpenedDropdown'; -import { string } from 'zod'; /** @public */ export type SelectInputBaseClassKey = 'root' | 'input'; From dde03ea950b01e65ac922c03738c2dd59b6711c0 Mon Sep 17 00:00:00 2001 From: Jente Sondervorst Date: Mon, 24 Jun 2024 23:39:04 +0200 Subject: [PATCH 081/510] Update api-report.md Signed-off-by: Jente Sondervorst --- plugins/catalog-backend-module-ldap/api-report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog-backend-module-ldap/api-report.md b/plugins/catalog-backend-module-ldap/api-report.md index 308b2d6da3..2ee3c1ec79 100644 --- a/plugins/catalog-backend-module-ldap/api-report.md +++ b/plugins/catalog-backend-module-ldap/api-report.md @@ -86,7 +86,7 @@ export const LDAP_UUID_ANNOTATION = 'backstage.io/ldap-uuid'; // @public export class LdapClient { - constructor(client: Client, logger: L oggerService); + constructor(client: Client, logger: LoggerService); // (undocumented) static create( logger: LoggerService, From 9112efc364d24f134881e9c09db1323fdfcc4165 Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Sat, 22 Jun 2024 03:02:42 +0200 Subject: [PATCH 082/510] feat(catalog,github): support `repository` events The provider adds a subscription to the topic `github.repository`. Hereby, it supports events of type `repository` with actions - `archived` - `deleted` - `edited` - `renamed` - `transferred` - `unarchived` Actions skipped as they don't require entity changes: - `created` - `privatized` - `publicized` If the config option `validateLocationsExist` is enabled, an API request is necessary and will be executed. This affects the actions `renamed`, `transferred`, and `unarchive` of event type `repository`. Catalog entities related to the `GithubEntityProvider` instance will be adjusted according to action and its meaning for them. Closes: #21906 Signed-off-by: Patrick Jungermann --- .changeset/poor-cheetahs-raise.md | 30 + docs/integrations/github/discovery.md | 15 +- .../src/lib/github.ts | 56 ++ .../providers/GithubEntityProvider.test.ts | 547 +++++++++++++++++- .../src/providers/GithubEntityProvider.ts | 386 ++++++++++-- 5 files changed, 971 insertions(+), 63 deletions(-) create mode 100644 .changeset/poor-cheetahs-raise.md diff --git a/.changeset/poor-cheetahs-raise.md b/.changeset/poor-cheetahs-raise.md new file mode 100644 index 0000000000..0ee2162a22 --- /dev/null +++ b/.changeset/poor-cheetahs-raise.md @@ -0,0 +1,30 @@ +--- +'@backstage/plugin-catalog-backend-module-github': patch +--- + +Adds support for `repository` events. + +The provider adds a subscription to the topic `github.repository`. + +Hereby, it supports events of type `repository` with actions + +- `archived` +- `deleted` +- `edited` +- `renamed` +- `transferred` +- `unarchived` + +Actions skipped as they don't require entity changes: + +- `created` +- `privatized` +- `publicized` + +If the config option `validateLocationsExist` is enabled, an API request +is necessary and will be executed. +This affects the actions `renamed`, `transferred`, and `unarchive` +of event type `repository`. + +Catalog entities related to the `GithubEntityProvider` instance will be adjusted +according to action and its meaning for them. diff --git a/docs/integrations/github/discovery.md b/docs/integrations/github/discovery.md index 5c3a33416b..d8374932b8 100644 --- a/docs/integrations/github/discovery.md +++ b/docs/integrations/github/discovery.md @@ -40,8 +40,9 @@ backend.add(import('@backstage/plugin-catalog-backend-module-github/alpha')); ## Events Support The catalog module for GitHub comes with events support enabled. -This will make it subscribe to its relevant topics (`github.push`) -and expects these events to be published via the `EventsService`. +This will make it subscribe to its relevant topics (`github.push`, +`github.repository`) and expects these events to be published +via the `EventsService`. Additionally, you should install the [event router by `events-backend-module-github`](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-github/README.md) @@ -55,7 +56,15 @@ You can decide between the following options (extensible): - [via HTTP endpoint](https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md) - [via an AWS SQS queue](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-aws-sqs/README.md) -You can check the official docs to [configure your webhook](https://docs.github.com/en/developers/webhooks-and-events/webhooks/creating-webhooks) and to [secure your request](https://docs.github.com/en/developers/webhooks-and-events/webhooks/securing-your-webhooks). The webhook will need to be configured to forward `push` events. +You can check the official docs to [configure your webhook](https://docs.github.com/en/developers/webhooks-and-events/webhooks/creating-webhooks) and to [secure your request](https://docs.github.com/en/developers/webhooks-and-events/webhooks/securing-your-webhooks). + +The webhook(s) will need to be configured to react to `push` and +`repository` events. + +Certain actions like `transferred` by the `repository` event type +will not be supported when you use repository webhooks. +Please check the GitHubs documentation for these event types and +its actions. ## Configuration diff --git a/plugins/catalog-backend-module-github/src/lib/github.ts b/plugins/catalog-backend-module-github/src/lib/github.ts index eff52ea98d..cba65e522e 100644 --- a/plugins/catalog-backend-module-github/src/lib/github.ts +++ b/plugins/catalog-backend-module-github/src/lib/github.ts @@ -38,6 +38,7 @@ export type QueryResponse = { type RepositoryOwnerResponse = { repositories?: Connection; + repository?: RepositoryResponse; }; export type OrganizationResponse = { @@ -509,6 +510,61 @@ export async function getOrganizationRepositories( return { repositories }; } +export async function getOrganizationRepository( + client: typeof graphql, + org: string, + repoName: string, + catalogPath: string, +): Promise { + let relativeCatalogPathRef: string; + // We must strip the leading slash or the query for objects does not work + if (catalogPath.startsWith('/')) { + relativeCatalogPathRef = catalogPath.substring(1); + } else { + relativeCatalogPathRef = catalogPath; + } + const catalogPathRef = `HEAD:${relativeCatalogPathRef}`; + const query = ` + query repository($org: String!, $repoName: String!, $catalogPathRef: String!) { + repositoryOwner(login: $org) { + repository(name: $repoName) { + name + catalogInfoFile: object(expression: $catalogPathRef) { + __typename + ... on Blob { + id + text + } + } + url + isArchived + isFork + visibility + repositoryTopics(first: 100) { + nodes { + ... on RepositoryTopic { + topic { + name + } + } + } + } + defaultBranchRef { + name + } + } + } + }`; + + const response: QueryResponse = await client(query, { + org, + repoName, + catalogPathRef, + }); + + return response.repositoryOwner?.repository || null; +} + /** * Gets all the users out of a Github organization. * diff --git a/plugins/catalog-backend-module-github/src/providers/GithubEntityProvider.test.ts b/plugins/catalog-backend-module-github/src/providers/GithubEntityProvider.test.ts index a28d216053..002b2bbfd1 100644 --- a/plugins/catalog-backend-module-github/src/providers/GithubEntityProvider.test.ts +++ b/plugins/catalog-backend-module-github/src/providers/GithubEntityProvider.test.ts @@ -29,7 +29,12 @@ import { GithubEntityProvider } from './GithubEntityProvider'; import * as helpers from '../lib/github'; import { EventParams } from '@backstage/plugin-events-node'; import { mockServices } from '@backstage/backend-test-utils'; -import { Commit, PushEvent } from '@octokit/webhooks-types'; +import { + Commit, + PushEvent, + RepositoryEvent, + RepositoryRenamedEvent, +} from '@octokit/webhooks-types'; jest.mock('../lib/github', () => { return { @@ -657,7 +662,7 @@ describe('GithubEntityProvider', () => { describe('on event', () => { const createExpectedEntitiesForEvent = ( - event: EventParams, + event: EventParams, options?: { branch?: string; catalogFilePath?: string }, ): DeferredEntity[] => { const url = `${event.eventPayload.repository.url}/blob/${ @@ -948,5 +953,543 @@ describe('GithubEntityProvider', () => { expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(0); }); }); + + describe('on repository event', () => { + const createRepoEvent = ( + action: RepositoryEvent['action'], + ): EventParams => { + const repo = { + name: 'test-repo', + url: 'https://github.com/test-org/test-repo', + default_branch: 'main', + master_branch: 'main', + organization: 'test-org', + topics: [], + archived: action === 'archived', + private: action !== 'publicized', + } as Partial; + + const event = { + action, + repository: repo as RepositoryEvent['repository'], + } as RepositoryEvent; + + if (action === 'renamed') { + (event as RepositoryRenamedEvent).changes = { + repository: { + name: { + from: `old-${event.repository.name}`, + }, + }, + }; + } + + return { + topic: 'github.repository', + metadata: { + 'x-github-event': 'repository', + }, + eventPayload: event, + }; + }; + + describe('on repository archived event', () => { + it('skip on non-matching org', async () => { + const config = createSingleProviderConfig({ + providerConfig: { + organization: 'other-org', + }, + }); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createRepoEvent('archived'); + + await provider.onEvent(event); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes( + 0, + ); + }); + + it('apply delta update removing entities', async () => { + const config = createSingleProviderConfig(); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createRepoEvent('archived'); + const expectedEntities = createExpectedEntitiesForEvent(event); + + await provider.onEvent(event); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes( + 1, + ); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: [], + removed: expectedEntities, + }); + }); + }); + + describe('on repository created event', () => { + it('skip', async () => { + const config = createSingleProviderConfig(); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createRepoEvent('created'); + + await provider.onEvent(event); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes( + 0, + ); + }); + }); + + describe('on repository deleted event', () => { + it('skip on non-matching org', async () => { + const config = createSingleProviderConfig({ + providerConfig: { + organization: 'other-org', + }, + }); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createRepoEvent('deleted'); + + await provider.onEvent(event); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes( + 0, + ); + }); + + it('apply delta update removing entities', async () => { + const config = createSingleProviderConfig(); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createRepoEvent('deleted'); + const expectedEntities = createExpectedEntitiesForEvent(event); + + await provider.onEvent(event); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes( + 1, + ); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: [], + removed: expectedEntities, + }); + }); + }); + + describe('on repository edited event', () => { + it('skip on non-matching org', async () => { + const config = createSingleProviderConfig({ + providerConfig: { + organization: 'other-org', + }, + }); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createRepoEvent('edited'); + + await provider.onEvent(event); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes( + 0, + ); + }); + + it('apply delta update removing entities with non-matching filters', async () => { + const config = createSingleProviderConfig({ + providerConfig: { + filters: { + topic: { + include: ['backstage-include'], + }, + }, + }, + }); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createRepoEvent('edited'); + const expectedEntities = createExpectedEntitiesForEvent(event); + + await provider.onEvent(event); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes( + 1, + ); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: [], + removed: expectedEntities, + }); + }); + + it('apply no delta update with matching filters', async () => { + const config = createSingleProviderConfig({ + providerConfig: { + filters: { + topic: { + include: ['backstage-include'], + }, + }, + }, + }); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createRepoEvent('edited'); + event.eventPayload.repository.topics = ['backstage-include']; + + await provider.onEvent(event); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes( + 0, + ); + }); + }); + + describe('on repository privatized event', () => { + it('skip', async () => { + const config = createSingleProviderConfig(); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createRepoEvent('privatized'); + + await provider.onEvent(event); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes( + 0, + ); + }); + }); + + describe('on repository publicized event', () => { + it('skip', async () => { + const config = createSingleProviderConfig(); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createRepoEvent('publicized'); + + await provider.onEvent(event); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes( + 0, + ); + }); + }); + + describe('on repository renamed event', () => { + it('skip on non-matching org', async () => { + const config = createSingleProviderConfig({ + providerConfig: { + organization: 'other-org', + }, + }); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createRepoEvent('renamed'); + + await provider.onEvent(event); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes( + 0, + ); + }); + + it('apply delta update removing entities with non-matching filters', async () => { + const config = createSingleProviderConfig({ + providerConfig: { + filters: { + repository: 'other-.*', + }, + }, + }); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createRepoEvent( + 'renamed', + ) as EventParams; + const urlOldRepo = `https://github.com/${event.eventPayload.repository.organization}/${event.eventPayload.changes.repository.name.from}/blob/main/catalog-info.yaml`; + const expectedEntitiesRemoved = + createExpectedEntitiesForUrl(urlOldRepo); + + await provider.onEvent(event); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes( + 1, + ); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: [], + removed: expectedEntitiesRemoved, + }); + }); + + it('apply delta update removing and adding entities with matching filters', async () => { + const config = createSingleProviderConfig(); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createRepoEvent( + 'renamed', + ) as EventParams; + const urlOldRepo = `https://github.com/${event.eventPayload.repository.organization}/${event.eventPayload.changes.repository.name.from}/blob/main/catalog-info.yaml`; + const expectedEntitiesRemoved = + createExpectedEntitiesForUrl(urlOldRepo); + const expectedEntitiesAdded = createExpectedEntitiesForEvent(event); + + await provider.onEvent(event); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes( + 2, + ); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: [], + removed: expectedEntitiesRemoved, + }); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: expectedEntitiesAdded, + removed: [], + }); + }); + }); + + describe('on repository transferred event', () => { + it('skip on non-matching org', async () => { + const config = createSingleProviderConfig({ + providerConfig: { + organization: 'other-org', + }, + }); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createRepoEvent('transferred'); + + await provider.onEvent(event); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes( + 0, + ); + }); + + it('apply no delta update with non-matching filters', async () => { + const config = createSingleProviderConfig({ + providerConfig: { + filters: { + topic: { + include: ['backstage-include'], + }, + }, + }, + }); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createRepoEvent('transferred'); + + await provider.onEvent(event); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes( + 0, + ); + }); + + it('apply delta update adding entities with matching filters', async () => { + const config = createSingleProviderConfig(); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createRepoEvent('transferred'); + const expectedEntitiesAdded = createExpectedEntitiesForEvent(event); + + await provider.onEvent(event); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes( + 1, + ); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: expectedEntitiesAdded, + removed: [], + }); + }); + }); + + describe('on repository unarchived event', () => { + it('skip on non-matching org', async () => { + const config = createSingleProviderConfig({ + providerConfig: { + organization: 'other-org', + }, + }); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createRepoEvent('unarchived'); + + await provider.onEvent(event); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes( + 0, + ); + }); + + it('apply no delta update with non-matching filters', async () => { + const config = createSingleProviderConfig({ + providerConfig: { + filters: { + topic: { + include: ['backstage-include'], + }, + }, + }, + }); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createRepoEvent('unarchived'); + + await provider.onEvent(event); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes( + 0, + ); + }); + + it('apply delta update adding entities with matching filters', async () => { + const config = createSingleProviderConfig(); + const provider = createProviders(config)[0]; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + await provider.connect(entityProviderConnection); + + const event = createRepoEvent('unarchived'); + const expectedEntitiesAdded = createExpectedEntitiesForEvent(event); + + await provider.onEvent(event); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes( + 1, + ); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: expectedEntitiesAdded, + removed: [], + }); + }); + }); + }); }); }); diff --git a/plugins/catalog-backend-module-github/src/providers/GithubEntityProvider.ts b/plugins/catalog-backend-module-github/src/providers/GithubEntityProvider.ts index 978d9593c1..daade9660a 100644 --- a/plugins/catalog-backend-module-github/src/providers/GithubEntityProvider.ts +++ b/plugins/catalog-backend-module-github/src/providers/GithubEntityProvider.ts @@ -38,7 +38,11 @@ import { GithubEntityProviderConfig, readProviderConfigs, } from './GithubEntityProviderConfig'; -import { getOrganizationRepositories } from '../lib/github'; +import { + getOrganizationRepositories, + getOrganizationRepository, + RepositoryResponse, +} from '../lib/github'; import { satisfiesForkFilter, satisfiesTopicFilter, @@ -50,11 +54,21 @@ import { EventsService, EventSubscriber, } from '@backstage/plugin-events-node'; -import { Commit, PushEvent } from '@octokit/webhooks-types'; +import { + Commit, + PushEvent, + RepositoryArchivedEvent, + RepositoryDeletedEvent, + RepositoryEditedEvent, + RepositoryEvent, + RepositoryRenamedEvent, + RepositoryTransferredEvent, + RepositoryUnarchivedEvent, +} from '@octokit/webhooks-types'; import { Minimatch } from 'minimatch'; import { LoggerService } from '@backstage/backend-plugin-api'; -const TOPIC_REPO_PUSH = 'github.push'; +const EVENT_TOPICS = ['github.push', 'github.repository']; type Repository = { name: string; @@ -157,7 +171,7 @@ export class GithubEntityProvider implements EntityProvider, EventSubscriber { this.connection = connection; await this.events?.subscribe({ id: this.getProviderName(), - topics: [TOPIC_REPO_PUSH], + topics: EVENT_TOPICS, onEvent: params => this.onEvent(params), }); return await this.scheduleFn(); @@ -194,15 +208,7 @@ export class GithubEntityProvider implements EntityProvider, EventSubscriber { const targets = await this.findCatalogFiles(); const matchingTargets = this.matchesFilters(targets); - const entities = matchingTargets - .map(repository => this.createLocationUrl(repository)) - .map(GithubEntityProvider.toLocationSpec) - .map(location => { - return { - locationKey: this.getProviderName(), - entity: locationSpecToLocationEntity({ location }), - }; - }); + const entities = this.toDeferredEntitiesFromRepos(matchingTargets); await this.connection.applyMutation({ type: 'full', @@ -214,38 +220,32 @@ export class GithubEntityProvider implements EntityProvider, EventSubscriber { ); } - // go to the server and get all of the repositories - private async findCatalogFiles(): Promise { + private async createGraphqlClient() { const organization = this.config.organization; const host = this.integration.host; - const catalogPath = this.config.catalogPath; const orgUrl = `https://${host}/${organization}`; const { headers } = await this.githubCredentialsProvider.getCredentials({ url: orgUrl, }); - const client = graphql.defaults({ + return graphql.defaults({ baseUrl: this.integration.apiBaseUrl, headers, }); + } + + // go to the server and get all repositories + private async findCatalogFiles(): Promise { + const organization = this.config.organization; + const catalogPath = this.config.catalogPath; + const client = await this.createGraphqlClient(); const { repositories: repositoriesFromGithub } = await getOrganizationRepositories(client, organization, catalogPath); - const repositories = repositoriesFromGithub.map(r => { - return { - url: r.url, - name: r.name, - defaultBranchRef: r.defaultBranchRef?.name, - repositoryTopics: r.repositoryTopics.nodes.map(t => t.topic.name), - isArchived: r.isArchived, - isFork: r.isFork, - isCatalogInfoFilePresent: - r.catalogInfoFile?.__typename === 'Blob' && - r.catalogInfoFile.text !== '', - visibility: r.visibility, - }; - }); + const repositories = repositoriesFromGithub.map( + this.createRepoFromGithubResponse, + ); if (this.config.validateLocationsExist) { return repositories.filter( @@ -256,13 +256,13 @@ export class GithubEntityProvider implements EntityProvider, EventSubscriber { return repositories; } - private matchesFilters(repositories: Repository[]) { + private matchesFilters(repositories: Repository[]): Repository[] { const repositoryFilter = this.config.filters?.repository; const topicFilters = this.config.filters?.topic; const allowForks = this.config.filters?.allowForks ?? true; const visibilities = this.config.filters?.visibility ?? []; - const matchingRepositories = repositories.filter(r => { + return repositories.filter(r => { const repoTopics: string[] = r.repositoryTopics; return ( !r.isArchived && @@ -273,7 +273,6 @@ export class GithubEntityProvider implements EntityProvider, EventSubscriber { r.defaultBranchRef ); }); - return matchingRepositories; } private createLocationUrl(repository: Repository): string { @@ -296,23 +295,34 @@ export class GithubEntityProvider implements EntityProvider, EventSubscriber { /** {@inheritdoc @backstage/plugin-events-node#EventSubscriber.onEvent} */ async onEvent(params: EventParams): Promise { this.logger.debug(`Received event from ${params.topic}`); - if (params.topic !== TOPIC_REPO_PUSH) { - return; - } + if (EVENT_TOPICS.some(topic => topic === params.topic)) { + if (!this.connection) { + throw new Error('Not initialized'); + } - await this.onRepoPush(params.eventPayload as PushEvent); + switch (params.topic) { + case 'github.push': + await this.onPush(params.eventPayload as PushEvent); + return; + + case 'github.repository': + await this.onRepoChange(params.eventPayload as RepositoryEvent); + return; + + default: // should never be reached + this.logger.warn( + `Missing implementation for event of topic ${params.topic}`, + ); + } + } } /** {@inheritdoc @backstage/plugin-events-node#EventSubscriber.supportsEventTopics} */ supportsEventTopics(): string[] { - return [TOPIC_REPO_PUSH]; + return EVENT_TOPICS; } - private async onRepoPush(event: PushEvent) { - if (!this.connection) { - throw new Error('Not initialized'); - } - + private async onPush(event: PushEvent) { if (this.config.organization !== event.repository.organization) { this.logger.debug( `skipping push event from organization ${event.repository.organization}`, @@ -332,18 +342,7 @@ export class GithubEntityProvider implements EntityProvider, EventSubscriber { return; } - const repository: Repository = { - url: event.repository.url, - name: event.repository.name, - defaultBranchRef: event.repository.default_branch, - repositoryTopics: event.repository.topics, - isArchived: event.repository.archived, - isFork: event.repository.fork, - // we can consider this file present because - // only the catalog file will be recovered from the commits - isCatalogInfoFilePresent: true, - visibility: event.repository.visibility, - }; + const repository = this.createRepoFromEvent(event); const matchingTargets = this.matchesFilters([repository]); if (matchingTargets.length === 0) { @@ -378,7 +377,7 @@ export class GithubEntityProvider implements EntityProvider, EventSubscriber { ? this.config.catalogPath.substring(1) : this.config.catalogPath; - await this.connection.refresh({ + await this.connection!.refresh({ keys: [ ...new Set([ ...modified.map( @@ -396,7 +395,7 @@ export class GithubEntityProvider implements EntityProvider, EventSubscriber { } if (added.length > 0 || removed.length > 0) { - await this.connection.applyMutation({ + await this.connection!.applyMutation({ type: 'delta', added: added, removed: removed, @@ -408,6 +407,263 @@ export class GithubEntityProvider implements EntityProvider, EventSubscriber { ); } + private async onRepoChange(event: RepositoryEvent) { + if (this.config.organization !== event.repository.organization) { + this.logger.debug( + `skipping repository event from organization ${event.repository.organization}`, + ); + return; + } + + const action = event.action; + switch (action) { + case 'archived': + await this.onRepoArchived(event as RepositoryArchivedEvent); + return; + + // A repository was created. + case 'created': + // skip these events + return; + + case 'deleted': + await this.onRepoDeleted(event as RepositoryDeletedEvent); + return; + + case 'edited': + await this.onRepoEdited(event as RepositoryEditedEvent); + return; + + // The visibility of a repository was changed to `private`. + case 'privatized': + // skip these events + return; + + // The visibility of a repository was changed to `public`. + case 'publicized': + // skip these events + return; + + case 'renamed': + await this.onRepoRenamed(event as RepositoryRenamedEvent); + return; + + case 'transferred': + await this.onRepoTransferred(event as RepositoryTransferredEvent); + return; + + case 'unarchived': + await this.onRepoUnarchived(event as RepositoryUnarchivedEvent); + return; + + default: // should never be reached + this.logger.warn( + `Missing implementation for event of topic repository with action ${action}`, + ); + } + } + + /** + * A repository was archived. + * + * Removes all entities associated with the repository. + * + * @param event - The repository archived event. + * @private + */ + private async onRepoArchived(event: RepositoryArchivedEvent) { + const repository = this.createRepoFromEvent(event); + await this.removeEntitiesForRepo(repository); + this.logger.debug( + `Removed entities for archived repository ${repository.name}`, + ); + } + + /** + * A repository was deleted. + * + * Removes all entities associated with the repository. + * + * @param event - The repository deleted event. + * @private + */ + private async onRepoDeleted(event: RepositoryDeletedEvent) { + const repository = this.createRepoFromEvent(event); + await this.removeEntitiesForRepo(repository); + this.logger.debug( + `Removed entities for deleted repository ${repository.name}`, + ); + } + + /** + * The topics, default branch, description, or homepage of a repository was changed. + * + * We are interested in potential topic changes as these can be used as part of the filters. + * + * Removes all entities associated with the repository if the repository no longer matches the filters. + * + * @param event - The repository edited event. + * @private + */ + private async onRepoEdited(event: RepositoryEditedEvent) { + const repository = this.createRepoFromEvent(event); + + const matchingTargets = this.matchesFilters([repository]); + if (matchingTargets.length === 0) { + await this.removeEntitiesForRepo(repository); + } + // else: repository is (still) matching the filters, so we don't need to do anything + } + + /** + * The name of a repository was changed. + * + * Removes all entities associated with the repository's old name. + * Creates new entities for the repository's new name if it still matches the filters. + * + * @param event - The repository renamed event. + * @private + */ + private async onRepoRenamed(event: RepositoryRenamedEvent) { + const repository = this.createRepoFromEvent(event); + const oldRepoName = event.changes.repository.name.from; + const urlParts = event.repository.url.split('/'); + urlParts[urlParts.length - 1] = oldRepoName; + const oldRepoUrl = urlParts.join('/'); + const oldRepository: Repository = { + ...repository, + name: oldRepoName, + url: oldRepoUrl, + }; + await this.removeEntitiesForRepo(oldRepository); + + const matchingTargets = this.matchesFilters([repository]); + if (matchingTargets.length === 0) { + this.logger.debug( + `skipping repository transferred event for repository ${repository.name} because it didn't match provider filters`, + ); + return; + } + + await this.addEntitiesForRepo(repository); + } + + /** + * Ownership of the repository was transferred to a user or organization account. + * This event is only sent to the account where the ownership is transferred. + * To receive the `repository.transferred` event, the new owner account must have the GitHub App installed, + * and the App must be subscribed to "Repository" events. + * + * Creates new entities for the repository if it matches the filters. + * + * @param event - The repository unarchived event. + * @private + */ + private async onRepoTransferred(event: RepositoryTransferredEvent) { + const repository = this.createRepoFromEvent(event); + + const matchingTargets = this.matchesFilters([repository]); + if (matchingTargets.length === 0) { + this.logger.debug( + `skipping repository transferred event for repository ${repository.name} because it didn't match provider filters`, + ); + return; + } + + await this.addEntitiesForRepo(repository); + } + + /** + * A previously archived repository was unarchived. + * + * Creates new entities for the repository if it matches the filters. + * + * @param event - The repository unarchived event. + * @private + */ + private async onRepoUnarchived(event: RepositoryUnarchivedEvent) { + const repository = this.createRepoFromEvent(event); + + const matchingTargets = this.matchesFilters([repository]); + if (matchingTargets.length === 0) { + this.logger.debug( + `skipping repository transferred event for repository ${repository.name} because it didn't match provider filters`, + ); + return; + } + + await this.addEntitiesForRepo(repository); + } + + private async removeEntitiesForRepo(repository: Repository) { + const removed = this.toDeferredEntitiesFromRepos([repository]); + await this.connection!.applyMutation({ + type: 'delta', + added: [], + removed: removed, + }); + } + + private async addEntitiesForRepo(repository: Repository) { + if (this.config.validateLocationsExist) { + const organization = this.config.organization; + const catalogPath = this.config.catalogPath; + const client = await this.createGraphqlClient(); + + const repositoryFromGithub = await getOrganizationRepository( + client, + organization, + repository.name, + catalogPath, + ).then(r => (r ? this.createRepoFromGithubResponse(r) : null)); + + if (!repositoryFromGithub?.isCatalogInfoFilePresent) { + return; + } + } + + const added = this.toDeferredEntitiesFromRepos([repository]); + await this.connection!.applyMutation({ + type: 'delta', + added: added, + removed: [], + }); + } + + private createRepoFromEvent(event: RepositoryEvent | PushEvent): Repository { + return { + url: event.repository.url, + name: event.repository.name, + defaultBranchRef: event.repository.default_branch, + repositoryTopics: event.repository.topics, + isArchived: event.repository.archived, + isFork: event.repository.fork, + // we can consider this file present because + // only the catalog file will be recovered from the commits + isCatalogInfoFilePresent: true, + visibility: event.repository.visibility, + }; + } + + private createRepoFromGithubResponse( + repositoryResponse: RepositoryResponse, + ): Repository { + return { + url: repositoryResponse.url, + name: repositoryResponse.name, + defaultBranchRef: repositoryResponse.defaultBranchRef?.name, + repositoryTopics: repositoryResponse.repositoryTopics.nodes.map( + t => t.topic.name, + ), + isArchived: repositoryResponse.isArchived, + isFork: repositoryResponse.isFork, + isCatalogInfoFilePresent: + repositoryResponse.catalogInfoFile?.__typename === 'Blob' && + repositoryResponse.catalogInfoFile.text !== '', + visibility: repositoryResponse.visibility, + }; + } + private collectDeferredEntitiesFromCommit( repositoryUrl: string, branch: string, @@ -454,6 +710,20 @@ export class GithubEntityProvider implements EntityProvider, EventSubscriber { }; }); } + + private toDeferredEntitiesFromRepos( + repositories: Repository[], + ): DeferredEntity[] { + return repositories + .map(repository => this.createLocationUrl(repository)) + .map(GithubEntityProvider.toLocationSpec) + .map(location => { + return { + locationKey: this.getProviderName(), + entity: locationSpecToLocationEntity({ location }), + }; + }); + } } /* From 70df2be217b7c26e23d5d7221d39182c145ee8de Mon Sep 17 00:00:00 2001 From: Jente Sondervorst Date: Tue, 25 Jun 2024 08:24:29 +0200 Subject: [PATCH 083/510] adapt test Closes: #25256 Signed-off-by: Jente Sondervorst --- .../src/ldap/config.test.ts | 64 ++++++++++--------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/plugins/catalog-backend-module-ldap/src/ldap/config.test.ts b/plugins/catalog-backend-module-ldap/src/ldap/config.test.ts index 9c9165580a..598bcc8839 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/config.test.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/config.test.ts @@ -115,38 +115,42 @@ describe('readLdapConfig', () => { frequency: { minutes: 3 }, timeout: { minutes: 1 }, }, - users: { - dn: 'udn', - options: { - scope: 'one', - attributes: ['*', '+'], + users: [ + { + dn: 'udn', + options: { + scope: 'one', + attributes: ['*', '+'], + }, + set: undefined, + map: { + rdn: 'uid', + name: 'uid', + displayName: 'cn', + email: 'mail', + memberOf: 'memberOf', + }, }, - set: undefined, - map: { - rdn: 'uid', - name: 'uid', - displayName: 'cn', - email: 'mail', - memberOf: 'memberOf', + ], + groups: [ + { + dn: 'gdn', + options: { + scope: 'one', + attributes: ['*', '+'], + }, + set: undefined, + map: { + rdn: 'cn', + name: 'cn', + description: 'description', + type: 'groupType', + displayName: 'cn', + memberOf: 'memberOf', + members: 'member', + }, }, - }, - groups: { - dn: 'gdn', - options: { - scope: 'one', - attributes: ['*', '+'], - }, - set: undefined, - map: { - rdn: 'cn', - name: 'cn', - description: 'description', - type: 'groupType', - displayName: 'cn', - memberOf: 'memberOf', - members: 'member', - }, - }, + ], }, ]; expect(actual).toEqual(expected); From 6f5c2482253f1ee99a3ae2f4472f24918ed9443b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 08:54:17 +0000 Subject: [PATCH 084/510] chore(deps): update dependency @changesets/cli to v2.27.6 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 409 +++--------------------------------------------------- 1 file changed, 21 insertions(+), 388 deletions(-) diff --git a/yarn.lock b/yarn.lock index d41120ce21..85d8841703 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8038,8 +8038,8 @@ __metadata: linkType: hard "@changesets/cli@npm:^2.14.0": - version: 2.27.5 - resolution: "@changesets/cli@npm:2.27.5" + version: 2.27.6 + resolution: "@changesets/cli@npm:2.27.6" dependencies: "@babel/runtime": ^7.20.1 "@changesets/apply-release-plan": ^7.0.3 @@ -8065,7 +8065,7 @@ __metadata: external-editor: ^3.1.0 fs-extra: ^7.0.1 human-id: ^1.0.2 - meow: ^6.0.0 + mri: ^1.2.0 outdent: ^0.5.0 p-limit: ^2.2.0 preferred-pm: ^3.0.0 @@ -8073,10 +8073,9 @@ __metadata: semver: ^7.5.3 spawndamnit: ^2.0.0 term-size: ^2.1.0 - tty-table: ^4.1.5 bin: changeset: bin.js - checksum: 7e0d0aadabcf3028abbb2e079b58135b8e39f78bc174f4fa669cf94482ca3a4ec873e4b4ff9a7e071d83aee592780f0c47bd36a3a12282ab5f13a493c796663f + checksum: efb3c7b569debb2bb0baae2d7bafee4ae19d3c7f0023ea97fa0b6518198c85ba16c2a66609561c9dd0f0601c3390d5933b00e3ad3cb962b4b0e7fcb4de929dfa languageName: node linkType: hard @@ -17967,13 +17966,6 @@ __metadata: languageName: node linkType: hard -"@types/normalize-package-data@npm:^2.4.0": - version: 2.4.1 - resolution: "@types/normalize-package-data@npm:2.4.1" - checksum: e87bccbf11f95035c89a132b52b79ce69a1e3652fe55962363063c9c0dae0fe2477ebc585e03a9652adc6f381d24ba5589cc5e51849df4ced3d3e004a7d40ed5 - languageName: node - linkType: hard - "@types/npm-packlist@npm:^3.0.0": version: 3.0.0 resolution: "@types/npm-packlist@npm:3.0.0" @@ -20724,7 +20716,7 @@ __metadata: languageName: node linkType: hard -"array.prototype.flat@npm:^1.2.3, array.prototype.flat@npm:^1.3.1, array.prototype.flat@npm:^1.3.2": +"array.prototype.flat@npm:^1.3.1, array.prototype.flat@npm:^1.3.2": version: 1.3.2 resolution: "array.prototype.flat@npm:1.3.2" dependencies: @@ -20789,13 +20781,6 @@ __metadata: languageName: node linkType: hard -"arrify@npm:^1.0.1": - version: 1.0.1 - resolution: "arrify@npm:1.0.1" - checksum: 745075dd4a4624ff0225c331dacb99be501a515d39bcb7c84d24660314a6ec28e68131b137e6f7e16318170842ce97538cd298fc4cd6b2cc798e0b957f2747e7 - languageName: node - linkType: hard - "arrify@npm:^2.0.0, arrify@npm:^2.0.1": version: 2.0.1 resolution: "arrify@npm:2.0.1" @@ -21695,15 +21680,6 @@ __metadata: languageName: node linkType: hard -"breakword@npm:^1.0.5": - version: 1.0.5 - resolution: "breakword@npm:1.0.5" - dependencies: - wcwidth: ^1.0.1 - checksum: 8ca7b10bbbbfe1c45c12c9119c4bc1e585452ddd58c5da93020a0c1deac3cf6bb335632675c9c705ba7b644065ae1d6623a25e79b7a48e0ee0ff42cb6e94b357 - languageName: node - linkType: hard - "brorand@npm:^1.0.1, brorand@npm:^1.1.0": version: 1.1.0 resolution: "brorand@npm:1.1.0" @@ -22133,17 +22109,6 @@ __metadata: languageName: node linkType: hard -"camelcase-keys@npm:^6.2.2": - version: 6.2.2 - resolution: "camelcase-keys@npm:6.2.2" - dependencies: - camelcase: ^5.3.1 - map-obj: ^4.0.0 - quick-lru: ^4.0.1 - checksum: 43c9af1adf840471e54c68ab3e5fe8a62719a6b7dbf4e2e86886b7b0ff96112c945736342b837bd2529ec9d1c7d1934e5653318478d98e0cf22c475c04658e2a - languageName: node - linkType: hard - "camelcase@npm:5.0.0": version: 5.0.0 resolution: "camelcase@npm:5.0.0" @@ -22151,7 +22116,7 @@ __metadata: languageName: node linkType: hard -"camelcase@npm:^5.0.0, camelcase@npm:^5.3.1": +"camelcase@npm:^5.3.1": version: 5.3.1 resolution: "camelcase@npm:5.3.1" checksum: e6effce26b9404e3c0f301498184f243811c30dfe6d0b9051863bd8e4034d09c8c2923794f280d6827e5aa055f6c434115ff97864a16a963366fb35fd673024b @@ -22573,17 +22538,6 @@ __metadata: languageName: node linkType: hard -"cliui@npm:^6.0.0": - version: 6.0.0 - resolution: "cliui@npm:6.0.0" - dependencies: - string-width: ^4.2.0 - strip-ansi: ^6.0.0 - wrap-ansi: ^6.2.0 - checksum: 4fcfd26d292c9f00238117f39fc797608292ae36bac2168cfee4c85923817d0607fe21b3329a8621e01aedf512c99b7eaa60e363a671ffd378df6649fb48ae42 - languageName: node - linkType: hard - "cliui@npm:^8.0.1": version: 8.0.1 resolution: "cliui@npm:8.0.1" @@ -23963,39 +23917,6 @@ __metadata: languageName: node linkType: hard -"csv-generate@npm:^3.4.3": - version: 3.4.3 - resolution: "csv-generate@npm:3.4.3" - checksum: 868dc630e8bcabf42d3d1ef22c09fb783de72d7e5929854aad0323f44059b1747edf8a2724e32fdc5008396e2ea38d5c45df0b0e3a1b506e3ab34f76f3e2fb3a - languageName: node - linkType: hard - -"csv-parse@npm:^4.16.3": - version: 4.16.3 - resolution: "csv-parse@npm:4.16.3" - checksum: 5ad7790fc31c32ca1623bad1a54906134ba44fa109e8dd2dfda440bf7e9fd93610d9076a78f45c872701bfafdf7f93c9b75500c09d7efd6611d863f1d45ec69f - languageName: node - linkType: hard - -"csv-stringify@npm:^5.6.5": - version: 5.6.5 - resolution: "csv-stringify@npm:5.6.5" - checksum: f93e1444857416081de3d86765b62e4c4f7c110974ad6bbcb0031d7db39b6624847ac9ee5705726e7011346f32f3696f27299b74b23a6c2b083adff0dd2755fe - languageName: node - linkType: hard - -"csv@npm:^5.5.0": - version: 5.5.3 - resolution: "csv@npm:5.5.3" - dependencies: - csv-generate: ^3.4.3 - csv-parse: ^4.16.3 - csv-stringify: ^5.6.5 - stream-transform: ^2.1.3 - checksum: 0decc2d0d7a0abf127f4556d6f3cef5a54015b78d348608b5e8f42256c2bd0a021f34f1efc9723b2cd162680917de4c0b3967bfb65a07305eca0827654ca727e - languageName: node - linkType: hard - "ctrlc-windows@npm:^2.1.0": version: 2.1.0 resolution: "ctrlc-windows@npm:2.1.0" @@ -24282,23 +24203,6 @@ __metadata: languageName: node linkType: hard -"decamelize-keys@npm:^1.1.0": - version: 1.1.0 - resolution: "decamelize-keys@npm:1.1.0" - dependencies: - decamelize: ^1.1.0 - map-obj: ^1.0.0 - checksum: 8bc5d32e035a072f5dffc1f1f3d26ca7ab1fb44a9cade34c97ab6cd1e62c81a87e718101e96de07d78cecda20a3fdb955df958e46671ccad01bb8dcf0de2e298 - languageName: node - linkType: hard - -"decamelize@npm:^1.1.0, decamelize@npm:^1.2.0": - version: 1.2.0 - resolution: "decamelize@npm:1.2.0" - checksum: ad8c51a7e7e0720c70ec2eeb1163b66da03e7616d7b98c9ef43cce2416395e84c1e9548dd94f5f6ffecfee9f8b94251fc57121a8b021f2ff2469b2bae247b8aa - languageName: node - linkType: hard - "decimal.js@npm:^10.2.1, decimal.js@npm:^10.3.1": version: 10.4.1 resolution: "decimal.js@npm:10.4.1" @@ -27847,7 +27751,7 @@ __metadata: languageName: node linkType: hard -"get-caller-file@npm:^2.0.1, get-caller-file@npm:^2.0.5": +"get-caller-file@npm:^2.0.5": version: 2.0.5 resolution: "get-caller-file@npm:2.0.5" checksum: b9769a836d2a98c3ee734a88ba712e62703f1df31b94b784762c433c27a386dd6029ff55c2a920c392e33657d80191edbf18c61487e198844844516f843496b9 @@ -28527,13 +28431,6 @@ __metadata: languageName: node linkType: hard -"hard-rejection@npm:^2.1.0": - version: 2.1.0 - resolution: "hard-rejection@npm:2.1.0" - checksum: 7baaf80a0c7fff4ca79687b4060113f1529589852152fa935e6787a2bc96211e784ad4588fb3048136ff8ffc9dfcf3ae385314a5b24db32de20bea0d1597f9dc - languageName: node - linkType: hard - "harmony-reflect@npm:^1.4.6": version: 1.6.1 resolution: "harmony-reflect@npm:1.6.1" @@ -28758,13 +28655,6 @@ __metadata: languageName: node linkType: hard -"hosted-git-info@npm:^2.1.4": - version: 2.8.9 - resolution: "hosted-git-info@npm:2.8.9" - checksum: c955394bdab888a1e9bb10eb33029e0f7ce5a2ac7b3f158099dc8c486c99e73809dca609f5694b223920ca2174db33d32b12f9a2a47141dc59607c29da5a62dd - languageName: node - linkType: hard - "hosted-git-info@npm:^4.0.1": version: 4.1.0 resolution: "hosted-git-info@npm:4.1.0" @@ -30030,13 +29920,6 @@ __metadata: languageName: node linkType: hard -"is-plain-obj@npm:^1.1.0": - version: 1.1.0 - resolution: "is-plain-obj@npm:1.1.0" - checksum: 0ee04807797aad50859652a7467481816cbb57e5cc97d813a7dcd8915da8195dc68c436010bf39d195226cde6a2d352f4b815f16f26b7bf486a5754290629931 - languageName: node - linkType: hard - "is-plain-obj@npm:^3.0.0": version: 3.0.0 resolution: "is-plain-obj@npm:3.0.0" @@ -31877,7 +31760,7 @@ __metadata: languageName: node linkType: hard -"kind-of@npm:^6.0.2, kind-of@npm:^6.0.3": +"kind-of@npm:^6.0.2": version: 6.0.3 resolution: "kind-of@npm:6.0.3" checksum: 3ab01e7b1d440b22fe4c31f23d8d38b4d9b91d9f291df683476576493d5dfd2e03848a8b05813dd0c3f0e835bc63f433007ddeceb71f05cb25c45ae1b19c6d3b @@ -31891,7 +31774,7 @@ __metadata: languageName: node linkType: hard -"kleur@npm:^4.0.3, kleur@npm:^4.1.4": +"kleur@npm:^4.0.3": version: 4.1.5 resolution: "kleur@npm:4.1.5" checksum: 1dc476e32741acf0b1b5b0627ffd0d722e342c1b0da14de3e8ae97821327ca08f9fb944542fb3c126d90ac5f27f9d804edbe7c585bf7d12ef495d115e0f22c12 @@ -32886,13 +32769,6 @@ __metadata: languageName: node linkType: hard -"map-obj@npm:^1.0.0": - version: 1.0.1 - resolution: "map-obj@npm:1.0.1" - checksum: 9949e7baec2a336e63b8d4dc71018c117c3ce6e39d2451ccbfd3b8350c547c4f6af331a4cbe1c83193d7c6b786082b6256bde843db90cb7da2a21e8fcc28afed - languageName: node - linkType: hard - "map-obj@npm:^2.0.0": version: 2.0.0 resolution: "map-obj@npm:2.0.0" @@ -32900,13 +32776,6 @@ __metadata: languageName: node linkType: hard -"map-obj@npm:^4.0.0": - version: 4.3.0 - resolution: "map-obj@npm:4.3.0" - checksum: fbc554934d1a27a1910e842bc87b177b1a556609dd803747c85ece420692380827c6ae94a95cce4407c054fa0964be3bf8226f7f2cb2e9eeee432c7c1985684e - languageName: node - linkType: hard - "markdown-it@npm:^12.2.0": version: 12.3.2 resolution: "markdown-it@npm:12.3.2" @@ -33263,25 +33132,6 @@ __metadata: languageName: node linkType: hard -"meow@npm:^6.0.0": - version: 6.1.1 - resolution: "meow@npm:6.1.1" - dependencies: - "@types/minimist": ^1.2.0 - camelcase-keys: ^6.2.2 - decamelize-keys: ^1.1.0 - hard-rejection: ^2.1.0 - minimist-options: ^4.0.2 - normalize-package-data: ^2.5.0 - read-pkg-up: ^7.0.1 - redent: ^3.0.0 - trim-newlines: ^3.0.0 - type-fest: ^0.13.1 - yargs-parser: ^18.1.3 - checksum: 77b569781145ad030be77130623d9f74d6eef0af5e0a349419d3df39bcf6d88cc25be046a7757062162a88160fb5d8604e540b5177b371d2bbc2aaf73ec01479 - languageName: node - linkType: hard - "merge-descriptors@npm:1.0.1": version: 1.0.1 resolution: "merge-descriptors@npm:1.0.1" @@ -33885,17 +33735,6 @@ __metadata: languageName: node linkType: hard -"minimist-options@npm:^4.0.2": - version: 4.1.0 - resolution: "minimist-options@npm:4.1.0" - dependencies: - arrify: ^1.0.1 - is-plain-obj: ^1.1.0 - kind-of: ^6.0.3 - checksum: 8c040b3068811e79de1140ca2b708d3e203c8003eb9a414c1ab3cd467fc5f17c9ca02a5aef23bedc51a7f8bfbe77f87e9a7e31ec81fba304cda675b019496f4e - languageName: node - linkType: hard - "minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.5, minimist@npm:^1.2.6, minimist@npm:^1.2.8": version: 1.2.8 resolution: "minimist@npm:1.2.8" @@ -34045,13 +33884,6 @@ __metadata: languageName: node linkType: hard -"mixme@npm:^0.5.1": - version: 0.5.4 - resolution: "mixme@npm:0.5.4" - checksum: cec5f6127c92455bc86d592f0a0628e188c7ccf3909bd106703a1d939f0e2f451ddaac6da0d77c5f14d53dd2d58f64f5b2f8ff55a68ec68be95a73d290e4d430 - languageName: node - linkType: hard - "mkdirp-classic@npm:^0.5.2, mkdirp-classic@npm:^0.5.3": version: 0.5.3 resolution: "mkdirp-classic@npm:0.5.3" @@ -34189,7 +34021,7 @@ __metadata: languageName: node linkType: hard -"mri@npm:^1.1.0": +"mri@npm:^1.1.0, mri@npm:^1.2.0": version: 1.2.0 resolution: "mri@npm:1.2.0" checksum: 83f515abbcff60150873e424894a2f65d68037e5a7fcde8a9e2b285ee9c13ac581b63cfc1e6826c4732de3aeb84902f7c1e16b7aff46cd3f897a0f757a894e85 @@ -34879,18 +34711,6 @@ __metadata: languageName: node linkType: hard -"normalize-package-data@npm:^2.5.0": - version: 2.5.0 - resolution: "normalize-package-data@npm:2.5.0" - dependencies: - hosted-git-info: ^2.1.4 - resolve: ^1.10.0 - semver: 2 || 3 || 4 || 5 - validate-npm-package-license: ^3.0.1 - checksum: 7999112efc35a6259bc22db460540cae06564aa65d0271e3bdfa86876d08b0e578b7b5b0028ee61b23f1cae9fc0e7847e4edc0948d3068a39a2a82853efc8499 - languageName: node - linkType: hard - "normalize-path@npm:^2.1.1": version: 2.1.1 resolution: "normalize-path@npm:2.1.1" @@ -37701,13 +37521,6 @@ __metadata: languageName: node linkType: hard -"quick-lru@npm:^4.0.1": - version: 4.0.1 - resolution: "quick-lru@npm:4.0.1" - checksum: bea46e1abfaa07023e047d3cf1716a06172c4947886c053ede5c50321893711577cb6119360f810cc3ffcd70c4d7db4069c3cee876b358ceff8596e062bd1154 - languageName: node - linkType: hard - "quick-lru@npm:^5.1.1": version: 5.1.1 resolution: "quick-lru@npm:5.1.1" @@ -38599,29 +38412,6 @@ __metadata: languageName: node linkType: hard -"read-pkg-up@npm:^7.0.1": - version: 7.0.1 - resolution: "read-pkg-up@npm:7.0.1" - dependencies: - find-up: ^4.1.0 - read-pkg: ^5.2.0 - type-fest: ^0.8.1 - checksum: e4e93ce70e5905b490ca8f883eb9e48b5d3cebc6cd4527c25a0d8f3ae2903bd4121c5ab9c5a3e217ada0141098eeb661313c86fa008524b089b8ed0b7f165e44 - languageName: node - linkType: hard - -"read-pkg@npm:^5.2.0": - version: 5.2.0 - resolution: "read-pkg@npm:5.2.0" - dependencies: - "@types/normalize-package-data": ^2.4.0 - normalize-package-data: ^2.5.0 - parse-json: ^5.0.0 - type-fest: ^0.6.0 - checksum: eb696e60528b29aebe10e499ba93f44991908c57d70f2d26f369e46b8b9afc208ef11b4ba64f67630f31df8b6872129e0a8933c8c53b7b4daf0eace536901222 - languageName: node - linkType: hard - "read-tls-client-hello@npm:^1.0.0": version: 1.0.1 resolution: "read-tls-client-hello@npm:1.0.1" @@ -39125,13 +38915,6 @@ __metadata: languageName: node linkType: hard -"require-main-filename@npm:^2.0.0": - version: 2.0.0 - resolution: "require-main-filename@npm:2.0.0" - checksum: e9e294695fea08b076457e9ddff854e81bffbe248ed34c1eec348b7abbd22a0d02e8d75506559e2265e96978f3c4720bd77a6dad84755de8162b357eb6c778c7 - languageName: node - linkType: hard - "requires-port@npm:^1.0.0": version: 1.0.0 resolution: "requires-port@npm:1.0.0" @@ -39197,7 +38980,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.1.6, resolve@npm:^1.10.0, resolve@npm:^1.14.2, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.4, resolve@npm:^1.22.8, resolve@npm:~1.22.1": +"resolve@npm:^1.1.6, resolve@npm:^1.14.2, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.4, resolve@npm:^1.22.8, resolve@npm:~1.22.1": version: 1.22.8 resolution: "resolve@npm:1.22.8" dependencies: @@ -39233,7 +39016,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@^1.1.6#~builtin, resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.17.0#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.1#~builtin, resolve@patch:resolve@^1.22.4#~builtin, resolve@patch:resolve@^1.22.8#~builtin, resolve@patch:resolve@~1.22.1#~builtin": +"resolve@patch:resolve@^1.1.6#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.17.0#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.1#~builtin, resolve@patch:resolve@^1.22.4#~builtin, resolve@patch:resolve@^1.22.8#~builtin, resolve@patch:resolve@~1.22.1#~builtin": version: 1.22.8 resolution: "resolve@patch:resolve@npm%3A1.22.8#~builtin::version=1.22.8&hash=c3c19d" dependencies: @@ -39973,15 +39756,6 @@ __metadata: languageName: node linkType: hard -"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.5.0, semver@npm:^5.6.0": - version: 5.7.2 - resolution: "semver@npm:5.7.2" - bin: - semver: bin/semver - checksum: fb4ab5e0dd1c22ce0c937ea390b4a822147a9c53dbd2a9a0132f12fe382902beef4fbf12cf51bb955248d8d15874ce8cd89532569756384f994309825f10b686 - languageName: node - linkType: hard - "semver@npm:7.5.4, semver@npm:~7.5.4": version: 7.5.4 resolution: "semver@npm:7.5.4" @@ -39993,6 +39767,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^5.5.0, semver@npm:^5.6.0": + version: 5.7.2 + resolution: "semver@npm:5.7.2" + bin: + semver: bin/semver + checksum: fb4ab5e0dd1c22ce0c937ea390b4a822147a9c53dbd2a9a0132f12fe382902beef4fbf12cf51bb955248d8d15874ce8cd89532569756384f994309825f10b686 + languageName: node + linkType: hard + "semver@npm:^6.0.0, semver@npm:^6.2.0, semver@npm:^6.3.0, semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" @@ -40483,22 +40266,6 @@ __metadata: languageName: node linkType: hard -"smartwrap@npm:^2.0.2": - version: 2.0.2 - resolution: "smartwrap@npm:2.0.2" - dependencies: - array.prototype.flat: ^1.2.3 - breakword: ^1.0.5 - grapheme-splitter: ^1.0.4 - strip-ansi: ^6.0.0 - wcwidth: ^1.0.1 - yargs: ^15.1.0 - bin: - smartwrap: src/terminal-adapter.js - checksum: 1a6833eb1c3d8488b036df66dcab37dcdda5270bb9629c471155785c09ee1b591177a9774c588c43f8fa28833204500019265da2ffed28ac7bbf4589b943d2fa - languageName: node - linkType: hard - "smol-toml@npm:^1.1.4": version: 1.2.1 resolution: "smol-toml@npm:1.2.1" @@ -40704,40 +40471,6 @@ __metadata: languageName: node linkType: hard -"spdx-correct@npm:^3.0.0": - version: 3.1.1 - resolution: "spdx-correct@npm:3.1.1" - dependencies: - spdx-expression-parse: ^3.0.0 - spdx-license-ids: ^3.0.0 - checksum: 77ce438344a34f9930feffa61be0eddcda5b55fc592906ef75621d4b52c07400a97084d8701557b13f7d2aae0cb64f808431f469e566ef3fe0a3a131dcb775a6 - languageName: node - linkType: hard - -"spdx-exceptions@npm:^2.1.0": - version: 2.3.0 - resolution: "spdx-exceptions@npm:2.3.0" - checksum: cb69a26fa3b46305637123cd37c85f75610e8c477b6476fa7354eb67c08128d159f1d36715f19be6f9daf4b680337deb8c65acdcae7f2608ba51931540687ac0 - languageName: node - linkType: hard - -"spdx-expression-parse@npm:^3.0.0": - version: 3.0.1 - resolution: "spdx-expression-parse@npm:3.0.1" - dependencies: - spdx-exceptions: ^2.1.0 - spdx-license-ids: ^3.0.0 - checksum: a1c6e104a2cbada7a593eaa9f430bd5e148ef5290d4c0409899855ce8b1c39652bcc88a725259491a82601159d6dc790bedefc9016c7472f7de8de7361f8ccde - languageName: node - linkType: hard - -"spdx-license-ids@npm:^3.0.0": - version: 3.0.12 - resolution: "spdx-license-ids@npm:3.0.12" - checksum: 92a4dddce62ce1db6fe54a7a839cf85e06abc308fc83b776a55b44e4f1906f02e7ebd506120847039e976bbbad359ea8bdfafb7925eae5cd7e73255f02e0b7d6 - languageName: node - linkType: hard - "spdy-transport@npm:^3.0.0": version: 3.0.0 resolution: "spdy-transport@npm:3.0.0" @@ -41092,15 +40825,6 @@ __metadata: languageName: node linkType: hard -"stream-transform@npm:^2.1.3": - version: 2.1.3 - resolution: "stream-transform@npm:2.1.3" - dependencies: - mixme: ^0.5.1 - checksum: 26ce872a6812d5c784fa1f042bfd403644bc1c019f64627b5012c4544830a5570bef98b47225b38120c5878b326f3d1a213cd999a2285c98b536e5e202ca5bdf - languageName: node - linkType: hard - "streamsearch@npm:^1.1.0": version: 1.1.0 resolution: "streamsearch@npm:1.1.0" @@ -42398,13 +42122,6 @@ __metadata: languageName: node linkType: hard -"trim-newlines@npm:^3.0.0": - version: 3.0.1 - resolution: "trim-newlines@npm:3.0.1" - checksum: b530f3fadf78e570cf3c761fb74fef655beff6b0f84b29209bac6c9622db75ad1417f4a7b5d54c96605dcd72734ad44526fef9f396807b90839449eb543c6206 - languageName: node - linkType: hard - "triple-beam@npm:^1.3.0, triple-beam@npm:^1.4.1": version: 1.4.1 resolution: "triple-beam@npm:1.4.1" @@ -42603,23 +42320,6 @@ __metadata: languageName: node linkType: hard -"tty-table@npm:^4.1.5": - version: 4.1.6 - resolution: "tty-table@npm:4.1.6" - dependencies: - chalk: ^4.1.2 - csv: ^5.5.0 - kleur: ^4.1.4 - smartwrap: ^2.0.2 - strip-ansi: ^6.0.0 - wcwidth: ^1.0.1 - yargs: ^17.1.1 - bin: - tty-table: adapters/terminal-adapter.js - checksum: 0f689b7d79ad6b9e608299e667a493309901fe802f1c4d66627a90cacb6fe11e0521e1a2dc5a75f793750ecdd849e98292d4874e5e6e988edd928b67045eb847 - languageName: node - linkType: hard - "tunnel-agent@npm:^0.6.0": version: 0.6.0 resolution: "tunnel-agent@npm:0.6.0" @@ -42710,20 +42410,6 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^0.6.0": - version: 0.6.0 - resolution: "type-fest@npm:0.6.0" - checksum: b2188e6e4b21557f6e92960ec496d28a51d68658018cba8b597bd3ef757721d1db309f120ae987abeeda874511d14b776157ff809f23c6d1ce8f83b9b2b7d60f - languageName: node - linkType: hard - -"type-fest@npm:^0.8.1": - version: 0.8.1 - resolution: "type-fest@npm:0.8.1" - checksum: d61c4b2eba24009033ae4500d7d818a94fd6d1b481a8111612ee141400d5f1db46f199c014766b9fa9b31a6a7374d96fc748c6d688a78a3ce5a33123839becb7 - languageName: node - linkType: hard - "type-fest@npm:^2.19.0": version: 2.19.0 resolution: "type-fest@npm:2.19.0" @@ -43644,16 +43330,6 @@ __metadata: languageName: node linkType: hard -"validate-npm-package-license@npm:^3.0.1": - version: 3.0.4 - resolution: "validate-npm-package-license@npm:3.0.4" - dependencies: - spdx-correct: ^3.0.0 - spdx-expression-parse: ^3.0.0 - checksum: 35703ac889d419cf2aceef63daeadbe4e77227c39ab6287eeb6c1b36a746b364f50ba22e88591f5d017bc54685d8137bc2d328d0a896e4d3fd22093c0f32a9ad - languageName: node - linkType: hard - "validate-npm-package-name@npm:^3.0.0": version: 3.0.0 resolution: "validate-npm-package-name@npm:3.0.0" @@ -44288,13 +43964,6 @@ __metadata: languageName: node linkType: hard -"which-module@npm:^2.0.0": - version: 2.0.0 - resolution: "which-module@npm:2.0.0" - checksum: 809f7fd3dfcb2cdbe0180b60d68100c88785084f8f9492b0998c051d7a8efe56784492609d3f09ac161635b78ea29219eb1418a98c15ce87d085bce905705c9c - languageName: node - linkType: hard - "which-pm@npm:2.0.0": version: 2.0.0 resolution: "which-pm@npm:2.0.0" @@ -44684,13 +44353,6 @@ __metadata: languageName: node linkType: hard -"y18n@npm:^4.0.0": - version: 4.0.3 - resolution: "y18n@npm:4.0.3" - checksum: 014dfcd9b5f4105c3bb397c1c8c6429a9df004aa560964fb36732bfb999bfe83d45ae40aeda5b55d21b1ee53d8291580a32a756a443e064317953f08025b1aa4 - languageName: node - linkType: hard - "y18n@npm:^5.0.5": version: 5.0.8 resolution: "y18n@npm:5.0.8" @@ -44757,16 +44419,6 @@ __metadata: languageName: node linkType: hard -"yargs-parser@npm:^18.1.2, yargs-parser@npm:^18.1.3": - version: 18.1.3 - resolution: "yargs-parser@npm:18.1.3" - dependencies: - camelcase: ^5.0.0 - decamelize: ^1.2.0 - checksum: 60e8c7d1b85814594d3719300ecad4e6ae3796748b0926137bfec1f3042581b8646d67e83c6fc80a692ef08b8390f21ddcacb9464476c39bbdf52e34961dd4d9 - languageName: node - linkType: hard - "yargs-parser@npm:^20.2.2": version: 20.2.9 resolution: "yargs-parser@npm:20.2.9" @@ -44781,25 +44433,6 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^15.1.0": - version: 15.4.1 - resolution: "yargs@npm:15.4.1" - dependencies: - cliui: ^6.0.0 - decamelize: ^1.2.0 - find-up: ^4.1.0 - get-caller-file: ^2.0.1 - require-directory: ^2.1.1 - require-main-filename: ^2.0.0 - set-blocking: ^2.0.0 - string-width: ^4.2.0 - which-module: ^2.0.0 - y18n: ^4.0.0 - yargs-parser: ^18.1.2 - checksum: 40b974f508d8aed28598087720e086ecd32a5fd3e945e95ea4457da04ee9bdb8bdd17fd91acff36dc5b7f0595a735929c514c40c402416bbb87c03f6fb782373 - languageName: node - linkType: hard - "yargs@npm:^16.2.0": version: 16.2.0 resolution: "yargs@npm:16.2.0" From 5132d28818568a0c45132f9f49b49cba138a6b08 Mon Sep 17 00:00:00 2001 From: Beth Griggs Date: Fri, 21 Jun 2024 18:35:30 +0100 Subject: [PATCH 085/510] fix(plugin-org): implement batching in useGetEntities to handle large headers The useGetEntities hook can result in requests to /api/catalog/entities where the headers exceed the default maximum Node.js header size of 16KB. This commit implements batching in the useGetEntities hook to handle cases where this is likely to occur. Refs: https://github.com/backstage/backstage/issues/22139 Signed-off-by: Beth Griggs --- .changeset/fast-pens-smell.md | 5 + .../OwnershipCard/useGetEntities.test.ts | 104 ++++++++++++++++++ .../Cards/OwnershipCard/useGetEntities.ts | 50 +++++---- 3 files changed, 140 insertions(+), 19 deletions(-) create mode 100644 .changeset/fast-pens-smell.md diff --git a/.changeset/fast-pens-smell.md b/.changeset/fast-pens-smell.md new file mode 100644 index 0000000000..6d909a397c --- /dev/null +++ b/.changeset/fast-pens-smell.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-org': patch +--- + +The `useGetEntities` hook could result in requests to `/api/catalog/entities` where the headers exceed the default maximum Node.js header size of 16KB. The hook logic has been adjusted to batch the requests. diff --git a/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.test.ts b/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.test.ts index eac5a171ba..2c223c3f4f 100644 --- a/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.test.ts +++ b/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.test.ts @@ -231,6 +231,110 @@ describe('useGetEntities', () => { ); }); }); + + describe('useGetEntities with 500+ relations', () => { + const manyGroups = Array.from({ length: 555 }, (_, i) => + createGroupEntityFromName(`group${i + 1}`), + ); + + const givenUserWithManyGroups = { + kind: 'User', + metadata: { + name: givenUser, + }, + spec: { + memberOf: manyGroups.map( + group => `group:default/${group.metadata.name}`, + ), + }, + } as Partial as Entity; + + beforeEach(() => { + getEntityRelationsMock.mockImplementation(entity => + entity?.kind === 'User' + ? manyGroups.map(group => createGroupRefFromName(group.metadata.name)) + : [], + ); + (catalogApiMock.getEntities as jest.Mock).mockClear(); + }); + + it('should handle 500+ relations without exceeding URL length limits', async () => { + const { result } = renderHook( + ({ entity }) => useGetEntities(entity, 'aggregated'), + { + initialProps: { entity: givenUserWithManyGroups }, + }, + ); + + await waitFor(() => expect(result.current.loading).toBe(false)); + + const callArgs = (catalogApiMock.getEntities as jest.Mock).mock + .calls[0][0]; + + expect( + callArgs.filter[0]['relations.ownedBy'].length, + ).toBeLessThanOrEqual(100); + + const owners = callArgs.filter[0]['relations.ownedBy']; + + expect(Array.isArray(owners)).toBeTruthy(); + expect(owners.length).toBeLessThanOrEqual(100); + }); + }); + + describe('useGetEntities exceeding default 16384 bytes header size', () => { + const largeNumberOfGroups = Array.from({ length: 600 }, (_, i) => + createGroupEntityFromName(`very-long-group-name-${i + 1}`), + ); + + const givenUserWithLargeNumberOfGroups = { + kind: 'User', + metadata: { + name: givenUser, + }, + spec: { + memberOf: largeNumberOfGroups.map( + group => `group:default/${group.metadata.name}`, + ), + }, + } as Partial as Entity; + + beforeEach(() => { + getEntityRelationsMock.mockImplementation(entity => + entity?.kind === 'User' + ? largeNumberOfGroups.map(group => + createGroupRefFromName(group.metadata.name), + ) + : [], + ); + (catalogApiMock.getEntities as jest.Mock).mockClear(); + }); + + it('should batch the request to avoid exceeding header size limits', async () => { + const { result } = renderHook( + ({ entity }) => useGetEntities(entity, 'aggregated'), + { + initialProps: { entity: givenUserWithLargeNumberOfGroups }, + }, + ); + + await waitFor(() => expect(result.current.loading).toBe(false)); + const callArgs = (catalogApiMock.getEntities as jest.Mock).mock + .calls[0][0]; + + const url = new URL( + `http://localhost/api/catalog/entities?${new URLSearchParams( + callArgs as any, + )}`, + ); + const headerSize = url.href.length; + expect(headerSize).toBeLessThanOrEqual(16384); + + const owners = callArgs.filter[0]['relations.ownedBy']; + expect(Array.isArray(owners)).toBeTruthy(); + expect(owners.length).toBeLessThanOrEqual(100); + }); + }); }); function createGroupEntityFromName(name: string): Entity { diff --git a/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts b/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts index 5a708bcfee..d919e1d7c5 100644 --- a/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts +++ b/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts @@ -143,26 +143,38 @@ const getOwners = async ( return [stringifyEntityRef(entity)]; }; -const getOwnedEntitiesByOwners = ( +const batchGetOwnedEntitiesByOwners = async ( owners: string[], kinds: string[], catalogApi: CatalogApi, -) => - catalogApi.getEntities({ - filter: [ - { - kind: kinds, - 'relations.ownedBy': owners, - }, - ], - fields: [ - 'kind', - 'metadata.name', - 'metadata.namespace', - 'spec.type', - 'relations', - ], - }); + batchSize: number = 100, +) => { + const batches = []; + + for (let i = 0; i < owners.length; i += batchSize) { + const batch = owners.slice(i, i + batchSize); + batches.push( + catalogApi.getEntities({ + filter: [ + { + kind: kinds, + 'relations.ownedBy': batch, + }, + ], + fields: [ + 'kind', + 'metadata.name', + 'metadata.namespace', + 'spec.type', + 'relations', + ], + }), + ); + } + + const results = await Promise.all(batches); + return results.flatMap(result => result.items); +}; export function useGetEntities( entity: Entity, @@ -191,13 +203,13 @@ export function useGetEntities( } = useAsync(async () => { const owners = await getOwners(entity, relations, catalogApi); - const ownedEntitiesList = await getOwnedEntitiesByOwners( + const ownedEntitiesList = await batchGetOwnedEntitiesByOwners( owners, kinds, catalogApi, ); - const counts = ownedEntitiesList.items.reduce( + const counts = ownedEntitiesList.reduce( (acc: EntityTypeProps[], ownedEntity) => { const match = acc.find( x => x.kind === ownedEntity.kind && x.type === ownedEntity.spec?.type, From a936761afefd680e87b8f04b3e96764ffdd0bb4a Mon Sep 17 00:00:00 2001 From: Alper Altay <43654387+alper98@users.noreply.github.com> Date: Tue, 25 Jun 2024 12:26:51 +0200 Subject: [PATCH 086/510] Update packages/cli/src/lib/new/factories/backendPlugin.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Alper Altay <43654387+alper98@users.noreply.github.com> --- packages/cli/src/lib/new/factories/backendPlugin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/lib/new/factories/backendPlugin.ts b/packages/cli/src/lib/new/factories/backendPlugin.ts index 5848a72047..e1bfac5eb8 100644 --- a/packages/cli/src/lib/new/factories/backendPlugin.ts +++ b/packages/cli/src/lib/new/factories/backendPlugin.ts @@ -97,7 +97,7 @@ export const backendPlugin = createFactory({ if (backendStartIndex !== -1) { const [indentation] = lines[backendStartIndex].match(/^\s*/) ?? []; - lines.splice(backendStartIndex, 0, indentation + backendAddLine); + lines.splice(backendStartIndex, 0, `${indentation}${backendAddLine}`); const newContent = lines.join('\n'); await fs.writeFile(backendFilePath, newContent, 'utf8'); From 1e88954016fb4e27cdd32b86b2918077cac2d20c Mon Sep 17 00:00:00 2001 From: Alper Altay <43654387+alper98@users.noreply.github.com> Date: Tue, 25 Jun 2024 12:27:10 +0200 Subject: [PATCH 087/510] Update packages/cli/src/lib/new/factories/backendPlugin.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Alper Altay <43654387+alper98@users.noreply.github.com> --- packages/cli/src/lib/new/factories/backendPlugin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/lib/new/factories/backendPlugin.ts b/packages/cli/src/lib/new/factories/backendPlugin.ts index e1bfac5eb8..c5cd043132 100644 --- a/packages/cli/src/lib/new/factories/backendPlugin.ts +++ b/packages/cli/src/lib/new/factories/backendPlugin.ts @@ -96,7 +96,7 @@ export const backendPlugin = createFactory({ ); if (backendStartIndex !== -1) { - const [indentation] = lines[backendStartIndex].match(/^\s*/) ?? []; + const [indentation] = lines[backendStartIndex].match(/^\s*/)!; lines.splice(backendStartIndex, 0, `${indentation}${backendAddLine}`); const newContent = lines.join('\n'); From e053c105f4a27fa29b76aea11a2a209c38664f49 Mon Sep 17 00:00:00 2001 From: Alper Altay Date: Tue, 25 Jun 2024 12:38:10 +0200 Subject: [PATCH 088/510] chore: breaking out into function Signed-off-by: Alper Altay --- .../src/lib/new/factories/backendModule.ts | 28 +++------------- .../src/lib/new/factories/backendPlugin.ts | 28 +++------------- packages/cli/src/lib/tasks.ts | 32 +++++++++++++++++++ 3 files changed, 40 insertions(+), 48 deletions(-) diff --git a/packages/cli/src/lib/new/factories/backendModule.ts b/packages/cli/src/lib/new/factories/backendModule.ts index e0c56b34ae..8cfa7f1e00 100644 --- a/packages/cli/src/lib/new/factories/backendModule.ts +++ b/packages/cli/src/lib/new/factories/backendModule.ts @@ -20,7 +20,7 @@ import camelCase from 'lodash/camelCase'; import { paths } from '../../paths'; import { addCodeownersEntry, getCodeownersFilePath } from '../../codeowners'; import { CreateContext, createFactory } from '../types'; -import { addPackageDependency, Task } from '../../tasks'; +import { addPackageDependency, addToBackend, Task } from '../../tasks'; import { moduleIdIdPrompt, ownerPrompt, @@ -91,29 +91,9 @@ export const backendModule = createFactory({ }); } - await Task.forItem('backend', 'adding module', async () => { - const backendFilePath = paths.resolveTargetRoot( - 'packages/backend/src/index.ts', - ); - if (!(await fs.pathExists(backendFilePath))) { - return; - } - - const content = await fs.readFile(backendFilePath, 'utf8'); - const lines = content.split('\n'); - const backendAddLine = `backend.add(import('${name}'));`; - - const backendStartIndex = lines.findIndex(line => - line.match(/backend.start/), - ); - - if (backendStartIndex !== -1) { - const [indentation] = lines[backendStartIndex].match(/^\s*/) ?? []; - lines.splice(backendStartIndex, 0, indentation + backendAddLine); - - const newContent = lines.join('\n'); - await fs.writeFile(backendFilePath, newContent, 'utf8'); - } + await addToBackend(name, { + defaultVersion: ctx.defaultVersion, + type: 'module', }); if (options.owner) { diff --git a/packages/cli/src/lib/new/factories/backendPlugin.ts b/packages/cli/src/lib/new/factories/backendPlugin.ts index c5cd043132..d7bf33b033 100644 --- a/packages/cli/src/lib/new/factories/backendPlugin.ts +++ b/packages/cli/src/lib/new/factories/backendPlugin.ts @@ -20,7 +20,7 @@ import camelCase from 'lodash/camelCase'; import { paths } from '../../paths'; import { addCodeownersEntry, getCodeownersFilePath } from '../../codeowners'; import { CreateContext, createFactory } from '../types'; -import { addPackageDependency, Task } from '../../tasks'; +import { addPackageDependency, addToBackend, Task } from '../../tasks'; import { ownerPrompt, pluginIdPrompt } from './common/prompts'; import { executePluginPackageTemplate } from './common/tasks'; import { resolvePackageName } from './common/util'; @@ -79,29 +79,9 @@ export const backendPlugin = createFactory({ ); }); - await Task.forItem('backend', 'adding plugin', async () => { - const backendFilePath = paths.resolveTargetRoot( - 'packages/backend/src/index.ts', - ); - if (!(await fs.pathExists(backendFilePath))) { - return; - } - - const content = await fs.readFile(backendFilePath, 'utf8'); - const lines = content.split('\n'); - const backendAddLine = `backend.add(import('${name}'));`; - - const backendStartIndex = lines.findIndex(line => - line.match(/backend.start/), - ); - - if (backendStartIndex !== -1) { - const [indentation] = lines[backendStartIndex].match(/^\s*/)!; - lines.splice(backendStartIndex, 0, `${indentation}${backendAddLine}`); - - const newContent = lines.join('\n'); - await fs.writeFile(backendFilePath, newContent, 'utf8'); - } + await addToBackend(name, { + defaultVersion: ctx.defaultVersion, + type: 'plugin', }); } diff --git a/packages/cli/src/lib/tasks.ts b/packages/cli/src/lib/tasks.ts index 851f962c62..84362d7856 100644 --- a/packages/cli/src/lib/tasks.ts +++ b/packages/cli/src/lib/tasks.ts @@ -196,3 +196,35 @@ export async function addPackageDependency( throw new Error(`Failed to add package dependencies, ${error}`); } } + +export async function addToBackend( + name: string, + ctx: { defaultVersion: string; type: 'plugin' | 'module' }, +) { + if (await fs.pathExists(paths.resolveTargetRoot('packages/backend'))) { + await Task.forItem('backend', `adding ${ctx.type}`, async () => { + const backendFilePath = paths.resolveTargetRoot( + 'packages/backend/src/index.ts', + ); + if (!(await fs.pathExists(backendFilePath))) { + return; + } + + const content = await fs.readFile(backendFilePath, 'utf8'); + const lines = content.split('\n'); + const backendAddLine = `backend.add(import('${name}'));`; + + const backendStartIndex = lines.findIndex(line => + line.match(/backend.start/), + ); + + if (backendStartIndex !== -1) { + const [indentation] = lines[backendStartIndex].match(/^\s*/)!; + lines.splice(backendStartIndex, 0, `${indentation}${backendAddLine}`); + + const newContent = lines.join('\n'); + await fs.writeFile(backendFilePath, newContent, 'utf8'); + } + }); + } +} From f812183f6cf19f1f4a2a1f204304d84e7f539e90 Mon Sep 17 00:00:00 2001 From: Alper Altay Date: Tue, 25 Jun 2024 12:41:53 +0200 Subject: [PATCH 089/510] chore: remove defaultversion Signed-off-by: Alper Altay --- packages/cli/src/lib/new/factories/backendModule.ts | 5 +---- packages/cli/src/lib/new/factories/backendPlugin.ts | 5 +---- packages/cli/src/lib/tasks.ts | 8 +++----- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/packages/cli/src/lib/new/factories/backendModule.ts b/packages/cli/src/lib/new/factories/backendModule.ts index 8cfa7f1e00..2ace64e165 100644 --- a/packages/cli/src/lib/new/factories/backendModule.ts +++ b/packages/cli/src/lib/new/factories/backendModule.ts @@ -91,10 +91,7 @@ export const backendModule = createFactory({ }); } - await addToBackend(name, { - defaultVersion: ctx.defaultVersion, - type: 'module', - }); + await addToBackend(name, 'module'); if (options.owner) { await addCodeownersEntry(`/plugins/${dirName}`, options.owner); diff --git a/packages/cli/src/lib/new/factories/backendPlugin.ts b/packages/cli/src/lib/new/factories/backendPlugin.ts index d7bf33b033..8671ef9952 100644 --- a/packages/cli/src/lib/new/factories/backendPlugin.ts +++ b/packages/cli/src/lib/new/factories/backendPlugin.ts @@ -79,10 +79,7 @@ export const backendPlugin = createFactory({ ); }); - await addToBackend(name, { - defaultVersion: ctx.defaultVersion, - type: 'plugin', - }); + await addToBackend(name, 'plugin'); } if (options.owner) { diff --git a/packages/cli/src/lib/tasks.ts b/packages/cli/src/lib/tasks.ts index 84362d7856..11cf53bf4f 100644 --- a/packages/cli/src/lib/tasks.ts +++ b/packages/cli/src/lib/tasks.ts @@ -23,6 +23,7 @@ import { basename, dirname } from 'path'; import recursive from 'recursive-readdir'; import { exec as execCb } from 'child_process'; import { assertError } from '@backstage/errors'; +import { paths } from './paths'; const exec = promisify(execCb); @@ -197,12 +198,9 @@ export async function addPackageDependency( } } -export async function addToBackend( - name: string, - ctx: { defaultVersion: string; type: 'plugin' | 'module' }, -) { +export async function addToBackend(name: string, type: 'plugin' | 'module') { if (await fs.pathExists(paths.resolveTargetRoot('packages/backend'))) { - await Task.forItem('backend', `adding ${ctx.type}`, async () => { + await Task.forItem('backend', `adding ${type}`, async () => { const backendFilePath = paths.resolveTargetRoot( 'packages/backend/src/index.ts', ); From 9572fe40dff9adcc953a1e4a3573d45c3919f308 Mon Sep 17 00:00:00 2001 From: Alper Altay Date: Tue, 25 Jun 2024 12:45:58 +0200 Subject: [PATCH 090/510] chore: options instead of positional args Signed-off-by: Alper Altay --- packages/cli/src/lib/new/factories/backendModule.ts | 4 +++- packages/cli/src/lib/new/factories/backendPlugin.ts | 4 +++- packages/cli/src/lib/tasks.ts | 9 +++++++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/lib/new/factories/backendModule.ts b/packages/cli/src/lib/new/factories/backendModule.ts index 2ace64e165..67860b812e 100644 --- a/packages/cli/src/lib/new/factories/backendModule.ts +++ b/packages/cli/src/lib/new/factories/backendModule.ts @@ -91,7 +91,9 @@ export const backendModule = createFactory({ }); } - await addToBackend(name, 'module'); + await addToBackend(name, { + type: 'module', + }); if (options.owner) { await addCodeownersEntry(`/plugins/${dirName}`, options.owner); diff --git a/packages/cli/src/lib/new/factories/backendPlugin.ts b/packages/cli/src/lib/new/factories/backendPlugin.ts index 8671ef9952..fc77896461 100644 --- a/packages/cli/src/lib/new/factories/backendPlugin.ts +++ b/packages/cli/src/lib/new/factories/backendPlugin.ts @@ -79,7 +79,9 @@ export const backendPlugin = createFactory({ ); }); - await addToBackend(name, 'plugin'); + await addToBackend(name, { + type: 'plugin', + }); } if (options.owner) { diff --git a/packages/cli/src/lib/tasks.ts b/packages/cli/src/lib/tasks.ts index 11cf53bf4f..ffff2892fb 100644 --- a/packages/cli/src/lib/tasks.ts +++ b/packages/cli/src/lib/tasks.ts @@ -198,9 +198,14 @@ export async function addPackageDependency( } } -export async function addToBackend(name: string, type: 'plugin' | 'module') { +export async function addToBackend( + name: string, + options: { + type: 'plugin' | 'module'; + }, +) { if (await fs.pathExists(paths.resolveTargetRoot('packages/backend'))) { - await Task.forItem('backend', `adding ${type}`, async () => { + await Task.forItem('backend', `adding ${options.type}`, async () => { const backendFilePath = paths.resolveTargetRoot( 'packages/backend/src/index.ts', ); From c4275d2d14b39750b47a44df48ee52d4d4744d3f Mon Sep 17 00:00:00 2001 From: Debabrata Panigrahi <50622005+Debanitrkl@users.noreply.github.com> Date: Tue, 25 Jun 2024 12:25:28 +0000 Subject: [PATCH 091/510] Signed-off-by: Debabrata Panigrahi <50622005+Debanitrkl@users.noreply.github.com> Fixed the incorrect plugin naming --- microsite/data/plugins/harness-chaos.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microsite/data/plugins/harness-chaos.yaml b/microsite/data/plugins/harness-chaos.yaml index ade6f9e566..e089b3d86b 100644 --- a/microsite/data/plugins/harness-chaos.yaml +++ b/microsite/data/plugins/harness-chaos.yaml @@ -1,4 +1,4 @@ -title: Harness Service Reliability Management +title: Harness Chaos Engineering author: harness.io authorUrl: https://github.com/harness/backstage-plugins category: Chaos Engineering From 37413c762fcc59eb1e2cbf47ef5bdce4a1f8b2d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 25 Jun 2024 15:45:59 +0200 Subject: [PATCH 092/510] OWNERS.md: add org member parsifal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- OWNERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/OWNERS.md b/OWNERS.md index 1437629881..9382b38f4f 100644 --- a/OWNERS.md +++ b/OWNERS.md @@ -187,6 +187,7 @@ Scope: The Scaffolder frontend and backend plugins, and related tooling. | Mark Avery | Cvent | [webark](https://github.com/webark) | `webark#8471` | | Miklós Kiss | Roadie.io | [kissmikijr](https://github.com/kissmikijr) | `Miklos#7416` | | Patrick Jungermann | Bonial International GmbH | [pjungermann](https://github.com/pjungermann) | `pjungermann#6933` | +| Peter Macdonald | VodafoneZiggo | [Parsifal-M](https://github.com/Parsifal-M) | `parsifal` | | Phil Kuang | FactSet Research Systems | [kuangp](https://github.com/kuangp) | `pkuang#3202` | | Sebastian Poxhofer | N26 | [secustor](https://github.com/secustor) | `secustor` | | Taras Mankovski | Frontside | [taras](https://github.com/taras) | `tarasm#1256` | From f9cdc108ec08d80490ac427e8fea2476a609726f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Wed, 26 Jun 2024 10:46:32 +0200 Subject: [PATCH 093/510] add vacation note MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 47ae539b6b..b422aec5fd 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ [![headline](docs/assets/headline.png)](https://backstage.io/) +> [!NOTE] +> 🏖 From July 1st through 16th, due to maintainers being on summer vacations, expect the project to move a little slower than normal, and support to be limited. Normal service will resume after that! 🏝 + # [Backstage](https://backstage.io) English \| [한국어](README-ko_kr.md) \| [中文版](README-zh_Hans.md) From e8c2fbb9ed28818cec130faab8b10a299d9f0ef1 Mon Sep 17 00:00:00 2001 From: Marek Libra Date: Wed, 26 Jun 2024 10:59:30 +0200 Subject: [PATCH 094/510] Set 001-notifications BEP to "implementable" Signed-off-by: Marek Libra --- beps/0001-notifications-system/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beps/0001-notifications-system/README.md b/beps/0001-notifications-system/README.md index 80751179dd..541e75e555 100644 --- a/beps/0001-notifications-system/README.md +++ b/beps/0001-notifications-system/README.md @@ -1,6 +1,6 @@ --- title: Backstage Notifications System -status: provisional +status: implementable authors: - '@Rugvip' - '@drodil' From 60caa9216d4becc5b93ca82ede7b6021c3ac9032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Wed, 26 Jun 2024 12:05:44 +0200 Subject: [PATCH 095/510] techdocs: fix double scroll bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/metal-parents-brush.md | 5 +++++ .../techdocs/src/reader/transformers/styles/rules/layout.ts | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 .changeset/metal-parents-brush.md diff --git a/.changeset/metal-parents-brush.md b/.changeset/metal-parents-brush.md new file mode 100644 index 0000000000..f73b0040fd --- /dev/null +++ b/.changeset/metal-parents-brush.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Fix double scrollbar bug in reader diff --git a/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts b/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts index d78f8222f8..78b73cb52a 100644 --- a/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts +++ b/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts @@ -74,6 +74,7 @@ export default ({ theme, sidebar }: RuleOptions) => ` } .md-sidebar .md-sidebar__scrollwrap { width: calc(12.1rem); + overflow-y: hidden; } .md-sidebar--secondary { right: ${theme.spacing(3)}px; @@ -234,7 +235,7 @@ export default ({ theme, sidebar }: RuleOptions) => ` #toggle-sidebar { display: none; } - + .md-content { margin: 0; width: 100%; From 546700b0c1acd565c089c6b8a9a89228d3f97909 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 26 Jun 2024 14:15:45 +0200 Subject: [PATCH 096/510] chore: some PR feedback suggestions Signed-off-by: blam --- .changeset/dry-squids-tap.md | 9 +- packages/frontend-plugin-api/api-report.md | 36 +++---- .../src/wiring/createExtension.ts | 4 +- .../src/wiring/createExtensionKind.test.tsx | 17 ++-- .../src/wiring/createExtensionKind.ts | 93 ++++++++++--------- .../frontend-plugin-api/src/wiring/index.ts | 2 +- 6 files changed, 84 insertions(+), 77 deletions(-) diff --git a/.changeset/dry-squids-tap.md b/.changeset/dry-squids-tap.md index a9eb7efb3b..5193e1f204 100644 --- a/.changeset/dry-squids-tap.md +++ b/.changeset/dry-squids-tap.md @@ -8,7 +8,7 @@ This allows the creation of extension with the following pattern: ```tsx // create the extension kind -const TestExtension = createExtensionKind({ +const TestExtensionKind = createExtensionKind({ kind: 'test-extension', attachTo: { id: 'test', input: 'default' }, output: { @@ -22,5 +22,10 @@ const TestExtension = createExtensionKind({ }); // create an instance of the extension kind with props -const testExtension = TestExtension.create({ text: 'Hello World' }); +const testExtension = TestExtensionKind.new({ + name: 'foo', + options: { + text: 'Hello World', + }, +}); ``` diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index b4c761ec05..48718f5375 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -524,13 +524,13 @@ export function createExtensionInput< // @public export function createExtensionKind< - TProps, + TOptions, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfig, >( - options: ExtensionKindOptions, -): ExtensionKind; + options: ExtensionKindOptions, +): ExtensionKind; // @public (undocumented) export interface CreateExtensionOptions< @@ -548,7 +548,7 @@ export interface CreateExtensionOptions< // (undocumented) disabled?: boolean; // (undocumented) - factory(options: { + factory(context: { node: AppNode; config: TConfig; inputs: Expand>; @@ -923,24 +923,24 @@ export interface ExtensionInput< extensionData: TExtensionData; } -// @public (undocumented) +// @public export class ExtensionKind< - TProps, + TOptions, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfig, > { // (undocumented) static create< - TProps, + TOptions, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfig, >( - options: ExtensionKindOptions, - ): ExtensionKind; + options: ExtensionKindOptions, + ): ExtensionKind; // (undocumented) - new(options: { + new(args: { namespace?: string; name?: string; attachTo?: { @@ -951,29 +951,29 @@ export class ExtensionKind< inputs?: TInputs; output?: TOutput; configSchema?: PortableSchema; - props: TProps; + options: TOptions; factory?( - options: { + context: { node: AppNode; config: TConfig; inputs: Expand>; orignalFactory( - options?: { + context?: { node?: AppNode; config?: TConfig; inputs?: Expand>; }, - props?: TProps, + options?: TOptions, ): Expand>; }, - props: TProps, + options: TOptions, ): Expand>; }): ExtensionDefinition; } // @public (undocumented) export interface ExtensionKindOptions< - TProps, + TOptions, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfig, @@ -989,12 +989,12 @@ export interface ExtensionKindOptions< disabled?: boolean; // (undocumented) factory( - options: { + context: { node: AppNode; config: TConfig; inputs: Expand>; }, - props: TProps, + options: TOptions, ): Expand>; // (undocumented) inputs?: TInputs; diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index be76fbc069..28dc6a4e29 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -91,7 +91,7 @@ export interface CreateExtensionOptions< inputs?: TInputs; output: TOutput; configSchema?: PortableSchema; - factory(options: { + factory(context: { node: AppNode; config: TConfig; inputs: Expand>; @@ -115,7 +115,7 @@ export interface InternalExtensionDefinition readonly version: 'v1'; readonly inputs: AnyExtensionInputMap; readonly output: AnyExtensionDataMap; - factory(options: { + factory(context: { node: AppNode; config: TConfig; inputs: ResolvedExtensionInputs; diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx b/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx index 2d5b218082..3bdcd3a7cc 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx +++ b/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import React from 'react'; import { coreExtensionData } from './coreExtensionData'; import { createExtensionKind } from './createExtensionKind'; @@ -26,16 +27,16 @@ describe('createExtensionKind', () => { output: { element: coreExtensionData.reactElement, }, - factory(_, props: { text: string }) { + factory(_, options: { text: string }) { return { - element:

    {props.text}

    , + element:

    {options.text}

    , }; }, }); const extension = TestExtension.new({ name: 'my-extension', - props: { + options: { text: 'Hello, world!', }, }); @@ -77,21 +78,21 @@ describe('createExtensionKind', () => { output: { element: coreExtensionData.reactElement, }, - factory(_, props: { text: string }) { + factory(_, options: { text: string }) { return { - element:

    {props.text}

    , + element:

    {options.text}

    , }; }, }); const extension = TestExtension.new({ name: 'my-extension', - props: { + options: { text: 'Hello, world!', }, - factory(_, props: { text: string }) { + factory(_, options: { text: string }) { return { - element:

    {props.text}

    , + element:

    {options.text}

    , }; }, }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts b/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts index 2067d18c04..52bf711822 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts @@ -1,14 +1,3 @@ -import { AppNode } from '../apis'; -import { PortableSchema } from '../schema'; -import { Expand } from '../types'; -import { - AnyExtensionDataMap, - AnyExtensionInputMap, - ExtensionDataValues, - ResolvedExtensionInputs, - createExtension, -} from './createExtension'; - /* * Copyright 2024 The Backstage Authors * @@ -25,11 +14,22 @@ import { * limitations under the License. */ +import { AppNode } from '../apis'; +import { PortableSchema } from '../schema'; +import { Expand } from '../types'; +import { + AnyExtensionDataMap, + AnyExtensionInputMap, + ExtensionDataValues, + ResolvedExtensionInputs, + createExtension, +} from './createExtension'; + /** * @public */ -export interface ExtensionKindOptions< - TProps, +export interface CreateExtensionKindOptions< + TOptions, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfig, @@ -43,45 +43,46 @@ export interface ExtensionKindOptions< output: TOutput; configSchema?: PortableSchema; factory( - options: { + context: { node: AppNode; config: TConfig; inputs: Expand>; }, - props: TProps, + options: TOptions, ): Expand>; } /** + * TODO: should we export an interface instead of a concrete class? * @public */ export class ExtensionKind< - TProps, + TOptions, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfig, > { static create< - TProps, + TOptions, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfig, >( - options: ExtensionKindOptions, - ): ExtensionKind { + options: CreateExtensionKindOptions, + ): ExtensionKind { return new ExtensionKind(options); } private constructor( - private readonly options: ExtensionKindOptions< - TProps, + private readonly options: CreateExtensionKindOptions< + TOptions, TInputs, TOutput, TConfig >, ) {} - public new(options: { + public new(args: { namespace?: string; name?: string; attachTo?: { id: string; input: string }; @@ -89,58 +90,58 @@ export class ExtensionKind< inputs?: TInputs; output?: TOutput; configSchema?: PortableSchema; - props: TProps; + options: TOptions; factory?( - options: { + context: { node: AppNode; config: TConfig; inputs: Expand>; orignalFactory( - options?: { + context?: { node?: AppNode; config?: TConfig; inputs?: Expand>; }, - props?: TProps, + options?: TOptions, ): Expand>; }, - props: TProps, + options: TOptions, ): Expand>; }) { return createExtension({ kind: this.options.kind, - namespace: options.namespace ?? this.options.namespace, - name: options.name ?? this.options.name, - attachTo: options.attachTo ?? this.options.attachTo, - disabled: options.disabled ?? this.options.disabled, - inputs: options.inputs ?? this.options.inputs, - output: options.output ?? this.options.output, - configSchema: options.configSchema ?? this.options.configSchema, // TODO: some config merging or smth + namespace: args.namespace ?? this.options.namespace, + name: args.name ?? this.options.name, + attachTo: args.attachTo ?? this.options.attachTo, + disabled: args.disabled ?? this.options.disabled, + inputs: args.inputs ?? this.options.inputs, + output: args.output ?? this.options.output, + configSchema: args.configSchema ?? this.options.configSchema, // TODO: some config merging or smth factory: ({ node, config, inputs }) => { - if (options.factory) { - return options.factory( + if (args.factory) { + return args.factory( { node, config, inputs, orignalFactory: ( - innerOptions?: { + innerContext?: { node?: AppNode; config?: TConfig; inputs?: Expand>; }, - innerProps?: TProps, + innerOptions?: TOptions, ) => this.options.factory( { - node: innerOptions?.node ?? node, - config: innerOptions?.config ?? config, - inputs: innerOptions?.inputs ?? inputs, + node: innerContext?.node ?? node, + config: innerContext?.config ?? config, + inputs: innerContext?.inputs ?? inputs, }, - innerProps ?? options.props, + innerOptions ?? args.options, ), }, - options.props, + args.options, ); } @@ -150,7 +151,7 @@ export class ExtensionKind< config, inputs, }, - options.props, + args.options, ); }, }); @@ -164,10 +165,10 @@ export class ExtensionKind< * @public */ export function createExtensionKind< - TProps, + TOptions, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfig, ->(options: ExtensionKindOptions) { +>(options: CreateExtensionKindOptions) { return ExtensionKind.create(options); } diff --git a/packages/frontend-plugin-api/src/wiring/index.ts b/packages/frontend-plugin-api/src/wiring/index.ts index e8c9afbaae..8fe9dc3a54 100644 --- a/packages/frontend-plugin-api/src/wiring/index.ts +++ b/packages/frontend-plugin-api/src/wiring/index.ts @@ -49,7 +49,7 @@ export { type FrontendFeature, } from './types'; export { - type ExtensionKindOptions, + type CreateExtensionKindOptions as ExtensionKindOptions, ExtensionKind, createExtensionKind, } from './createExtensionKind'; From 6fa652c88deafbc61ad27b79eea7e9f801c76cd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Wed, 26 Jun 2024 17:12:28 +0200 Subject: [PATCH 097/510] improve default docs sorting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/eleven-radios-begin.md | 5 +++++ .../src/home/components/Tables/DocsTable.tsx | 14 +++++++------- .../src/home/components/Tables/columns.tsx | 6 ++++++ 3 files changed, 18 insertions(+), 7 deletions(-) create mode 100644 .changeset/eleven-radios-begin.md diff --git a/.changeset/eleven-radios-begin.md b/.changeset/eleven-radios-begin.md new file mode 100644 index 0000000000..3fc2dd7895 --- /dev/null +++ b/.changeset/eleven-radios-begin.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Improve default sorting of docs table diff --git a/plugins/techdocs/src/home/components/Tables/DocsTable.tsx b/plugins/techdocs/src/home/components/Tables/DocsTable.tsx index c0b39878cd..de57c70e6a 100644 --- a/plugins/techdocs/src/home/components/Tables/DocsTable.tsx +++ b/plugins/techdocs/src/home/components/Tables/DocsTable.tsx @@ -51,6 +51,13 @@ export type DocsTableProps = { options?: TableOptions; }; +const defaultColumns: TableColumn[] = [ + columnFactories.createNameColumn(), + columnFactories.createOwnerColumn(), + columnFactories.createKindColumn(), + columnFactories.createTypeColumn(), +]; + /** * Component which renders a table documents * @@ -84,13 +91,6 @@ export const DocsTable = (props: DocsTableProps) => { }; }); - const defaultColumns: TableColumn[] = [ - columnFactories.createNameColumn(), - columnFactories.createOwnerColumn(), - columnFactories.createKindColumn(), - columnFactories.createTypeColumn(), - ]; - const defaultActions: TableProps['actions'] = [ actionFactories.createCopyDocsUrlAction(copyToClipboard), ]; diff --git a/plugins/techdocs/src/home/components/Tables/columns.tsx b/plugins/techdocs/src/home/components/Tables/columns.tsx index bc85bb7a63..8c8346b406 100644 --- a/plugins/techdocs/src/home/components/Tables/columns.tsx +++ b/plugins/techdocs/src/home/components/Tables/columns.tsx @@ -35,6 +35,12 @@ export const columnFactories = { title: 'Document', field: 'entity.metadata.name', highlight: true, + defaultSort: 'asc', + customSort: (row1, row2) => { + const title1 = customTitle(row1.entity).toLocaleLowerCase(); + const title2 = customTitle(row2.entity).toLocaleLowerCase(); + return title1.localeCompare(title2); + }, render: (row: DocsTableRow) => ( Date: Wed, 26 Jun 2024 17:48:55 +0000 Subject: [PATCH 098/510] Add OLX to ADOPTERS.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Márcio Eduardo Gomes Barbosa --- ADOPTERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ADOPTERS.md b/ADOPTERS.md index 5fe359bf1e..3ff0c5e1b5 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -271,3 +271,4 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [Scania](https://www.scania.com) | [Santosh Rangavajjula](https://linkedin.com/in/rsbth) | We are implementing backstage at Scania to consolidate operational information from Gitlab, Jira, Confluence, Artifactory, Servicenow and other tools into one place. | | [Senora.dev](https://senora.dev) | [Shaked Braimok Yosef](https://github.com/ShakedBraimok) | We are using Backstage as a service catalog for our costumers. | | [Covestro](https://www.covestro.com) | [Julien Gedeon](https://github.com/cvvcv1) | We use Backstage as our Internal developer portal for the Digital R&D department. | +| [Grupo OLX](https://www.olx.com.br/) | [@marciorgb](https://github.com/marciorgb), [@jeffbraga](https://github.com/jeffbraga), [@rogerfernandes](https://github.com/rogerfernandes), [@stockrt](https://github.com/stockrt) | At Grupo OLX, we are using Backstage to reduce friction and enhance developer autonomy by creating Golden Paths, which automate previously manual processes. Additionally, Backstage's catalog integrates various views of our organizational structure and workflows, offering a comprehensive overview of how different components interconnect. | From b9ed1bb50f734678d596d9800d3dda8b8ba6de53 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Wed, 5 Jun 2024 11:54:22 -0400 Subject: [PATCH 099/510] bump better-sqlite3 from ^9.0.0 to ^11.0.0 Signed-off-by: Karl Haworth --- .changeset/weak-boats-float.md | 9 +++++++++ packages/backend-common/package.json | 2 +- packages/backend-defaults/package.json | 2 +- packages/backend-legacy/package.json | 2 +- packages/backend-test-utils/package.json | 2 +- plugins/catalog-backend/package.json | 2 +- yarn.lock | 18 +++++++++--------- 7 files changed, 23 insertions(+), 14 deletions(-) create mode 100644 .changeset/weak-boats-float.md diff --git a/.changeset/weak-boats-float.md b/.changeset/weak-boats-float.md new file mode 100644 index 0000000000..c4c41c5922 --- /dev/null +++ b/.changeset/weak-boats-float.md @@ -0,0 +1,9 @@ +--- +'@backstage/plugin-catalog-backend': minor +'@backstage/backend-test-utils': patch +'@backstage/backend-defaults': patch +'@backstage/backend-common': patch +'example-backend-legacy': patch +--- + +bumped better-sqlite3 from ^9.0.0 to ^11.0.0 diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 7944477c88..28378f6c41 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -137,7 +137,7 @@ "@types/webpack-env": "^1.15.2", "@types/yauzl": "^2.10.0", "aws-sdk-client-mock": "^4.0.0", - "better-sqlite3": "^9.0.0", + "better-sqlite3": "^11.0.0", "http-errors": "^2.0.0", "msw": "^1.0.0", "mysql2": "^3.0.0", diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index 376aa9d36f..824f1893bd 100644 --- a/packages/backend-defaults/package.json +++ b/packages/backend-defaults/package.json @@ -143,7 +143,7 @@ "@types/express": "^4.17.6", "archiver": "^6.0.0", "base64-stream": "^1.0.0", - "better-sqlite3": "^9.0.0", + "better-sqlite3": "^11.0.0", "compression": "^1.7.4", "concat-stream": "^2.0.0", "cookie": "^0.6.0", diff --git a/packages/backend-legacy/package.json b/packages/backend-legacy/package.json index c8b019848f..6b9bb3523a 100644 --- a/packages/backend-legacy/package.json +++ b/packages/backend-legacy/package.json @@ -66,7 +66,7 @@ "@gitbeaker/node": "^35.1.0", "@octokit/rest": "^19.0.3", "azure-devops-node-api": "^12.0.0", - "better-sqlite3": "^9.0.0", + "better-sqlite3": "^11.0.0", "dockerode": "^4.0.0", "example-app": "link:../app", "express": "^4.17.1", diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index 47f2c9c628..540b4f9ee4 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -56,7 +56,7 @@ "@keyv/memcache": "^1.3.5", "@keyv/redis": "^2.5.3", "@types/keyv": "^4.2.0", - "better-sqlite3": "^9.0.0", + "better-sqlite3": "^11.0.0", "cookie": "^0.6.0", "express": "^4.17.1", "fs-extra": "^11.0.0", diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index d9bc71ae91..596e51435e 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -110,7 +110,7 @@ "@types/lodash": "^4.14.151", "@types/supertest": "^2.0.8", "@types/uuid": "^9.0.0", - "better-sqlite3": "^9.0.0", + "better-sqlite3": "^11.0.0", "luxon": "^3.0.0", "msw": "^1.0.0", "supertest": "^6.1.3", diff --git a/yarn.lock b/yarn.lock index 912220ac86..fec9c84b79 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3559,7 +3559,7 @@ __metadata: archiver: ^6.0.0 aws-sdk-client-mock: ^4.0.0 base64-stream: ^1.0.0 - better-sqlite3: ^9.0.0 + better-sqlite3: ^11.0.0 compression: ^1.7.4 concat-stream: ^2.0.0 cors: ^2.8.5 @@ -3647,7 +3647,7 @@ __metadata: archiver: ^6.0.0 aws-sdk-client-mock: ^4.0.0 base64-stream: ^1.0.0 - better-sqlite3: ^9.0.0 + better-sqlite3: ^11.0.0 compression: ^1.7.4 concat-stream: ^2.0.0 cookie: ^0.6.0 @@ -3818,7 +3818,7 @@ __metadata: "@keyv/redis": ^2.5.3 "@types/keyv": ^4.2.0 "@types/supertest": ^2.0.8 - better-sqlite3: ^9.0.0 + better-sqlite3: ^11.0.0 cookie: ^0.6.0 express: ^4.17.1 fs-extra: ^11.0.0 @@ -5694,7 +5694,7 @@ __metadata: "@types/lodash": ^4.14.151 "@types/supertest": ^2.0.8 "@types/uuid": ^9.0.0 - better-sqlite3: ^9.0.0 + better-sqlite3: ^11.0.0 codeowners-utils: ^1.0.2 core-js: ^3.6.5 express: ^4.17.1 @@ -21618,14 +21618,14 @@ __metadata: languageName: node linkType: hard -"better-sqlite3@npm:^9.0.0": - version: 9.6.0 - resolution: "better-sqlite3@npm:9.6.0" +"better-sqlite3@npm:^11.0.0": + version: 11.0.0 + resolution: "better-sqlite3@npm:11.0.0" dependencies: bindings: ^1.5.0 node-gyp: latest prebuild-install: ^7.1.1 - checksum: be3a1d2a3f6f9b5141be6607a38c0a51fa5849495b071955e507bc0c2a2fb08430852c1bf03796eec1a53344b25645807db48dcb51c71b0662b74c5a70420bb0 + checksum: 7bf02ea6ba3253f53cb36bd872f86379ebf1a66cb103d39b91c610995c4396dde2b976bdf866f07eb7d67eb6f5433aa5490a6a4f4264244f83a53562f68832dc languageName: node linkType: hard @@ -26624,7 +26624,7 @@ __metadata: "@types/express-serve-static-core": ^4.17.5 "@types/luxon": ^3.0.0 azure-devops-node-api: ^12.0.0 - better-sqlite3: ^9.0.0 + better-sqlite3: ^11.0.0 dockerode: ^4.0.0 example-app: "link:../app" express: ^4.17.1 From f16e1b4d39e2081d373c7adabd1d0683fcafac23 Mon Sep 17 00:00:00 2001 From: Karl Haworth Date: Fri, 7 Jun 2024 10:40:09 -0400 Subject: [PATCH 100/510] remove changeset item per goalie Signed-off-by: Karl Haworth --- .changeset/weak-boats-float.md | 1 - 1 file changed, 1 deletion(-) diff --git a/.changeset/weak-boats-float.md b/.changeset/weak-boats-float.md index c4c41c5922..4fe6fe73a0 100644 --- a/.changeset/weak-boats-float.md +++ b/.changeset/weak-boats-float.md @@ -3,7 +3,6 @@ '@backstage/backend-test-utils': patch '@backstage/backend-defaults': patch '@backstage/backend-common': patch -'example-backend-legacy': patch --- bumped better-sqlite3 from ^9.0.0 to ^11.0.0 From 616932aa47c2e31db6990c9970f6f9fac62a079d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 26 Jun 2024 21:50:24 +0000 Subject: [PATCH 101/510] fix(deps): update aws-sdk-js-v3 monorepo Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 2164 ++++++++++++++++++++++++++++------------------------- 1 file changed, 1127 insertions(+), 1037 deletions(-) diff --git a/yarn.lock b/yarn.lock index 912220ac86..08218f6ee9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -385,69 +385,58 @@ __metadata: languageName: node linkType: hard -"@aws-crypto/crc32c@npm:3.0.0": - version: 3.0.0 - resolution: "@aws-crypto/crc32c@npm:3.0.0" +"@aws-crypto/crc32@npm:5.2.0": + version: 5.2.0 + resolution: "@aws-crypto/crc32@npm:5.2.0" dependencies: - "@aws-crypto/util": ^3.0.0 + "@aws-crypto/util": ^5.2.0 "@aws-sdk/types": ^3.222.0 - tslib: ^1.11.1 - checksum: 0a116b5d1c5b09a3dde65aab04a07b32f543e87b68f2d175081e3f4a1a17502343f223d691dd883ace1ddce65cd40093673e7c7415dcd99062202ba87ffb4038 + tslib: ^2.6.2 + checksum: 1ddf7ec3fccf106205ff2476d90ae1d6625eabd47752f689c761b71e41fe451962b7a1c9ed25fe54e17dd747a62fbf4de06030fe56fe625f95285f6f70b96c57 languageName: node linkType: hard -"@aws-crypto/ie11-detection@npm:^3.0.0": - version: 3.0.0 - resolution: "@aws-crypto/ie11-detection@npm:3.0.0" +"@aws-crypto/crc32c@npm:5.2.0": + version: 5.2.0 + resolution: "@aws-crypto/crc32c@npm:5.2.0" dependencies: - tslib: ^1.11.1 - checksum: 299b2ddd46eddac1f2d54d91386ceb37af81aef8a800669281c73d634ed17fd855dcfb8b3157f2879344b93a2666a6d602550eb84b71e4d7868100ad6da8f803 + "@aws-crypto/util": ^5.2.0 + "@aws-sdk/types": ^3.222.0 + tslib: ^2.6.2 + checksum: 0b399de8607c59e1e46c05d2b24a16b56d507944fdac925c611f0ba7302f5555c098139806d7da1ebef1f89bf4e4b5d4dec74d4809ce0f18238b72072065effe languageName: node linkType: hard -"@aws-crypto/sha1-browser@npm:3.0.0": - version: 3.0.0 - resolution: "@aws-crypto/sha1-browser@npm:3.0.0" +"@aws-crypto/sha1-browser@npm:5.2.0": + version: 5.2.0 + resolution: "@aws-crypto/sha1-browser@npm:5.2.0" dependencies: - "@aws-crypto/ie11-detection": ^3.0.0 - "@aws-crypto/supports-web-crypto": ^3.0.0 - "@aws-crypto/util": ^3.0.0 + "@aws-crypto/supports-web-crypto": ^5.2.0 + "@aws-crypto/util": ^5.2.0 "@aws-sdk/types": ^3.222.0 "@aws-sdk/util-locate-window": ^3.0.0 - "@aws-sdk/util-utf8-browser": ^3.0.0 - tslib: ^1.11.1 - checksum: 78c379e105a0c4e7b2ed745dffd8f55054d7dde8b350b61de682bbc3cd081a50e2f87861954fa9cd53c7ea711ebca1ca0137b14cb36483efc971f60f573cf129 + "@smithy/util-utf8": ^2.0.0 + tslib: ^2.6.2 + checksum: 8b04af601d945c5ef0f5f733b55681edc95b81c02ce5067b57f1eb4ee718e45485cf9aeeb7a84da9131656d09e1c4bc78040ec759f557a46703422d8df098d59 languageName: node linkType: hard -"@aws-crypto/sha256-browser@npm:3.0.0": - version: 3.0.0 - resolution: "@aws-crypto/sha256-browser@npm:3.0.0" +"@aws-crypto/sha256-browser@npm:5.2.0": + version: 5.2.0 + resolution: "@aws-crypto/sha256-browser@npm:5.2.0" dependencies: - "@aws-crypto/ie11-detection": ^3.0.0 - "@aws-crypto/sha256-js": ^3.0.0 - "@aws-crypto/supports-web-crypto": ^3.0.0 - "@aws-crypto/util": ^3.0.0 + "@aws-crypto/sha256-js": ^5.2.0 + "@aws-crypto/supports-web-crypto": ^5.2.0 + "@aws-crypto/util": ^5.2.0 "@aws-sdk/types": ^3.222.0 "@aws-sdk/util-locate-window": ^3.0.0 - "@aws-sdk/util-utf8-browser": ^3.0.0 - tslib: ^1.11.1 - checksum: ca89456bf508db2e08060a7f656460db97ac9a15b11e39d6fa7665e2b156508a1758695bff8e82d0a00178d6ac5c36f35eb4bcfac2e48621265224ca14a19bd2 + "@smithy/util-utf8": ^2.0.0 + tslib: ^2.6.2 + checksum: 773f12f2026d82a6bb4a23a8f491894a6d32525bd9b8bfbc12896526cf11882a7607a671c478c45f9cd7d6ba1caaed48a62b67c6f725244bd83a1275108f46c7 languageName: node linkType: hard -"@aws-crypto/sha256-js@npm:3.0.0, @aws-crypto/sha256-js@npm:^3.0.0": - version: 3.0.0 - resolution: "@aws-crypto/sha256-js@npm:3.0.0" - dependencies: - "@aws-crypto/util": ^3.0.0 - "@aws-sdk/types": ^3.222.0 - tslib: ^1.11.1 - checksum: 644ded32ea310237811afae873d3c7320739cb6f6cc39dced9c94801379e68e5ee2cca0c34f0384793fa9e750a7e0a5e2468f95754bd08e6fd72ab833c8fe23c - languageName: node - linkType: hard - -"@aws-crypto/sha256-js@npm:^5.0.0": +"@aws-crypto/sha256-js@npm:5.2.0, @aws-crypto/sha256-js@npm:^5.0.0, @aws-crypto/sha256-js@npm:^5.2.0": version: 5.2.0 resolution: "@aws-crypto/sha256-js@npm:5.2.0" dependencies: @@ -458,12 +447,12 @@ __metadata: languageName: node linkType: hard -"@aws-crypto/supports-web-crypto@npm:^3.0.0": - version: 3.0.0 - resolution: "@aws-crypto/supports-web-crypto@npm:3.0.0" +"@aws-crypto/supports-web-crypto@npm:^5.2.0": + version: 5.2.0 + resolution: "@aws-crypto/supports-web-crypto@npm:5.2.0" dependencies: - tslib: ^1.11.1 - checksum: 35479a1558db9e9a521df6877a99f95670e972c602f2a0349303477e5d638a5baf569fb037c853710e382086e6fd77e8ed58d3fb9b49f6e1186a9d26ce7be006 + tslib: ^2.6.2 + checksum: 6ffc21de48b2b2c3e918193101d7e8fe949d47b37688892e1c39eaedaa938be80c0f404fe1c874c30cce16781026777a53bf47d5d90143ca91d0feb7c4a6f830 languageName: node linkType: hard @@ -500,665 +489,674 @@ __metadata: linkType: hard "@aws-sdk/client-codecommit@npm:^3.350.0": - version: 3.556.0 - resolution: "@aws-sdk/client-codecommit@npm:3.556.0" + version: 3.600.0 + resolution: "@aws-sdk/client-codecommit@npm:3.600.0" dependencies: - "@aws-crypto/sha256-browser": 3.0.0 - "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.556.0 - "@aws-sdk/core": 3.556.0 - "@aws-sdk/credential-provider-node": 3.556.0 - "@aws-sdk/middleware-host-header": 3.535.0 - "@aws-sdk/middleware-logger": 3.535.0 - "@aws-sdk/middleware-recursion-detection": 3.535.0 - "@aws-sdk/middleware-user-agent": 3.540.0 - "@aws-sdk/region-config-resolver": 3.535.0 - "@aws-sdk/types": 3.535.0 - "@aws-sdk/util-endpoints": 3.540.0 - "@aws-sdk/util-user-agent-browser": 3.535.0 - "@aws-sdk/util-user-agent-node": 3.535.0 - "@smithy/config-resolver": ^2.2.0 - "@smithy/core": ^1.4.2 - "@smithy/fetch-http-handler": ^2.5.0 - "@smithy/hash-node": ^2.2.0 - "@smithy/invalid-dependency": ^2.2.0 - "@smithy/middleware-content-length": ^2.2.0 - "@smithy/middleware-endpoint": ^2.5.1 - "@smithy/middleware-retry": ^2.3.1 - "@smithy/middleware-serde": ^2.3.0 - "@smithy/middleware-stack": ^2.2.0 - "@smithy/node-config-provider": ^2.3.0 - "@smithy/node-http-handler": ^2.5.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/smithy-client": ^2.5.1 - "@smithy/types": ^2.12.0 - "@smithy/url-parser": ^2.2.0 - "@smithy/util-base64": ^2.3.0 - "@smithy/util-body-length-browser": ^2.2.0 - "@smithy/util-body-length-node": ^2.3.0 - "@smithy/util-defaults-mode-browser": ^2.2.1 - "@smithy/util-defaults-mode-node": ^2.3.1 - "@smithy/util-endpoints": ^1.2.0 - "@smithy/util-middleware": ^2.2.0 - "@smithy/util-retry": ^2.2.0 - "@smithy/util-utf8": ^2.3.0 + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/client-sso-oidc": 3.600.0 + "@aws-sdk/client-sts": 3.600.0 + "@aws-sdk/core": 3.598.0 + "@aws-sdk/credential-provider-node": 3.600.0 + "@aws-sdk/middleware-host-header": 3.598.0 + "@aws-sdk/middleware-logger": 3.598.0 + "@aws-sdk/middleware-recursion-detection": 3.598.0 + "@aws-sdk/middleware-user-agent": 3.598.0 + "@aws-sdk/region-config-resolver": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-endpoints": 3.598.0 + "@aws-sdk/util-user-agent-browser": 3.598.0 + "@aws-sdk/util-user-agent-node": 3.598.0 + "@smithy/config-resolver": ^3.0.2 + "@smithy/core": ^2.2.1 + "@smithy/fetch-http-handler": ^3.0.2 + "@smithy/hash-node": ^3.0.1 + "@smithy/invalid-dependency": ^3.0.1 + "@smithy/middleware-content-length": ^3.0.1 + "@smithy/middleware-endpoint": ^3.0.2 + "@smithy/middleware-retry": ^3.0.4 + "@smithy/middleware-serde": ^3.0.1 + "@smithy/middleware-stack": ^3.0.1 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/node-http-handler": ^3.0.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/url-parser": ^3.0.1 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.4 + "@smithy/util-defaults-mode-node": ^3.0.4 + "@smithy/util-endpoints": ^2.0.2 + "@smithy/util-middleware": ^3.0.1 + "@smithy/util-retry": ^3.0.1 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 uuid: ^9.0.1 - checksum: 09a7393ba36cf0eaf527041580e468b62346634768ee1ced243e5e894d6a532f96332642ddc1965c9e2078cbe4183c84bc6003a427a05e6ea781ceff5c143e0d + checksum: 1a8197ffcf74b27a4b6159d8b4923db0f5c27b3d5daacb321ef956c49b0250800ce904c1c03264c67366c14244a8ba7a067849700b382979da19f7bc4c20a3fd languageName: node linkType: hard -"@aws-sdk/client-cognito-identity@npm:3.556.0": - version: 3.556.0 - resolution: "@aws-sdk/client-cognito-identity@npm:3.556.0" +"@aws-sdk/client-cognito-identity@npm:3.600.0": + version: 3.600.0 + resolution: "@aws-sdk/client-cognito-identity@npm:3.600.0" dependencies: - "@aws-crypto/sha256-browser": 3.0.0 - "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.556.0 - "@aws-sdk/core": 3.556.0 - "@aws-sdk/credential-provider-node": 3.556.0 - "@aws-sdk/middleware-host-header": 3.535.0 - "@aws-sdk/middleware-logger": 3.535.0 - "@aws-sdk/middleware-recursion-detection": 3.535.0 - "@aws-sdk/middleware-user-agent": 3.540.0 - "@aws-sdk/region-config-resolver": 3.535.0 - "@aws-sdk/types": 3.535.0 - "@aws-sdk/util-endpoints": 3.540.0 - "@aws-sdk/util-user-agent-browser": 3.535.0 - "@aws-sdk/util-user-agent-node": 3.535.0 - "@smithy/config-resolver": ^2.2.0 - "@smithy/core": ^1.4.2 - "@smithy/fetch-http-handler": ^2.5.0 - "@smithy/hash-node": ^2.2.0 - "@smithy/invalid-dependency": ^2.2.0 - "@smithy/middleware-content-length": ^2.2.0 - "@smithy/middleware-endpoint": ^2.5.1 - "@smithy/middleware-retry": ^2.3.1 - "@smithy/middleware-serde": ^2.3.0 - "@smithy/middleware-stack": ^2.2.0 - "@smithy/node-config-provider": ^2.3.0 - "@smithy/node-http-handler": ^2.5.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/smithy-client": ^2.5.1 - "@smithy/types": ^2.12.0 - "@smithy/url-parser": ^2.2.0 - "@smithy/util-base64": ^2.3.0 - "@smithy/util-body-length-browser": ^2.2.0 - "@smithy/util-body-length-node": ^2.3.0 - "@smithy/util-defaults-mode-browser": ^2.2.1 - "@smithy/util-defaults-mode-node": ^2.3.1 - "@smithy/util-endpoints": ^1.2.0 - "@smithy/util-middleware": ^2.2.0 - "@smithy/util-retry": ^2.2.0 - "@smithy/util-utf8": ^2.3.0 + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/client-sso-oidc": 3.600.0 + "@aws-sdk/client-sts": 3.600.0 + "@aws-sdk/core": 3.598.0 + "@aws-sdk/credential-provider-node": 3.600.0 + "@aws-sdk/middleware-host-header": 3.598.0 + "@aws-sdk/middleware-logger": 3.598.0 + "@aws-sdk/middleware-recursion-detection": 3.598.0 + "@aws-sdk/middleware-user-agent": 3.598.0 + "@aws-sdk/region-config-resolver": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-endpoints": 3.598.0 + "@aws-sdk/util-user-agent-browser": 3.598.0 + "@aws-sdk/util-user-agent-node": 3.598.0 + "@smithy/config-resolver": ^3.0.2 + "@smithy/core": ^2.2.1 + "@smithy/fetch-http-handler": ^3.0.2 + "@smithy/hash-node": ^3.0.1 + "@smithy/invalid-dependency": ^3.0.1 + "@smithy/middleware-content-length": ^3.0.1 + "@smithy/middleware-endpoint": ^3.0.2 + "@smithy/middleware-retry": ^3.0.4 + "@smithy/middleware-serde": ^3.0.1 + "@smithy/middleware-stack": ^3.0.1 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/node-http-handler": ^3.0.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/url-parser": ^3.0.1 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.4 + "@smithy/util-defaults-mode-node": ^3.0.4 + "@smithy/util-endpoints": ^2.0.2 + "@smithy/util-middleware": ^3.0.1 + "@smithy/util-retry": ^3.0.1 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 964ee562d41df0fc3d71a739ef86846dddbfa8742df74831926dd629de0111ace69faed4869d9b7a50cd5eb8d2c1ac09da2126b7071e9d69f8ba8e8d85d24323 + checksum: ad01c387061da6d46767e209f3d422281e6af97d60ed61af687980990c7600ecbd88e2f430d975f029648d4475bf84234f710f4099edd2d61f90fef3444ee4a0 languageName: node linkType: hard "@aws-sdk/client-eks@npm:^3.350.0": - version: 3.556.0 - resolution: "@aws-sdk/client-eks@npm:3.556.0" + version: 3.605.0 + resolution: "@aws-sdk/client-eks@npm:3.605.0" dependencies: - "@aws-crypto/sha256-browser": 3.0.0 - "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.556.0 - "@aws-sdk/core": 3.556.0 - "@aws-sdk/credential-provider-node": 3.556.0 - "@aws-sdk/middleware-host-header": 3.535.0 - "@aws-sdk/middleware-logger": 3.535.0 - "@aws-sdk/middleware-recursion-detection": 3.535.0 - "@aws-sdk/middleware-user-agent": 3.540.0 - "@aws-sdk/region-config-resolver": 3.535.0 - "@aws-sdk/types": 3.535.0 - "@aws-sdk/util-endpoints": 3.540.0 - "@aws-sdk/util-user-agent-browser": 3.535.0 - "@aws-sdk/util-user-agent-node": 3.535.0 - "@smithy/config-resolver": ^2.2.0 - "@smithy/core": ^1.4.2 - "@smithy/fetch-http-handler": ^2.5.0 - "@smithy/hash-node": ^2.2.0 - "@smithy/invalid-dependency": ^2.2.0 - "@smithy/middleware-content-length": ^2.2.0 - "@smithy/middleware-endpoint": ^2.5.1 - "@smithy/middleware-retry": ^2.3.1 - "@smithy/middleware-serde": ^2.3.0 - "@smithy/middleware-stack": ^2.2.0 - "@smithy/node-config-provider": ^2.3.0 - "@smithy/node-http-handler": ^2.5.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/smithy-client": ^2.5.1 - "@smithy/types": ^2.12.0 - "@smithy/url-parser": ^2.2.0 - "@smithy/util-base64": ^2.3.0 - "@smithy/util-body-length-browser": ^2.2.0 - "@smithy/util-body-length-node": ^2.3.0 - "@smithy/util-defaults-mode-browser": ^2.2.1 - "@smithy/util-defaults-mode-node": ^2.3.1 - "@smithy/util-endpoints": ^1.2.0 - "@smithy/util-middleware": ^2.2.0 - "@smithy/util-retry": ^2.2.0 - "@smithy/util-utf8": ^2.3.0 - "@smithy/util-waiter": ^2.2.0 + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/client-sso-oidc": 3.600.0 + "@aws-sdk/client-sts": 3.600.0 + "@aws-sdk/core": 3.598.0 + "@aws-sdk/credential-provider-node": 3.600.0 + "@aws-sdk/middleware-host-header": 3.598.0 + "@aws-sdk/middleware-logger": 3.598.0 + "@aws-sdk/middleware-recursion-detection": 3.598.0 + "@aws-sdk/middleware-user-agent": 3.598.0 + "@aws-sdk/region-config-resolver": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-endpoints": 3.598.0 + "@aws-sdk/util-user-agent-browser": 3.598.0 + "@aws-sdk/util-user-agent-node": 3.598.0 + "@smithy/config-resolver": ^3.0.2 + "@smithy/core": ^2.2.1 + "@smithy/fetch-http-handler": ^3.0.2 + "@smithy/hash-node": ^3.0.1 + "@smithy/invalid-dependency": ^3.0.1 + "@smithy/middleware-content-length": ^3.0.1 + "@smithy/middleware-endpoint": ^3.0.2 + "@smithy/middleware-retry": ^3.0.4 + "@smithy/middleware-serde": ^3.0.1 + "@smithy/middleware-stack": ^3.0.1 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/node-http-handler": ^3.0.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/url-parser": ^3.0.1 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.4 + "@smithy/util-defaults-mode-node": ^3.0.4 + "@smithy/util-endpoints": ^2.0.2 + "@smithy/util-middleware": ^3.0.1 + "@smithy/util-retry": ^3.0.1 + "@smithy/util-utf8": ^3.0.0 + "@smithy/util-waiter": ^3.0.1 tslib: ^2.6.2 uuid: ^9.0.1 - checksum: c36a0f23d3f01ed9fcbeec286b5e919cacc2ecb0bb3e880844e9b84018d81935c4b8f3dc33a3392c808a6e001659f5ca0c99889d830491c48040b9df3d474cc8 + checksum: 6cd87756d631fd18b12d21a89a938612ba17446cdc1de06c3c3a0ee488ffd8c9de4af3d27567524eb0e17155d423394e374002cb5a45d4376df6d82255abe870 languageName: node linkType: hard "@aws-sdk/client-organizations@npm:^3.350.0": - version: 3.556.0 - resolution: "@aws-sdk/client-organizations@npm:3.556.0" + version: 3.600.0 + resolution: "@aws-sdk/client-organizations@npm:3.600.0" dependencies: - "@aws-crypto/sha256-browser": 3.0.0 - "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.556.0 - "@aws-sdk/core": 3.556.0 - "@aws-sdk/credential-provider-node": 3.556.0 - "@aws-sdk/middleware-host-header": 3.535.0 - "@aws-sdk/middleware-logger": 3.535.0 - "@aws-sdk/middleware-recursion-detection": 3.535.0 - "@aws-sdk/middleware-user-agent": 3.540.0 - "@aws-sdk/region-config-resolver": 3.535.0 - "@aws-sdk/types": 3.535.0 - "@aws-sdk/util-endpoints": 3.540.0 - "@aws-sdk/util-user-agent-browser": 3.535.0 - "@aws-sdk/util-user-agent-node": 3.535.0 - "@smithy/config-resolver": ^2.2.0 - "@smithy/core": ^1.4.2 - "@smithy/fetch-http-handler": ^2.5.0 - "@smithy/hash-node": ^2.2.0 - "@smithy/invalid-dependency": ^2.2.0 - "@smithy/middleware-content-length": ^2.2.0 - "@smithy/middleware-endpoint": ^2.5.1 - "@smithy/middleware-retry": ^2.3.1 - "@smithy/middleware-serde": ^2.3.0 - "@smithy/middleware-stack": ^2.2.0 - "@smithy/node-config-provider": ^2.3.0 - "@smithy/node-http-handler": ^2.5.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/smithy-client": ^2.5.1 - "@smithy/types": ^2.12.0 - "@smithy/url-parser": ^2.2.0 - "@smithy/util-base64": ^2.3.0 - "@smithy/util-body-length-browser": ^2.2.0 - "@smithy/util-body-length-node": ^2.3.0 - "@smithy/util-defaults-mode-browser": ^2.2.1 - "@smithy/util-defaults-mode-node": ^2.3.1 - "@smithy/util-endpoints": ^1.2.0 - "@smithy/util-middleware": ^2.2.0 - "@smithy/util-retry": ^2.2.0 - "@smithy/util-utf8": ^2.3.0 + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/client-sso-oidc": 3.600.0 + "@aws-sdk/client-sts": 3.600.0 + "@aws-sdk/core": 3.598.0 + "@aws-sdk/credential-provider-node": 3.600.0 + "@aws-sdk/middleware-host-header": 3.598.0 + "@aws-sdk/middleware-logger": 3.598.0 + "@aws-sdk/middleware-recursion-detection": 3.598.0 + "@aws-sdk/middleware-user-agent": 3.598.0 + "@aws-sdk/region-config-resolver": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-endpoints": 3.598.0 + "@aws-sdk/util-user-agent-browser": 3.598.0 + "@aws-sdk/util-user-agent-node": 3.598.0 + "@smithy/config-resolver": ^3.0.2 + "@smithy/core": ^2.2.1 + "@smithy/fetch-http-handler": ^3.0.2 + "@smithy/hash-node": ^3.0.1 + "@smithy/invalid-dependency": ^3.0.1 + "@smithy/middleware-content-length": ^3.0.1 + "@smithy/middleware-endpoint": ^3.0.2 + "@smithy/middleware-retry": ^3.0.4 + "@smithy/middleware-serde": ^3.0.1 + "@smithy/middleware-stack": ^3.0.1 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/node-http-handler": ^3.0.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/url-parser": ^3.0.1 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.4 + "@smithy/util-defaults-mode-node": ^3.0.4 + "@smithy/util-endpoints": ^2.0.2 + "@smithy/util-middleware": ^3.0.1 + "@smithy/util-retry": ^3.0.1 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: e747d1f2f75a9985944765ac920408bffe5fc79dfb700c56b1633fec4e6f480b9568e30f72a6c80f09dcb7998480f158fa5c40646e8af4fed4a68e694d78c4f8 + checksum: b403a51e298fec8ec93553ac8a22a452408b0634b3a01d6c61ce271d7af69b1cef8907a9dce31fad79fa2cfc01fd6912d848e9b656b7a16f973e986b00bd727c languageName: node linkType: hard "@aws-sdk/client-s3@npm:^3.350.0": - version: 3.556.0 - resolution: "@aws-sdk/client-s3@npm:3.556.0" + version: 3.600.0 + resolution: "@aws-sdk/client-s3@npm:3.600.0" dependencies: - "@aws-crypto/sha1-browser": 3.0.0 - "@aws-crypto/sha256-browser": 3.0.0 - "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.556.0 - "@aws-sdk/core": 3.556.0 - "@aws-sdk/credential-provider-node": 3.556.0 - "@aws-sdk/middleware-bucket-endpoint": 3.535.0 - "@aws-sdk/middleware-expect-continue": 3.535.0 - "@aws-sdk/middleware-flexible-checksums": 3.535.0 - "@aws-sdk/middleware-host-header": 3.535.0 - "@aws-sdk/middleware-location-constraint": 3.535.0 - "@aws-sdk/middleware-logger": 3.535.0 - "@aws-sdk/middleware-recursion-detection": 3.535.0 - "@aws-sdk/middleware-sdk-s3": 3.556.0 - "@aws-sdk/middleware-signing": 3.556.0 - "@aws-sdk/middleware-ssec": 3.537.0 - "@aws-sdk/middleware-user-agent": 3.540.0 - "@aws-sdk/region-config-resolver": 3.535.0 - "@aws-sdk/signature-v4-multi-region": 3.556.0 - "@aws-sdk/types": 3.535.0 - "@aws-sdk/util-endpoints": 3.540.0 - "@aws-sdk/util-user-agent-browser": 3.535.0 - "@aws-sdk/util-user-agent-node": 3.535.0 - "@aws-sdk/xml-builder": 3.535.0 - "@smithy/config-resolver": ^2.2.0 - "@smithy/core": ^1.4.2 - "@smithy/eventstream-serde-browser": ^2.2.0 - "@smithy/eventstream-serde-config-resolver": ^2.2.0 - "@smithy/eventstream-serde-node": ^2.2.0 - "@smithy/fetch-http-handler": ^2.5.0 - "@smithy/hash-blob-browser": ^2.2.0 - "@smithy/hash-node": ^2.2.0 - "@smithy/hash-stream-node": ^2.2.0 - "@smithy/invalid-dependency": ^2.2.0 - "@smithy/md5-js": ^2.2.0 - "@smithy/middleware-content-length": ^2.2.0 - "@smithy/middleware-endpoint": ^2.5.1 - "@smithy/middleware-retry": ^2.3.1 - "@smithy/middleware-serde": ^2.3.0 - "@smithy/middleware-stack": ^2.2.0 - "@smithy/node-config-provider": ^2.3.0 - "@smithy/node-http-handler": ^2.5.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/smithy-client": ^2.5.1 - "@smithy/types": ^2.12.0 - "@smithy/url-parser": ^2.2.0 - "@smithy/util-base64": ^2.3.0 - "@smithy/util-body-length-browser": ^2.2.0 - "@smithy/util-body-length-node": ^2.3.0 - "@smithy/util-defaults-mode-browser": ^2.2.1 - "@smithy/util-defaults-mode-node": ^2.3.1 - "@smithy/util-endpoints": ^1.2.0 - "@smithy/util-retry": ^2.2.0 - "@smithy/util-stream": ^2.2.0 - "@smithy/util-utf8": ^2.3.0 - "@smithy/util-waiter": ^2.2.0 + "@aws-crypto/sha1-browser": 5.2.0 + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/client-sso-oidc": 3.600.0 + "@aws-sdk/client-sts": 3.600.0 + "@aws-sdk/core": 3.598.0 + "@aws-sdk/credential-provider-node": 3.600.0 + "@aws-sdk/middleware-bucket-endpoint": 3.598.0 + "@aws-sdk/middleware-expect-continue": 3.598.0 + "@aws-sdk/middleware-flexible-checksums": 3.598.0 + "@aws-sdk/middleware-host-header": 3.598.0 + "@aws-sdk/middleware-location-constraint": 3.598.0 + "@aws-sdk/middleware-logger": 3.598.0 + "@aws-sdk/middleware-recursion-detection": 3.598.0 + "@aws-sdk/middleware-sdk-s3": 3.598.0 + "@aws-sdk/middleware-signing": 3.598.0 + "@aws-sdk/middleware-ssec": 3.598.0 + "@aws-sdk/middleware-user-agent": 3.598.0 + "@aws-sdk/region-config-resolver": 3.598.0 + "@aws-sdk/signature-v4-multi-region": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-endpoints": 3.598.0 + "@aws-sdk/util-user-agent-browser": 3.598.0 + "@aws-sdk/util-user-agent-node": 3.598.0 + "@aws-sdk/xml-builder": 3.598.0 + "@smithy/config-resolver": ^3.0.2 + "@smithy/core": ^2.2.1 + "@smithy/eventstream-serde-browser": ^3.0.2 + "@smithy/eventstream-serde-config-resolver": ^3.0.1 + "@smithy/eventstream-serde-node": ^3.0.2 + "@smithy/fetch-http-handler": ^3.0.2 + "@smithy/hash-blob-browser": ^3.1.0 + "@smithy/hash-node": ^3.0.1 + "@smithy/hash-stream-node": ^3.1.0 + "@smithy/invalid-dependency": ^3.0.1 + "@smithy/md5-js": ^3.0.1 + "@smithy/middleware-content-length": ^3.0.1 + "@smithy/middleware-endpoint": ^3.0.2 + "@smithy/middleware-retry": ^3.0.4 + "@smithy/middleware-serde": ^3.0.1 + "@smithy/middleware-stack": ^3.0.1 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/node-http-handler": ^3.0.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/url-parser": ^3.0.1 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.4 + "@smithy/util-defaults-mode-node": ^3.0.4 + "@smithy/util-endpoints": ^2.0.2 + "@smithy/util-retry": ^3.0.1 + "@smithy/util-stream": ^3.0.2 + "@smithy/util-utf8": ^3.0.0 + "@smithy/util-waiter": ^3.0.1 tslib: ^2.6.2 - checksum: e5b04013a9270b438b196ccf60bedba14187ee059fbd3fd42a8bac927c7935226ba031c1a5312befa6e37e4ea8cd075fe28b8b524fe51b5b372bf5543dd46216 + checksum: be9940ac1a9bff2e8efbf6f0ac782b0bcd66ab229639dc46d60aa71e041b3ef16a327e37c92397691a16c982cf5e529ab2ffd60351a9d9730bf4947bb391ced4 languageName: node linkType: hard "@aws-sdk/client-ses@npm:^3.550.0": - version: 3.556.0 - resolution: "@aws-sdk/client-ses@npm:3.556.0" + version: 3.600.0 + resolution: "@aws-sdk/client-ses@npm:3.600.0" dependencies: - "@aws-crypto/sha256-browser": 3.0.0 - "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.556.0 - "@aws-sdk/core": 3.556.0 - "@aws-sdk/credential-provider-node": 3.556.0 - "@aws-sdk/middleware-host-header": 3.535.0 - "@aws-sdk/middleware-logger": 3.535.0 - "@aws-sdk/middleware-recursion-detection": 3.535.0 - "@aws-sdk/middleware-user-agent": 3.540.0 - "@aws-sdk/region-config-resolver": 3.535.0 - "@aws-sdk/types": 3.535.0 - "@aws-sdk/util-endpoints": 3.540.0 - "@aws-sdk/util-user-agent-browser": 3.535.0 - "@aws-sdk/util-user-agent-node": 3.535.0 - "@smithy/config-resolver": ^2.2.0 - "@smithy/core": ^1.4.2 - "@smithy/fetch-http-handler": ^2.5.0 - "@smithy/hash-node": ^2.2.0 - "@smithy/invalid-dependency": ^2.2.0 - "@smithy/middleware-content-length": ^2.2.0 - "@smithy/middleware-endpoint": ^2.5.1 - "@smithy/middleware-retry": ^2.3.1 - "@smithy/middleware-serde": ^2.3.0 - "@smithy/middleware-stack": ^2.2.0 - "@smithy/node-config-provider": ^2.3.0 - "@smithy/node-http-handler": ^2.5.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/smithy-client": ^2.5.1 - "@smithy/types": ^2.12.0 - "@smithy/url-parser": ^2.2.0 - "@smithy/util-base64": ^2.3.0 - "@smithy/util-body-length-browser": ^2.2.0 - "@smithy/util-body-length-node": ^2.3.0 - "@smithy/util-defaults-mode-browser": ^2.2.1 - "@smithy/util-defaults-mode-node": ^2.3.1 - "@smithy/util-endpoints": ^1.2.0 - "@smithy/util-middleware": ^2.2.0 - "@smithy/util-retry": ^2.2.0 - "@smithy/util-utf8": ^2.3.0 - "@smithy/util-waiter": ^2.2.0 + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/client-sso-oidc": 3.600.0 + "@aws-sdk/client-sts": 3.600.0 + "@aws-sdk/core": 3.598.0 + "@aws-sdk/credential-provider-node": 3.600.0 + "@aws-sdk/middleware-host-header": 3.598.0 + "@aws-sdk/middleware-logger": 3.598.0 + "@aws-sdk/middleware-recursion-detection": 3.598.0 + "@aws-sdk/middleware-user-agent": 3.598.0 + "@aws-sdk/region-config-resolver": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-endpoints": 3.598.0 + "@aws-sdk/util-user-agent-browser": 3.598.0 + "@aws-sdk/util-user-agent-node": 3.598.0 + "@smithy/config-resolver": ^3.0.2 + "@smithy/core": ^2.2.1 + "@smithy/fetch-http-handler": ^3.0.2 + "@smithy/hash-node": ^3.0.1 + "@smithy/invalid-dependency": ^3.0.1 + "@smithy/middleware-content-length": ^3.0.1 + "@smithy/middleware-endpoint": ^3.0.2 + "@smithy/middleware-retry": ^3.0.4 + "@smithy/middleware-serde": ^3.0.1 + "@smithy/middleware-stack": ^3.0.1 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/node-http-handler": ^3.0.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/url-parser": ^3.0.1 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.4 + "@smithy/util-defaults-mode-node": ^3.0.4 + "@smithy/util-endpoints": ^2.0.2 + "@smithy/util-middleware": ^3.0.1 + "@smithy/util-retry": ^3.0.1 + "@smithy/util-utf8": ^3.0.0 + "@smithy/util-waiter": ^3.0.1 tslib: ^2.6.2 - checksum: 913108e79061185faae51711b121df99da624f988f530af23c3e4270299be60771be83f507dc8ed4af4051765077ea038edab19e4d0d32e159c4e67faf5fc9f8 + checksum: f0c042db4e20b8165f7da42ba2026ee6c32944c10c6a3508c021efbc0a3474fd0ef888367db47f54dc89a6bbad482858b0c816f6d3ec4ac84bfc156d315b2381 languageName: node linkType: hard "@aws-sdk/client-sqs@npm:^3.350.0": - version: 3.556.0 - resolution: "@aws-sdk/client-sqs@npm:3.556.0" + version: 3.600.0 + resolution: "@aws-sdk/client-sqs@npm:3.600.0" dependencies: - "@aws-crypto/sha256-browser": 3.0.0 - "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.556.0 - "@aws-sdk/core": 3.556.0 - "@aws-sdk/credential-provider-node": 3.556.0 - "@aws-sdk/middleware-host-header": 3.535.0 - "@aws-sdk/middleware-logger": 3.535.0 - "@aws-sdk/middleware-recursion-detection": 3.535.0 - "@aws-sdk/middleware-sdk-sqs": 3.552.0 - "@aws-sdk/middleware-user-agent": 3.540.0 - "@aws-sdk/region-config-resolver": 3.535.0 - "@aws-sdk/types": 3.535.0 - "@aws-sdk/util-endpoints": 3.540.0 - "@aws-sdk/util-user-agent-browser": 3.535.0 - "@aws-sdk/util-user-agent-node": 3.535.0 - "@smithy/config-resolver": ^2.2.0 - "@smithy/core": ^1.4.2 - "@smithy/fetch-http-handler": ^2.5.0 - "@smithy/hash-node": ^2.2.0 - "@smithy/invalid-dependency": ^2.2.0 - "@smithy/md5-js": ^2.2.0 - "@smithy/middleware-content-length": ^2.2.0 - "@smithy/middleware-endpoint": ^2.5.1 - "@smithy/middleware-retry": ^2.3.1 - "@smithy/middleware-serde": ^2.3.0 - "@smithy/middleware-stack": ^2.2.0 - "@smithy/node-config-provider": ^2.3.0 - "@smithy/node-http-handler": ^2.5.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/smithy-client": ^2.5.1 - "@smithy/types": ^2.12.0 - "@smithy/url-parser": ^2.2.0 - "@smithy/util-base64": ^2.3.0 - "@smithy/util-body-length-browser": ^2.2.0 - "@smithy/util-body-length-node": ^2.3.0 - "@smithy/util-defaults-mode-browser": ^2.2.1 - "@smithy/util-defaults-mode-node": ^2.3.1 - "@smithy/util-endpoints": ^1.2.0 - "@smithy/util-middleware": ^2.2.0 - "@smithy/util-retry": ^2.2.0 - "@smithy/util-utf8": ^2.3.0 + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/client-sso-oidc": 3.600.0 + "@aws-sdk/client-sts": 3.600.0 + "@aws-sdk/core": 3.598.0 + "@aws-sdk/credential-provider-node": 3.600.0 + "@aws-sdk/middleware-host-header": 3.598.0 + "@aws-sdk/middleware-logger": 3.598.0 + "@aws-sdk/middleware-recursion-detection": 3.598.0 + "@aws-sdk/middleware-sdk-sqs": 3.598.0 + "@aws-sdk/middleware-user-agent": 3.598.0 + "@aws-sdk/region-config-resolver": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-endpoints": 3.598.0 + "@aws-sdk/util-user-agent-browser": 3.598.0 + "@aws-sdk/util-user-agent-node": 3.598.0 + "@smithy/config-resolver": ^3.0.2 + "@smithy/core": ^2.2.1 + "@smithy/fetch-http-handler": ^3.0.2 + "@smithy/hash-node": ^3.0.1 + "@smithy/invalid-dependency": ^3.0.1 + "@smithy/md5-js": ^3.0.1 + "@smithy/middleware-content-length": ^3.0.1 + "@smithy/middleware-endpoint": ^3.0.2 + "@smithy/middleware-retry": ^3.0.4 + "@smithy/middleware-serde": ^3.0.1 + "@smithy/middleware-stack": ^3.0.1 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/node-http-handler": ^3.0.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/url-parser": ^3.0.1 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.4 + "@smithy/util-defaults-mode-node": ^3.0.4 + "@smithy/util-endpoints": ^2.0.2 + "@smithy/util-middleware": ^3.0.1 + "@smithy/util-retry": ^3.0.1 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: fe14caaffe9115b430d7c89895b193b2415532862b6cb70918ea0790f01017ca4bbf998ed221bf7fb4285b7eb6090c156bca4c8ccf49f61f2c34f96fd57e7ed4 + checksum: e0ec11d0d89539ae1964cc2f0655af7367c0c43153ab16fe9542e303cd1b69c5f0e9f3d912c52ff7bbfc5f557733d52e187e72563f0bfed3a21ed6249ae37c8a languageName: node linkType: hard -"@aws-sdk/client-sso-oidc@npm:3.556.0": - version: 3.556.0 - resolution: "@aws-sdk/client-sso-oidc@npm:3.556.0" +"@aws-sdk/client-sso-oidc@npm:3.600.0": + version: 3.600.0 + resolution: "@aws-sdk/client-sso-oidc@npm:3.600.0" dependencies: - "@aws-crypto/sha256-browser": 3.0.0 - "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.556.0 - "@aws-sdk/core": 3.556.0 - "@aws-sdk/middleware-host-header": 3.535.0 - "@aws-sdk/middleware-logger": 3.535.0 - "@aws-sdk/middleware-recursion-detection": 3.535.0 - "@aws-sdk/middleware-user-agent": 3.540.0 - "@aws-sdk/region-config-resolver": 3.535.0 - "@aws-sdk/types": 3.535.0 - "@aws-sdk/util-endpoints": 3.540.0 - "@aws-sdk/util-user-agent-browser": 3.535.0 - "@aws-sdk/util-user-agent-node": 3.535.0 - "@smithy/config-resolver": ^2.2.0 - "@smithy/core": ^1.4.2 - "@smithy/fetch-http-handler": ^2.5.0 - "@smithy/hash-node": ^2.2.0 - "@smithy/invalid-dependency": ^2.2.0 - "@smithy/middleware-content-length": ^2.2.0 - "@smithy/middleware-endpoint": ^2.5.1 - "@smithy/middleware-retry": ^2.3.1 - "@smithy/middleware-serde": ^2.3.0 - "@smithy/middleware-stack": ^2.2.0 - "@smithy/node-config-provider": ^2.3.0 - "@smithy/node-http-handler": ^2.5.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/smithy-client": ^2.5.1 - "@smithy/types": ^2.12.0 - "@smithy/url-parser": ^2.2.0 - "@smithy/util-base64": ^2.3.0 - "@smithy/util-body-length-browser": ^2.2.0 - "@smithy/util-body-length-node": ^2.3.0 - "@smithy/util-defaults-mode-browser": ^2.2.1 - "@smithy/util-defaults-mode-node": ^2.3.1 - "@smithy/util-endpoints": ^1.2.0 - "@smithy/util-middleware": ^2.2.0 - "@smithy/util-retry": ^2.2.0 - "@smithy/util-utf8": ^2.3.0 + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/client-sts": 3.600.0 + "@aws-sdk/core": 3.598.0 + "@aws-sdk/credential-provider-node": 3.600.0 + "@aws-sdk/middleware-host-header": 3.598.0 + "@aws-sdk/middleware-logger": 3.598.0 + "@aws-sdk/middleware-recursion-detection": 3.598.0 + "@aws-sdk/middleware-user-agent": 3.598.0 + "@aws-sdk/region-config-resolver": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-endpoints": 3.598.0 + "@aws-sdk/util-user-agent-browser": 3.598.0 + "@aws-sdk/util-user-agent-node": 3.598.0 + "@smithy/config-resolver": ^3.0.2 + "@smithy/core": ^2.2.1 + "@smithy/fetch-http-handler": ^3.0.2 + "@smithy/hash-node": ^3.0.1 + "@smithy/invalid-dependency": ^3.0.1 + "@smithy/middleware-content-length": ^3.0.1 + "@smithy/middleware-endpoint": ^3.0.2 + "@smithy/middleware-retry": ^3.0.4 + "@smithy/middleware-serde": ^3.0.1 + "@smithy/middleware-stack": ^3.0.1 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/node-http-handler": ^3.0.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/url-parser": ^3.0.1 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.4 + "@smithy/util-defaults-mode-node": ^3.0.4 + "@smithy/util-endpoints": ^2.0.2 + "@smithy/util-middleware": ^3.0.1 + "@smithy/util-retry": ^3.0.1 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - peerDependencies: - "@aws-sdk/credential-provider-node": ^3.556.0 - checksum: d932569016b811e14bd977e2e198556e3e4bf156108b098eb8850f83486cf361e23e17cc2fbae2ae7ebb1c2268f312a64c90dafb9f19e8dd6e9a817397e79552 + checksum: ef7a40ce69de30b25a8a7a5ee035f17e87edc1060c128b3b50f30f19b681aaa7b99b564ffc348cd74fe0e1079bd46087a6784674266d743c45564bcd4d5221b3 languageName: node linkType: hard -"@aws-sdk/client-sso@npm:3.556.0": - version: 3.556.0 - resolution: "@aws-sdk/client-sso@npm:3.556.0" +"@aws-sdk/client-sso@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/client-sso@npm:3.598.0" dependencies: - "@aws-crypto/sha256-browser": 3.0.0 - "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/core": 3.556.0 - "@aws-sdk/middleware-host-header": 3.535.0 - "@aws-sdk/middleware-logger": 3.535.0 - "@aws-sdk/middleware-recursion-detection": 3.535.0 - "@aws-sdk/middleware-user-agent": 3.540.0 - "@aws-sdk/region-config-resolver": 3.535.0 - "@aws-sdk/types": 3.535.0 - "@aws-sdk/util-endpoints": 3.540.0 - "@aws-sdk/util-user-agent-browser": 3.535.0 - "@aws-sdk/util-user-agent-node": 3.535.0 - "@smithy/config-resolver": ^2.2.0 - "@smithy/core": ^1.4.2 - "@smithy/fetch-http-handler": ^2.5.0 - "@smithy/hash-node": ^2.2.0 - "@smithy/invalid-dependency": ^2.2.0 - "@smithy/middleware-content-length": ^2.2.0 - "@smithy/middleware-endpoint": ^2.5.1 - "@smithy/middleware-retry": ^2.3.1 - "@smithy/middleware-serde": ^2.3.0 - "@smithy/middleware-stack": ^2.2.0 - "@smithy/node-config-provider": ^2.3.0 - "@smithy/node-http-handler": ^2.5.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/smithy-client": ^2.5.1 - "@smithy/types": ^2.12.0 - "@smithy/url-parser": ^2.2.0 - "@smithy/util-base64": ^2.3.0 - "@smithy/util-body-length-browser": ^2.2.0 - "@smithy/util-body-length-node": ^2.3.0 - "@smithy/util-defaults-mode-browser": ^2.2.1 - "@smithy/util-defaults-mode-node": ^2.3.1 - "@smithy/util-endpoints": ^1.2.0 - "@smithy/util-middleware": ^2.2.0 - "@smithy/util-retry": ^2.2.0 - "@smithy/util-utf8": ^2.3.0 + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.598.0 + "@aws-sdk/middleware-host-header": 3.598.0 + "@aws-sdk/middleware-logger": 3.598.0 + "@aws-sdk/middleware-recursion-detection": 3.598.0 + "@aws-sdk/middleware-user-agent": 3.598.0 + "@aws-sdk/region-config-resolver": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-endpoints": 3.598.0 + "@aws-sdk/util-user-agent-browser": 3.598.0 + "@aws-sdk/util-user-agent-node": 3.598.0 + "@smithy/config-resolver": ^3.0.2 + "@smithy/core": ^2.2.1 + "@smithy/fetch-http-handler": ^3.0.2 + "@smithy/hash-node": ^3.0.1 + "@smithy/invalid-dependency": ^3.0.1 + "@smithy/middleware-content-length": ^3.0.1 + "@smithy/middleware-endpoint": ^3.0.2 + "@smithy/middleware-retry": ^3.0.4 + "@smithy/middleware-serde": ^3.0.1 + "@smithy/middleware-stack": ^3.0.1 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/node-http-handler": ^3.0.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/url-parser": ^3.0.1 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.4 + "@smithy/util-defaults-mode-node": ^3.0.4 + "@smithy/util-endpoints": ^2.0.2 + "@smithy/util-middleware": ^3.0.1 + "@smithy/util-retry": ^3.0.1 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: bf0f2d449983c650e25befbee80dd48508464c1814e5b412a8f5e725e88e0764ac75a1b959df509c746b638dbbb571f51617be4c02f7b0ef8185c045255f6c52 + checksum: b570f54643ac0ab0f300bf074e77c2fbba70206a11d2aed1f6ecd361027f2f6a1d62719627e905bcb44dd73d481a29ef5a70878c676386afe2a133f479a445d4 languageName: node linkType: hard -"@aws-sdk/client-sts@npm:3.556.0, @aws-sdk/client-sts@npm:^3.350.0": - version: 3.556.0 - resolution: "@aws-sdk/client-sts@npm:3.556.0" +"@aws-sdk/client-sts@npm:3.600.0, @aws-sdk/client-sts@npm:^3.350.0": + version: 3.600.0 + resolution: "@aws-sdk/client-sts@npm:3.600.0" dependencies: - "@aws-crypto/sha256-browser": 3.0.0 - "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/core": 3.556.0 - "@aws-sdk/middleware-host-header": 3.535.0 - "@aws-sdk/middleware-logger": 3.535.0 - "@aws-sdk/middleware-recursion-detection": 3.535.0 - "@aws-sdk/middleware-user-agent": 3.540.0 - "@aws-sdk/region-config-resolver": 3.535.0 - "@aws-sdk/types": 3.535.0 - "@aws-sdk/util-endpoints": 3.540.0 - "@aws-sdk/util-user-agent-browser": 3.535.0 - "@aws-sdk/util-user-agent-node": 3.535.0 - "@smithy/config-resolver": ^2.2.0 - "@smithy/core": ^1.4.2 - "@smithy/fetch-http-handler": ^2.5.0 - "@smithy/hash-node": ^2.2.0 - "@smithy/invalid-dependency": ^2.2.0 - "@smithy/middleware-content-length": ^2.2.0 - "@smithy/middleware-endpoint": ^2.5.1 - "@smithy/middleware-retry": ^2.3.1 - "@smithy/middleware-serde": ^2.3.0 - "@smithy/middleware-stack": ^2.2.0 - "@smithy/node-config-provider": ^2.3.0 - "@smithy/node-http-handler": ^2.5.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/smithy-client": ^2.5.1 - "@smithy/types": ^2.12.0 - "@smithy/url-parser": ^2.2.0 - "@smithy/util-base64": ^2.3.0 - "@smithy/util-body-length-browser": ^2.2.0 - "@smithy/util-body-length-node": ^2.3.0 - "@smithy/util-defaults-mode-browser": ^2.2.1 - "@smithy/util-defaults-mode-node": ^2.3.1 - "@smithy/util-endpoints": ^1.2.0 - "@smithy/util-middleware": ^2.2.0 - "@smithy/util-retry": ^2.2.0 - "@smithy/util-utf8": ^2.3.0 + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/client-sso-oidc": 3.600.0 + "@aws-sdk/core": 3.598.0 + "@aws-sdk/credential-provider-node": 3.600.0 + "@aws-sdk/middleware-host-header": 3.598.0 + "@aws-sdk/middleware-logger": 3.598.0 + "@aws-sdk/middleware-recursion-detection": 3.598.0 + "@aws-sdk/middleware-user-agent": 3.598.0 + "@aws-sdk/region-config-resolver": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-endpoints": 3.598.0 + "@aws-sdk/util-user-agent-browser": 3.598.0 + "@aws-sdk/util-user-agent-node": 3.598.0 + "@smithy/config-resolver": ^3.0.2 + "@smithy/core": ^2.2.1 + "@smithy/fetch-http-handler": ^3.0.2 + "@smithy/hash-node": ^3.0.1 + "@smithy/invalid-dependency": ^3.0.1 + "@smithy/middleware-content-length": ^3.0.1 + "@smithy/middleware-endpoint": ^3.0.2 + "@smithy/middleware-retry": ^3.0.4 + "@smithy/middleware-serde": ^3.0.1 + "@smithy/middleware-stack": ^3.0.1 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/node-http-handler": ^3.0.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/url-parser": ^3.0.1 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.4 + "@smithy/util-defaults-mode-node": ^3.0.4 + "@smithy/util-endpoints": ^2.0.2 + "@smithy/util-middleware": ^3.0.1 + "@smithy/util-retry": ^3.0.1 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - peerDependencies: - "@aws-sdk/credential-provider-node": ^3.556.0 - checksum: 81ce40440de0c3012b6e21d7f9b748bc46982e72ffaccc763efeed34d79eee519ed9a95e2cb37b2e411460cced2897f409d90e42a5b012344358839c717fa435 + checksum: 47d6d145d481c8dc285b68baccf36ab76b92ed1fbf5a58a0900bbe913a7caf3eddc84414428b013e58c91242e7ffd5a55b0620217dc295c75c2729ccb89b9ae8 languageName: node linkType: hard -"@aws-sdk/core@npm:3.556.0": - version: 3.556.0 - resolution: "@aws-sdk/core@npm:3.556.0" +"@aws-sdk/core@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/core@npm:3.598.0" dependencies: - "@smithy/core": ^1.4.2 - "@smithy/protocol-http": ^3.3.0 - "@smithy/signature-v4": ^2.3.0 - "@smithy/smithy-client": ^2.5.1 - "@smithy/types": ^2.12.0 + "@smithy/core": ^2.2.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/signature-v4": ^3.1.0 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 fast-xml-parser: 4.2.5 tslib: ^2.6.2 - checksum: 9b446f0939f8573289b598282194aeff81b3e8c9aa76b29d6e865fe40f38b301f041fab39d565f975ed6e8a3ba4d4b9b43444aaab7dbf2c7ea84e67d370a2695 + checksum: e58944a6571808b53d21f012b9671ffec597d2a826a9c0f1fbcbe160189a3c47f5b4671ac92b7437c349f19b8a8df7e12255c57795ab0224c318ed69a0d23229 languageName: node linkType: hard -"@aws-sdk/credential-provider-cognito-identity@npm:3.556.0": - version: 3.556.0 - resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.556.0" +"@aws-sdk/credential-provider-cognito-identity@npm:3.600.0": + version: 3.600.0 + resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.600.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.556.0 - "@aws-sdk/types": 3.535.0 - "@smithy/property-provider": ^2.2.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/client-cognito-identity": 3.600.0 + "@aws-sdk/types": 3.598.0 + "@smithy/property-provider": ^3.1.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 4c66b780f9f8c3e5df9d5e397069e0bbd31596bfb93b5ac76baa39cb0ef7bebc848a879b940dbcdda7c40cb78beeb46e0b10fab94e71ea317e0512e49c9b6f80 + checksum: 9e7e325fde26192fbd7f542ad0ff69d193b5edb65b0361cdeb13f538b1b563de999e82da34493921351ea599643c4884bd17fdc16eba423d3343e681f346072f languageName: node linkType: hard -"@aws-sdk/credential-provider-env@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/credential-provider-env@npm:3.535.0" +"@aws-sdk/credential-provider-env@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/credential-provider-env@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/property-provider": ^2.2.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@smithy/property-provider": ^3.1.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: ec7d011051d69643efd26fe7f3767b1301c6e6bdba12640dad542b60efb2b5fe31df01f8137703d814cf857a69485cc928d0de49ab56c5d05f79815dce19bdbf + checksum: 517f06dd47b7aa4c8d5a9fe82698150237c28c46ed9f82cd1d92d1453690b9d6139b65519d92dea611d319c4418fe4540e7d52c03d3897e7e471731fb0156afb languageName: node linkType: hard -"@aws-sdk/credential-provider-http@npm:3.552.0": - version: 3.552.0 - resolution: "@aws-sdk/credential-provider-http@npm:3.552.0" +"@aws-sdk/credential-provider-http@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/credential-provider-http@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/fetch-http-handler": ^2.5.0 - "@smithy/node-http-handler": ^2.5.0 - "@smithy/property-provider": ^2.2.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/smithy-client": ^2.5.1 - "@smithy/types": ^2.12.0 - "@smithy/util-stream": ^2.2.0 + "@aws-sdk/types": 3.598.0 + "@smithy/fetch-http-handler": ^3.0.2 + "@smithy/node-http-handler": ^3.0.1 + "@smithy/property-provider": ^3.1.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/util-stream": ^3.0.2 tslib: ^2.6.2 - checksum: 86be07b2a0c73b5c1140557e00b08c091303da1908ff40a29bcc69b73bf4ad175a5ad945e0d45d5c76b02bee3f15a947abb18838b2771ad71feb795a5309a446 + checksum: e2f6208491a6e58b7ac7368c2247dee55080be740511ded01cc3454920ef29d0b7712930571651a8d0ec2aea4e0a107c7d5dd6ecd01bd4de3c264c54e32959b3 languageName: node linkType: hard -"@aws-sdk/credential-provider-ini@npm:3.556.0": - version: 3.556.0 - resolution: "@aws-sdk/credential-provider-ini@npm:3.556.0" +"@aws-sdk/credential-provider-ini@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.598.0" dependencies: - "@aws-sdk/client-sts": 3.556.0 - "@aws-sdk/credential-provider-env": 3.535.0 - "@aws-sdk/credential-provider-process": 3.535.0 - "@aws-sdk/credential-provider-sso": 3.556.0 - "@aws-sdk/credential-provider-web-identity": 3.556.0 - "@aws-sdk/types": 3.535.0 - "@smithy/credential-provider-imds": ^2.3.0 - "@smithy/property-provider": ^2.2.0 - "@smithy/shared-ini-file-loader": ^2.4.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/credential-provider-env": 3.598.0 + "@aws-sdk/credential-provider-http": 3.598.0 + "@aws-sdk/credential-provider-process": 3.598.0 + "@aws-sdk/credential-provider-sso": 3.598.0 + "@aws-sdk/credential-provider-web-identity": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@smithy/credential-provider-imds": ^3.1.1 + "@smithy/property-provider": ^3.1.1 + "@smithy/shared-ini-file-loader": ^3.1.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 24b7dc1349f80090455bde95856955aef824752bff8b91dbad1dea784dc03b48b9671650aa2002de8427bd1df832c33be52b5bf157ad2759ad65a6d37247e339 + peerDependencies: + "@aws-sdk/client-sts": ^3.598.0 + checksum: 9fab1e9c312e20150c96daf15e0347b79f0589cc44eb299c15e80c7d5380e8966805fa8893d3c906f99b7eb3c0f872f0795415f75921204580a30d869dd87f54 languageName: node linkType: hard -"@aws-sdk/credential-provider-node@npm:3.556.0, @aws-sdk/credential-provider-node@npm:^3.350.0": - version: 3.556.0 - resolution: "@aws-sdk/credential-provider-node@npm:3.556.0" +"@aws-sdk/credential-provider-node@npm:3.600.0, @aws-sdk/credential-provider-node@npm:^3.350.0": + version: 3.600.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.600.0" dependencies: - "@aws-sdk/credential-provider-env": 3.535.0 - "@aws-sdk/credential-provider-http": 3.552.0 - "@aws-sdk/credential-provider-ini": 3.556.0 - "@aws-sdk/credential-provider-process": 3.535.0 - "@aws-sdk/credential-provider-sso": 3.556.0 - "@aws-sdk/credential-provider-web-identity": 3.556.0 - "@aws-sdk/types": 3.535.0 - "@smithy/credential-provider-imds": ^2.3.0 - "@smithy/property-provider": ^2.2.0 - "@smithy/shared-ini-file-loader": ^2.4.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/credential-provider-env": 3.598.0 + "@aws-sdk/credential-provider-http": 3.598.0 + "@aws-sdk/credential-provider-ini": 3.598.0 + "@aws-sdk/credential-provider-process": 3.598.0 + "@aws-sdk/credential-provider-sso": 3.598.0 + "@aws-sdk/credential-provider-web-identity": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@smithy/credential-provider-imds": ^3.1.1 + "@smithy/property-provider": ^3.1.1 + "@smithy/shared-ini-file-loader": ^3.1.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: c4b83c36426941caff81a25393eec101cf2d21264c29c69e5a7a940ae8af1f4b2a8f0a26f47c2294a32f381d53eed9ba2dc2cbbcd053585aa9016acb79e98ad8 + checksum: 480c7c36a8558667a25617e6f7f2292b4362b0e894bc204ce62f565dc8e8cc46c713dc04621321336ce715b493590b3b854b33dc6d5123ed39a17643158d94fc languageName: node linkType: hard -"@aws-sdk/credential-provider-process@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/credential-provider-process@npm:3.535.0" +"@aws-sdk/credential-provider-process@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/credential-provider-process@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/property-provider": ^2.2.0 - "@smithy/shared-ini-file-loader": ^2.4.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@smithy/property-provider": ^3.1.1 + "@smithy/shared-ini-file-loader": ^3.1.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: af5fad70513e8d0bc10013f220588e45e83d488e0780873d7e76bf5b7099e70c9b4e49b6409d16add64ae212c53a472b12a2178e8bafd7878fdf121d6e2fd112 + checksum: cd1f0dbbc38b137a0e9c2cfa9bb9e55eed1da5166e13576295205d276ab313e9d4a2f97a566d576abc85c6f4e9e84ad676ca5c32f90de17e027d6a1372fb00e6 languageName: node linkType: hard -"@aws-sdk/credential-provider-sso@npm:3.556.0": - version: 3.556.0 - resolution: "@aws-sdk/credential-provider-sso@npm:3.556.0" +"@aws-sdk/credential-provider-sso@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.598.0" dependencies: - "@aws-sdk/client-sso": 3.556.0 - "@aws-sdk/token-providers": 3.556.0 - "@aws-sdk/types": 3.535.0 - "@smithy/property-provider": ^2.2.0 - "@smithy/shared-ini-file-loader": ^2.4.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/client-sso": 3.598.0 + "@aws-sdk/token-providers": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@smithy/property-provider": ^3.1.1 + "@smithy/shared-ini-file-loader": ^3.1.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: ea6c9bd7f183abedf79ff7959fdc31c16cb250afece2304d3005343aae4a203d04f2421ac1dd0a815a6d1823c721b277449d0ab27dc17fe8c75b211e44a31667 + checksum: 16828609b9ac17772eecd89deb9ac9b98a1decad42ca1f8cf6a57e6873eeb3563db00bfb67684cbb08108d5ee6b8f98ec23047d7f6750cb67c1342cd8b96ac1c languageName: node linkType: hard -"@aws-sdk/credential-provider-web-identity@npm:3.556.0": - version: 3.556.0 - resolution: "@aws-sdk/credential-provider-web-identity@npm:3.556.0" +"@aws-sdk/credential-provider-web-identity@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.598.0" dependencies: - "@aws-sdk/client-sts": 3.556.0 - "@aws-sdk/types": 3.535.0 - "@smithy/property-provider": ^2.2.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@smithy/property-provider": ^3.1.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 79d3277db07130b201b5788a76e8a71c2816be1e190ce7f96d174c2c8153fdcfb6adbf17575d8fd5c928452327a37872f18a48e563805997247bdc3cda2b9cac + peerDependencies: + "@aws-sdk/client-sts": ^3.598.0 + checksum: e62352ae7f408ae8969d22fd42a502ec078536952be1253f184bf96c57f3c88589fd431762b2300b494159df4eb4af975358645772ac36f2cc722c86a88ff85e languageName: node linkType: hard "@aws-sdk/credential-providers@npm:^3.350.0": - version: 3.556.0 - resolution: "@aws-sdk/credential-providers@npm:3.556.0" + version: 3.600.0 + resolution: "@aws-sdk/credential-providers@npm:3.600.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.556.0 - "@aws-sdk/client-sso": 3.556.0 - "@aws-sdk/client-sts": 3.556.0 - "@aws-sdk/credential-provider-cognito-identity": 3.556.0 - "@aws-sdk/credential-provider-env": 3.535.0 - "@aws-sdk/credential-provider-http": 3.552.0 - "@aws-sdk/credential-provider-ini": 3.556.0 - "@aws-sdk/credential-provider-node": 3.556.0 - "@aws-sdk/credential-provider-process": 3.535.0 - "@aws-sdk/credential-provider-sso": 3.556.0 - "@aws-sdk/credential-provider-web-identity": 3.556.0 - "@aws-sdk/types": 3.535.0 - "@smithy/credential-provider-imds": ^2.3.0 - "@smithy/property-provider": ^2.2.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/client-cognito-identity": 3.600.0 + "@aws-sdk/client-sso": 3.598.0 + "@aws-sdk/client-sts": 3.600.0 + "@aws-sdk/credential-provider-cognito-identity": 3.600.0 + "@aws-sdk/credential-provider-env": 3.598.0 + "@aws-sdk/credential-provider-http": 3.598.0 + "@aws-sdk/credential-provider-ini": 3.598.0 + "@aws-sdk/credential-provider-node": 3.600.0 + "@aws-sdk/credential-provider-process": 3.598.0 + "@aws-sdk/credential-provider-sso": 3.598.0 + "@aws-sdk/credential-provider-web-identity": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@smithy/credential-provider-imds": ^3.1.1 + "@smithy/property-provider": ^3.1.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 6d00b6ab7fbd0e0ca83ecd2823b446290be20d68f7c2b26128b8f678ab9d6e0f7fb423adf94bb12903abdeb324b4aa7ce8dd81e0b17f5b3322f6b14e634552e0 + checksum: d957d851a9d4aba30e941c12515ce08fda66cadf2623fa329a2f651e2229e901a7845b139cd15404c8a714985e9b358747f1a8aacf0951e9b05331c5ae92af7c languageName: node linkType: hard @@ -1184,34 +1182,34 @@ __metadata: linkType: hard "@aws-sdk/lib-storage@npm:^3.350.0": - version: 3.556.0 - resolution: "@aws-sdk/lib-storage@npm:3.556.0" + version: 3.600.0 + resolution: "@aws-sdk/lib-storage@npm:3.600.0" dependencies: - "@smithy/abort-controller": ^2.2.0 - "@smithy/middleware-endpoint": ^2.5.1 - "@smithy/smithy-client": ^2.5.1 + "@smithy/abort-controller": ^3.0.1 + "@smithy/middleware-endpoint": ^3.0.2 + "@smithy/smithy-client": ^3.1.2 buffer: 5.6.0 events: 3.3.0 stream-browserify: 3.0.0 tslib: ^2.6.2 peerDependencies: - "@aws-sdk/client-s3": ^3.0.0 - checksum: 361e87ce38f566e7ffe0da2bd436bfda5dfce1c9e4f86f4fbab9e157ba24a47e169824dd9723f02eab8cd682b381a765453bd8d4c5fa0ae3c5273ff6d3a166e5 + "@aws-sdk/client-s3": ^3.600.0 + checksum: 3fc04712f61289ac47f9502f0f33351a50e581d7999398575e84713750c77261b20ef8ac4f0a68514737c9950b313a563752b6856f63acaff23d128a4b4a9f4b languageName: node linkType: hard -"@aws-sdk/middleware-bucket-endpoint@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.535.0" +"@aws-sdk/middleware-bucket-endpoint@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@aws-sdk/util-arn-parser": 3.535.0 - "@smithy/node-config-provider": ^2.3.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/types": ^2.12.0 - "@smithy/util-config-provider": ^2.3.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-arn-parser": 3.568.0 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/types": ^3.1.0 + "@smithy/util-config-provider": ^3.0.0 tslib: ^2.6.2 - checksum: d72dfd197dc9aa1ed8ea3de6fb0a18363688fa8e18f6a9d01cb2f425087c5b72aa4bfd0955715c84da86adf9a46029755cff55a02a6ffbf4459009982a5a5415 + checksum: 45a4adc3427a70f7129675439c9396073dc418e9e5ede4acd0dc0620d76610e8adf3f1c863120f7714bc67053a194289ac55ce6814a79960c4746cbd45f7116f languageName: node linkType: hard @@ -1228,108 +1226,108 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-expect-continue@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/middleware-expect-continue@npm:3.535.0" +"@aws-sdk/middleware-expect-continue@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-expect-continue@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@smithy/protocol-http": ^4.0.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: fdac9bc59833ca9688155f115f85c31f690df5ef690e9a8921b94b87c4faac3eb3ff10641699822faaaf9a6cc4ce4c67e693a7b4befe8baf8138a9d276d6714d + checksum: 1038945711d48d661cbf21343fd78968240f43b18f5b7fade7e41a7bf5308a65f37859f2b349e5fb038dded0136e0ea734e38e52085178b6a546a6ac48c630e9 languageName: node linkType: hard -"@aws-sdk/middleware-flexible-checksums@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.535.0" +"@aws-sdk/middleware-flexible-checksums@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.598.0" dependencies: - "@aws-crypto/crc32": 3.0.0 - "@aws-crypto/crc32c": 3.0.0 - "@aws-sdk/types": 3.535.0 - "@smithy/is-array-buffer": ^2.2.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/types": ^2.12.0 - "@smithy/util-utf8": ^2.3.0 + "@aws-crypto/crc32": 5.2.0 + "@aws-crypto/crc32c": 5.2.0 + "@aws-sdk/types": 3.598.0 + "@smithy/is-array-buffer": ^3.0.0 + "@smithy/protocol-http": ^4.0.1 + "@smithy/types": ^3.1.0 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 14c04cd932bdb9029466079b248c1fa8222183de4c288bf12ad661cdc7717938485fdb973b7948da729e5be218573cfd2cbe74b51a1bc2bd27131ca7d67909c1 + checksum: 1311849976b0631055d2d79f991647a87cae742bba23a94f01d18164612ba303ff3bed629744ba58c04bfde371b69ad4eb29e266a7b022ea8529b9a7f6a18415 languageName: node linkType: hard -"@aws-sdk/middleware-host-header@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/middleware-host-header@npm:3.535.0" +"@aws-sdk/middleware-host-header@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-host-header@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@smithy/protocol-http": ^4.0.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 13a22a5b19912a86fe872c9c0f6ba9ab758ba9483ce9a2e73fa68acae498b68404e38e7fc1e3962639a6c3f80ebe19ea5c5340e1024e11ab417998696c8a5dca + checksum: c505de5bf4f39051a55011b9b2da0b673bda668def00a9b3b4696a3146bfbf0e5509d3bde28ef238648158b863816ce85fbf5829228bb97450c826b7d24d40d0 languageName: node linkType: hard -"@aws-sdk/middleware-location-constraint@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/middleware-location-constraint@npm:3.535.0" +"@aws-sdk/middleware-location-constraint@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-location-constraint@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 4e89b6c5d4253568e599f0e8be37e80cf12a755ba89b89d9c9ae2ced75213850c41922fa1871a9c92345057e15d5db956a353841eb63353d8f2bb69a61d4a10d + checksum: ab1ae3ad3dc7fad76688c039136d602abe25ebd6b98b6fb61a86f02dbec4414a74334169d12581aae720fe9d372549e9b9dfb56ee87388602264b697db09ff9f languageName: node linkType: hard -"@aws-sdk/middleware-logger@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/middleware-logger@npm:3.535.0" +"@aws-sdk/middleware-logger@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-logger@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: e264d05aa88fadd94d17000b1df79bf1931c5fbc2c871616de9b836bab7254d8c21e0fc2ac509a07af578bd823b795efafaf48daca805bc4493986288ed0c4ab + checksum: 8c90bf68b65fe82ae08bf0c665bfea335fef757f8be7ddac6f9059f9f149c9bebc68e034bc225d131d168a61d61a409936d4f4d260c4b2aa2251385238df765a languageName: node linkType: hard -"@aws-sdk/middleware-recursion-detection@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/middleware-recursion-detection@npm:3.535.0" +"@aws-sdk/middleware-recursion-detection@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@smithy/protocol-http": ^4.0.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: b6b518243a10dcdcea7c1fd4790cf2e1e0e3d4363ebce51ac364c9b15631a6f3d1db44d00e7c75cbdf1d558a0d868583d6e1853e571e15e23d0d2901f168e2e4 + checksum: 161247dbbc8aa31d77c8d4c9c55264c775b5f9996e58451574605435c4a0ff6b9fce28be6f133ddce9f93a24f08c7af6fde59ef93ecb2cc4cd170a4db72b4833 languageName: node linkType: hard -"@aws-sdk/middleware-sdk-s3@npm:3.556.0": - version: 3.556.0 - resolution: "@aws-sdk/middleware-sdk-s3@npm:3.556.0" +"@aws-sdk/middleware-sdk-s3@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-sdk-s3@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@aws-sdk/util-arn-parser": 3.535.0 - "@smithy/node-config-provider": ^2.3.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/signature-v4": ^2.3.0 - "@smithy/smithy-client": ^2.5.1 - "@smithy/types": ^2.12.0 - "@smithy/util-config-provider": ^2.3.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-arn-parser": 3.568.0 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/signature-v4": ^3.1.0 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/util-config-provider": ^3.0.0 tslib: ^2.6.2 - checksum: a50d96f898a8e6f7cfa0bc61c888240e1fd7aa55cb9fd9376d720f43d30a83d7ad4bd9d828224c125f62b362d77ccfc7fbd64c5c4563f97790f9683ea87abe93 + checksum: 2953ae0f2729ffc4ca68e51e8f3247d447004e5d3d787b333351f2972cc94b49f8379f3403d153c3c5940bda47e1930b0386b77c448ca81bc54bf40f7cb4111f languageName: node linkType: hard -"@aws-sdk/middleware-sdk-sqs@npm:3.552.0": - version: 3.552.0 - resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.552.0" +"@aws-sdk/middleware-sdk-sqs@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/smithy-client": ^2.5.1 - "@smithy/types": ^2.12.0 - "@smithy/util-hex-encoding": ^2.2.0 - "@smithy/util-utf8": ^2.3.0 + "@aws-sdk/types": 3.598.0 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/util-hex-encoding": ^3.0.0 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: a2dfeab25b89b8c0f3204195df58bf5deefb261883db936c6701e70d5a1f6e2a0e8e3a756fea6a4f0e3a1dc4023d820c6b8b3717f759622ffa7cd8851cd9ed59 + checksum: 5b31bc50ffb2973a1a5108ca0a9a2fbf3cc96a403fd06e58994eb9e98e5804cb8fd2d2db977214d92ce30a5a256b54df156b285f7a89e286e7d0ceb3d9f69414 languageName: node linkType: hard @@ -1343,42 +1341,42 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-signing@npm:3.556.0": - version: 3.556.0 - resolution: "@aws-sdk/middleware-signing@npm:3.556.0" +"@aws-sdk/middleware-signing@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-signing@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/property-provider": ^2.2.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/signature-v4": ^2.3.0 - "@smithy/types": ^2.12.0 - "@smithy/util-middleware": ^2.2.0 + "@aws-sdk/types": 3.598.0 + "@smithy/property-provider": ^3.1.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/signature-v4": ^3.1.0 + "@smithy/types": ^3.1.0 + "@smithy/util-middleware": ^3.0.1 tslib: ^2.6.2 - checksum: b72c0223cc531d9eaac41124c3dcf60d974dbe0a5698fa6cf2ec877d73d83ff02ae310636478054ba5f7d1c3240ff277831c5144955ddb59e513b3de7cb4f272 + checksum: c952da22635dbca7b91c47e43df43a9f4826bbebc36e5851ce325e07f43451de015232145df32eed3190b23d3b051469bf4c381b94ab4eb367ca8f22de4a4670 languageName: node linkType: hard -"@aws-sdk/middleware-ssec@npm:3.537.0": - version: 3.537.0 - resolution: "@aws-sdk/middleware-ssec@npm:3.537.0" +"@aws-sdk/middleware-ssec@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-ssec@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 7a963134cab4c9056d249113f6d5e2847be28847fc8c39b943c487ff5d22b9b1d91092e801694e2da95929a4820c45f6b5afc22c655a6dcfb5eb82e44952de14 + checksum: 600afb96254d1085c402fec6c5b7f260ca64126104c4cf3ff6da9811c5cdf0dab5f34fadf68e449ec61f89a165479e1cfab8cd3135c720a2e7a678be4572c215 languageName: node linkType: hard -"@aws-sdk/middleware-user-agent@npm:3.540.0": - version: 3.540.0 - resolution: "@aws-sdk/middleware-user-agent@npm:3.540.0" +"@aws-sdk/middleware-user-agent@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@aws-sdk/util-endpoints": 3.540.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-endpoints": 3.598.0 + "@smithy/protocol-http": ^4.0.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 7ee609fb2b669f93657a87c291dff17f8315973ddbbeee36c54a0233b4911091916880f6e27da93fef01e5fd53654b3834a68cf74256b88b1c4dbe5880a4c14f + checksum: 11dcf64badadf8c6b3283b3cec4cb684467eaf57206782c68a9b758e6f7a4f1b632d5ed89bb6ffbc855bf6d3fb855f0a56858bda640a67c0812ced08cd19959f languageName: node linkType: hard @@ -1426,31 +1424,31 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/region-config-resolver@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/region-config-resolver@npm:3.535.0" +"@aws-sdk/region-config-resolver@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/region-config-resolver@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/node-config-provider": ^2.3.0 - "@smithy/types": ^2.12.0 - "@smithy/util-config-provider": ^2.3.0 - "@smithy/util-middleware": ^2.2.0 + "@aws-sdk/types": 3.598.0 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/types": ^3.1.0 + "@smithy/util-config-provider": ^3.0.0 + "@smithy/util-middleware": ^3.0.1 tslib: ^2.6.2 - checksum: 7b556e47c721c0829ae635203a1dbcab7040e2885d2bdc37898eb3139dabb5f6da580b860202e3b7737330bfc02de5084a98ff8f8b5c36adcfe8e076b82d3487 + checksum: 649115771cb6b77e793088f3ee6eec346c1379f9f5d0e925f71103ad55c5f4a1132fca7e859a6b75ff46ecd1cc165a4eb260227596e4a2871118e6918602a726 languageName: node linkType: hard -"@aws-sdk/signature-v4-multi-region@npm:3.556.0": - version: 3.556.0 - resolution: "@aws-sdk/signature-v4-multi-region@npm:3.556.0" +"@aws-sdk/signature-v4-multi-region@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/signature-v4-multi-region@npm:3.598.0" dependencies: - "@aws-sdk/middleware-sdk-s3": 3.556.0 - "@aws-sdk/types": 3.535.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/signature-v4": ^2.3.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/middleware-sdk-s3": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@smithy/protocol-http": ^4.0.1 + "@smithy/signature-v4": ^3.1.0 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 0a23fbb8f99e1b8ab6c7523d5584864749a2ad5b244b78667d88d4a0eb0f74127e22fff4b44a9b694c235e70a66520ee72e0e57b129847d9405c6d907abf5e81 + checksum: 6e0aa7adfe98c452eaa269ea9dc68d2b914a3c5bdc00b5923c0a9003e54899b7d3b9ce14d305b5229200e658a18fdebb93977437f029e9a576c9fe9a3cded0b1 languageName: node linkType: hard @@ -1470,17 +1468,18 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/token-providers@npm:3.556.0": - version: 3.556.0 - resolution: "@aws-sdk/token-providers@npm:3.556.0" +"@aws-sdk/token-providers@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/token-providers@npm:3.598.0" dependencies: - "@aws-sdk/client-sso-oidc": 3.556.0 - "@aws-sdk/types": 3.535.0 - "@smithy/property-provider": ^2.2.0 - "@smithy/shared-ini-file-loader": ^2.4.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@smithy/property-provider": ^3.1.1 + "@smithy/shared-ini-file-loader": ^3.1.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 15726af45c8a52837eb3291391c23e5b66a153218275c4fcc228a80f63169b401270ff736271401b6d4c301944bc20620d63dfb14a87bbe743a50e3157e68c7e + peerDependencies: + "@aws-sdk/client-sso-oidc": ^3.598.0 + checksum: 24197672226e1e953fa57ca10c6adae9c3f6b571fbf40f517609e028d8ea6ab45c3afd285bd999bc35c0690b3427be04d4af3f677ced6778b0a716e0dd4e5280 languageName: node linkType: hard @@ -1494,13 +1493,13 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/types@npm:3.535.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0": - version: 3.535.0 - resolution: "@aws-sdk/types@npm:3.535.0" +"@aws-sdk/types@npm:3.598.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0": + version: 3.598.0 + resolution: "@aws-sdk/types@npm:3.598.0" dependencies: - "@smithy/types": ^2.12.0 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 3f735c78ea3a6f37d05387286f6d18b0e5deb41442095bd2f7c27b000659962872d1c801fa8484a6ac4b7d2725b2e176dc628c3fa2a903a3141d4be76488d48f + checksum: 9b2bd50d6935422dd1046e6eaa48c4c774d06aa1374bf4600a3af2c7a52432b5e25ec111cf49976b07b03d7cb5f4fa6fd44b7ce8a67dd0b3a4cee4abaf9e6fa5 languageName: node linkType: hard @@ -1515,12 +1514,12 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-arn-parser@npm:3.535.0, @aws-sdk/util-arn-parser@npm:^3.310.0": - version: 3.535.0 - resolution: "@aws-sdk/util-arn-parser@npm:3.535.0" +"@aws-sdk/util-arn-parser@npm:3.568.0, @aws-sdk/util-arn-parser@npm:^3.310.0": + version: 3.568.0 + resolution: "@aws-sdk/util-arn-parser@npm:3.568.0" dependencies: tslib: ^2.6.2 - checksum: 0e4c4ea080c7c6da00d359c337a1f9d961eac20c35cebad9cb6bb9b618f981955643990de7bfd6b53c29367a6d33550fe27b2a7539efdff08e01bdd303f0c5c2 + checksum: e3c45e5d524a772954d0a33614d397414185b9eb635423d01253cad1c1b9add625798ed9cf23343d156fae89c701f484bc062ab673f67e2e2edfe362fde6d170 languageName: node linkType: hard @@ -1534,15 +1533,15 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-endpoints@npm:3.540.0": - version: 3.540.0 - resolution: "@aws-sdk/util-endpoints@npm:3.540.0" +"@aws-sdk/util-endpoints@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/util-endpoints@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/types": ^2.12.0 - "@smithy/util-endpoints": ^1.2.0 + "@aws-sdk/types": 3.598.0 + "@smithy/types": ^3.1.0 + "@smithy/util-endpoints": ^2.0.2 tslib: ^2.6.2 - checksum: 62312773965480f8df5edb62ecf82ab3e54d5aa1b1f7eebdad78a2925eab47218b0268bc25a5d03598ac4d0c08935733031a2e3e1ce72531535ed1ea8a9b56c3 + checksum: 6fb92e8c99b6ce96cda21c9d1744a290c683bae8d82394c1b1fe7ed7d3cb0a18d4025b8863532680db3f550ad130e54d528c64a0a32f398f3c00c5ce2e043ecd languageName: node linkType: hard @@ -1594,32 +1593,32 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-user-agent-browser@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/util-user-agent-browser@npm:3.535.0" +"@aws-sdk/util-user-agent-browser@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@smithy/types": ^3.1.0 bowser: ^2.11.0 tslib: ^2.6.2 - checksum: 148b82900e4b9efd24f5fc4152a8d6010c90eb019517fa3c00c3ac42205055f7611ef3834fb63397def40e600ea20f901177a7dd5b6aefa2aef4208e994f7d90 + checksum: c53afc0fe7a07838ad22ae1e9ed6834d56a69cb0ad623d4912deeaa715af479b64266965fce30e7210e576118f80ceb525f79f504dc459fe0294fd15e694752e languageName: node linkType: hard -"@aws-sdk/util-user-agent-node@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/util-user-agent-node@npm:3.535.0" +"@aws-sdk/util-user-agent-node@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/node-config-provider": ^2.3.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 peerDependencies: aws-crt: ">=1.0.0" peerDependenciesMeta: aws-crt: optional: true - checksum: f214c406fccde14591d1df25fed662e573510cdf1d5829d22e7a93e517ea4a3905acd123eaaeafdb8b217400e8c8e159231d37be02b67307922023996b398f42 + checksum: 1560fabf19b236cfbce42769e1ef7e46bdad881b8a4b0ce069401d9a6edd5e1b195f45cb2847abf9ef1453d2e69447e7a3dabc92b037d9a41fe58960538db1ae languageName: node linkType: hard @@ -1642,13 +1641,13 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/xml-builder@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/xml-builder@npm:3.535.0" +"@aws-sdk/xml-builder@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/xml-builder@npm:3.598.0" dependencies: - "@smithy/types": ^2.12.0 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 9320f6600c7852b681ed4171f1521eda166321ef7ffea5a6b99a1d328835bb12f7423431ea23a696c678ec4fc8e6dbb2f979d941289f6e0cb55c3da7d5eee140 + checksum: 6b9fa385f749219d0a0654445e5deba54c7753d3e0da795dfc2bfdbaeb59fbfc8ef0e3f477c6aff6181a12a11ac87e3f84dedbbd1d1adb2c32941b149401abcf languageName: node linkType: hard @@ -15002,177 +15001,187 @@ __metadata: languageName: node linkType: hard -"@smithy/chunked-blob-reader-native@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/chunked-blob-reader-native@npm:2.2.0" +"@smithy/abort-controller@npm:^3.0.1, @smithy/abort-controller@npm:^3.1.0": + version: 3.1.0 + resolution: "@smithy/abort-controller@npm:3.1.0" dependencies: - "@smithy/util-base64": ^2.3.0 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: ac619f18844e8a8288672c40b8967a82b78f5398119638b3e4fcadf451a3356139307c2d9f24c8c041530238f1ce6e0f90ce82adfcb050d08afefa2f0541c2d0 + checksum: 78643bddda2bcb68e00bb95ae866741407236b92b1834796c0855710950386ae1e5e67d72fb42ec444e8a4dc4357a1527c4f331324a2fad156468f5a0cccf128 languageName: node linkType: hard -"@smithy/chunked-blob-reader@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/chunked-blob-reader@npm:2.2.0" +"@smithy/chunked-blob-reader-native@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/chunked-blob-reader-native@npm:3.0.0" dependencies: + "@smithy/util-base64": ^3.0.0 tslib: ^2.6.2 - checksum: f5acb1e812f97d7c233ccf955557ac10c7e94c8c9610d2fad715d1010fe30ee686a93a5d6e589ce8ae4eb7cf201d5eab61cee5e8646bbebdfa8a5f23693d7a5a + checksum: f97c0c0ce5e9bd2350883df3c232311aa82eb87eb387125f685900326f86fc3aca208e9004291f742f6978abf91a0c1112cc9a803cd0caf0dffbcfa9b6d0239e languageName: node linkType: hard -"@smithy/config-resolver@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/config-resolver@npm:2.2.0" +"@smithy/chunked-blob-reader@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/chunked-blob-reader@npm:3.0.0" dependencies: - "@smithy/node-config-provider": ^2.3.0 - "@smithy/types": ^2.12.0 - "@smithy/util-config-provider": ^2.3.0 - "@smithy/util-middleware": ^2.2.0 tslib: ^2.6.2 - checksum: dcb15d40faf46c370cd83dfbf1e632fae29c64c500b33b53850a520cfb02c9fa6f7e239c07824793b47645462567d51cb1554c02f9ec4531bd51bc759aede2ed + checksum: 6f520884ade14f1073adb640db2f03eb22a9920f342f37958df3e98327890b741cd909b16cbbc6f70c6c8dd250d6b3a8d76841b685d4871b0403f309267def4f languageName: node linkType: hard -"@smithy/core@npm:^1.4.2": - version: 1.4.2 - resolution: "@smithy/core@npm:1.4.2" +"@smithy/config-resolver@npm:^3.0.2, @smithy/config-resolver@npm:^3.0.3": + version: 3.0.3 + resolution: "@smithy/config-resolver@npm:3.0.3" dependencies: - "@smithy/middleware-endpoint": ^2.5.1 - "@smithy/middleware-retry": ^2.3.1 - "@smithy/middleware-serde": ^2.3.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/smithy-client": ^2.5.1 - "@smithy/types": ^2.12.0 - "@smithy/util-middleware": ^2.2.0 + "@smithy/node-config-provider": ^3.1.2 + "@smithy/types": ^3.2.0 + "@smithy/util-config-provider": ^3.0.0 + "@smithy/util-middleware": ^3.0.2 tslib: ^2.6.2 - checksum: 414ec1c392ab5346f2b833f310078d7e850df8b9e5db6fedbce65116146c2fda116d56db841401ba05b5e7399a5f5c426870d324bf6fd060143ce66e2f3eafbb + checksum: 7a7baf23e64ed85d4229bfd320a3ea96087c57ce1b94638a89bab5f92dcc24ec22c11740d90f2fab38eb39eeb860463ae98b24598555c2b55a01bd79c20ef99b languageName: node linkType: hard -"@smithy/credential-provider-imds@npm:^2.3.0": - version: 2.3.0 - resolution: "@smithy/credential-provider-imds@npm:2.3.0" +"@smithy/core@npm:^2.2.1": + version: 2.2.3 + resolution: "@smithy/core@npm:2.2.3" dependencies: - "@smithy/node-config-provider": ^2.3.0 - "@smithy/property-provider": ^2.2.0 - "@smithy/types": ^2.12.0 - "@smithy/url-parser": ^2.2.0 + "@smithy/middleware-endpoint": ^3.0.3 + "@smithy/middleware-retry": ^3.0.6 + "@smithy/middleware-serde": ^3.0.2 + "@smithy/protocol-http": ^4.0.2 + "@smithy/smithy-client": ^3.1.4 + "@smithy/types": ^3.2.0 + "@smithy/util-middleware": ^3.0.2 tslib: ^2.6.2 - checksum: dd57e09e60bd51ed103f7a5363a43e1373470ea3cee04ace66f5bbaafab005355ffbfa3e137e2ecac34aa28911fb5b6ecac60845846c6a4a5432f3e57a74b837 + checksum: 6addaede7f4699c48d690872647bbc86efc5bf9adb088557cfd4263e629e6bd7d45a1de983824a7c5ff608ec2cd42d7c6f61854d3d33b8ded352df550789b34b languageName: node linkType: hard -"@smithy/eventstream-codec@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/eventstream-codec@npm:2.2.0" +"@smithy/credential-provider-imds@npm:^3.1.1, @smithy/credential-provider-imds@npm:^3.1.2": + version: 3.1.2 + resolution: "@smithy/credential-provider-imds@npm:3.1.2" dependencies: - "@aws-crypto/crc32": 3.0.0 - "@smithy/types": ^2.12.0 - "@smithy/util-hex-encoding": ^2.2.0 + "@smithy/node-config-provider": ^3.1.2 + "@smithy/property-provider": ^3.1.2 + "@smithy/types": ^3.2.0 + "@smithy/url-parser": ^3.0.2 tslib: ^2.6.2 - checksum: ae59067964e19c6728b1be74a6e19793e4d3decdcbcea546bd40f77c3cc1eacc48c30272ef68927ba477c2b6450d023474f2dec516dfd93e204150ba18cab697 + checksum: bf0ce9f7c510f5f7e05d08c2b1d861f133016457e3872bfc5e4ac9b22f26123adcf773a562189971e2ce97bdad2f576a4eefb764808df2ae1833e77be86358f2 languageName: node linkType: hard -"@smithy/eventstream-serde-browser@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/eventstream-serde-browser@npm:2.2.0" +"@smithy/eventstream-codec@npm:^3.1.1": + version: 3.1.1 + resolution: "@smithy/eventstream-codec@npm:3.1.1" dependencies: - "@smithy/eventstream-serde-universal": ^2.2.0 - "@smithy/types": ^2.12.0 + "@aws-crypto/crc32": 5.2.0 + "@smithy/types": ^3.2.0 + "@smithy/util-hex-encoding": ^3.0.0 tslib: ^2.6.2 - checksum: c00bd592365f42ddafcad83f06d3c85ce8ee21bd806de903043ef132de9acca8bf1592ed811b11daba1742332928fc73a66c9032b06df2f6526da0339918f8d5 + checksum: fdc7a2bcf99f7c830ba24b5745877ec26556613423a025c6b122b167ef92a76a860f7dffe21f25667f12c2736a121f4e2064050dcf768406a60ce3ebc029e402 languageName: node linkType: hard -"@smithy/eventstream-serde-config-resolver@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/eventstream-serde-config-resolver@npm:2.2.0" +"@smithy/eventstream-serde-browser@npm:^3.0.2": + version: 3.0.3 + resolution: "@smithy/eventstream-serde-browser@npm:3.0.3" dependencies: - "@smithy/types": ^2.12.0 + "@smithy/eventstream-serde-universal": ^3.0.3 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: a35dbcbc14ad1825ce22a9e7daac93067d8ade6173a3ce33b819eed61390f8d93ea63b70945f6d1bced175fad58def3d09a14ee3043c63a798ecef407b2d1701 + checksum: 3e41fb32f06dc266ab41185482e441068c1e84ac5637462fc107511a495a7338972f10568bb57970e22eef2d14e024f93e0991b30b54545bca5b5189add5d41e languageName: node linkType: hard -"@smithy/eventstream-serde-node@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/eventstream-serde-node@npm:2.2.0" +"@smithy/eventstream-serde-config-resolver@npm:^3.0.1": + version: 3.0.2 + resolution: "@smithy/eventstream-serde-config-resolver@npm:3.0.2" dependencies: - "@smithy/eventstream-serde-universal": ^2.2.0 - "@smithy/types": ^2.12.0 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 1d4971b99654c4672716608a63e668ccefd78cc1806c0ea4df5c3cc0ca0208b7647f7914d2c77a37d0a29b31b66cff660ce2ab2f46f56d997c9a58ea6b6241b2 + checksum: 5c2113b6acc65df61f6fc844054c5a85825305e1d9f47987a5f350b603e304c8d90ad2c62cb7a098f10b7243c4f466fa413264821d261a3b69dc12c33fa976d4 languageName: node linkType: hard -"@smithy/eventstream-serde-universal@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/eventstream-serde-universal@npm:2.2.0" +"@smithy/eventstream-serde-node@npm:^3.0.2": + version: 3.0.3 + resolution: "@smithy/eventstream-serde-node@npm:3.0.3" dependencies: - "@smithy/eventstream-codec": ^2.2.0 - "@smithy/types": ^2.12.0 + "@smithy/eventstream-serde-universal": ^3.0.3 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: c28038c2f57deed7b5e0e5f8ab8150d4a7947f2971241da96ef1d53b45d83dfa661717065f059099c420ee66ae2455818ae124bb8601b609558040d4a7509227 + checksum: 29e2323b92a87302518ecfd75096e856c77a3d39ffa2680ff56e11c2c01b4434f56f86940e13c636e207af7cadf867f824f5c60249c53e1c27faa1cf932b6eb9 languageName: node linkType: hard -"@smithy/fetch-http-handler@npm:^2.5.0": - version: 2.5.0 - resolution: "@smithy/fetch-http-handler@npm:2.5.0" +"@smithy/eventstream-serde-universal@npm:^3.0.3": + version: 3.0.3 + resolution: "@smithy/eventstream-serde-universal@npm:3.0.3" dependencies: - "@smithy/protocol-http": ^3.3.0 - "@smithy/querystring-builder": ^2.2.0 - "@smithy/types": ^2.12.0 - "@smithy/util-base64": ^2.3.0 + "@smithy/eventstream-codec": ^3.1.1 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 91a58ac32c6b4afc6d7fb2b9ac3e3b817171f76e09b013a6506308b044455054444a92e1acbd8f98bdd159b15fdd44b1e3fb52c21cbb2e69be8e3698d2206021 + checksum: 6c0c3602e3e79bb0abe47f1d7b8c277f58879ab613cda99d80cf0e825653055f892daee313e6d40e5096932e004838e3c9f674e440b97921520257f80337bed8 languageName: node linkType: hard -"@smithy/hash-blob-browser@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/hash-blob-browser@npm:2.2.0" +"@smithy/fetch-http-handler@npm:^3.0.2, @smithy/fetch-http-handler@npm:^3.1.0": + version: 3.1.0 + resolution: "@smithy/fetch-http-handler@npm:3.1.0" dependencies: - "@smithy/chunked-blob-reader": ^2.2.0 - "@smithy/chunked-blob-reader-native": ^2.2.0 - "@smithy/types": ^2.12.0 + "@smithy/protocol-http": ^4.0.2 + "@smithy/querystring-builder": ^3.0.2 + "@smithy/types": ^3.2.0 + "@smithy/util-base64": ^3.0.0 tslib: ^2.6.2 - checksum: 1b748b4449ccee723c8b47a412491283fa7b5a2a6c27b0b73e03d905c2af70b56b74d63a658d8ef0bd330cc4617bc11431c86e24a4932b4722aad08e1b25e576 + checksum: 7b9b928e8a094e41a9c7516aa2fcfd3bb88b0271737e1d4fa301973a49f577094fa967ba481a0cf6e5c977be6bb8b2898d868b3269a476cae2aaaed582277733 languageName: node linkType: hard -"@smithy/hash-node@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/hash-node@npm:2.2.0" +"@smithy/hash-blob-browser@npm:^3.1.0": + version: 3.1.1 + resolution: "@smithy/hash-blob-browser@npm:3.1.1" dependencies: - "@smithy/types": ^2.12.0 - "@smithy/util-buffer-from": ^2.2.0 - "@smithy/util-utf8": ^2.3.0 + "@smithy/chunked-blob-reader": ^3.0.0 + "@smithy/chunked-blob-reader-native": ^3.0.0 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 3305b5778fa99558375b16629ad98fd00a1fb33ea905037977b0a7c93d92c8de1481756ef7dbc004e45210b23f983dec04bcd13d43c98f36a5f47291cbed9d89 + checksum: 9a54f0b7d48d5a411c2e3361f8a946d71b75d54965bc3d2a0524d0fe01fc032c2ee2a4e105104daefa14e3e02f0e38b9e83faf0b40d3933a33b87d8b8b142c8f languageName: node linkType: hard -"@smithy/hash-stream-node@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/hash-stream-node@npm:2.2.0" +"@smithy/hash-node@npm:^3.0.1": + version: 3.0.2 + resolution: "@smithy/hash-node@npm:3.0.2" dependencies: - "@smithy/types": ^2.12.0 - "@smithy/util-utf8": ^2.3.0 + "@smithy/types": ^3.2.0 + "@smithy/util-buffer-from": ^3.0.0 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 191d76fd1df705c32d24463794f8b8b391061c7ca7265591cd4f070259fa80395c2f115fd3d37f6bb3a4a2303b3811a31509ea767d0c3d0a9644789ae8283118 + checksum: 2b7b678d429b9806a28f18472f8beec45f5a2e1d004b084cc4b591c1239565c46435b278c7f76be09790d6d6eabc617e7d0f3aef11c375721b78600506d62856 languageName: node linkType: hard -"@smithy/invalid-dependency@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/invalid-dependency@npm:2.2.0" +"@smithy/hash-stream-node@npm:^3.1.0": + version: 3.1.1 + resolution: "@smithy/hash-stream-node@npm:3.1.1" dependencies: - "@smithy/types": ^2.12.0 + "@smithy/types": ^3.2.0 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: ed17980ccdf4c564cfcb517f3959dfeb7c7dbddd76eaf2c9e10031ebd19e78e56609df3377626215e51a6c4b98db03cfa88ad46f15ba26bb55c34351f3182a98 + checksum: 21d4d8ffca488a1aa83d97eb418197ca4b9c25329ce2d67a5978cd4b74ee7e609ebcb510fce3a271ce240b5e421073cda516e23cde7d9fedbb682ee02d7b7c9f + languageName: node + linkType: hard + +"@smithy/invalid-dependency@npm:^3.0.1": + version: 3.0.2 + resolution: "@smithy/invalid-dependency@npm:3.0.2" + dependencies: + "@smithy/types": ^3.2.0 + tslib: ^2.6.2 + checksum: 21f0f2669989d9b8ffdc86e80fa8d0a39b5ada187a21c61bc4405936a31fa054a59577fa8fde4de707de559cc3e08c80aaac0205aaacf0eaf3a2ff620fa12830 languageName: node linkType: hard @@ -15185,93 +15194,102 @@ __metadata: languageName: node linkType: hard -"@smithy/md5-js@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/md5-js@npm:2.2.0" +"@smithy/is-array-buffer@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/is-array-buffer@npm:3.0.0" dependencies: - "@smithy/types": ^2.12.0 - "@smithy/util-utf8": ^2.3.0 tslib: ^2.6.2 - checksum: ae343c198a8d8c6689bcb1d7f766e29578d370e8d79180db9b6183b5c74ac091829e8abe3053df0589f53324c01a79c7f9e889e5cd92094e3b5c4be96fb7b970 + checksum: ce7440fcb1ce3c46722cff11c33e2f62a9df86d74fa2054a8e6b540302a91211cf6e4e3b1b7aac7030c6c8909158c1b6867c394201fa8afc6b631979956610e5 languageName: node linkType: hard -"@smithy/middleware-content-length@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/middleware-content-length@npm:2.2.0" +"@smithy/md5-js@npm:^3.0.1": + version: 3.0.2 + resolution: "@smithy/md5-js@npm:3.0.2" dependencies: - "@smithy/protocol-http": ^3.3.0 - "@smithy/types": ^2.12.0 + "@smithy/types": ^3.2.0 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 1eae8d2b6f432ce9a849e741d4f2426baee8a51f22a5262c11802e125078ee33d9d8f4183fb142043ba9d1371adad9c835c784333a394d865fb248339f7482e6 + checksum: cc8857d043b53234ce280776ac7592ed6287c911d7ac45d3b9836adbf01b9e814a1f164b8a8c5b654bde14e8ce4baed17494b983d4cfee61584da623f9b794e5 languageName: node linkType: hard -"@smithy/middleware-endpoint@npm:^2.5.1": - version: 2.5.1 - resolution: "@smithy/middleware-endpoint@npm:2.5.1" +"@smithy/middleware-content-length@npm:^3.0.1": + version: 3.0.2 + resolution: "@smithy/middleware-content-length@npm:3.0.2" dependencies: - "@smithy/middleware-serde": ^2.3.0 - "@smithy/node-config-provider": ^2.3.0 - "@smithy/shared-ini-file-loader": ^2.4.0 - "@smithy/types": ^2.12.0 - "@smithy/url-parser": ^2.2.0 - "@smithy/util-middleware": ^2.2.0 + "@smithy/protocol-http": ^4.0.2 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 7ac2a35a6f52c33d868fc4b73330ae34fecfc43c59b8d501ee9fb81924c6747494700b55b3025b83fe7bea3d4e323c8853ec5b117c17cccf06cc27bbc4f492b2 + checksum: 67758207c3a26eb6d44fd922d178299418fc42a07937813364a17a76547bf736df75d279cb493fca9ac5c3897c0c8d24c6e124f3edc143c991a26b44521eb423 languageName: node linkType: hard -"@smithy/middleware-retry@npm:^2.3.1": - version: 2.3.1 - resolution: "@smithy/middleware-retry@npm:2.3.1" +"@smithy/middleware-endpoint@npm:^3.0.2, @smithy/middleware-endpoint@npm:^3.0.3": + version: 3.0.3 + resolution: "@smithy/middleware-endpoint@npm:3.0.3" dependencies: - "@smithy/node-config-provider": ^2.3.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/service-error-classification": ^2.1.5 - "@smithy/smithy-client": ^2.5.1 - "@smithy/types": ^2.12.0 - "@smithy/util-middleware": ^2.2.0 - "@smithy/util-retry": ^2.2.0 + "@smithy/middleware-serde": ^3.0.2 + "@smithy/node-config-provider": ^3.1.2 + "@smithy/shared-ini-file-loader": ^3.1.2 + "@smithy/types": ^3.2.0 + "@smithy/url-parser": ^3.0.2 + "@smithy/util-middleware": ^3.0.2 + tslib: ^2.6.2 + checksum: 15a37293aa590bd0c8ab59430e967f786500603bca92dbde655480c3b7c1812a8cbcd267ff31691c2d8ea596f7917769ef91fa4033e07ec9971bf252fc12ebcd + languageName: node + linkType: hard + +"@smithy/middleware-retry@npm:^3.0.4, @smithy/middleware-retry@npm:^3.0.6": + version: 3.0.6 + resolution: "@smithy/middleware-retry@npm:3.0.6" + dependencies: + "@smithy/node-config-provider": ^3.1.2 + "@smithy/protocol-http": ^4.0.2 + "@smithy/service-error-classification": ^3.0.2 + "@smithy/smithy-client": ^3.1.4 + "@smithy/types": ^3.2.0 + "@smithy/util-middleware": ^3.0.2 + "@smithy/util-retry": ^3.0.2 tslib: ^2.6.2 uuid: ^9.0.1 - checksum: 5eebf9d26fccc6c8c517924463e93d244edebe52d120b28d5d705904f83773da1734296b8d57b4f30a15cbf36690e508f5946dfd56749cbcda501d08cb778933 + checksum: c17ac5665e0dd2315e996c219b5aa2327c9270a49ca7dc64b8d81c80261f9d0098d3725641f2e4c87aac293c283d709fb062b5c7be6912e72f9042492a3e91d9 languageName: node linkType: hard -"@smithy/middleware-serde@npm:^2.3.0": - version: 2.3.0 - resolution: "@smithy/middleware-serde@npm:2.3.0" +"@smithy/middleware-serde@npm:^3.0.1, @smithy/middleware-serde@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/middleware-serde@npm:3.0.2" dependencies: - "@smithy/types": ^2.12.0 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 5393370c0f8a820d8ca36eccecff5b6434c4f81fbaad8800088fb4c8dad5312bf3eb47f67533784de959807bbb3379c23d81a1bcbaf8824254034dd2b83fd76b + checksum: 16c933ecb8061ff9fcf49ecabcc54b6d56de0e02464e5dd995ac729ad06e70be7a341c329b0b7cc1b33c8dbaa31372e337130e9eb6aac4c2df63ce37cb36d54f languageName: node linkType: hard -"@smithy/middleware-stack@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/middleware-stack@npm:2.2.0" +"@smithy/middleware-stack@npm:^3.0.1, @smithy/middleware-stack@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/middleware-stack@npm:3.0.2" dependencies: - "@smithy/types": ^2.12.0 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 293d76764e327a5ada4ea7de268f451e62a6a56983ba7dcdbc63fdbb0427c01071a9a81d7807b16586977df829ce5d9587facbd9367b089841bbc9fc329ce6af + checksum: 70ec59d020ae6d8c53aefecb039fb511cfa67a57ce00ba1e41d2c3da346265cc18bdf1e0724b0df10f1ef838807e151e93f6da6e886fafbac51d2ed962b795d1 languageName: node linkType: hard -"@smithy/node-config-provider@npm:^2.3.0": - version: 2.3.0 - resolution: "@smithy/node-config-provider@npm:2.3.0" +"@smithy/node-config-provider@npm:^3.1.1, @smithy/node-config-provider@npm:^3.1.2": + version: 3.1.2 + resolution: "@smithy/node-config-provider@npm:3.1.2" dependencies: - "@smithy/property-provider": ^2.2.0 - "@smithy/shared-ini-file-loader": ^2.4.0 - "@smithy/types": ^2.12.0 + "@smithy/property-provider": ^3.1.2 + "@smithy/shared-ini-file-loader": ^3.1.2 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 9c1dc6d97e0379d947498e7d64e593ea183d5f2c89dace4561c1c613850bf264581b597105c15d64ceabdea954e57ad8e6bf9e42642ddc3f737464f350ffbb5b + checksum: 596e7a6b92fa68f6c172969bde6a04aadf35634f78a601351642b44bc271f3ad5444588a8c3dea8f7cdbe65a2d69e1c1d93291bf8d240736a035ac8db4e96ce3 languageName: node linkType: hard -"@smithy/node-http-handler@npm:^2.1.7, @smithy/node-http-handler@npm:^2.5.0": +"@smithy/node-http-handler@npm:^2.1.7": version: 2.5.0 resolution: "@smithy/node-http-handler@npm:2.5.0" dependencies: @@ -15284,13 +15302,26 @@ __metadata: languageName: node linkType: hard -"@smithy/property-provider@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/property-provider@npm:2.2.0" +"@smithy/node-http-handler@npm:^3.0.1, @smithy/node-http-handler@npm:^3.1.0": + version: 3.1.0 + resolution: "@smithy/node-http-handler@npm:3.1.0" dependencies: - "@smithy/types": ^2.12.0 + "@smithy/abort-controller": ^3.1.0 + "@smithy/protocol-http": ^4.0.2 + "@smithy/querystring-builder": ^3.0.2 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 8d257cbc5222baf6706e288c3b51196588f135878141f8af76fcb3f0abafc027ed46cf4bb938266d1906111175082ee85f73806d5a2b1c929aee16ec8b5283e6 + checksum: 915cc2876cfe5b2330e868aa512930d4c126192d7695354dc2a88aab1c6639968ace36c1e8778c8a647a8b6f3f3faac2a14870607043cba972e05ee94491738a + languageName: node + linkType: hard + +"@smithy/property-provider@npm:^3.1.1, @smithy/property-provider@npm:^3.1.2": + version: 3.1.2 + resolution: "@smithy/property-provider@npm:3.1.2" + dependencies: + "@smithy/types": ^3.2.0 + tslib: ^2.6.2 + checksum: 9ec0cce2728dd4a0d327fef523ca5bddcba9a7750e6e5a614293d6ba4c12d6b86c32020689481a529b4797d07315fd84647f13ea0dbe91f1da7932c954b08421 languageName: node linkType: hard @@ -15304,6 +15335,16 @@ __metadata: languageName: node linkType: hard +"@smithy/protocol-http@npm:^4.0.1, @smithy/protocol-http@npm:^4.0.2": + version: 4.0.2 + resolution: "@smithy/protocol-http@npm:4.0.2" + dependencies: + "@smithy/types": ^3.2.0 + tslib: ^2.6.2 + checksum: e1b419e0324f20300c490491cbc32b9d151579a6ce11f708b76ed265ef3499d404d9c0e3443692984514a0f8042b456f5c7e1a62694d42c7dc9bc64bfcff0301 + languageName: node + linkType: hard + "@smithy/querystring-builder@npm:^2.2.0": version: 2.2.0 resolution: "@smithy/querystring-builder@npm:2.2.0" @@ -15315,61 +15356,72 @@ __metadata: languageName: node linkType: hard -"@smithy/querystring-parser@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/querystring-parser@npm:2.2.0" +"@smithy/querystring-builder@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/querystring-builder@npm:3.0.2" dependencies: - "@smithy/types": ^2.12.0 + "@smithy/types": ^3.2.0 + "@smithy/util-uri-escape": ^3.0.0 tslib: ^2.6.2 - checksum: 9b27751c329fecc84bdfe7f128ab766c7e5f1d4bdda6184699a0df8999e95aef21fafc6179d6c693e519c78874e738fd9afb5ac4679901cb68d092a86a612419 + checksum: c6f6fc8681879daed9c85b3fd2d81cbbf553addbdc1d6ab2660687d967af40eba0112e40cf1157bdd4c42784bc22977a3da9ed9dde674b7ede5e70720a0b38af languageName: node linkType: hard -"@smithy/service-error-classification@npm:^2.1.5": - version: 2.1.5 - resolution: "@smithy/service-error-classification@npm:2.1.5" +"@smithy/querystring-parser@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/querystring-parser@npm:3.0.2" dependencies: - "@smithy/types": ^2.12.0 - checksum: 00ac54110a258c7a47c62d4f655d4998bd40e5adb47e10281b28df7a585f2f1e960dc35325eac006636280e7fb2b81dbeb32b89e08bac87acc136c4d29a4dc53 + "@smithy/types": ^3.2.0 + tslib: ^2.6.2 + checksum: 7f18281e8d73c70dc020e1a8719a8322d88130c24e8c8cffa39ffe83e9f18d28bb9d420e6026ddb17d60ac950b0fb5b9465a4ba8493086e6186f60a9573b2ad8 languageName: node linkType: hard -"@smithy/shared-ini-file-loader@npm:^2.4.0": - version: 2.4.0 - resolution: "@smithy/shared-ini-file-loader@npm:2.4.0" +"@smithy/service-error-classification@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/service-error-classification@npm:3.0.2" dependencies: - "@smithy/types": ^2.12.0 - tslib: ^2.6.2 - checksum: b0c9e045bfe2150e07f4b31ae7d69d3646679337df9fec1e1201b845cc64ea2250c37db8e8d0e7573fc3c11188164adba43bbaf32275fa8a9f70e8bbc77146bf + "@smithy/types": ^3.2.0 + checksum: f7cfd6438286942ec1f7f059c4bdac517c64833fcbea27198880106c7e55d0c2083f0c8e22c8fe5a68f0d86e5bd33a78f644898b48008b2f14c0c13d46f0923c languageName: node linkType: hard -"@smithy/signature-v4@npm:^2.3.0": - version: 2.3.0 - resolution: "@smithy/signature-v4@npm:2.3.0" +"@smithy/shared-ini-file-loader@npm:^3.1.1, @smithy/shared-ini-file-loader@npm:^3.1.2": + version: 3.1.2 + resolution: "@smithy/shared-ini-file-loader@npm:3.1.2" dependencies: - "@smithy/is-array-buffer": ^2.2.0 - "@smithy/types": ^2.12.0 - "@smithy/util-hex-encoding": ^2.2.0 - "@smithy/util-middleware": ^2.2.0 - "@smithy/util-uri-escape": ^2.2.0 - "@smithy/util-utf8": ^2.3.0 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 96050956b86876d0137af9b003d0a30005766bffc730495d7c106bd2eb05c8ada2da23ceac51d56e04f98b304e0ea55d698e1a10c99cda3ade44b3ac30166a00 + checksum: bbb7ceaefdcbe4e43e5a65cf424e41f6a70e44fc9b05b7f8c968bd6134253e04af4455ad0fa91fda18f55695b7992c8bfc5281aa201be2a69f7733014fd84042 languageName: node linkType: hard -"@smithy/smithy-client@npm:^2.5.1": - version: 2.5.1 - resolution: "@smithy/smithy-client@npm:2.5.1" +"@smithy/signature-v4@npm:^3.1.0": + version: 3.1.1 + resolution: "@smithy/signature-v4@npm:3.1.1" dependencies: - "@smithy/middleware-endpoint": ^2.5.1 - "@smithy/middleware-stack": ^2.2.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/types": ^2.12.0 - "@smithy/util-stream": ^2.2.0 + "@smithy/is-array-buffer": ^3.0.0 + "@smithy/types": ^3.2.0 + "@smithy/util-hex-encoding": ^3.0.0 + "@smithy/util-middleware": ^3.0.2 + "@smithy/util-uri-escape": ^3.0.0 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 10d51793aab8f6e0ba0890a2a101216ffc3a1c43664f8ed9688dcbc174ca0f83f2d1c8d7af484c84491174067af3d6b235b765a58b12f2308a6bfe42b1d74f59 + checksum: f7eca9889ac4252e8fff76bf31a75bbc8afebc7ac690e3fddffadaccde64fd05305b6e22ad00f8d8da3bb3ca8739d310d6abe70350a4c12c996fb0335a8bd975 + languageName: node + linkType: hard + +"@smithy/smithy-client@npm:^3.1.2, @smithy/smithy-client@npm:^3.1.4": + version: 3.1.4 + resolution: "@smithy/smithy-client@npm:3.1.4" + dependencies: + "@smithy/middleware-endpoint": ^3.0.3 + "@smithy/middleware-stack": ^3.0.2 + "@smithy/protocol-http": ^4.0.2 + "@smithy/types": ^3.2.0 + "@smithy/util-stream": ^3.0.4 + tslib: ^2.6.2 + checksum: be1ce3523d5b49d1c2fb75695201dcc3748583050675efc7910b0a8bc9444c781daf435bec711166e6d2f0238ed301187283362c33aa31aefd2c21b09fb305a5 languageName: node linkType: hard @@ -15391,43 +15443,52 @@ __metadata: languageName: node linkType: hard -"@smithy/url-parser@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/url-parser@npm:2.2.0" +"@smithy/types@npm:^3.1.0, @smithy/types@npm:^3.2.0": + version: 3.2.0 + resolution: "@smithy/types@npm:3.2.0" dependencies: - "@smithy/querystring-parser": ^2.2.0 - "@smithy/types": ^2.12.0 tslib: ^2.6.2 - checksum: f21f1e44bc2a4634220465990651f5ee0708cb6759b3685b8a8c00cc2cd64bbbc7807f66cd79ec6e654f7245867d4fb4ced406ad5c14612ebc47eae3f34e63c5 + checksum: f07caa63cd2f1ed9a14612a9493fcc9c0aca974593e16c1328daecc7f36af2ece5e5e79c24212966180f88a183abf078bfbcd98cf362a8d8f95f3f8642d41389 languageName: node linkType: hard -"@smithy/util-base64@npm:^2.3.0": - version: 2.3.0 - resolution: "@smithy/util-base64@npm:2.3.0" +"@smithy/url-parser@npm:^3.0.1, @smithy/url-parser@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/url-parser@npm:3.0.2" dependencies: - "@smithy/util-buffer-from": ^2.2.0 - "@smithy/util-utf8": ^2.3.0 + "@smithy/querystring-parser": ^3.0.2 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 2ce995c5d12037e9518bb2732f24090bc493d48118dfd6519faa41e19cd91863895bc0b5958b790d2cdeb919a8c410790dcffa3a452d560f0eeab73dc0c92cbd + checksum: a0dac1ff3eac440d3dba7f2ad80eb3cfb46cf912ceb4a533b0bd87ad5b5f1e9b641ca9a247844129c33dc2901cbe753c89185b70c6d323b781b83451a738702e languageName: node linkType: hard -"@smithy/util-body-length-browser@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/util-body-length-browser@npm:2.2.0" +"@smithy/util-base64@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-base64@npm:3.0.0" dependencies: + "@smithy/util-buffer-from": ^3.0.0 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: e9c1d16b3b95d529011476e6154eaf282d3a983204b29dcf1e7ef04a9f5c2deae30167e06190f315771c813c768f19f486d3139fe9fcaf34d12c2333350f3412 + checksum: 413f26046a7e98b2661a078f218a8d040c820fc5a02f5e364aff58c3957e28fde1ac4048c2ebbad5d87b9da4b9aa98a8d4a7fb0d2ce97def33738bd7d8d79aa0 languageName: node linkType: hard -"@smithy/util-body-length-node@npm:^2.3.0": - version: 2.3.0 - resolution: "@smithy/util-body-length-node@npm:2.3.0" +"@smithy/util-body-length-browser@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-body-length-browser@npm:3.0.0" dependencies: tslib: ^2.6.2 - checksum: 5d5c31b071e0b3222dcfe863ea2d179253f0dfaa30d03f40ebfa352ed292e00a451053cc523e27527e61094d5ed475069d2287ef19a857c6da0364ca71cfdf3c + checksum: b01d8258b9a25b262734fc49cefefe48583ba193c3eefd49a6f7fd5922c3015d23dda88b52f3dd9a16827cad16b5b9425eef01e91bd0c71bb5abc469d2952c07 + languageName: node + linkType: hard + +"@smithy/util-body-length-node@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-body-length-node@npm:3.0.0" + dependencies: + tslib: ^2.6.2 + checksum: da1baf4790609d3dc28c88385c7274fdf9b91a641fe3c5af22b78e18156df17bd470181348f43b2c739680936b1dafb1526158dfd817c3d9ecb71e653b4cbe3f languageName: node linkType: hard @@ -15441,97 +15502,107 @@ __metadata: languageName: node linkType: hard -"@smithy/util-config-provider@npm:^2.3.0": - version: 2.3.0 - resolution: "@smithy/util-config-provider@npm:2.3.0" +"@smithy/util-buffer-from@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-buffer-from@npm:3.0.0" dependencies: + "@smithy/is-array-buffer": ^3.0.0 tslib: ^2.6.2 - checksum: 0f3f113c2658bd5a79f98dc28d53ca9c0adf8ec3c8c86c7dd91d2cd37149b4cf83d85cc89d5fe67ffe5cd319ec85f139ef229844eb039017193b307a4c315399 + checksum: 1bfc4ab093fe98132bbc1ccd36a0b9ad75a31ed26bac4b7e9350205513a2481eb190ae44679ab4fecc5e10d367b5e6592bbfbf792671579d17d17bd7f7f233f5 languageName: node linkType: hard -"@smithy/util-defaults-mode-browser@npm:^2.2.1": - version: 2.2.1 - resolution: "@smithy/util-defaults-mode-browser@npm:2.2.1" +"@smithy/util-config-provider@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-config-provider@npm:3.0.0" dependencies: - "@smithy/property-provider": ^2.2.0 - "@smithy/smithy-client": ^2.5.1 - "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: fc0f5f57d30261cf3a6693d8e338b9d269332c478ee18d905309a769844188190caf0564855d7e84f6c61e56aa556195dda89f65e8c30791951cf4999e4a70e7 + languageName: node + linkType: hard + +"@smithy/util-defaults-mode-browser@npm:^3.0.4": + version: 3.0.6 + resolution: "@smithy/util-defaults-mode-browser@npm:3.0.6" + dependencies: + "@smithy/property-provider": ^3.1.2 + "@smithy/smithy-client": ^3.1.4 + "@smithy/types": ^3.2.0 bowser: ^2.11.0 tslib: ^2.6.2 - checksum: 286337d9165181e1df3d28d348210e88f20662ec63a9d6c1bcfce3342003de130a218dab42ce64aa4399ef345e2528414f73f399f8f4c8e9a6fcbc8e48250f98 + checksum: 753e21d8b6c9cbfb874dd9468823bce7ebfa979da8972fb5c67a31333513cebe09072fcb9ae803219bf41775569c8277e49f83abd96041042d3c487d299c7a0a languageName: node linkType: hard -"@smithy/util-defaults-mode-node@npm:^2.3.1": - version: 2.3.1 - resolution: "@smithy/util-defaults-mode-node@npm:2.3.1" +"@smithy/util-defaults-mode-node@npm:^3.0.4": + version: 3.0.6 + resolution: "@smithy/util-defaults-mode-node@npm:3.0.6" dependencies: - "@smithy/config-resolver": ^2.2.0 - "@smithy/credential-provider-imds": ^2.3.0 - "@smithy/node-config-provider": ^2.3.0 - "@smithy/property-provider": ^2.2.0 - "@smithy/smithy-client": ^2.5.1 - "@smithy/types": ^2.12.0 + "@smithy/config-resolver": ^3.0.3 + "@smithy/credential-provider-imds": ^3.1.2 + "@smithy/node-config-provider": ^3.1.2 + "@smithy/property-provider": ^3.1.2 + "@smithy/smithy-client": ^3.1.4 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 7fb9d0ac8b5919955399284c1801f49a1f5275f6cf240894ba0a91a8825248bb167938647a983d89905d6bfa7b226789781e85d2ff7f27c58cdd32c2e68600ae + checksum: d64efd2b5bd7b4b3b1a668725d34018bd8cae00b8a59991eadabf122e590ad153be4f9beda58b063b451d9f03371575c9a8e2806bcc0b7790e63fc9d839f5c95 languageName: node linkType: hard -"@smithy/util-endpoints@npm:^1.2.0": - version: 1.2.0 - resolution: "@smithy/util-endpoints@npm:1.2.0" +"@smithy/util-endpoints@npm:^2.0.2": + version: 2.0.3 + resolution: "@smithy/util-endpoints@npm:2.0.3" dependencies: - "@smithy/node-config-provider": ^2.3.0 - "@smithy/types": ^2.12.0 + "@smithy/node-config-provider": ^3.1.2 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 19a59b1c9b214457371d4d7109b190c237de5ebd06f5b4f3665dddc5fe0879dbb19bcdc5dec23d1825cd04388b7f9bf7fddf354e1a23e84d9c690ad21e71cb86 + checksum: f8b77a7f68bd99b73362b29a56e35270b509f76ed82c003e82dae1468f46c2c986060aea1fcb78f3d9346830f62c1c3f3e0aa4de856b8897ba183efabc22969d languageName: node linkType: hard -"@smithy/util-hex-encoding@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/util-hex-encoding@npm:2.2.0" +"@smithy/util-hex-encoding@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-hex-encoding@npm:3.0.0" dependencies: tslib: ^2.6.2 - checksum: 7d14589bc4a44eebf878595290c53ee4d90cc6b5445b5fe130608d6dea477c292730b85e4e08190a1555ef7664214f0f00dc478ba725516787a49fff658e725e + checksum: dd32fd71e915825987a18bf7c0f8f0c4956d0b17a0ee71592b5563bb20e04f24dbf81d36161aac07caab3bb5e535cc609fce20aa4a38f66b457c4c6f5c7748d9 languageName: node linkType: hard -"@smithy/util-middleware@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/util-middleware@npm:2.2.0" +"@smithy/util-middleware@npm:^3.0.1, @smithy/util-middleware@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/util-middleware@npm:3.0.2" dependencies: - "@smithy/types": ^2.12.0 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 312dc86e5415a12e2580a02311750b350aec8fb9da5a60c3010c10694990ded869b7ca5b87aa20e5facbacdd233e928e418b7765d7797019cd48177052aedd03 + checksum: 8a6183d3fd4a7c01787fbfd1dd901b1cdf0937f3c5e73646e8377b1e3322782e191cb7c1c9278e6c84d7462d4b0e70bcac9cfca52367728b3357914db96f90cc languageName: node linkType: hard -"@smithy/util-retry@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/util-retry@npm:2.2.0" +"@smithy/util-retry@npm:^3.0.1, @smithy/util-retry@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/util-retry@npm:3.0.2" dependencies: - "@smithy/service-error-classification": ^2.1.5 - "@smithy/types": ^2.12.0 + "@smithy/service-error-classification": ^3.0.2 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 1a8071c8ac5a2646b3d3894e3bd9c36a9db045f52eadb194f32b02d2fdedd69fb267a2b02bcef9f91d0f8f3fe061754ac075d07ac166d90894acb27d68c62a41 + checksum: 68846a52a6c71658db40f54681afad8c9bdb4687dc3c12fd13c27cf9aa3b96c57469a4d5658d4caabc9c710d95f920c0a3faafc9503fb99fb6466f51072fe852 languageName: node linkType: hard -"@smithy/util-stream@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/util-stream@npm:2.2.0" +"@smithy/util-stream@npm:^3.0.2, @smithy/util-stream@npm:^3.0.4": + version: 3.0.4 + resolution: "@smithy/util-stream@npm:3.0.4" dependencies: - "@smithy/fetch-http-handler": ^2.5.0 - "@smithy/node-http-handler": ^2.5.0 - "@smithy/types": ^2.12.0 - "@smithy/util-base64": ^2.3.0 - "@smithy/util-buffer-from": ^2.2.0 - "@smithy/util-hex-encoding": ^2.2.0 - "@smithy/util-utf8": ^2.3.0 + "@smithy/fetch-http-handler": ^3.1.0 + "@smithy/node-http-handler": ^3.1.0 + "@smithy/types": ^3.2.0 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-buffer-from": ^3.0.0 + "@smithy/util-hex-encoding": ^3.0.0 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: f0febd1a7558201d9178c0018478f89729800e9b8962dc735ec99f41ce01d1128373e3bd6008f0b4ff79b25ee4476db4fd5fa18d6feeb8b5b715d416da7027c3 + checksum: ba4a785d30606e82cbf80e644be05fad7a1813e19226ec8893a91993e0c943bc222643ab9c70625f72ee760b4f4d1632e74af586e028e7d3dc8197b1927e580b languageName: node linkType: hard @@ -15544,7 +15615,16 @@ __metadata: languageName: node linkType: hard -"@smithy/util-utf8@npm:^2.0.0, @smithy/util-utf8@npm:^2.3.0": +"@smithy/util-uri-escape@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-uri-escape@npm:3.0.0" + dependencies: + tslib: ^2.6.2 + checksum: d7ee01c978e2b08d0a89a3b678f5d5e5d5bb4ab4ab85567a238b1a6195dff1bdaf9ae62497e7f32ff5121b3dc007c370bcb6e8ef79b01fe5acdec5bbce8c7ce4 + languageName: node + linkType: hard + +"@smithy/util-utf8@npm:^2.0.0": version: 2.3.0 resolution: "@smithy/util-utf8@npm:2.3.0" dependencies: @@ -15554,14 +15634,24 @@ __metadata: languageName: node linkType: hard -"@smithy/util-waiter@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/util-waiter@npm:2.2.0" +"@smithy/util-utf8@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-utf8@npm:3.0.0" dependencies: - "@smithy/abort-controller": ^2.2.0 - "@smithy/types": ^2.12.0 + "@smithy/util-buffer-from": ^3.0.0 tslib: ^2.6.2 - checksum: 303f56beb9ba4afada862eff4950a17d904a4fdfc01bd8acb932b0457e457730981162777004414252e700014c554d894a1ce9d32e0bad75e1a4a2ca6492429e + checksum: d97be1748963263a1161ba80417d82318b977b38542f3fdf0379b0162461188be680e5bfb66a89d65652f0fad6ecf2ab23a43205979216e50602488f73434da3 + languageName: node + linkType: hard + +"@smithy/util-waiter@npm:^3.0.1": + version: 3.1.1 + resolution: "@smithy/util-waiter@npm:3.1.1" + dependencies: + "@smithy/abort-controller": ^3.1.0 + "@smithy/types": ^3.2.0 + tslib: ^2.6.2 + checksum: dda2666bc0c91a158fdcd04eab41f01130b5d34a9d8a86ea5ed9a8d1c87829caf381fda34a0595bf4748e99365a36842afe12fbf045f532c55f0d14f49c6a448 languageName: node linkType: hard From 5f0a3eea33af613ca92a47adac689c78fc2dfaf8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 26 Jun 2024 22:29:47 +0000 Subject: [PATCH 102/510] chore(deps): update dependency nodemon to v3.1.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 08218f6ee9..831fdf7e92 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34903,8 +34903,8 @@ __metadata: linkType: hard "nodemon@npm:^3.0.1": - version: 3.1.3 - resolution: "nodemon@npm:3.1.3" + version: 3.1.4 + resolution: "nodemon@npm:3.1.4" dependencies: chokidar: ^3.5.2 debug: ^4 @@ -34918,7 +34918,7 @@ __metadata: undefsafe: ^2.0.5 bin: nodemon: bin/nodemon.js - checksum: ac2fa8865ab292b7ddf66731487acca4b4282b2728361e0de633c0c74cd705d6a0852b52f785c09469d959241d038ba824f50375622e687a2a318be747d9cd9d + checksum: 3f003fc2c7bdaba559108320f188b7cb063220455e5da218ff3bf4f7468ad7059852da6e35a52b8c690cc27f6e36a433a9ad1f1bdb8096ec1ee3d930629cbeca languageName: node linkType: hard From 9ca6af45fc07c5692efcfd170db0682f8538034a Mon Sep 17 00:00:00 2001 From: Kevin L Date: Wed, 26 Jun 2024 18:55:32 -0400 Subject: [PATCH 103/510] Minor fix in the homepage setup and customization documentation Signed-off-by: Kevin L --- docs/getting-started/app-custom-theme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/app-custom-theme.md b/docs/getting-started/app-custom-theme.md index 3fb0365ad0..4c013440da 100644 --- a/docs/getting-started/app-custom-theme.md +++ b/docs/getting-started/app-custom-theme.md @@ -64,7 +64,7 @@ const app = createApp({ }) ``` -Note that your list of custom themes overrides the default themes. If you still want to use the default themes, they are exported as `themes.light` and `themes.light` from [`@backstage/theme`](https://www.npmjs.com/package/@backstage/theme). +Note that your list of custom themes overrides the default themes. If you still want to use the default themes, they are exported as `themes.light` and `themes.dark` from [`@backstage/theme`](https://www.npmjs.com/package/@backstage/theme). ## Example of a custom theme From e1d58ced052f8f404b9610ebcf212cd33895f6a4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 26 Jun 2024 23:09:32 +0000 Subject: [PATCH 104/510] fix(deps): update dependency @types/express-serve-static-core to v4.19.5 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 831fdf7e92..ffb1e0c157 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17540,14 +17540,14 @@ __metadata: linkType: hard "@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^4.17.33, @types/express-serve-static-core@npm:^4.17.5": - version: 4.19.3 - resolution: "@types/express-serve-static-core@npm:4.19.3" + version: 4.19.5 + resolution: "@types/express-serve-static-core@npm:4.19.5" dependencies: "@types/node": "*" "@types/qs": "*" "@types/range-parser": "*" "@types/send": "*" - checksum: fff38a7f43baeb6a62380682d39846c9d92047e0dce1737d76ebd944528619abc18addc4f0548bf43dbf4514090a1bd5140ba36695024656f941a87424b8ed7d + checksum: 72076c2f8df55e89136d4343fc874050d56c0f4afd885772a8aa506b98c3f4f3ddc7dcba42295a8b931c61000234fd679aec79ef50db15f376bf37d46234939a languageName: node linkType: hard From 834ecd0c1e02f84c7f50e9ca72e7a44b8b38eeb1 Mon Sep 17 00:00:00 2001 From: Kevin L Date: Wed, 26 Jun 2024 19:21:25 -0400 Subject: [PATCH 105/510] Updated the AWS S3 integration docs Signed-off-by: Kevin L --- docs/integrations/aws-s3/discovery--old.md | 89 ++++++++++++++++++++++ docs/integrations/aws-s3/discovery.md | 26 +++---- 2 files changed, 100 insertions(+), 15 deletions(-) create mode 100644 docs/integrations/aws-s3/discovery--old.md diff --git a/docs/integrations/aws-s3/discovery--old.md b/docs/integrations/aws-s3/discovery--old.md new file mode 100644 index 0000000000..bff63af9e5 --- /dev/null +++ b/docs/integrations/aws-s3/discovery--old.md @@ -0,0 +1,89 @@ +--- +id: discovery--old +title: AWS S3 Discovery +sidebar_label: Discovery +# prettier-ignore +description: Automatically discovering catalog entities from an AWS S3 Bucket +--- + +:::info +This documentation is written for the old backend which has been replaced by [the new backend system](../../backend-system/index.md), being the default since Backstage [version 1.24](../../releases/v1.24.0.md). If have migrated to the new backend system, you may want to read [its own article](./discovery.md) instead. Otherwise, [consider migrating](../../backend-system/building-backends/08-migrating.md)! +::: + +The AWS S3 integration has a special entity provider for discovering catalog +entities located in an S3 Bucket. If you have a bucket that contains multiple +catalog files, and you want to automatically discover them, you can use this +provider. The provider will crawl your S3 bucket and register entities +matching the configured path. This can be useful as an alternative to static +locations or manually adding things to the catalog. + +To use the entity provider, you'll need an AWS S3 integration +[set up](locations.md) with `accessKeyId` and `secretAccessKey`, and/or +a `roleArn` or none of these (e.g., profile- or instance-based credentials). + +At production deployments, you likely manage these with the permissions attached +to your instance. + +In your configuration, you add a provider config per bucket: + +```yaml +# app-config.yaml + +catalog: + providers: + awsS3: + yourProviderId: # identifies your dataset / provider independent of config changes + bucketName: sample-bucket + prefix: prefix/ # optional + region: us-east-2 # optional, uses the default region otherwise + 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 + timeout: { minutes: 3 } +``` + +For simple setups, you can omit the provider ID at the config +which has the same effect as using `default` for it. + +```yaml +# app-config.yaml + +catalog: + providers: + awsS3: + # uses "default" as provider ID + bucketName: sample-bucket + prefix: prefix/ # optional + region: us-east-2 # optional, uses the default region otherwise + 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 + timeout: { minutes: 3 } +``` + +As this provider is not one of the default providers, you will first need to install +the AWS catalog plugin: + +```bash +# From your Backstage root directory +yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-aws +``` + +Once you've done that, you'll also need to add the segment below to `packages/backend/src/plugins/catalog.ts`: + +```ts +/* packages/backend/src/plugins/catalog.ts */ + +import { AwsS3EntityProvider } from '@backstage/plugin-catalog-backend-module-aws'; + +const builder = await CatalogBuilder.create(env); +/** ... other processors and/or providers ... */ +builder.addEntityProvider( + AwsS3EntityProvider.fromConfig(env.config, { + logger: env.logger, + scheduler: env.scheduler, + }), +); +``` diff --git a/docs/integrations/aws-s3/discovery.md b/docs/integrations/aws-s3/discovery.md index d664466a16..cce410ea8b 100644 --- a/docs/integrations/aws-s3/discovery.md +++ b/docs/integrations/aws-s3/discovery.md @@ -6,6 +6,10 @@ sidebar_label: Discovery description: Automatically discovering catalog entities from an AWS S3 Bucket --- +:::info +This documentation is written for [the new backend system](../../backend-system/index.md) which is the default since Backstage [version 1.24](../../releases/v1.24.0.md). If you are still on the old backend system, you may want to read [its own article](./discovery--old.md) instead, and [consider migrating](../../backend-system/building-backends/08-migrating.md)! +::: + The AWS S3 integration has a special entity provider for discovering catalog entities located in an S3 Bucket. If you have a bucket that contains multiple catalog files, and you want to automatically discover them, you can use this @@ -20,7 +24,7 @@ a `roleArn` or none of these (e.g., profile- or instance-based credentials). At production deployments, you likely manage these with the permissions attached to your instance. -At your configuration, you add a provider config per bucket: +In your configuration, you add a provider config per bucket: ```yaml # app-config.yaml @@ -67,19 +71,11 @@ the AWS catalog plugin: yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-aws ``` -Once you've done that, you'll also need to add the segment below to `packages/backend/src/plugins/catalog.ts`: +Then update your backend by adding the following line: -```ts -/* packages/backend/src/plugins/catalog.ts */ - -import { AwsS3EntityProvider } from '@backstage/plugin-catalog-backend-module-aws'; - -const builder = await CatalogBuilder.create(env); -/** ... other processors and/or providers ... */ -builder.addEntityProvider( - AwsS3EntityProvider.fromConfig(env.config, { - logger: env.logger, - scheduler: env.scheduler, - }), -); +```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 */ ``` From a5a73eb6f569a92993a46d1de56919d5d2d3cd5e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 26 Jun 2024 23:48:22 +0000 Subject: [PATCH 106/510] fix(deps): update dependency eslint-plugin-react to v7.34.3 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/yarn.lock b/yarn.lock index ffb1e0c157..e7d5b62b9a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -21003,16 +21003,16 @@ __metadata: languageName: node linkType: hard -"array.prototype.tosorted@npm:^1.1.3": - version: 1.1.3 - resolution: "array.prototype.tosorted@npm:1.1.3" +"array.prototype.tosorted@npm:^1.1.4": + version: 1.1.4 + resolution: "array.prototype.tosorted@npm:1.1.4" dependencies: - call-bind: ^1.0.5 + call-bind: ^1.0.7 define-properties: ^1.2.1 - es-abstract: ^1.22.3 - es-errors: ^1.1.0 + es-abstract: ^1.23.3 + es-errors: ^1.3.0 es-shim-unscopables: ^1.0.2 - checksum: 555e8808086bbde9e634c5dc5a8c0a2f1773075447b43b2fa76ab4f94f4e90f416d2a4f881024e1ce1a2931614caf76cd6b408af901c9d7cd13061d0d268f5af + checksum: e4142d6f556bcbb4f393c02e7dbaea9af8f620c040450c2be137c9cbbd1a17f216b9c688c5f2c08fbb038ab83f55993fa6efdd9a05881d84693c7bcb5422127a languageName: node linkType: hard @@ -25571,7 +25571,7 @@ __metadata: languageName: node linkType: hard -"es-errors@npm:^1.1.0, es-errors@npm:^1.2.1, es-errors@npm:^1.3.0": +"es-errors@npm:^1.2.1, es-errors@npm:^1.3.0": version: 1.3.0 resolution: "es-errors@npm:1.3.0" checksum: ec1414527a0ccacd7f15f4a3bc66e215f04f595ba23ca75cdae0927af099b5ec865f9f4d33e9d7e86f512f252876ac77d4281a7871531a50678132429b1271b5 @@ -26207,14 +26207,14 @@ __metadata: linkType: hard "eslint-plugin-react@npm:^7.28.0": - version: 7.34.2 - resolution: "eslint-plugin-react@npm:7.34.2" + version: 7.34.3 + resolution: "eslint-plugin-react@npm:7.34.3" dependencies: array-includes: ^3.1.8 array.prototype.findlast: ^1.2.5 array.prototype.flatmap: ^1.3.2 array.prototype.toreversed: ^1.1.2 - array.prototype.tosorted: ^1.1.3 + array.prototype.tosorted: ^1.1.4 doctrine: ^2.1.0 es-iterator-helpers: ^1.0.19 estraverse: ^5.3.0 @@ -26230,7 +26230,7 @@ __metadata: string.prototype.matchall: ^4.0.11 peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - checksum: aed331239f3a64fcd884380534ece4b8716f1eca4899c8636d04306879e6b4e7339e28e427bdd571d372b78b713025e0767e5f5b5486a8d19bff82616ebe8959 + checksum: 1a519b9792ab9392a5157f2543ce98ab1218c62f4a31c4c3ceb5dd3e7997def4aa07ab39f7276af0fe116ef002db29d97216a15b7aa3b200e55b641cf77d6292 languageName: node linkType: hard From e5f7503dbb1455ae6f79226beaa378db2e0f9351 Mon Sep 17 00:00:00 2001 From: Caleb Troughton Date: Wed, 26 Jun 2024 17:11:16 -0700 Subject: [PATCH 107/510] Fix package install instructions for plugin-events-backend Signed-off-by: Caleb Troughton --- docs/features/software-catalog/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/software-catalog/configuration.md b/docs/features/software-catalog/configuration.md index 3bbbfd6716..e02dc355e2 100644 --- a/docs/features/software-catalog/configuration.md +++ b/docs/features/software-catalog/configuration.md @@ -186,7 +186,7 @@ The first step is to add the events backend plugin to your Backstage application ```ts # From your Backstage root directory -yarn --cwd packages/backend add @backstage/plugin-events-node +yarn --cwd packages/backend add @backstage/plugin-events-backend ``` Now you can install the events backend plugin in your backend. From c95fc38d0558f92c31ecaddcbf3bc50c8faa05e3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 00:44:50 +0000 Subject: [PATCH 108/510] fix(deps): update dependency minimatch to v9.0.5 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 e7d5b62b9a..12305b634c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -33971,11 +33971,11 @@ __metadata: linkType: hard "minimatch@npm:^9.0.0, minimatch@npm:^9.0.1, minimatch@npm:^9.0.3": - version: 9.0.4 - resolution: "minimatch@npm:9.0.4" + version: 9.0.5 + resolution: "minimatch@npm:9.0.5" dependencies: brace-expansion: ^2.0.1 - checksum: cf717f597ec3eed7dabc33153482a2e8d49f4fd3c26e58fd9c71a94c5029a0838728841b93f46bf1263b65a8010e2ee800d0dc9b004ab8ba8b6d1ec07cc115b5 + checksum: 2c035575eda1e50623c731ec6c14f65a85296268f749b9337005210bb2b34e2705f8ef1a358b188f69892286ab99dc42c8fb98a57bde55c8d81b3023c19cea28 languageName: node linkType: hard From 9f72e31617cd4779ca693789b84bd8ee89289320 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 08:01:05 +0000 Subject: [PATCH 109/510] fix(deps): update dependency nodemailer to v6.9.14 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 65f3c565c4..5d92f37a1d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34896,9 +34896,9 @@ __metadata: linkType: hard "nodemailer@npm:^6.9.13": - version: 6.9.13 - resolution: "nodemailer@npm:6.9.13" - checksum: 1b591ef480be2ff69480127cbff819e6593b1ef263b6f920e1a4e83e40280582daf7a14a809ef92f9828e2a70bdb3ce22b11924e209f2afe4975f9ff37e08e9d + version: 6.9.14 + resolution: "nodemailer@npm:6.9.14" + checksum: 4037a45e24dbca47c0ea9a962d2c316deef7afe6ebf73c7da3a84942a8d501d85aae7f36dc1c5dac58dec7275f7cb1c92fd4f9c7c19f037225019ad2f402a9dc languageName: node linkType: hard From cc81579db2319e76213648a1863aec443d6c86e1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 08:10:28 +0000 Subject: [PATCH 110/510] fix(deps): update rjsf monorepo to v5.18.5 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .changeset/renovate-ced359b.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-ced359b.md diff --git a/.changeset/renovate-ced359b.md b/.changeset/renovate-ced359b.md new file mode 100644 index 0000000000..2c100b6e23 --- /dev/null +++ b/.changeset/renovate-ced359b.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.18.5`. +Updated dependency `@rjsf/core` to `5.18.5`. +Updated dependency `@rjsf/material-ui` to `5.18.5`. +Updated dependency `@rjsf/validator-ajv8` to `5.18.5`. diff --git a/plugins/home-react/package.json b/plugins/home-react/package.json index 819c87e20d..9c7667b4d0 100644 --- a/plugins/home-react/package.json +++ b/plugins/home-react/package.json @@ -46,7 +46,7 @@ "@backstage/core-plugin-api": "workspace:^", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", - "@rjsf/utils": "5.18.4", + "@rjsf/utils": "5.18.5", "@types/react": "^16.13.1 || ^17.0.0" }, "devDependencies": { diff --git a/plugins/home/package.json b/plugins/home/package.json index d6fbc13d29..2bc646b417 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -70,10 +70,10 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", - "@rjsf/core": "5.18.4", - "@rjsf/material-ui": "5.18.4", - "@rjsf/utils": "5.18.4", - "@rjsf/validator-ajv8": "5.18.4", + "@rjsf/core": "5.18.5", + "@rjsf/material-ui": "5.18.5", + "@rjsf/utils": "5.18.5", + "@rjsf/validator-ajv8": "5.18.5", "@types/react": "^16.13.1 || ^17.0.0 || ^18.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 6e37ff3e71..d5fe7ca9cb 100644 --- a/plugins/scaffolder-react/package.json +++ b/plugins/scaffolder-react/package.json @@ -72,10 +72,10 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", "@react-hookz/web": "^24.0.0", - "@rjsf/core": "5.18.4", - "@rjsf/material-ui": "5.18.4", - "@rjsf/utils": "5.18.4", - "@rjsf/validator-ajv8": "5.18.4", + "@rjsf/core": "5.18.5", + "@rjsf/material-ui": "5.18.5", + "@rjsf/utils": "5.18.5", + "@rjsf/validator-ajv8": "5.18.5", "@types/json-schema": "^7.0.9", "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "classnames": "^2.2.6", diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 4cce0a83ce..33cf7be16f 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -81,10 +81,10 @@ "@material-ui/lab": "4.0.0-alpha.61", "@microsoft/fetch-event-source": "^2.0.1", "@react-hookz/web": "^24.0.0", - "@rjsf/core": "5.18.4", - "@rjsf/material-ui": "5.18.4", - "@rjsf/utils": "5.18.4", - "@rjsf/validator-ajv8": "5.18.4", + "@rjsf/core": "5.18.5", + "@rjsf/material-ui": "5.18.5", + "@rjsf/utils": "5.18.5", + "@rjsf/validator-ajv8": "5.18.5", "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "@uiw/react-codemirror": "^4.9.3", "classnames": "^2.2.6", diff --git a/yarn.lock b/yarn.lock index 65f3c565c4..89f9c68c95 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6222,7 +6222,7 @@ __metadata: "@backstage/core-plugin-api": "workspace:^" "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 - "@rjsf/utils": 5.18.4 + "@rjsf/utils": 5.18.5 "@types/react": ^16.13.1 || ^17.0.0 "@types/react-grid-layout": ^1.3.2 peerDependencies: @@ -6253,10 +6253,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.18.4 - "@rjsf/material-ui": 5.18.4 - "@rjsf/utils": 5.18.4 - "@rjsf/validator-ajv8": 5.18.4 + "@rjsf/core": 5.18.5 + "@rjsf/material-ui": 5.18.5 + "@rjsf/utils": 5.18.5 + "@rjsf/validator-ajv8": 5.18.5 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^15.0.0 @@ -7234,10 +7234,10 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 "@react-hookz/web": ^24.0.0 - "@rjsf/core": 5.18.4 - "@rjsf/material-ui": 5.18.4 - "@rjsf/utils": 5.18.4 - "@rjsf/validator-ajv8": 5.18.4 + "@rjsf/core": 5.18.5 + "@rjsf/material-ui": 5.18.5 + "@rjsf/utils": 5.18.5 + "@rjsf/validator-ajv8": 5.18.5 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^15.0.0 @@ -7300,10 +7300,10 @@ __metadata: "@material-ui/lab": 4.0.0-alpha.61 "@microsoft/fetch-event-source": ^2.0.1 "@react-hookz/web": ^24.0.0 - "@rjsf/core": 5.18.4 - "@rjsf/material-ui": 5.18.4 - "@rjsf/utils": 5.18.4 - "@rjsf/validator-ajv8": 5.18.4 + "@rjsf/core": 5.18.5 + "@rjsf/material-ui": 5.18.5 + "@rjsf/utils": 5.18.5 + "@rjsf/validator-ajv8": 5.18.5 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^15.0.0 @@ -14479,9 +14479,9 @@ __metadata: languageName: node linkType: hard -"@rjsf/core@npm:5.18.4": - version: 5.18.4 - resolution: "@rjsf/core@npm:5.18.4" +"@rjsf/core@npm:5.18.5": + version: 5.18.5 + resolution: "@rjsf/core@npm:5.18.5" dependencies: lodash: ^4.17.21 lodash-es: ^4.17.21 @@ -14491,26 +14491,26 @@ __metadata: peerDependencies: "@rjsf/utils": ^5.18.x react: ^16.14.0 || >=17 - checksum: 8c3f49914be396595ce67dc4c36ac25c5cb6673917ec82c47f79321f5bb78d02741e8dca39287d0435270e7c9ccb06f7d40e396bdf71a3e9eb1371ef16954817 + checksum: 7b986ec075d5b2de503d01172abdb3e3d33d04e5298fbf80842400e682f0aecdabfe4bb8482dde8a6aed90a35f4f5574cb7b24a11d689566c0cc0599485b334a languageName: node linkType: hard -"@rjsf/material-ui@npm:5.18.4": - version: 5.18.4 - resolution: "@rjsf/material-ui@npm:5.18.4" +"@rjsf/material-ui@npm:5.18.5": + version: 5.18.5 + resolution: "@rjsf/material-ui@npm:5.18.5" peerDependencies: "@material-ui/core": ^4.12.3 "@material-ui/icons": ^4.11.2 "@rjsf/core": ^5.18.x "@rjsf/utils": ^5.18.x react: ^16.14.0 || >=17 - checksum: 2bb0eeb0603bd11b034785ac1902cfcf3630cb4d04161728adff86b2629ca4d21bbb42beb9e6acdd4c9a6a4d84cce1ca325413a9bd1fd94eda47f58d62eb3164 + checksum: 61337141bcd7bcb46013d81ae6b618919eff3f55319800511443e524876bf5c84089970e14148716de203d5def341aa15c4d102243f0b694f120f05189a3adb7 languageName: node linkType: hard -"@rjsf/utils@npm:5.18.4": - version: 5.18.4 - resolution: "@rjsf/utils@npm:5.18.4" +"@rjsf/utils@npm:5.18.5": + version: 5.18.5 + resolution: "@rjsf/utils@npm:5.18.5" dependencies: json-schema-merge-allof: ^0.8.1 jsonpointer: ^5.0.1 @@ -14519,13 +14519,13 @@ __metadata: react-is: ^18.2.0 peerDependencies: react: ^16.14.0 || >=17 - checksum: d7cf514527ec50a94751c5ec1f9e5eafd89d0c56441a22ae28a4e667aaa7c60447e1e1ccf8355c5be5b97e9a1163853c116816b13307e3463433d50f6b89bb3e + checksum: 8da3ce82a0ec83e78806461db7226fd20489f6e8c41906ccde9d55c554aec3f50b8b8bac8c35e3cdf12d788c18fdad71c992f0d8b44f6161a1bf9e13598ded99 languageName: node linkType: hard -"@rjsf/validator-ajv8@npm:5.18.4": - version: 5.18.4 - resolution: "@rjsf/validator-ajv8@npm:5.18.4" +"@rjsf/validator-ajv8@npm:5.18.5": + version: 5.18.5 + resolution: "@rjsf/validator-ajv8@npm:5.18.5" dependencies: ajv: ^8.12.0 ajv-formats: ^2.1.1 @@ -14533,7 +14533,7 @@ __metadata: lodash-es: ^4.17.21 peerDependencies: "@rjsf/utils": ^5.18.x - checksum: edf3b24e07babe972e57645d396467c6404ff3f95a79118667f2d62082aa28e4ee7df5fad81e28071cd24b5455fe687a9f9bcf714718d4fd6036912b04c69a84 + checksum: 350d1f8043b7bbd88cf5d7fa28560062f4141e1ef9ef004c2997b63d0281d4a1af04be4b951c2c9c4d1c56d10f0e2fbab665c7176b38e87dd6da6d5303e1c84e languageName: node linkType: hard From e467708ca43384c97b04ce4b850a6f8eb26099e6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 09:21:46 +0000 Subject: [PATCH 111/510] chore(deps): update dependency @playwright/test to v1.45.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/yarn.lock b/yarn.lock index 5d92f37a1d..66b353a237 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13734,13 +13734,13 @@ __metadata: linkType: hard "@playwright/test@npm:^1.32.3": - version: 1.44.1 - resolution: "@playwright/test@npm:1.44.1" + version: 1.45.0 + resolution: "@playwright/test@npm:1.45.0" dependencies: - playwright: 1.44.1 + playwright: 1.45.0 bin: playwright: cli.js - checksum: 90507b77e388aa984deb92db56f7bb3b305c6be441e1d0087ca046989cfdda068bbc26d75bd29c20ad3dbb2434e69a8ff0d6b30003b88c9234cd3aa6a9f7deb9 + checksum: 55fb72f393b05f6684b5098e0681712f71e1fe25aa6a00bd636133f9ccc26d096d61ee30f569b83368e4bf6a1288d2f8f6fd5364da5d396eab180f89f61b7164 languageName: node linkType: hard @@ -36647,27 +36647,27 @@ __metadata: languageName: node linkType: hard -"playwright-core@npm:1.44.1": - version: 1.44.1 - resolution: "playwright-core@npm:1.44.1" +"playwright-core@npm:1.45.0": + version: 1.45.0 + resolution: "playwright-core@npm:1.45.0" bin: playwright-core: cli.js - checksum: ebc6fa0ff77792fe52648fda06cc4474d4e9746db6dc5750d262b7fe2caf9f9e2327a71f1fb365e862213403a9daf95361c5040a9b0fd462928d7eb4fdc760e1 + checksum: e81a55eeefa997fcb559527127c9cefbbabe81f196de486224e6c2a3a66852dab883379ff28a05b8008fb0ad4992840ad53c2415cee27e2d1778836210d9248e languageName: node linkType: hard -"playwright@npm:1.44.1": - version: 1.44.1 - resolution: "playwright@npm:1.44.1" +"playwright@npm:1.45.0": + version: 1.45.0 + resolution: "playwright@npm:1.45.0" dependencies: fsevents: 2.3.2 - playwright-core: 1.44.1 + playwright-core: 1.45.0 dependenciesMeta: fsevents: optional: true bin: playwright: cli.js - checksum: c2e8ff0a855e4a9e665ae5ffa0ff90423289546157be55e83f78916d17075c5910a7244773739c2a973da884a4ff0b3cf9b6e6b543de112e43b12169a9208e86 + checksum: 2a5f827fdcc90f1ec0ea4d9e4f2021ae894df88d3c0577677a81f72a09d91fb15584346e63ec2f85bfc24f872976ff2a76cee6ca7d7f29a8cc3159ced4f25b50 languageName: node linkType: hard From 2defad94e3237184cdb6d1528a64dd8d8bcac021 Mon Sep 17 00:00:00 2001 From: blam Date: Thu, 27 Jun 2024 11:58:20 +0200 Subject: [PATCH 112/510] chore: disabled and readonly props are optional from rjsf now, let's default them to something sane Signed-off-by: blam --- plugins/scaffolder-react/src/next/components/Form/Form.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/scaffolder-react/src/next/components/Form/Form.tsx b/plugins/scaffolder-react/src/next/components/Form/Form.tsx index 8717c8b55a..05c8a4934f 100644 --- a/plugins/scaffolder-react/src/next/components/Form/Form.tsx +++ b/plugins/scaffolder-react/src/next/components/Form/Form.tsx @@ -44,6 +44,8 @@ export const Form = (props: PropsWithChildren) => { uiSchema={wrapperProps.uiSchema ?? {}} formData={wrapperProps.formData} rawErrors={wrapperProps.rawErrors ?? []} + disabled={wrapperProps.disabled ?? false} + readonly={wrapperProps.readonly ?? false} /> ); }, From f2f01f0350666208f05bf3e3ab45e38aeb33f8af Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 10:08:54 +0000 Subject: [PATCH 113/510] fix(deps): update dependency prom-client to v15.1.3 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 66b353a237..8e50d73b0d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -37404,12 +37404,12 @@ __metadata: linkType: hard "prom-client@npm:^15.0.0": - version: 15.1.2 - resolution: "prom-client@npm:15.1.2" + version: 15.1.3 + resolution: "prom-client@npm:15.1.3" dependencies: "@opentelemetry/api": ^1.4.0 tdigest: ^0.1.1 - checksum: b9b2f439588a462c0aec840e8aa857bb0a77284174d6587ca042eb13ea6ac36ba13277f45ae6ed3696b3007a1020c5ee2c5ee46b23be033a7bb45207a5365c21 + checksum: 9a57f3c16f39aa9a03da021883a4231c0bb56fc9d02f6ef9c28f913379f275640a5a33b98d9946ebf53c71011a29b580e9d2d6e3806cb1c229a3f59c65993968 languageName: node linkType: hard From 31337accbab3a823b5911496a03084b0a69f1dea Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 10:51:36 +0000 Subject: [PATCH 114/510] chore(deps): update dependency knip to v5.23.1 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 5322ef697d..2df9262dc5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -32065,8 +32065,8 @@ __metadata: linkType: hard "knip@npm:^5.0.0": - version: 5.22.2 - resolution: "knip@npm:5.22.2" + version: 5.23.1 + resolution: "knip@npm:5.23.1" dependencies: "@ericcornelissen/bash-parser": 0.5.3 "@nodelib/fs.walk": 2.0.0 @@ -32092,7 +32092,7 @@ __metadata: bin: knip: bin/knip.js knip-bun: bin/knip-bun.js - checksum: 995924973618391af39ba6bfb324f1f4dac427879a944eeecbcf48b61ec165f10f18196f27a7d079076f351223ed067bb917bc863e0424153c3fae2dd65582d6 + checksum: d3c39f266907b2c8f241e4d7d7c4b3a4fa1500c57f7e60f86bd3e9cd2684696e4c84b823d2a461b23cdc729a310ad571eec6ac22acacb5a4b17130d19ef5b866 languageName: node linkType: hard From e7098b6d9a8342ee98f46853698083127685566c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 11:12:21 +0000 Subject: [PATCH 115/510] chore(deps): update dependency node-mocks-http to v1.15.0 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 259687412b..cc6d1c7d42 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34817,8 +34817,8 @@ __metadata: linkType: hard "node-mocks-http@npm:^1.0.0": - version: 1.14.1 - resolution: "node-mocks-http@npm:1.14.1" + version: 1.15.0 + resolution: "node-mocks-http@npm:1.15.0" dependencies: "@types/express": ^4.17.21 "@types/node": ^20.10.6 @@ -34832,7 +34832,7 @@ __metadata: parseurl: ^1.3.3 range-parser: ^1.2.0 type-is: ^1.6.18 - checksum: cc37618fb5f44a6049f8fcfc73373c4b42943e35e4b0f7463939d3f219663fe647e00e6eb9c3b8aedd48e88e10e1542993ac1a7ff8442ee2c3f6b97f23ced0e0 + checksum: 9be3ef4eec1b283800bbae50d7615fb633c7d28a0bedcf13e2ddfaa7ed4aa865d00c1d26e929ee8d617b3734958d8c19345f615760004f1940a8268c9bbacf07 languageName: node linkType: hard From 53ae33ab796504a2b66460dd808e10829df1957b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 11:40:47 +0000 Subject: [PATCH 116/510] fix(deps): update dependency @azure/identity to v4.3.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/yarn.lock b/yarn.lock index 965d939677..a871cf4e0b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1660,6 +1660,15 @@ __metadata: languageName: node linkType: hard +"@azure/abort-controller@npm:^2.0.0": + version: 2.1.2 + resolution: "@azure/abort-controller@npm:2.1.2" + dependencies: + tslib: ^2.6.2 + checksum: 22176c04ea01498311c6bbd336669f6e3faffad1cbb0c9ebc6ee9c1ff2cf958fd17ce73c7354b99d8bda9fcd311325ece7bee248875279174e3fc460e8b1a63d + languageName: node + linkType: hard + "@azure/core-auth@npm:^1.3.0, @azure/core-auth@npm:^1.4.0, @azure/core-auth@npm:^1.5.0": version: 1.5.0 resolution: "@azure/core-auth@npm:1.5.0" @@ -1671,18 +1680,18 @@ __metadata: languageName: node linkType: hard -"@azure/core-client@npm:^1.4.0": - version: 1.7.3 - resolution: "@azure/core-client@npm:1.7.3" +"@azure/core-client@npm:^1.9.2": + version: 1.9.2 + resolution: "@azure/core-client@npm:1.9.2" dependencies: - "@azure/abort-controller": ^1.0.0 + "@azure/abort-controller": ^2.0.0 "@azure/core-auth": ^1.4.0 "@azure/core-rest-pipeline": ^1.9.1 "@azure/core-tracing": ^1.0.0 - "@azure/core-util": ^1.0.0 + "@azure/core-util": ^1.6.1 "@azure/logger": ^1.0.0 - tslib: ^2.2.0 - checksum: 155a188b75b2d5ea783d5fde50479337c41796736f0fced1576466c8251e429195c229f2aff0bf897761f15c19d8fd0deea9a54aab514bd3584e37140e3f0cdc + tslib: ^2.6.2 + checksum: 961b829dfda4f734a763e9480a2ea622a7031ba2da4126d0add6e351a9f73ddc5782bf2b766735d976b61da3857014e0a90223d1f85d1c68468747a7a56851c3 languageName: node linkType: hard @@ -1765,23 +1774,23 @@ __metadata: languageName: node linkType: hard -"@azure/core-util@npm:^1.0.0, @azure/core-util@npm:^1.1.0, @azure/core-util@npm:^1.1.1, @azure/core-util@npm:^1.2.0, @azure/core-util@npm:^1.3.0": - version: 1.6.1 - resolution: "@azure/core-util@npm:1.6.1" +"@azure/core-util@npm:^1.1.0, @azure/core-util@npm:^1.1.1, @azure/core-util@npm:^1.2.0, @azure/core-util@npm:^1.3.0, @azure/core-util@npm:^1.6.1": + version: 1.9.0 + resolution: "@azure/core-util@npm:1.9.0" dependencies: - "@azure/abort-controller": ^1.0.0 - tslib: ^2.2.0 - checksum: 1f8cd130993f161c98925070af863510cbcc79e0471864e4b16852afc2ee7413c9c7fabe72f20f3e521ee75c3cd7e3085661fdc8d5d0a643a6e1b1b7bf691ddd + "@azure/abort-controller": ^2.0.0 + tslib: ^2.6.2 + checksum: 9246dc5bd246e7b94883ea8130fce04e2f22abd1e94afcff7a3e92a4c2da5e9b382dbf89a606b21d70bc8b01c7c89c84e803ca9da27f78d87f72bdff91ec7380 languageName: node linkType: hard "@azure/identity@npm:^4.0.0": - version: 4.2.1 - resolution: "@azure/identity@npm:4.2.1" + version: 4.3.0 + resolution: "@azure/identity@npm:4.3.0" dependencies: "@azure/abort-controller": ^1.0.0 "@azure/core-auth": ^1.5.0 - "@azure/core-client": ^1.4.0 + "@azure/core-client": ^1.9.2 "@azure/core-rest-pipeline": ^1.1.0 "@azure/core-tracing": ^1.0.0 "@azure/core-util": ^1.3.0 @@ -1793,7 +1802,7 @@ __metadata: open: ^8.0.0 stoppable: ^1.1.0 tslib: ^2.2.0 - checksum: 2dbd7b0fa6b92904b7b8f828374d7316384cc4e00c71cdac3a2f2544b9e02c7287fe7ad58149bb8794c57913d77a927f5a7b5d1367e05abe82b0f2e1b162415c + checksum: 7f4256b39c4e27bf072c33f02dd63bd50dcf54ad578e3e483dcf89283546a6086b1640adfe4c93a537cbe483dd2e3a29f6d7b837e51f333229f7bbbc448966b3 languageName: node linkType: hard From 605df406e2ef874e16cedf39bdd8888267b55be0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 12:30:58 +0000 Subject: [PATCH 117/510] fix(deps): update dependency @azure/storage-blob to v12.23.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 108 +++++++++++++++++++++++------------------------------- 1 file changed, 46 insertions(+), 62 deletions(-) diff --git a/yarn.lock b/yarn.lock index 7e09ea2f97..f1efc58328 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1669,7 +1669,7 @@ __metadata: languageName: node linkType: hard -"@azure/core-auth@npm:^1.3.0, @azure/core-auth@npm:^1.4.0, @azure/core-auth@npm:^1.5.0": +"@azure/core-auth@npm:^1.4.0, @azure/core-auth@npm:^1.5.0": version: 1.5.0 resolution: "@azure/core-auth@npm:1.5.0" dependencies: @@ -1680,7 +1680,7 @@ __metadata: languageName: node linkType: hard -"@azure/core-client@npm:^1.9.2": +"@azure/core-client@npm:^1.3.0, @azure/core-client@npm:^1.6.2, @azure/core-client@npm:^1.9.2": version: 1.9.2 resolution: "@azure/core-client@npm:1.9.2" dependencies: @@ -1695,25 +1695,14 @@ __metadata: languageName: node linkType: hard -"@azure/core-http@npm:^3.0.0": - version: 3.0.2 - resolution: "@azure/core-http@npm:3.0.2" +"@azure/core-http-compat@npm:^2.0.0": + version: 2.1.2 + resolution: "@azure/core-http-compat@npm:2.1.2" dependencies: - "@azure/abort-controller": ^1.0.0 - "@azure/core-auth": ^1.3.0 - "@azure/core-tracing": 1.0.0-preview.13 - "@azure/core-util": ^1.1.1 - "@azure/logger": ^1.0.0 - "@types/node-fetch": ^2.5.0 - "@types/tunnel": ^0.0.3 - form-data: ^4.0.0 - node-fetch: ^2.6.7 - process: ^0.11.10 - tslib: ^2.2.0 - tunnel: ^0.0.6 - uuid: ^8.3.0 - xml2js: ^0.5.0 - checksum: 01b5a75e09533476dbb69c672dcd00d48298cf81db5015cd261c510c5be377176db8e3dc4809e6952459bfbe214f52f8a1ed84a116ac31b8a7388b2025098f66 + "@azure/abort-controller": ^2.0.0 + "@azure/core-client": ^1.3.0 + "@azure/core-rest-pipeline": ^1.3.0 + checksum: 387d0187607d95a6876f63d4b689210bce6ad243f48e56413136ba3875a8a9c4e238813307fb0cf0c53298f4b9d0893d04321c9331812bc74cf0f4e3e6872069 languageName: node linkType: hard @@ -1738,30 +1727,19 @@ __metadata: languageName: node linkType: hard -"@azure/core-rest-pipeline@npm:^1.1.0, @azure/core-rest-pipeline@npm:^1.9.1": - version: 1.12.2 - resolution: "@azure/core-rest-pipeline@npm:1.12.2" +"@azure/core-rest-pipeline@npm:^1.1.0, @azure/core-rest-pipeline@npm:^1.10.1, @azure/core-rest-pipeline@npm:^1.3.0, @azure/core-rest-pipeline@npm:^1.9.1": + version: 1.16.1 + resolution: "@azure/core-rest-pipeline@npm:1.16.1" dependencies: - "@azure/abort-controller": ^1.0.0 + "@azure/abort-controller": ^2.0.0 "@azure/core-auth": ^1.4.0 "@azure/core-tracing": ^1.0.1 - "@azure/core-util": ^1.3.0 + "@azure/core-util": ^1.9.0 "@azure/logger": ^1.0.0 - form-data: ^4.0.0 - http-proxy-agent: ^5.0.0 - https-proxy-agent: ^5.0.0 - tslib: ^2.2.0 - checksum: a774ab2e87ff56d7f3ef1844a814bbd76264ea1c33534081d38ce6df1098d803d0b13b15912f9053d0695ca2669b0dd104c8feec8dbf24df80a3608ea784fc9e - languageName: node - linkType: hard - -"@azure/core-tracing@npm:1.0.0-preview.13": - version: 1.0.0-preview.13 - resolution: "@azure/core-tracing@npm:1.0.0-preview.13" - dependencies: - "@opentelemetry/api": ^1.0.1 - tslib: ^2.2.0 - checksum: bc3ea8dce1fc6bb6e4cb2e82ec0c361b3e6f6e18e162f352eb347e6991c6461ebc249f5d1b36402cc0d295e2a6bcbaa68014445d7f4293c0792a698c430f145e + http-proxy-agent: ^7.0.0 + https-proxy-agent: ^7.0.0 + tslib: ^2.6.2 + checksum: ab2c5b715c4ebb9f6554f12d8e804833be29db0f23868adc092f4841aa8c7f140a6821dbcd9fa046bfb31e435085f171a87dab3f97d851cf9a62127d042fa75e languageName: node linkType: hard @@ -1774,7 +1752,7 @@ __metadata: languageName: node linkType: hard -"@azure/core-util@npm:^1.1.0, @azure/core-util@npm:^1.1.1, @azure/core-util@npm:^1.2.0, @azure/core-util@npm:^1.3.0, @azure/core-util@npm:^1.6.1": +"@azure/core-util@npm:^1.1.0, @azure/core-util@npm:^1.2.0, @azure/core-util@npm:^1.3.0, @azure/core-util@npm:^1.6.1, @azure/core-util@npm:^1.9.0": version: 1.9.0 resolution: "@azure/core-util@npm:1.9.0" dependencies: @@ -1784,6 +1762,16 @@ __metadata: languageName: node linkType: hard +"@azure/core-xml@npm:^1.3.2": + version: 1.4.2 + resolution: "@azure/core-xml@npm:1.4.2" + dependencies: + fast-xml-parser: ^4.3.2 + tslib: ^2.6.2 + checksum: f3815db55f0280db6080a3fc5b6187ad45cacf5c3842ea806a5565886edf2ebf2fa9fc1175407cf58d462341962a8396513943543b332b37b313ac3a79dc28fa + languageName: node + linkType: hard + "@azure/identity@npm:^4.0.0": version: 4.3.0 resolution: "@azure/identity@npm:4.3.0" @@ -1850,18 +1838,23 @@ __metadata: linkType: hard "@azure/storage-blob@npm:^12.5.0": - version: 12.17.0 - resolution: "@azure/storage-blob@npm:12.17.0" + version: 12.23.0 + resolution: "@azure/storage-blob@npm:12.23.0" dependencies: "@azure/abort-controller": ^1.0.0 - "@azure/core-http": ^3.0.0 + "@azure/core-auth": ^1.4.0 + "@azure/core-client": ^1.6.2 + "@azure/core-http-compat": ^2.0.0 "@azure/core-lro": ^2.2.0 "@azure/core-paging": ^1.1.1 - "@azure/core-tracing": 1.0.0-preview.13 + "@azure/core-rest-pipeline": ^1.10.1 + "@azure/core-tracing": ^1.0.0 + "@azure/core-util": ^1.6.1 + "@azure/core-xml": ^1.3.2 "@azure/logger": ^1.0.0 events: ^3.0.0 tslib: ^2.2.0 - checksum: 2e5d3f26577f698498bba7ff7b7cfeb942709a713d9c72864b80633bee28e2b369370afc55f18e49ccc02b4dad9d1de3a4602caa99dce1f8d8196c8472a8add1 + checksum: 7f09b4bfae0d73f7cf8f383038edeaf8bc8610960bc24a9b8c140f4084bb3afd62971fb56e2ff5e013168165dcfff7b9a545f6cc837fe2669618184e4b77c107 languageName: node linkType: hard @@ -12490,7 +12483,7 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/api@npm:^1.0.0, @opentelemetry/api@npm:^1.0.1, @opentelemetry/api@npm:^1.3.0, @opentelemetry/api@npm:^1.4.0": +"@opentelemetry/api@npm:^1.0.0, @opentelemetry/api@npm:^1.3.0, @opentelemetry/api@npm:^1.4.0": version: 1.8.0 resolution: "@opentelemetry/api@npm:1.8.0" checksum: 0e32079975f05bee6de2ad8ade097f0afdc63f462c76550150fce2444c73ab92aaf851ac85e638b6e3b269da6640ac7e63f33913a0fd7df9f9beec2e100759df @@ -18152,7 +18145,7 @@ __metadata: languageName: node linkType: hard -"@types/node-fetch@npm:^2.5.0, @types/node-fetch@npm:^2.5.12": +"@types/node-fetch@npm:^2.5.12": version: 2.6.11 resolution: "@types/node-fetch@npm:2.6.11" dependencies: @@ -18873,15 +18866,6 @@ __metadata: languageName: node linkType: hard -"@types/tunnel@npm:^0.0.3": - version: 0.0.3 - resolution: "@types/tunnel@npm:0.0.3" - dependencies: - "@types/node": "*" - checksum: 53e23a1f9fb14a491c00425b2a4fc443817564d77be5e1b95fcbeb6d009551b62ea82ffc3e5ca0c6b9f6b186824ca6ec46e7450c1bcd6674a46d1325f0116e24 - languageName: node - linkType: hard - "@types/unist@npm:*, @types/unist@npm:^2.0.0": version: 2.0.6 resolution: "@types/unist@npm:2.0.6" @@ -27181,14 +27165,14 @@ __metadata: languageName: node linkType: hard -"fast-xml-parser@npm:^4.3.0": - version: 4.3.2 - resolution: "fast-xml-parser@npm:4.3.2" +"fast-xml-parser@npm:^4.3.0, fast-xml-parser@npm:^4.3.2": + version: 4.4.0 + resolution: "fast-xml-parser@npm:4.4.0" dependencies: strnum: ^1.0.5 bin: fxparser: src/cli/cli.js - checksum: d507ce2efa5fd13d0a5ba28bd76dd68f2fc30ad8748357c37b70f360d19417866d79e35a688af067d5bceaaa796033fa985206aef9692f7a421e1326b6e73309 + checksum: ad33a4b5165a0ffcb6e17ae78825bd4619a8298844a8a8408f2ea141a0d2d9439d18865dc5254162f09fe54d510ff18e5d5c0a190869cab21fc745ee66be816b languageName: node linkType: hard @@ -29202,7 +29186,7 @@ __metadata: languageName: node linkType: hard -"https-proxy-agent@npm:7.0.4, https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.2": +"https-proxy-agent@npm:7.0.4, https-proxy-agent@npm:^7.0.0, https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.2": version: 7.0.4 resolution: "https-proxy-agent@npm:7.0.4" dependencies: From bfc2fb356c5c330a29c6e5f6276d143d29d37f3d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 12:31:57 +0000 Subject: [PATCH 118/510] fix(deps): update dependency @codemirror/view to v6.28.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 7e09ea2f97..9a906af154 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8502,13 +8502,13 @@ __metadata: linkType: hard "@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.23.0": - version: 6.26.3 - resolution: "@codemirror/view@npm:6.26.3" + version: 6.28.2 + resolution: "@codemirror/view@npm:6.28.2" dependencies: "@codemirror/state": ^6.4.0 style-mod: ^4.1.0 w3c-keyname: ^2.2.4 - checksum: fdee35fb5e0bbba7b6f1a9b43a865880911bbfafd30360da5dda21b35f81ba2d080ff66b6c3d94dbe946b6b7ec98a76208786360b8f030ef10bcb054b816de05 + checksum: d2d36d7bbb1fc094fb421251b96144b67a932f43d12092bd2318ced283db0081e6e78cc99c5cecf9eedd24278d39fe41deaa490fcc03637d85c5cf332af58fec languageName: node linkType: hard From fb3ef145d355581066d4314573d30ad1607c6f31 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 12:32:58 +0000 Subject: [PATCH 119/510] fix(deps): update dependency @google-cloud/container to v5.15.0 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 7e09ea2f97..a29356da1d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9475,11 +9475,11 @@ __metadata: linkType: hard "@google-cloud/container@npm:^5.0.0": - version: 5.12.0 - resolution: "@google-cloud/container@npm:5.12.0" + version: 5.15.0 + resolution: "@google-cloud/container@npm:5.15.0" dependencies: google-gax: ^4.0.3 - checksum: bf22c6754d67b133f272522b41f9f383e960a3288847d345407a171cce593856527cd3ee3df13bb4b09091bfce03f3404d24559ce2c28733ce71866068fb5277 + checksum: e31332b17816688f0cf831c66ef1ccc24c7600e4ec798fdeed33b66ed934372b1a962e92c665903bae661db5aaf872d79becc7d67b3f9c6a55b403acdfd534ec languageName: node linkType: hard From db1cc30358eb629e0d6d380a174b0616ccfaede3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 13:16:04 +0000 Subject: [PATCH 120/510] fix(deps): update dependency @google-cloud/firestore to v7.9.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 97 +++++++++++++++++++------------------------------------ 1 file changed, 34 insertions(+), 63 deletions(-) diff --git a/yarn.lock b/yarn.lock index 7c407dc27e..b8bffa5b78 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9477,14 +9477,14 @@ __metadata: linkType: hard "@google-cloud/firestore@npm:^7.0.0": - version: 7.4.0 - resolution: "@google-cloud/firestore@npm:7.4.0" + version: 7.9.0 + resolution: "@google-cloud/firestore@npm:7.9.0" dependencies: fast-deep-equal: ^3.1.1 functional-red-black-tree: ^1.0.1 - google-gax: ^4.0.4 - protobufjs: ^7.2.5 - checksum: df0094c3be5473a96f925d7bcd4234f376e4928065bdd96bdc2debc73b4c976df160c2553dfc8ed3d73f859778996159e69770983fa0224a53afbe4e77754db3 + google-gax: ^4.3.3 + protobufjs: ^7.2.6 + checksum: 5d0657736f1e364cd110ea6083eb8b6aeb1605ea409ea5478d5c8430bfa568c62d472b41e892d0849dfb405b06d8aba412fd57a5d1e807429ba5264c48eb2673 languageName: node linkType: hard @@ -9862,27 +9862,17 @@ __metadata: languageName: node linkType: hard -"@grpc/grpc-js@npm:^1.7.1": - version: 1.10.7 - resolution: "@grpc/grpc-js@npm:1.10.7" +"@grpc/grpc-js@npm:^1.10.9, @grpc/grpc-js@npm:^1.7.1": + version: 1.10.10 + resolution: "@grpc/grpc-js@npm:1.10.10" dependencies: "@grpc/proto-loader": ^0.7.13 "@js-sdsl/ordered-map": ^4.4.2 - checksum: 69e88768e59b53ca020e2cfa9474fbd645f4ee7dd3269559c9fb91970273da6e8db480c0c439bdd73b49f1831d8f47c9bc5305dc5f9ed4db8873d53572e4f019 + checksum: e48274ab6e377031a2314197d33416c3261abf9601638ba05d8ae523e6e28338f97f852efdf9f9f763e49056812c83d3719cdf5913881d46cfca837dea2ab23c languageName: node linkType: hard -"@grpc/grpc-js@npm:~1.9.6": - version: 1.9.11 - resolution: "@grpc/grpc-js@npm:1.9.11" - dependencies: - "@grpc/proto-loader": ^0.7.8 - "@types/node": ">=12.12.47" - checksum: ed11ebcb0f8c34e2ada1d16ac2eef2465e1812871dd42bf40a405dfa06e2bfe895e680aff10644f9d51c33ce1ee1882ee466237ee478365c5ed265c0d7c5c015 - languageName: node - linkType: hard - -"@grpc/proto-loader@npm:^0.7.0, @grpc/proto-loader@npm:^0.7.13, @grpc/proto-loader@npm:^0.7.8": +"@grpc/proto-loader@npm:^0.7.13": version: 0.7.13 resolution: "@grpc/proto-loader@npm:0.7.13" dependencies: @@ -18164,7 +18154,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:>=12.12.47, @types/node@npm:>=13.7.0, @types/node@npm:^20.1.1, @types/node@npm:^20.10.6, @types/node@npm:^20.11.16": +"@types/node@npm:*, @types/node@npm:>=13.7.0, @types/node@npm:^20.1.1, @types/node@npm:^20.10.6, @types/node@npm:^20.11.16": version: 20.12.7 resolution: "@types/node@npm:20.12.7" dependencies: @@ -28350,9 +28340,9 @@ __metadata: languageName: node linkType: hard -"google-auth-library@npm:^9.0.0, google-auth-library@npm:^9.6.3": - version: 9.8.0 - resolution: "google-auth-library@npm:9.8.0" +"google-auth-library@npm:^9.0.0, google-auth-library@npm:^9.3.0, google-auth-library@npm:^9.6.3": + version: 9.11.0 + resolution: "google-auth-library@npm:9.11.0" dependencies: base64-js: ^1.3.0 ecdsa-sig-formatter: ^1.0.11 @@ -28360,26 +28350,27 @@ __metadata: gcp-metadata: ^6.1.0 gtoken: ^7.0.0 jws: ^4.0.0 - checksum: dd67972861e16d47de494ac333bd76c57a5132e300793ae2dc8866fb76b3e57099846ce84b036ab2564bc4e85e0dc4d4cf245f4ca95aedebf53a9a2c03f35b38 + checksum: 984d344b5e0a21ea1e097d06e27173035619c0e8f89a363e538b445adb1414b79e938b56b4432aa36fda074c5922fa6a34f9b64734765c01dff73c45c8568554 languageName: node linkType: hard -"google-gax@npm:^4.0.3, google-gax@npm:^4.0.4": - version: 4.0.5 - resolution: "google-gax@npm:4.0.5" +"google-gax@npm:^4.0.3, google-gax@npm:^4.3.3": + version: 4.3.7 + resolution: "google-gax@npm:4.3.7" dependencies: - "@grpc/grpc-js": ~1.9.6 - "@grpc/proto-loader": ^0.7.0 + "@grpc/grpc-js": ^1.10.9 + "@grpc/proto-loader": ^0.7.13 "@types/long": ^4.0.0 abort-controller: ^3.0.0 duplexify: ^4.0.0 - google-auth-library: ^9.0.0 + google-auth-library: ^9.3.0 node-fetch: ^2.6.1 object-hash: ^3.0.0 - proto3-json-serializer: ^2.0.0 - protobufjs: 7.2.5 + proto3-json-serializer: ^2.0.2 + protobufjs: ^7.3.2 retry-request: ^7.0.0 - checksum: d4b5f2fc4a902b29d23552ab0fa498785ce88516ff07f7e7f08cac0f6572a78113a7f468f47b17e98d235d4049eeda8d77cfcad6291f6d14bda39b9eb19f935d + uuid: ^9.0.1 + checksum: f03327e42b5d0166c6655347c9ae56787a1cf0f2d32147530164f18deb808688e857e0017703d5b070c8b4ab9a003eda9598891b1cb5cdf007026be7a1c752d7 languageName: node linkType: hard @@ -37517,18 +37508,18 @@ __metadata: languageName: node linkType: hard -"proto3-json-serializer@npm:^2.0.0": - version: 2.0.0 - resolution: "proto3-json-serializer@npm:2.0.0" +"proto3-json-serializer@npm:^2.0.2": + version: 2.0.2 + resolution: "proto3-json-serializer@npm:2.0.2" dependencies: - protobufjs: ^7.0.0 - checksum: aea3433d5e0204625b97bda53001f71fc060eb83709d58d001c5bf75728f14b5ebfca39b54d81e7c90e4de363f68aecf1d203a410f33ebda9590a812f8f30b13 + protobufjs: ^7.2.5 + checksum: 21b8aa65be6dac2bb24920e5bdabef48b249bdf65b1498ae7e69ac4e70722275b083cd60a21d2b4be3ead9d768de2f6f5fb6b188bd177d51c824a539b5ba55cc languageName: node linkType: hard -"protobufjs@npm:7.2.5": - version: 7.2.5 - resolution: "protobufjs@npm:7.2.5" +"protobufjs@npm:^7.2.3, protobufjs@npm:^7.2.5, protobufjs@npm:^7.2.6, protobufjs@npm:^7.3.2": + version: 7.3.2 + resolution: "protobufjs@npm:7.3.2" dependencies: "@protobufjs/aspromise": ^1.1.2 "@protobufjs/base64": ^1.1.2 @@ -37542,27 +37533,7 @@ __metadata: "@protobufjs/utf8": ^1.1.0 "@types/node": ">=13.7.0" long: ^5.0.0 - checksum: 3770a072114061faebbb17cfd135bc4e187b66bc6f40cd8bac624368b0270871ec0cfb43a02b9fb4f029c8335808a840f1afba3c2e7ede7063b98ae6b98a703f - languageName: node - linkType: hard - -"protobufjs@npm:^7.0.0, protobufjs@npm:^7.2.3, protobufjs@npm:^7.2.5, protobufjs@npm:^7.2.6": - version: 7.2.6 - resolution: "protobufjs@npm:7.2.6" - dependencies: - "@protobufjs/aspromise": ^1.1.2 - "@protobufjs/base64": ^1.1.2 - "@protobufjs/codegen": ^2.0.4 - "@protobufjs/eventemitter": ^1.1.0 - "@protobufjs/fetch": ^1.1.0 - "@protobufjs/float": ^1.0.2 - "@protobufjs/inquire": ^1.1.0 - "@protobufjs/path": ^1.1.2 - "@protobufjs/pool": ^1.1.0 - "@protobufjs/utf8": ^1.1.0 - "@types/node": ">=13.7.0" - long: ^5.0.0 - checksum: 3c62e48f7d50017ac3b0dcd2a58e617cf858f9fba56a488bd48b9aa3482893a75540052dbcb3c12dfbaab42b1d04964611175faf06bdadcd33a4ebac982a511e + checksum: cfb2a744787f26ee7c82f3e7c4b72cfc000e9bb4c07828ed78eb414db0ea97a340c0cc3264d0e88606592f847b12c0351411f10e9af255b7ba864eec44d7705f languageName: node linkType: hard From efb4e480897b9b72c75eeda8cf545210e07b8ae8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 14:18:13 +0000 Subject: [PATCH 121/510] fix(deps): update dependency @jest-mock/express to v2.1.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/yarn.lock b/yarn.lock index 7c407dc27e..6f4f365ea1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10225,11 +10225,11 @@ __metadata: linkType: hard "@jest-mock/express@npm:^2.0.1": - version: 2.0.2 - resolution: "@jest-mock/express@npm:2.0.2" + version: 2.1.0 + resolution: "@jest-mock/express@npm:2.1.0" dependencies: - "@types/express": ^4.17.17 - checksum: 558feb47e7e9620a5e53b83c51b3802782ecf7ab32b8d81077b16f641b7e1a6dc6fffa652d2ab48b28ba0f0634fa6387bd21b08f62b92bd730dfca167a4c2795 + "@types/express": ^4.17.21 + checksum: 305b72c214c1e80ed16271aa48e4d6d906346f5221a4e873d1e8ae48c32c2316cb88bed819b195c934c339b9ab41d4b34c4e41ac66feefe980d2cd16bc0b6d20 languageName: node linkType: hard @@ -17562,7 +17562,7 @@ __metadata: languageName: node linkType: hard -"@types/express@npm:*, @types/express@npm:^4.17.14, @types/express@npm:^4.17.17, @types/express@npm:^4.17.21, @types/express@npm:^4.17.6": +"@types/express@npm:*, @types/express@npm:^4.17.14, @types/express@npm:^4.17.21, @types/express@npm:^4.17.6": version: 4.17.21 resolution: "@types/express@npm:4.17.21" dependencies: From 715f8d5dc08e2eb9327ecb4ae2c74b031d84355c Mon Sep 17 00:00:00 2001 From: mario ma Date: Thu, 27 Jun 2024 23:35:22 +0800 Subject: [PATCH 122/510] fix: update by review comments Signed-off-by: mario ma --- plugins/catalog-react/api-report-alpha.md | 14 +++++----- .../EntityLifecyclePicker.tsx | 2 +- .../EntityNamespacePicker.tsx | 2 +- .../EntityOwnerPicker/EntityOwnerPicker.tsx | 2 +- .../EntityProcessingStatusPicker.tsx | 2 +- .../EntitySearchBar/EntitySearchBar.tsx | 2 +- .../EntityTagPicker/EntityTagPicker.tsx | 2 +- .../FavoriteEntity/FavoriteEntity.tsx | 2 +- plugins/catalog-react/src/translation.ts | 26 ++++++++++++++----- 9 files changed, 33 insertions(+), 21 deletions(-) diff --git a/plugins/catalog-react/api-report-alpha.md b/plugins/catalog-react/api-report-alpha.md index ea01122ccc..b82c7ae3e2 100644 --- a/plugins/catalog-react/api-report-alpha.md +++ b/plugins/catalog-react/api-report-alpha.md @@ -33,21 +33,21 @@ export const catalogReactTranslationRef: TranslationRef< readonly 'catalogFilter.buttonTitle': 'Filters'; readonly 'entityKindPicker.title': 'Kind'; readonly 'entityKindPicker.errorMessage': 'Failed to load entity kinds'; - readonly entityLifecyclePickerTitle: 'Lifecycle'; - readonly entityNamespacePickerTitle: 'Namespace'; - readonly entityOwnerPickerTitle: 'Owner'; + readonly 'entityLifecyclePicker.title': 'Lifecycle'; + readonly 'entityNamespacePicker.title': 'Namespace'; + readonly 'entityOwnerPicker.title': 'Owner'; + readonly 'entityProcessingStatusPicker.title': 'Processing Status'; + readonly 'entityTagPicker.title': 'Tags'; readonly 'entityPeekAheadPopover.title': 'Drill into the entity to see all of the tags.'; readonly 'entityPeekAheadPopover.entityCardActionsTitle': 'Show details'; readonly 'entityPeekAheadPopover.emailCardAction.title': 'Email {{email}}'; readonly 'entityPeekAheadPopover.emailCardAction.subTitle': 'mailto {{email}}'; - readonly entityProcessingStatusPickerTitle: 'Processing Status'; - readonly entitySearchBarPlaceholder: 'Search'; - readonly entityTagPickerTitle: 'Tags'; + readonly 'entitySearchBar.placeholder': 'Search'; readonly 'entityTypePicker.title': 'Type'; readonly 'entityTypePicker.errorMessage': 'Failed to load entity types'; readonly 'entityTypePicker.optionAllTitle': 'all'; readonly 'favoriteEntity.addToFavorites': 'Add to favorites'; - readonly 'favoriteEntity.RemoveFromFavorites': 'Remove from favorites'; + readonly 'favoriteEntity.removeFromFavorites': 'Remove from favorites'; readonly 'inspectEntityDialog.title': 'Entity Inspector'; readonly 'inspectEntityDialog.closeButtonTitle': 'Close'; readonly 'inspectEntityDialog.ancestryPage.title': 'Ancestry'; diff --git a/plugins/catalog-react/src/components/EntityLifecyclePicker/EntityLifecyclePicker.tsx b/plugins/catalog-react/src/components/EntityLifecyclePicker/EntityLifecyclePicker.tsx index 3c4e9e5573..2d8a0dea32 100644 --- a/plugins/catalog-react/src/components/EntityLifecyclePicker/EntityLifecyclePicker.tsx +++ b/plugins/catalog-react/src/components/EntityLifecyclePicker/EntityLifecyclePicker.tsx @@ -41,7 +41,7 @@ export const EntityLifecyclePicker = (props: { initialFilter?: string[] }) => { return ( { return ( { return ( - {t('entityOwnerPickerTitle')} + {t('entityOwnerPicker.title')} (
    {popperProps.children as ReactNode}
    diff --git a/plugins/catalog-react/src/components/EntityProcessingStatusPicker/EntityProcessingStatusPicker.tsx b/plugins/catalog-react/src/components/EntityProcessingStatusPicker/EntityProcessingStatusPicker.tsx index 08ce756923..20190a9907 100644 --- a/plugins/catalog-react/src/components/EntityProcessingStatusPicker/EntityProcessingStatusPicker.tsx +++ b/plugins/catalog-react/src/components/EntityProcessingStatusPicker/EntityProcessingStatusPicker.tsx @@ -74,7 +74,7 @@ export const EntityProcessingStatusPicker = () => { return ( - {t('entityProcessingStatusPickerTitle')} + {t('entityProcessingStatusPicker.title')} PopperComponent={popperProps => (
    {popperProps.children as ReactNode}
    diff --git a/plugins/catalog-react/src/components/EntitySearchBar/EntitySearchBar.tsx b/plugins/catalog-react/src/components/EntitySearchBar/EntitySearchBar.tsx index 671d582a57..abde5430bc 100644 --- a/plugins/catalog-react/src/components/EntitySearchBar/EntitySearchBar.tsx +++ b/plugins/catalog-react/src/components/EntitySearchBar/EntitySearchBar.tsx @@ -88,7 +88,7 @@ export const EntitySearchBar = () => { aria-label="search" id="input-with-icon-adornment" className={classes.input} - placeholder={t('entitySearchBarPlaceholder')} + placeholder={t('entitySearchBar.placeholder')} autoComplete="off" onChange={event => setSearch(event.target.value)} value={search} diff --git a/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.tsx b/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.tsx index a18e4f3b4e..2ab3622474 100644 --- a/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.tsx +++ b/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.tsx @@ -41,7 +41,7 @@ export const EntityTagPicker = (props: EntityTagPickerProps) => { return ( { diff --git a/plugins/catalog-react/src/translation.ts b/plugins/catalog-react/src/translation.ts index 685bf1fd00..7f9661380f 100644 --- a/plugins/catalog-react/src/translation.ts +++ b/plugins/catalog-react/src/translation.ts @@ -28,9 +28,21 @@ export const catalogReactTranslationRef = createTranslationRef({ title: 'Kind', errorMessage: 'Failed to load entity kinds', }, - entityLifecyclePickerTitle: 'Lifecycle', - entityNamespacePickerTitle: 'Namespace', - entityOwnerPickerTitle: 'Owner', + entityLifecyclePicker: { + title: 'Lifecycle', + }, + entityNamespacePicker: { + title: 'Namespace', + }, + entityOwnerPicker: { + title: 'Owner', + }, + entityProcessingStatusPicker: { + title: 'Processing Status', + }, + entityTagPicker: { + title: 'Tags', + }, entityPeekAheadPopover: { title: 'Drill into the entity to see all of the tags.', emailCardAction: { @@ -39,9 +51,9 @@ export const catalogReactTranslationRef = createTranslationRef({ }, entityCardActionsTitle: 'Show details', }, - entityProcessingStatusPickerTitle: 'Processing Status', - entitySearchBarPlaceholder: 'Search', - entityTagPickerTitle: 'Tags', + entitySearchBar: { + placeholder: 'Search', + }, entityTypePicker: { title: 'Type', errorMessage: 'Failed to load entity types', @@ -49,7 +61,7 @@ export const catalogReactTranslationRef = createTranslationRef({ }, favoriteEntity: { addToFavorites: 'Add to favorites', - RemoveFromFavorites: 'Remove from favorites', + removeFromFavorites: 'Remove from favorites', }, inspectEntityDialog: { title: 'Entity Inspector', From e36966c3e9d4536c33b79b8d4640dbcb1e30863c Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Thu, 27 Jun 2024 18:50:05 +0200 Subject: [PATCH 123/510] docs: create backstage engineer journey post Signed-off-by: Camila Belo --- .../2024-06-27-backstage-engineer-journey.mdx | 135 +++++++ .../2024-06-27/backstage-engineer-journey.svg | 362 ++++++++++++++++++ 2 files changed, 497 insertions(+) create mode 100644 microsite/blog/2024-06-27-backstage-engineer-journey.mdx create mode 100644 microsite/blog/assets/2024-06-27/backstage-engineer-journey.svg diff --git a/microsite/blog/2024-06-27-backstage-engineer-journey.mdx b/microsite/blog/2024-06-27-backstage-engineer-journey.mdx new file mode 100644 index 0000000000..b9bfc20e4e --- /dev/null +++ b/microsite/blog/2024-06-27-backstage-engineer-journey.mdx @@ -0,0 +1,135 @@ +--- +# prettier-ignore +title: "1,186 days with Backstage: A journey through the eyes of a developer" +author: Camila Loiola, Spotify +authorURL: https://github.com/camilaibs +authorImageURL: https://avatars.githubusercontent.com/u/6290749?v=4 +--- + +**TL;DR** There is no shortage of content that discusses the benefits that Backstage brings to organizations (and if you want to read more on that, you can just click [here](https://engineering.atspotify.com/category/backstage/), [here](https://backstage.io/blog), or [here](https://backstage.spotify.com/discover/blog/)). But I want to share what it did for me, a developer here at Spotify. And not just what it did, but how I’ve used Backstage to help me achieve goals at each stage of my journey at Spotify — from my first day as a brand new employee to today, my 1,186th day as a contributor. + +![Backstage Engineer Journey](assets/2024-06-27/backstage-engineer-journey.svg) + +{/* truncate */} + +## A new joiner with a need to get up to speed + +My first six months after joining Spotify, I was eager and determined to get up to speed so that I’d be able to start contributing as soon as possible. I set goals for myself and developed concrete activities to reach those goals: + +### Goal 1: Learn the internal process to develop, test, secure, and publish applications. + +Understanding a company’s practices and technologies is absolutely essential to getting started, no matter what company you join. + +At Spotify, we use a Backstage plugin called [TechDocs](https://backstage.io/docs/features/techdocs/) to document [Golden Paths](https://engineering.atspotify.com/2020/08/how-we-use-golden-paths-to-solve-fragmentation-in-our-software-ecosystem/) — tutorials that teach us the development process for each role at the company — for web, backend, mobile, data science development, and so on. + +With Backstage, I had an understanding of how to put things into production, even before I had my first task. I used the web Golden Path to guide me on setting up my environment; creating and structuring projects; and building, publishing, and monitoring production applications. + +> **Reflection:**
    _“Is it easy for newly hired engineers to settle in and find information critical to getting started?”_ + +With Backstage, new hires can quickly and easily understand the nuances of their particular positions and be ready to deliver their first task to production. + +### Goal 2: Find and read the documentation and source code of the products my team maintains. + +Having familiarized myself with the ways of working, it was a good time to understand my specific team’s business domain. This meant spending time reading through documentation and source code to find out the value we provide to our customers. In the past, I would spend time with colleagues for knowledge transfer as opposed to learning on my own and consult my colleagues if needed. + +With the [Backstage Software Catalog](https://backstage.io/docs/features/software-catalog/), I could easily browse the components my team owns, find the source repo and documentation. + +> **Reflection:**
    _“Are you able to accomplish this without asking a teammate for help?”_ + +Use Backstage to get to know the products that you will be working on, and use your peers' time to ask contextualized clarifying questions instead. + +### Goal 3: Figure out where my team fits within the company and with other teams. + +It was also crucial for me to build a network from the beginning so that I could explore collaboration opportunities. + +At Spotify, we use a Backstage plugin called Band Manager which displays information about each team and allows employees to see not only their own teams but also those within the same product area and company domain. + +> **Reflection:**
    _“Are you going to need a one-on-one with your manager to ask this question?”_ + +Backstage helped me find the teams close to mine, and I took the opportunity to develop my network and talk to members from those teams to understand our boundaries and gather ideas to contribute. + +It’s pretty likely that you can relate to one or more of these examples, so use Backstage to support your goals from the very beginning! + +Now let’s move on to the middle of the journey, between six months and two years into life at the company. + +## Two years in — from contributor to leader + +After about two years of contributing to my team’s products, I began to look for opportunities to actually lead initiatives and create a new project. One of my objectives was to ensure I was upholding Spotify’s standards and choosing Spotify-approved technologies. + +My goal has changed from being a contributor to being the driver, i.e., from doing what I was told to do to defining what needed to be done. I “started driving initiatives” and “supporting my peers” in order to position myself as a reference in my technical area. + +### Goal 1: Quickly spin up new projects using the most appropriate technology stack. + +At Spotify, we expect engineers to use technologies approved by our [Tech Radar](https://backstage.io/blog/2020/05/14/tech-radar-plugin/#what-is-tech-radar) and follow the best quality standards. + +To do so, we use a plugin called [Scaffolder](https://backstage.io/docs/reference/plugin-scaffolder) (aka Software Templates), which allows engineers to create templates for setting up new projects. Templates automate actions such as creating repositories, allocating resources, registering in the catalog, configuring deployments, and connecting to other internal systems. + +> **Reflection:**
    _“Do you need to create a ticket to get these things done before you even start coding? And is there a lot of time spent looking for boilerplate code to start a new project and connecting it to other internal systems?"_ + +Backstage enabled me to quickly create and publish a new backend that can deploy code to production with just a few clicks, so I could focus on building solutions for the business. I could use Backstage to easily build the right thing. Instead of spending time scaffolding projects, I could spend my time writing code. + +### Goal 2: Create products that have a healthy operational state and are easy to evolve. + +Keeping track of vulnerabilities and letting my team know about technical debts were other parts of my routine. + +With the [Soundcheck plugin](https://backstage.spotify.com/marketplace/spotify/plugin/soundcheck/), developers can easily configure checks to verify component health, such as reliability and other development and operational standards. We also have an internal Vulnerabilities plugin that displays fragilities in our components, so we can continuously prevent security issues. + +> **Reflection:**
    _“Do you know which components owned by your team follows best practices and standards and which ones are lagging behind?”_ + +Backstage helped me gather and better understand our technical debts, enabling me to effectively prioritize during our team’s planning, visualize which entities were compliant to our team’s best practices, and identify which ones needed improvement. + +### Goal 3: Respond effectively to incidents within our components or their dependencies. + +If you’ve been with a company for around two years, you might have had to manage incidents in one way or another — this was certainly the case for me. A typical problem was to determine if the issue is with the service that I own or a downstream dependency. + +Spotify has adopted [PagerDuty](https://backstage.spotify.com/marketplace/pagerduty/plugin/pagerduty/) to manage on-call rotation and to track incident resolutions. We integrated the PagerDuty plugin in Backstage, so we see who is on call and if there is an incident for a particular component. + +> **Reflection:**
    _“When a downstream dependency is failing, do you know who to contact?”_ + +In the event that one of our components starts failing, I check whether any of the systems we rely on is experiencing an incident, and Backstage again makes it easy for me to see the dependencies between systems and the status of those dependencies. + +## Today and beyond! + +With three-plus years of experience at Spotify, I’m taking on more and more responsibility by embracing challenges outside my team’s scope, coordinating cross-team collaboration, attending and facilitating courses for personal development and growth, and mentoring my peers. + +Backstage has allowed me to drive my pursuit of growth in a multitude of ways. + +### Goal 1: Stay in the flow and optimize my time management practices. + +At this point, finding time to focus — with all that I have on my plate — while also making time to learn new concepts is both fundamental and challenging for me. + +Spotify encourages its developers to manage their time in order to stay in the flow and to turn to the tools that help them prioritize effectively and focus on their work. + +> **Reflection:**
    _“How do you surface the most important notifications and avoid non-emergency distractions?”_ + +Backstage has been instrumental in helping me stay in the flow by surfacing the most critical notifications and call to actions related to cost spikes, security vulnerabilities in my homepage. + +### Goal 2: Platformize our solutions and reuse code to boost my productivity. + +Reinventing the wheel is a common problem in software development and Spotify is no different. + +Autonomous teams tend to prioritize speed over reuse and develop the same solutions in different places (1) as it unblocks the delivery for their team and (2) there is no easy way to discover if a particular functionality has been developed in another part of the company and if it can be reused for their requirement. + +> **Reflection:**
    _“Do you find yourself wondering if someone else already did it before starting a task?”_ + +With the [Backstage Search plugin](https://backstage.io/docs/features/search/), I can discover solutions to reuse, find inspiration, and also share what I’ve built for other developers to discover and use. + +### Goal 3: Grow my career and take steps toward the next level. + +I began looking for opportunities to gain new experiences and responsibilities while expanding my knowledge. + +With Spotify’s [Skill Exchange plugin](https://backstage.spotify.com/marketplace/spotify/plugin/skill-exchange/) for Backstage, engineers temporarily embed with a different team, allowing them to partake in work outside their day-to-day. The plugin also helps engineers connect with mentees or mentors that align with their skills profiles. + +> **Reflection:**
    _“Are you able to find opportunities that match your current skill set?”_ + +With Backstage, I've applied for an embed to experience working with another team and eventually make a permanent move to this new team, calling it my new home. + +I am passionate about teaching and eager to share my knowledge to help others. Through Skill Exchange, I found a mentee, a colleague transitioning into engineering, and I am helping them take their first steps. + +## What’s next? + +Backstage is highly customizable, and with its extensive plugin ecosystem, engineers can use it strategically to achieve their goals. + +No matter what point in your journey you are, you can find value with [Backstage](http://backstage.io). It was, after all, made by engineers for engineers. 💚 + +Special thanks to [Stanley Nicholl](https://github.com/stanley-nicholl), [Patrik Oldsberg](https://github.com/Rugvip), [Vincenzo Scamporlino](https://github.com/vinzscam), [Mihai Tabara](https://github.com/MihaiTabara), [Emma Indal](https://github.com/emmaindal), [Raghunandan Balachandran](https://github.com/soapraj) for all of their support. diff --git a/microsite/blog/assets/2024-06-27/backstage-engineer-journey.svg b/microsite/blog/assets/2024-06-27/backstage-engineer-journey.svg new file mode 100644 index 0000000000..1e302206a5 --- /dev/null +++ b/microsite/blog/assets/2024-06-27/backstage-engineer-journey.svg @@ -0,0 +1,362 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From a629fb22914852cd5f2c2e431b372833773c5156 Mon Sep 17 00:00:00 2001 From: 1337 <19777147+the-serious-programmer@users.noreply.github.com> Date: Thu, 27 Jun 2024 17:26:29 +0000 Subject: [PATCH 124/510] Added setAllowedLocationTypes with new CatalogLocationsExtensionPoint Signed-off-by: The serious programmer <19777147+the-serious-programmer@users.noreply.github.com> Signed-off-by: 1337 <19777147+the-serious-programmer@users.noreply.github.com> --- .changeset/hip-hairs-exist.md | 6 +++++ .../src/service/CatalogPlugin.ts | 26 +++++++++++++++++++ plugins/catalog-node/api-report-alpha.md | 8 ++++++ plugins/catalog-node/src/alpha.ts | 2 ++ plugins/catalog-node/src/extensions.ts | 19 ++++++++++++++ 5 files changed, 61 insertions(+) create mode 100644 .changeset/hip-hairs-exist.md diff --git a/.changeset/hip-hairs-exist.md b/.changeset/hip-hairs-exist.md new file mode 100644 index 0000000000..d8cb939dfb --- /dev/null +++ b/.changeset/hip-hairs-exist.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-catalog-backend': patch +'@backstage/plugin-catalog-node': patch +--- + +Added setAllowedLocationTypes while introducing a new extension point called CatalogLocationsExtensionPoint diff --git a/plugins/catalog-backend/src/service/CatalogPlugin.ts b/plugins/catalog-backend/src/service/CatalogPlugin.ts index aebd969701..2f5fd9103d 100644 --- a/plugins/catalog-backend/src/service/CatalogPlugin.ts +++ b/plugins/catalog-backend/src/service/CatalogPlugin.ts @@ -28,6 +28,8 @@ import { catalogPermissionExtensionPoint, CatalogProcessingExtensionPoint, catalogProcessingExtensionPoint, + CatalogLocationsExtensionPoint, + catalogLocationsExtensionPoint, } from '@backstage/plugin-catalog-node/alpha'; import { CatalogProcessor, @@ -41,6 +43,20 @@ import { merge } from 'lodash'; import { Permission } from '@backstage/plugin-permission-common'; import { ForwardedError } from '@backstage/errors'; +class CatalogLocationsExtensionPointImpl + implements CatalogLocationsExtensionPoint +{ + #locationTypes = new Array(); + + setAllowedLocationTypes(locationTypes: Array) { + this.#locationTypes = locationTypes; + } + + get allowedLocationTypes() { + return this.#locationTypes; + } +} + class CatalogProcessingExtensionPointImpl implements CatalogProcessingExtensionPoint { @@ -199,6 +215,12 @@ export const catalogPlugin = createBackendPlugin({ const modelExtensions = new CatalogModelExtensionPointImpl(); env.registerExtensionPoint(catalogModelExtensionPoint, modelExtensions); + const locationTypeExtensions = new CatalogLocationsExtensionPointImpl(); + env.registerExtensionPoint( + catalogLocationsExtensionPoint, + locationTypeExtensions, + ); + env.registerInit({ deps: { logger: coreServices.logger, @@ -271,6 +293,10 @@ export const catalogPlugin = createBackendPlugin({ builder.addPermissionRules(...permissionExtensions.permissionRules); builder.setFieldFormatValidators(modelExtensions.fieldValidators); + builder.setAllowedLocationTypes( + locationTypeExtensions.allowedLocationTypes, + ); + const { processingEngine, router } = await builder.build(); lifecycle.addStartupHook(async () => { diff --git a/plugins/catalog-node/api-report-alpha.md b/plugins/catalog-node/api-report-alpha.md index b61d1b1d27..e14f55c196 100644 --- a/plugins/catalog-node/api-report-alpha.md +++ b/plugins/catalog-node/api-report-alpha.md @@ -34,6 +34,14 @@ export interface CatalogAnalysisExtensionPoint { // @alpha (undocumented) export const catalogAnalysisExtensionPoint: ExtensionPoint; +// @alpha (undocumented) +export interface CatalogLocationsExtensionPoint { + setAllowedLocationTypes(locationTypes: Array): void; +} + +// @alpha (undocumented) +export const catalogLocationsExtensionPoint: ExtensionPoint; + // @alpha (undocumented) export interface CatalogModelExtensionPoint { setEntityDataParser(parser: CatalogProcessorParser): void; diff --git a/plugins/catalog-node/src/alpha.ts b/plugins/catalog-node/src/alpha.ts index 91b5bb99b6..b75ec48a7f 100644 --- a/plugins/catalog-node/src/alpha.ts +++ b/plugins/catalog-node/src/alpha.ts @@ -15,6 +15,8 @@ */ export { catalogServiceRef } from './catalogService'; +export type { CatalogLocationsExtensionPoint } from './extensions'; +export { catalogLocationsExtensionPoint } from './extensions'; export type { CatalogProcessingExtensionPoint } from './extensions'; export { catalogProcessingExtensionPoint } from './extensions'; export type { CatalogAnalysisExtensionPoint } from './extensions'; diff --git a/plugins/catalog-node/src/extensions.ts b/plugins/catalog-node/src/extensions.ts index 7c1fe6c30d..a971e1588d 100644 --- a/plugins/catalog-node/src/extensions.ts +++ b/plugins/catalog-node/src/extensions.ts @@ -31,6 +31,25 @@ import { } from '@backstage/plugin-permission-common'; import { PermissionRule } from '@backstage/plugin-permission-node'; +/** + * @alpha + */ +export interface CatalogLocationsExtensionPoint { + /** + * Allows setting custom location types, such as showcased in: https://backstage.io/docs/features/software-catalog/external-integrations/#creating-a-catalog-data-reader-processor + * @param locationTypes - List of location types to allow, default is "url" and "file" + */ + setAllowedLocationTypes(locationTypes: Array): void; +} + +/** + * @alpha + */ +export const catalogLocationsExtensionPoint = + createExtensionPoint({ + id: 'catalog.locations', + }); + /** * @alpha */ From 8a4c24e036daf76220b27c28f55178b8c1ea8814 Mon Sep 17 00:00:00 2001 From: Alex Lorenzi Date: Wed, 26 Jun 2024 17:21:37 -0400 Subject: [PATCH 125/510] Rollback the changes in #25332 Add MutationObserver in useShadowRootElements to we can trigger update when the elements under the shadow root change Signed-off-by: Alex Lorenzi Signed-off-by: Jackson Chen --- plugins/techdocs-react/src/context.tsx | 9 +------ plugins/techdocs-react/src/hooks.ts | 25 ++++++++++++++++--- .../TechDocsReaderPageContent.tsx | 4 +-- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/plugins/techdocs-react/src/context.tsx b/plugins/techdocs-react/src/context.tsx index 2e7cd9586d..43fdada98e 100644 --- a/plugins/techdocs-react/src/context.tsx +++ b/plugins/techdocs-react/src/context.tsx @@ -25,7 +25,6 @@ import React, { } from 'react'; import useAsync, { AsyncState } from 'react-use/esm/useAsync'; import useAsyncRetry from 'react-use/esm/useAsyncRetry'; -import useCounter from 'react-use/esm/useCounter'; import { CompoundEntityRef, @@ -65,8 +64,6 @@ export type TechDocsReaderPageValue = { entityMetadata: AsyncState; shadowRoot?: ShadowRoot; setShadowRoot: Dispatch>; - shadowRootVersion: number; - incShadowRootVersion: () => void; title: string; setTitle: Dispatch>; subtitle: string; @@ -83,8 +80,6 @@ const defaultTechDocsReaderPageValue: TechDocsReaderPageValue = { setTitle: () => {}, setSubtitle: () => {}, setShadowRoot: () => {}, - shadowRootVersion: 0, - incShadowRootVersion: () => {}, metadata: { loading: true }, entityMetadata: { loading: true }, entityRef: { kind: '', name: '', namespace: '' }, @@ -139,7 +134,6 @@ export const TechDocsReaderPageProvider = memo( const [shadowRoot, setShadowRoot] = useState( defaultTechDocsReaderPageValue.shadowRoot, ); - const [shadowRootVersion, { inc: incShadowRootVersion }] = useCounter(0); useEffect(() => { if (shadowRoot && !metadata.value && !metadata.loading) { @@ -159,8 +153,6 @@ export const TechDocsReaderPageProvider = memo( entityMetadata, shadowRoot, setShadowRoot, - shadowRootVersion, - incShadowRootVersion, title, setTitle, subtitle, @@ -198,5 +190,6 @@ export const useTechDocsReaderPage = () => { if (context === undefined) { throw new Error('No context found for version 1.'); } + return context; }; diff --git a/plugins/techdocs-react/src/hooks.ts b/plugins/techdocs-react/src/hooks.ts index 2984a4b588..bbff875f3a 100644 --- a/plugins/techdocs-react/src/hooks.ts +++ b/plugins/techdocs-react/src/hooks.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { useState, useEffect, useMemo } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import debounce from 'lodash/debounce'; import { useTechDocsReaderPage } from './context'; @@ -39,9 +39,28 @@ export const useShadowRootElements = < selectors: string[], ): TReturnedElement[] => { const shadowRoot = useShadowRoot(); - if (!shadowRoot) return []; + const [root, setRootNode] = useState(shadowRoot?.querySelector('html')); + + useEffect(() => { + let observer: MutationObserver; + if (shadowRoot) { + observer = new MutationObserver(() => { + setRootNode(shadowRoot.querySelector('html')); + }); + observer.observe(shadowRoot, { + attributes: true, + characterData: true, + childList: true, + subtree: true, + }); + } + return () => observer?.disconnect(); + }, [shadowRoot]); + + if (!root) return []; + return selectors - .map(selector => shadowRoot?.querySelectorAll(selector)) + .map(selector => root.querySelectorAll(selector)) .filter(nodeList => nodeList.length) .map(nodeList => Array.from(nodeList)) .flat(); diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContent.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContent.tsx index 00df73cab3..3692ed22d3 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContent.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContent.tsx @@ -80,7 +80,6 @@ export const TechDocsReaderPageContent = withTechDocsReaderProvider( entityMetadata: { value: entityMetadata, loading: entityMetadataLoading }, entityRef, setShadowRoot, - incShadowRootVersion, } = useTechDocsReaderPage(); const dom = useTechDocsReaderDom(entityRef); const path = window.location.pathname; @@ -103,12 +102,11 @@ export const TechDocsReaderPageContent = withTechDocsReaderProvider( const handleAppend = useCallback( (newShadowRoot: ShadowRoot) => { setShadowRoot(newShadowRoot); - incShadowRootVersion(); if (onReady instanceof Function) { onReady(); } }, - [setShadowRoot, incShadowRootVersion, onReady], + [setShadowRoot, onReady], ); // No entity metadata = 404. Don't render content at all. From ed67c8a16d53215c3a3176e13f8569c566a5c9f1 Mon Sep 17 00:00:00 2001 From: Alex Lorenzi Date: Wed, 26 Jun 2024 17:31:16 -0400 Subject: [PATCH 126/510] Updated changelog message Signed-off-by: Alex Lorenzi Signed-off-by: Jackson Chen --- .changeset/clever-waves-judge.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.changeset/clever-waves-judge.md b/.changeset/clever-waves-judge.md index 585ad01bbe..100ab66f90 100644 --- a/.changeset/clever-waves-judge.md +++ b/.changeset/clever-waves-judge.md @@ -1,6 +1,5 @@ --- '@backstage/plugin-techdocs-react': patch -'@backstage/plugin-techdocs': patch --- -Fixed a bug with the TechDocsReaderPageProvider not re-rendering when setShadowDom is called, meaning that the useShadowDom hooks were inconsistent. This issue caused the TextSize addon changes not to reapply during navigation. +Resolved the issue where changes in TechDoc add-ons, including the TextSize add-on, were not reapplying during navigation From 3c60a1095a644fb3fa406650eca2e8b843d35833 Mon Sep 17 00:00:00 2001 From: Alex Lorenzi Date: Wed, 26 Jun 2024 17:51:00 -0400 Subject: [PATCH 127/510] Reset API report Signed-off-by: Alex Lorenzi Signed-off-by: Jackson Chen --- plugins/techdocs-react/api-report.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/techdocs-react/api-report.md b/plugins/techdocs-react/api-report.md index 7d787c4da6..c158bbd81e 100644 --- a/plugins/techdocs-react/api-report.md +++ b/plugins/techdocs-react/api-report.md @@ -116,8 +116,6 @@ export type TechDocsReaderPageValue = { entityMetadata: AsyncState; shadowRoot?: ShadowRoot; setShadowRoot: Dispatch>; - shadowRootVersion: number; - incShadowRootVersion: () => void; title: string; setTitle: Dispatch>; subtitle: string; From 64e7e9409f6bc84fed0241adca226d09ac396561 Mon Sep 17 00:00:00 2001 From: ElaineDeMattosSilvaB Date: Thu, 27 Jun 2024 21:44:08 +0200 Subject: [PATCH 128/510] feat: add oauth token option for fetch action Signed-off-by: ElaineDeMattosSilvaB --- .../urlReader/lib/GitlabUrlReader.ts | 26 +++++++-------- packages/integration/src/gitlab/core.test.ts | 32 ++++++++++++++++++- packages/integration/src/gitlab/core.ts | 17 +++++++--- 3 files changed, 57 insertions(+), 18 deletions(-) diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.ts index 615eeb20a2..35123da851 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.ts @@ -23,21 +23,21 @@ import { UrlReaderServiceSearchOptions, UrlReaderServiceSearchResponse, } from '@backstage/backend-plugin-api'; +import { NotFoundError, NotModifiedError } from '@backstage/errors'; import { + GitLabIntegration, + ScmIntegrations, getGitLabFileFetchUrl, getGitLabIntegrationRelativePath, getGitLabRequestOptions, - GitLabIntegration, - ScmIntegrations, } from '@backstage/integration'; -import fetch, { Response } from 'node-fetch'; import parseGitUrl from 'git-url-parse'; -import { Minimatch } from 'minimatch'; -import { Readable } from 'stream'; -import { NotFoundError, NotModifiedError } from '@backstage/errors'; -import { ReadTreeResponseFactory, ReaderFactory } from './types'; import { trimEnd, trimStart } from 'lodash'; +import { Minimatch } from 'minimatch'; +import fetch, { Response } from 'node-fetch'; +import { Readable } from 'stream'; import { ReadUrlResponseFactory } from './ReadUrlResponseFactory'; +import { ReadTreeResponseFactory, ReaderFactory } from './types'; import { parseLastModified } from './util'; /** @@ -71,14 +71,14 @@ export class GitlabUrlReader implements UrlReaderService { url: string, options?: UrlReaderServiceReadUrlOptions, ): Promise { - const { etag, lastModifiedAfter, signal } = options ?? {}; + const { etag, lastModifiedAfter, signal, token } = options ?? {}; const builtUrl = await this.getGitlabFetchUrl(url); let response: Response; try { response = await fetch(builtUrl, { headers: { - ...getGitLabRequestOptions(this.integration.config).headers, + ...getGitLabRequestOptions(this.integration.config, token).headers, ...(etag && { 'If-None-Match': etag }), ...(lastModifiedAfter && { 'If-Modified-Since': lastModifiedAfter.toUTCString(), @@ -120,7 +120,7 @@ export class GitlabUrlReader implements UrlReaderService { url: string, options?: UrlReaderServiceReadTreeOptions, ): Promise { - const { etag, signal } = options ?? {}; + const { etag, signal, token } = options ?? {}; const { ref, full_name, filepath } = parseGitUrl(url); let repoFullName = full_name; @@ -147,7 +147,7 @@ export class GitlabUrlReader implements UrlReaderService { repoFullName, )}`, ).toString(), - getGitLabRequestOptions(this.integration.config), + getGitLabRequestOptions(this.integration.config, token), ); if (!projectGitlabResponse.ok) { const msg = `Failed to read tree from ${url}, ${projectGitlabResponse.status} ${projectGitlabResponse.statusText}`; @@ -175,7 +175,7 @@ export class GitlabUrlReader implements UrlReaderService { )}/repository/commits?${commitsReqParams.toString()}`, ).toString(), { - ...getGitLabRequestOptions(this.integration.config), + ...getGitLabRequestOptions(this.integration.config, token), // TODO(freben): The signal cast is there because pre-3.x versions of // node-fetch have a very slightly deviating AbortSignal type signature. // The difference does not affect us in practice however. The cast can @@ -209,7 +209,7 @@ export class GitlabUrlReader implements UrlReaderService { repoFullName, )}/repository/archive?${archiveReqParams.toString()}`, { - ...getGitLabRequestOptions(this.integration.config), + ...getGitLabRequestOptions(this.integration.config, token), // TODO(freben): The signal cast is there because pre-3.x versions of // node-fetch have a very slightly deviating AbortSignal type signature. // The difference does not affect us in practice however. The cast can diff --git a/packages/integration/src/gitlab/core.test.ts b/packages/integration/src/gitlab/core.test.ts index 98fd9b7c13..fd374ea56f 100644 --- a/packages/integration/src/gitlab/core.test.ts +++ b/packages/integration/src/gitlab/core.test.ts @@ -17,7 +17,7 @@ import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { GitLabIntegrationConfig } from './config'; -import { getGitLabFileFetchUrl } from './core'; +import { getGitLabFileFetchUrl, getGitLabRequestOptions } from './core'; const worker = setupServer(); @@ -186,4 +186,34 @@ describe('gitlab core', () => { }); }); }); + + describe('getGitLabRequestOptions', () => { + it('should return Authorization header when oauthToken is provided', () => { + const oauthToken = 'mock-oauth-token'; + const result = getGitLabRequestOptions( + configSelfHosteWithRelativePath, + oauthToken, + ); + + expect(result).toEqual({ + headers: { + Authorization: `Bearer ${oauthToken}`, + }, + }); + }); + + it('should return private-token header when oauthToken is undefined', () => { + const oauthToken = undefined; + const result = getGitLabRequestOptions( + configSelfHosteWithRelativePath, + oauthToken, + ); + + expect(result).toEqual({ + headers: { + 'PRIVATE-TOKEN': configSelfHosteWithRelativePath.token, + }, + }); + }); + }); }); diff --git a/packages/integration/src/gitlab/core.ts b/packages/integration/src/gitlab/core.ts index 040ca202d6..e940440ea4 100644 --- a/packages/integration/src/gitlab/core.ts +++ b/packages/integration/src/gitlab/core.ts @@ -14,11 +14,11 @@ * limitations under the License. */ +import fetch from 'cross-fetch'; import { getGitLabIntegrationRelativePath, GitLabIntegrationConfig, } from './config'; -import fetch from 'cross-fetch'; /** * Given a URL pointing to a file on a provider, returns a URL that is suitable @@ -51,9 +51,18 @@ export async function getGitLabFileFetchUrl( * @param config - The relevant provider config * @public */ -export function getGitLabRequestOptions(config: GitLabIntegrationConfig): { - headers: Record; -} { +export function getGitLabRequestOptions( + config: GitLabIntegrationConfig, + oauthToken?: string, +): { headers: Record } { + if (oauthToken) { + return { + headers: { + Authorization: `Bearer ${oauthToken}`, + }, + }; + } + const { token = '' } = config; return { headers: { From 2f7a7df46b557ddb747e2952cc657aa9f46be133 Mon Sep 17 00:00:00 2001 From: ElaineDeMattosSilvaB Date: Thu, 27 Jun 2024 22:10:40 +0200 Subject: [PATCH 129/510] feat: add possibility of a user provided glpat Signed-off-by: ElaineDeMattosSilvaB --- packages/integration/src/gitlab/core.test.ts | 22 ++++++++++++++++---- packages/integration/src/gitlab/core.ts | 18 ++++++++-------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/packages/integration/src/gitlab/core.test.ts b/packages/integration/src/gitlab/core.test.ts index fd374ea56f..c6e7410932 100644 --- a/packages/integration/src/gitlab/core.test.ts +++ b/packages/integration/src/gitlab/core.test.ts @@ -189,15 +189,30 @@ describe('gitlab core', () => { describe('getGitLabRequestOptions', () => { it('should return Authorization header when oauthToken is provided', () => { - const oauthToken = 'mock-oauth-token'; + const token = + 'de6780bc506a0446309bd9362820ba8aed28aa506c71eedbe1c5c4f9dd350e54'; const result = getGitLabRequestOptions( configSelfHosteWithRelativePath, - oauthToken, + token, ); expect(result).toEqual({ headers: { - Authorization: `Bearer ${oauthToken}`, + Authorization: `Bearer ${token}`, + }, + }); + }); + + it('should return private-token header when gl-token is provided', () => { + const token = 'glpat-1234566'; + const result = getGitLabRequestOptions( + configSelfHosteWithRelativePath, + token, + ); + + expect(result).toEqual({ + headers: { + 'PRIVATE-TOKEN': token, }, }); }); @@ -208,7 +223,6 @@ describe('gitlab core', () => { configSelfHosteWithRelativePath, oauthToken, ); - expect(result).toEqual({ headers: { 'PRIVATE-TOKEN': configSelfHosteWithRelativePath.token, diff --git a/packages/integration/src/gitlab/core.ts b/packages/integration/src/gitlab/core.ts index e940440ea4..94f4b65d9f 100644 --- a/packages/integration/src/gitlab/core.ts +++ b/packages/integration/src/gitlab/core.ts @@ -53,21 +53,21 @@ export async function getGitLabFileFetchUrl( */ export function getGitLabRequestOptions( config: GitLabIntegrationConfig, - oauthToken?: string, + token?: string, ): { headers: Record } { - if (oauthToken) { + if (token) { + // If token comes from the user and starts with "gl", it's a private token (see https://docs.gitlab.com/ee/security/token_overview.html#token-prefixes) return { - headers: { - Authorization: `Bearer ${oauthToken}`, - }, + headers: token.startsWith('gl') + ? { 'PRIVATE-TOKEN': token } + : { Authorization: `Bearer ${token}` }, // Otherwise, it's a bearer token }; } - const { token = '' } = config; + // If token not provided, fetch the integration token + const { token: configToken = '' } = config; return { - headers: { - 'PRIVATE-TOKEN': token, - }, + headers: { 'PRIVATE-TOKEN': configToken }, }; } From 78c13290e470387e4e490bece3362fe86f115bc6 Mon Sep 17 00:00:00 2001 From: ElaineDeMattosSilvaB Date: Thu, 27 Jun 2024 22:21:59 +0200 Subject: [PATCH 130/510] chore: add changeset and api-report Signed-off-by: ElaineDeMattosSilvaB --- .changeset/nice-peas-retire.md | 6 ++++++ packages/integration/api-report.md | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 .changeset/nice-peas-retire.md diff --git a/.changeset/nice-peas-retire.md b/.changeset/nice-peas-retire.md new file mode 100644 index 0000000000..7b7b13706d --- /dev/null +++ b/.changeset/nice-peas-retire.md @@ -0,0 +1,6 @@ +--- +'@backstage/integration': minor +'@backstage/backend-defaults': patch +--- + +Updated `GitlabUrlReader.readUrl` and `GitlabUrlReader.readTree` to accept a user-provided token, supporting both bearer and private tokens. diff --git a/packages/integration/api-report.md b/packages/integration/api-report.md index 4c8e8accf2..cf4b380ad9 100644 --- a/packages/integration/api-report.md +++ b/packages/integration/api-report.md @@ -508,7 +508,10 @@ export function getGitLabIntegrationRelativePath( ): string; // @public -export function getGitLabRequestOptions(config: GitLabIntegrationConfig): { +export function getGitLabRequestOptions( + config: GitLabIntegrationConfig, + token?: string, +): { headers: Record; }; From 28d3cf8c9db6f72f1d7f14c0c5d34d53a0599d80 Mon Sep 17 00:00:00 2001 From: ElaineDeMattosSilvaB Date: Thu, 27 Jun 2024 22:42:29 +0200 Subject: [PATCH 131/510] fix: change mocked bearer token format Signed-off-by: ElaineDeMattosSilvaB --- packages/integration/src/gitlab/core.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/integration/src/gitlab/core.test.ts b/packages/integration/src/gitlab/core.test.ts index c6e7410932..81adc29701 100644 --- a/packages/integration/src/gitlab/core.test.ts +++ b/packages/integration/src/gitlab/core.test.ts @@ -189,8 +189,7 @@ describe('gitlab core', () => { describe('getGitLabRequestOptions', () => { it('should return Authorization header when oauthToken is provided', () => { - const token = - 'de6780bc506a0446309bd9362820ba8aed28aa506c71eedbe1c5c4f9dd350e54'; + const token = '1234567890'; const result = getGitLabRequestOptions( configSelfHosteWithRelativePath, token, From 92583daf57de6cb64b0ed889deba220c66b933c7 Mon Sep 17 00:00:00 2001 From: Chap Ambrose Date: Thu, 27 Jun 2024 16:43:38 -0500 Subject: [PATCH 132/510] Update heroku deploy docs Signed-off-by: Chap Ambrose --- docs/deployment/heroku.md | 99 ++++++++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 33 deletions(-) diff --git a/docs/deployment/heroku.md b/docs/deployment/heroku.md index 1545c34733..a70ff66ca5 100644 --- a/docs/deployment/heroku.md +++ b/docs/deployment/heroku.md @@ -5,40 +5,40 @@ sidebar_label: Heroku description: How to deploy Backstage to Heroku --- -Heroku is a Platform as a Service (PaaS) designed to handle application -deployment in a hands-off way. Heroku supports container deployment of Docker -images, a natural fit for Backstage. +Heroku is a Platform as a Service (PaaS) designed to simplify application deployment. -## Configuring the CLI +## Create App -First, install the -[heroku-cli](https://devcenter.heroku.com/articles/heroku-cli) and login: +Start with an exisiting Backstage app or follow the [getting started guide](https://backstage.io/docs/getting-started/) to create a new one: ```shell -$ heroku login +$ npx @backstage/create-app@latest + Enter a name ``` -If you have not yet created a project through the Heroku interface, you can create it through the CLI. +Install the +[Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli) and create a new Heroku app: ```shell -$ heroku create +$ cd your-app/ +$ heroku apps:create ``` -You _might_ also need to set your Heroku app's stack to `container`: +## Domain -```bash -$ heroku stack:set container -a +Get Heroku app URL: +```shell +$ heroku domains -a +.herokuapp.com ``` -Configuring your `app-config.yaml`: - +Update `baseUrl` and `port` in `app-config.yaml`. The core [app-backend plugin](https://www.npmjs.com/package/@backstage/plugin-app-backend) allows a single Heroku app to serve the frontend and backend: ```yaml app: - # Should be the same as backend.baseUrl when using the `app-backend` plugin - baseUrl: https://.herokuapp.com + baseUrl: https://.herokuapp.com backend: - baseUrl: https://.herokuapp.com + baseUrl: https://.herokuapp.com listen: port: $env: PORT @@ -46,28 +46,61 @@ backend: # https://devcenter.heroku.com/articles/dynos#web-dynos ``` -> Make sure your file is being copied into your container in the `Dockerfile`. +## Build Script -Before building the Docker image, run the [backstage host build commands](https://backstage.io/docs/deployment/docker#host-build). They must be run whenever you are going to publish a new image. +Add a build script in `package.json` to compile frontend during deployment: +```json +"scripts": { + "build": "yarn build:backend --config ../../app-config.yaml" +``` -Heroku runs a container registry on `registry.heroku.com`. To push Backstage -Docker images, log in to the container registry also: +## Start Command + +Create a [Procfile](https://devcenter.heroku.com/articles/procfile) in the app's root: +```shell +$ echo "web: yarn workspace backend start --config ../../app-config.yaml" > Procfile +``` + +## Database + +Provision a [Heroku Postgres](https://elements.heroku.com/addons/heroku-postgresql) database: +```shell +$ heroku addons:create heroku-postgresql -a +``` + +Update `database` in `app-config.yaml`: +```yaml +backend: + database: + client: pg + pluginDivisionMode: schema + ensureExists: false + ensureSchemaExists: true + connection: ${DATABASE_URL} +``` + +Allow postgres self-signed certificates: +```shell +$ heroku config:set PGSSLMODE=no-verify -a +``` + +## Deployment + +Commit changes and push to Heroku to build and deploy: ```shell -$ heroku container:login +$ git add Procfile && git commit -am "configure heroku" +$ git push heroku main ``` -## Push and deploy a Docker image +View the app in the browser: -Now we can push a Backstage [Docker image](docker.md) to Heroku's container -registry and release it to the `web` worker: - -```bash -$ docker image build . -f packages/backend/Dockerfile --tag registry.heroku.com//web - -$ docker push registry.heroku.com//web - -$ heroku container:release web -a +```shell +$ heroku open -a ``` -Now you should have Backstage up and running! 🎉 +View logs: + +```shell +$ heroku heroku -a +``` From 354e68c9537b0794634960101909fe05564b659a Mon Sep 17 00:00:00 2001 From: Stephen Glass Date: Wed, 19 Jun 2024 22:14:49 -0400 Subject: [PATCH 133/510] Improve validation error display text in scaffolder UI Signed-off-by: Stephen Glass --- .changeset/swift-dots-cough.md | 5 + .../errorListTemplate.test.tsx | 99 +++++++++++++++---- .../ErrorListTemplate/errorListTemplate.tsx | 26 ++++- 3 files changed, 109 insertions(+), 21 deletions(-) create mode 100644 .changeset/swift-dots-cough.md diff --git a/.changeset/swift-dots-cough.md b/.changeset/swift-dots-cough.md new file mode 100644 index 0000000000..255ee192a0 --- /dev/null +++ b/.changeset/swift-dots-cough.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-react': minor +--- + +Improve validation error display text in scaffolder diff --git a/plugins/scaffolder-react/src/next/components/Stepper/ErrorListTemplate/errorListTemplate.test.tsx b/plugins/scaffolder-react/src/next/components/Stepper/ErrorListTemplate/errorListTemplate.test.tsx index c5ddf6854f..d632340031 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/ErrorListTemplate/errorListTemplate.test.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/ErrorListTemplate/errorListTemplate.test.tsx @@ -19,25 +19,88 @@ import { renderInTestApp } from '@backstage/test-utils'; import { ErrorListProps } from '@rjsf/utils'; describe('Error List Template', () => { - const errorList = { - errors: [ - { - stack: 'Test error 1', - }, - { - stack: 'Test error 2', - }, - ], - errorSchema: {}, - } as Partial as ErrorListProps; + describe('should render the error messages', () => { + it('no properties', async () => { + const errorList = { + errors: [ + { + stack: 'Test error 1', + }, + { + stack: 'Test error 2', + }, + ], + errorSchema: {}, + } as Partial as ErrorListProps; - it('should render the error messages', async () => { - const { getByText } = await renderInTestApp( - , - ); + const { getByText } = await renderInTestApp( + , + ); - for (const error of errorList.errors) { - expect(getByText(error.stack)).toBeInTheDocument(); - } + for (const error of errorList.errors) { + expect(getByText(error.stack)).toBeInTheDocument(); + } + }); + + it('properties no title', async () => { + const errorList = { + errors: [ + { + property: '.foo', + stack: 'Test error 1', + message: 'Test error 1', + }, + { + property: '.anExampleTitle', + stack: 'Test error 2', + message: 'Test error 2', + }, + ], + errorSchema: {}, + schema: {}, + } as Partial as ErrorListProps; + + const { getByText } = await renderInTestApp( + , + ); + + expect(getByText("'Foo' Test error 1")).toBeInTheDocument(); + expect(getByText("'An Example Title' Test error 2")).toBeInTheDocument(); + }); + + it('properties with title', async () => { + const errorList = { + errors: [ + { + property: '.foo', + stack: 'Test error 1', + message: 'Test error 1', + }, + { + property: '.bar', + stack: 'Test error 2', + message: 'Test error 2', + }, + ], + errorSchema: {}, + schema: { + properties: { + foo: { + title: 'Hello', + }, + bar: { + title: 'Example Title', + }, + }, + }, + } as Partial as ErrorListProps; + + const { getByText } = await renderInTestApp( + , + ); + + expect(getByText("'Hello' Test error 1")).toBeInTheDocument(); + expect(getByText("'Example Title' Test error 2")).toBeInTheDocument(); + }); }); }); diff --git a/plugins/scaffolder-react/src/next/components/Stepper/ErrorListTemplate/errorListTemplate.tsx b/plugins/scaffolder-react/src/next/components/Stepper/ErrorListTemplate/errorListTemplate.tsx index a5310a5806..6b664fc235 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/ErrorListTemplate/errorListTemplate.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/ErrorListTemplate/errorListTemplate.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ import React from 'react'; -import { ErrorListProps } from '@rjsf/utils'; +import { ErrorListProps, RJSFValidationError } from '@rjsf/utils'; import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; import ListItemIcon from '@material-ui/core/ListItemIcon'; @@ -22,6 +22,7 @@ import ListItemText from '@material-ui/core/ListItemText'; import Paper from '@material-ui/core/Paper'; import { Theme, createStyles, makeStyles } from '@material-ui/core/styles'; import ErrorIcon from '@material-ui/icons/Error'; +import startCase from 'lodash/startCase'; const useStyles = makeStyles((_theme: Theme) => createStyles({ @@ -39,9 +40,28 @@ const useStyles = makeStyles((_theme: Theme) => * * @public */ -export const ErrorListTemplate = ({ errors }: ErrorListProps) => { +export const ErrorListTemplate = ({ errors, schema }: ErrorListProps) => { const classes = useStyles(); + function formatErrorMessage(error: RJSFValidationError) { + if (error.property && error.message) { + const propertyName = error.property.startsWith('.') + ? error.property.substring(1) + : error.property; + if (schema.properties && propertyName in schema.properties) { + const property = schema.properties[propertyName]; + + if (typeof property === 'object' && 'title' in property) { + return `'${property.title}' ${error.message}`; + } + } + // fall back to property name + return `'${startCase(propertyName)}' ${error.message}`; + } + // fall back if property does not exist + return error.stack; + } + return ( @@ -52,7 +72,7 @@ export const ErrorListTemplate = ({ errors }: ErrorListProps) => { ))} From df4d3ca4939802045f2a0dd7157fee44077c4ee6 Mon Sep 17 00:00:00 2001 From: Jackson Chen Date: Thu, 27 Jun 2024 15:33:39 -0400 Subject: [PATCH 134/510] Fix tests Signed-off-by: Jackson Chen --- plugins/techdocs-react/src/hooks.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/techdocs-react/src/hooks.ts b/plugins/techdocs-react/src/hooks.ts index bbff875f3a..2d922ab7f4 100644 --- a/plugins/techdocs-react/src/hooks.ts +++ b/plugins/techdocs-react/src/hooks.ts @@ -39,13 +39,13 @@ export const useShadowRootElements = < selectors: string[], ): TReturnedElement[] => { const shadowRoot = useShadowRoot(); - const [root, setRootNode] = useState(shadowRoot?.querySelector('html')); + const [render, rerender] = useState(false); useEffect(() => { let observer: MutationObserver; if (shadowRoot) { observer = new MutationObserver(() => { - setRootNode(shadowRoot.querySelector('html')); + rerender(!render); }); observer.observe(shadowRoot, { attributes: true, @@ -55,12 +55,12 @@ export const useShadowRootElements = < }); } return () => observer?.disconnect(); - }, [shadowRoot]); + }, [shadowRoot, render, rerender]); - if (!root) return []; + if (!shadowRoot) return []; return selectors - .map(selector => root.querySelectorAll(selector)) + .map(selector => shadowRoot.querySelectorAll(selector)) .filter(nodeList => nodeList.length) .map(nodeList => Array.from(nodeList)) .flat(); From 19d495939d23984987ac1097e61faadb3b0fd2aa Mon Sep 17 00:00:00 2001 From: Stephen Glass Date: Thu, 27 Jun 2024 23:20:51 -0400 Subject: [PATCH 135/510] Extract condition check to function Signed-off-by: Stephen Glass --- .../components/ReviewState/ReviewState.tsx | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx index ac7ac989e3..202e0c0fbf 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx +++ b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx @@ -47,11 +47,8 @@ function flattenObject( // Recurse into nested objects if ( - backstageReviewOptions && - backstageReviewOptions.explode && - typeof value === 'object' && - value !== null && - !Array.isArray(value) + backstageReviewOptions?.explode && + isJsonObject(value) ) { return flattenObject(value, prefixedKey, schema, formState); } @@ -61,6 +58,14 @@ function flattenObject( }); } +function isJsonObject(value?: JsonValue): value is JsonObject { + return ( + typeof value === 'object' && + value !== null && + !Array.isArray(value) + ); +} + /** * The component used by the {@link Stepper} to render the review step. * @alpha @@ -89,9 +94,7 @@ export const ReviewState = (props: ReviewStateProps) => { } if ( backstageReviewOptions.explode && - typeof value === 'object' && - value !== null && - !Array.isArray(value) + isJsonObject(value) ) { return flattenObject(value, key, parsedSchema, props.formState); } @@ -106,7 +109,7 @@ export const ReviewState = (props: ReviewStateProps) => { [ key, definitionInSchema.enumNames[ - definitionInSchema.enum.indexOf(value) + definitionInSchema.enum.indexOf(value) ] || value, ], ]; From 7193d02b32b27eed9519875a03456b687e738936 Mon Sep 17 00:00:00 2001 From: Stephen Glass Date: Fri, 28 Jun 2024 01:18:20 -0400 Subject: [PATCH 136/510] Fix formatting Signed-off-by: Stephen Glass --- .../components/ReviewState/ReviewState.tsx | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx index 202e0c0fbf..22ec54ac26 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx +++ b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx @@ -46,10 +46,7 @@ function flattenObject( const backstageReviewOptions = definitionInSchema['ui:backstage']?.review; // Recurse into nested objects - if ( - backstageReviewOptions?.explode && - isJsonObject(value) - ) { + if (backstageReviewOptions?.explode && isJsonObject(value)) { return flattenObject(value, prefixedKey, schema, formState); } } @@ -59,11 +56,7 @@ function flattenObject( } function isJsonObject(value?: JsonValue): value is JsonObject { - return ( - typeof value === 'object' && - value !== null && - !Array.isArray(value) - ); + return typeof value === 'object' && value !== null && !Array.isArray(value); } /** @@ -92,10 +85,7 @@ export const ReviewState = (props: ReviewStateProps) => { if (backstageReviewOptions.show === false) { return []; } - if ( - backstageReviewOptions.explode && - isJsonObject(value) - ) { + if (backstageReviewOptions.explode && isJsonObject(value)) { return flattenObject(value, key, parsedSchema, props.formState); } } @@ -109,7 +99,7 @@ export const ReviewState = (props: ReviewStateProps) => { [ key, definitionInSchema.enumNames[ - definitionInSchema.enum.indexOf(value) + definitionInSchema.enum.indexOf(value) ] || value, ], ]; From c59167016378de2b5206737ab283b43d5b77887a Mon Sep 17 00:00:00 2001 From: Calvin Lee Date: Wed, 26 Jun 2024 16:07:06 -0600 Subject: [PATCH 137/510] fix: enable support for account and org level urls Signed-off-by: Calvin Lee --- .changeset/witty-bears-behave.md | 5 ++ packages/integration/src/harness/core.ts | 71 +++++++++++++++++------- 2 files changed, 55 insertions(+), 21 deletions(-) create mode 100644 .changeset/witty-bears-behave.md diff --git a/.changeset/witty-bears-behave.md b/.changeset/witty-bears-behave.md new file mode 100644 index 0000000000..33b4c0b187 --- /dev/null +++ b/.changeset/witty-bears-behave.md @@ -0,0 +1,5 @@ +--- +'@backstage/integration': patch +--- + +Updated function for getHarnessEditContentsUrl, getHarnessFileContentsUrl, getHarnessArchiveUrl, getHarnessLatestCommitUrl and parseHarnessUrl to handle account and org level urls diff --git a/packages/integration/src/harness/core.ts b/packages/integration/src/harness/core.ts index 81281eaa6e..1887a5c0d8 100644 --- a/packages/integration/src/harness/core.ts +++ b/packages/integration/src/harness/core.ts @@ -34,7 +34,12 @@ export function getHarnessEditContentsUrl( url: string, ) { const parsedUrl = parseHarnessUrl(config, url); - return `${parsedUrl.baseUrl}/ng/account/${parsedUrl.accountId}/module/code/orgs/${parsedUrl.orgName}/projects/${parsedUrl.projectName}/repos/${parsedUrl.repoName}/files/${parsedUrl.branch}/~/${parsedUrl.path}`; + + return `${parsedUrl.baseUrl}/ng/account/${parsedUrl.accountId}/module/code${ + parsedUrl.orgName !== '' ? `/orgs/${parsedUrl.orgName}` : '' + }${ + parsedUrl.projectName !== '' ? `/projects/${parsedUrl.projectName}` : '' + }/repos/${parsedUrl.repoName}/files/${parsedUrl.branch}/~/${parsedUrl.path}`; } /** @@ -44,6 +49,7 @@ export function getHarnessEditContentsUrl( * * Converts * from: https://app.harness.io/ng/account/accountId/module/code/orgs/orgName/projects/projName/repos/repoName/files/refMain/~/all-apis.yaml + * https://qa.harness.io/ng/account/bDCAuAjFSJCLFj_0ug3lCg/module/code/orgs/HiteshTest/repos/impoorter/files/main/~/catalog.yaml * to: https://app.harness.io/gateway/code/api/v1/repos/accountId/orgName/projName/repoName/+/content/all-apis.yaml?routingId=accountId&include_commit=false&ref=refMain * * @param url - A URL pointing to a file @@ -55,7 +61,14 @@ export function getHarnessFileContentsUrl( url: string, ) { const parsedUrl = parseHarnessUrl(config, url); - return `${parsedUrl.baseUrl}/gateway/code/api/v1/repos/${parsedUrl.accountId}/${parsedUrl.orgName}/${parsedUrl.projectName}/${parsedUrl.repoName}/+/raw/${parsedUrl.path}?routingId=${parsedUrl.accountId}&git_ref=refs/heads/${parsedUrl.refString}`; + + return `${parsedUrl.baseUrl}/gateway/code/api/v1/repos/${ + parsedUrl.accountId + }/${parsedUrl.orgName}${ + parsedUrl.projectName !== '' ? `/${parsedUrl.projectName}/` : '/' + }${parsedUrl.repoName}/+/raw/${parsedUrl.path}?routingId=${ + parsedUrl.accountId + }&git_ref=refs/heads/${parsedUrl.refString}`; } /** @@ -77,7 +90,13 @@ export function getHarnessArchiveUrl( url: string, ) { const parsedUrl = parseHarnessUrl(config, url); - return `${parsedUrl.baseUrl}/gateway/code/api/v1/repos/${parsedUrl.accountId}/${parsedUrl.orgName}/${parsedUrl.projectName}/${parsedUrl.repoName}/+/archive/${parsedUrl.branch}.zip?routingId=${parsedUrl.accountId}`; + return `${parsedUrl.baseUrl}/gateway/code/api/v1/repos/${ + parsedUrl.accountId + }/${parsedUrl.orgName}${ + parsedUrl.projectName !== '' ? `/${parsedUrl.projectName}/` : '/' + }${parsedUrl.repoName}/+/archive/${parsedUrl.branch}.zip?routingId=${ + parsedUrl.accountId + }`; } /** @@ -99,7 +118,13 @@ export function getHarnessLatestCommitUrl( url: string, ) { const parsedUrl = parseHarnessUrl(config, url); - return `${parsedUrl.baseUrl}/gateway/code/api/v1/repos/${parsedUrl.accountId}/${parsedUrl.orgName}/${parsedUrl.projectName}/${parsedUrl.repoName}/+/content?routingId=${parsedUrl.accountId}&include_commit=true&git_ref=refs/heads/${parsedUrl.branch}`; + return `${parsedUrl.baseUrl}/gateway/code/api/v1/repos/${ + parsedUrl.accountId + }/${parsedUrl.orgName}${ + parsedUrl.projectName !== '' ? `/${parsedUrl.projectName}/` : '/' + }${parsedUrl.repoName}/+/content?routingId=${ + parsedUrl.accountId + }&include_commit=true&git_ref=refs/heads/${parsedUrl.branch}`; } /** @@ -153,27 +178,30 @@ export function parseHarnessUrl( .split('/') .filter(segment => segment !== ''); const urlParts = pathUrl.pathname.split('/'); - const [ - _ng, - _account, - accountId, - _module, - _moduleName, - _org, - orgName, - _projects, - projectName, - _repos, - repoName, - _files, - _ref, - _branch, - ..._path - ] = pathSegments; + + const accountIdIndex = + pathSegments.findIndex(segment => segment === 'account') + 1; + const accountId = pathSegments[accountIdIndex]; + + const orgNameIndex = pathSegments.findIndex(segment => segment === 'orgs'); + const orgName = orgNameIndex !== -1 ? pathSegments[orgNameIndex + 1] : ''; + + const projectNameIndex = pathSegments.findIndex( + segment => segment === 'projects', + ); + + const projectName = + projectNameIndex !== -1 ? pathSegments[projectNameIndex + 1] : ''; + + const repoNameIndex = + pathSegments.findIndex(segment => segment === 'repos') + 1; + const repoName = pathSegments[repoNameIndex]; + const refAndPath = urlParts.slice( urlParts.findIndex(i => i === 'files' || i === 'edit') + 1, ); const refIndex = refAndPath.findIndex(item => item === '~'); + const refString = refAndPath.slice(0, refIndex).join('/'); const pathWithoutSlash = refIndex !== -1 @@ -182,6 +210,7 @@ export function parseHarnessUrl( .join('/') .replace(/^\//, '') : ''; + return { baseUrl: baseUrl, accountId: accountId, From a840355a10f9ad1b47975b65b30e89a4e7181876 Mon Sep 17 00:00:00 2001 From: Calvin Lee Date: Fri, 28 Jun 2024 11:41:43 -0600 Subject: [PATCH 138/510] fix: update changeset Signed-off-by: Calvin Lee --- .changeset/witty-bears-behave.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/witty-bears-behave.md b/.changeset/witty-bears-behave.md index 33b4c0b187..7514759189 100644 --- a/.changeset/witty-bears-behave.md +++ b/.changeset/witty-bears-behave.md @@ -2,4 +2,4 @@ '@backstage/integration': patch --- -Updated function for getHarnessEditContentsUrl, getHarnessFileContentsUrl, getHarnessArchiveUrl, getHarnessLatestCommitUrl and parseHarnessUrl to handle account and org level urls +Updated functions for getHarnessEditContentsUrl, getHarnessFileContentsUrl, getHarnessArchiveUrl, getHarnessLatestCommitUrl and parseHarnessUrl to handle account and org level urls From 141f36662561d0c7cbc62a27a8aa0deff89603c7 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 21 Jun 2024 11:29:29 -0500 Subject: [PATCH 139/510] Added action to enable GitHub Pages on a repo Signed-off-by: Andre Wanlin --- .changeset/spotty-crabs-shop.md | 5 + .../api-report.md | 15 ++ .../src/actions/githubPages.examples.test.ts | 90 ++++++++++++ .../src/actions/githubPages.examples.ts | 40 ++++++ .../src/actions/githubPages.test.ts | 93 +++++++++++++ .../src/actions/githubPages.ts | 130 ++++++++++++++++++ .../src/actions/index.ts | 2 +- .../src/module.ts | 5 + 8 files changed, 379 insertions(+), 1 deletion(-) create mode 100644 .changeset/spotty-crabs-shop.md create mode 100644 plugins/scaffolder-backend-module-github/src/actions/githubPages.examples.test.ts create mode 100644 plugins/scaffolder-backend-module-github/src/actions/githubPages.examples.ts create mode 100644 plugins/scaffolder-backend-module-github/src/actions/githubPages.test.ts create mode 100644 plugins/scaffolder-backend-module-github/src/actions/githubPages.ts diff --git a/.changeset/spotty-crabs-shop.md b/.changeset/spotty-crabs-shop.md new file mode 100644 index 0000000000..6bc1bcfe0c --- /dev/null +++ b/.changeset/spotty-crabs-shop.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-github': patch +--- + +Added action to enable GitHub Pages on a repo diff --git a/plugins/scaffolder-backend-module-github/api-report.md b/plugins/scaffolder-backend-module-github/api-report.md index 94b642bdbf..aa4d94dcd6 100644 --- a/plugins/scaffolder-backend-module-github/api-report.md +++ b/plugins/scaffolder-backend-module-github/api-report.md @@ -107,6 +107,21 @@ export function createGithubIssuesLabelAction(options: { JsonObject >; +// @public +export function createGithubPagesAction(options: { + integrations: ScmIntegrationRegistry; + githubCredentialsProvider?: GithubCredentialsProvider; +}): TemplateAction< + { + repoUrl: string; + buildType?: 'legacy' | 'workflow' | undefined; + sourceBranch?: string | undefined; + sourcePath?: '/' | '/docs' | undefined; + token?: string | undefined; + }, + JsonObject +>; + // @public export interface CreateGithubPullRequestActionOptions { clientFactory?: (input: { diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubPages.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubPages.examples.test.ts new file mode 100644 index 0000000000..7480d8d478 --- /dev/null +++ b/plugins/scaffolder-backend-module-github/src/actions/githubPages.examples.test.ts @@ -0,0 +1,90 @@ +/* + * 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 { TemplateAction } from '@backstage/plugin-scaffolder-node'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { ConfigReader } from '@backstage/config'; +import { + DefaultGithubCredentialsProvider, + GithubCredentialsProvider, + ScmIntegrations, +} from '@backstage/integration'; +import { createGithubPagesAction } from './githubPages'; +import { examples } from './githubPages.examples'; +import yaml from 'yaml'; + +const mockOctokit = { + request: jest.fn(), +}; + +jest.mock('octokit', () => ({ + Octokit: class { + constructor() { + return mockOctokit; + } + }, +})); + +describe('github:pages', () => { + const config = new ConfigReader({ + integrations: { + github: [ + { host: 'github.com', token: 'mock-token' }, + { host: 'ghe.github.com' }, + ], + }, + }); + + const integrations = ScmIntegrations.fromConfig(config); + let githubCredentialsProvider: GithubCredentialsProvider; + let action: TemplateAction; + + const input = yaml.parse(examples[0].example).steps[0].input; + const mockContext = createMockActionContext({ + input, + }); + + beforeEach(() => { + githubCredentialsProvider = + DefaultGithubCredentialsProvider.fromIntegrations(integrations); + action = createGithubPagesAction({ + integrations, + githubCredentialsProvider, + }); + }); + + afterEach(jest.resetAllMocks); + + it('should work with example input', async () => { + await action.handler(mockContext); + + expect(mockOctokit.request).toHaveBeenCalledWith( + 'POST /repos/{owner}/{repo}/pages', + { + owner: 'owner', + repo: 'repo', + build_type: 'workflow', + source: { + branch: 'main', + path: '/', + }, + headers: { + 'X-GitHub-Api-Version': '2022-11-28', + }, + }, + ); + }); +}); diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubPages.examples.ts b/plugins/scaffolder-backend-module-github/src/actions/githubPages.examples.ts new file mode 100644 index 0000000000..be4a33e5df --- /dev/null +++ b/plugins/scaffolder-backend-module-github/src/actions/githubPages.examples.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: 'Enables GitHub Pages for a repository.', + example: yaml.stringify({ + steps: [ + { + action: 'github:pages', + id: 'github-pages', + name: 'Enable GitHub Pages', + input: { + repoUrl: 'github.com?repo=repo&owner=owner', + buildType: 'workflow', + sourceBranch: 'main', + sourcePath: '/', + token: 'gph_YourGitHubToken', + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubPages.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubPages.test.ts new file mode 100644 index 0000000000..266f4c5a53 --- /dev/null +++ b/plugins/scaffolder-backend-module-github/src/actions/githubPages.test.ts @@ -0,0 +1,93 @@ +/* + * 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 { TemplateAction } from '@backstage/plugin-scaffolder-node'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { ConfigReader } from '@backstage/config'; +import { + DefaultGithubCredentialsProvider, + GithubCredentialsProvider, + ScmIntegrations, +} from '@backstage/integration'; +import { createGithubPagesAction } from './githubPages'; + +const mockOctokit = { + request: jest.fn(), +}; + +jest.mock('octokit', () => ({ + Octokit: class { + constructor() { + return mockOctokit; + } + }, +})); + +describe('github:pages', () => { + const config = new ConfigReader({ + integrations: { + github: [ + { host: 'github.com', token: 'mock-token' }, + { host: 'ghe.github.com' }, + ], + }, + }); + + const integrations = ScmIntegrations.fromConfig(config); + let githubCredentialsProvider: GithubCredentialsProvider; + let action: TemplateAction; + + const mockContext = createMockActionContext({ + input: { + repoUrl: 'github.com?repo=repo&owner=owner', + buildType: 'workflow', + sourceBranch: 'main', + sourcePath: '/', + token: 'gph_YourGitHubToken', + }, + }); + + beforeEach(() => { + githubCredentialsProvider = + DefaultGithubCredentialsProvider.fromIntegrations(integrations); + action = createGithubPagesAction({ + integrations, + githubCredentialsProvider, + }); + }); + + afterEach(jest.resetAllMocks); + + it('should work happy path', async () => { + await action.handler(mockContext); + + expect(mockOctokit.request).toHaveBeenCalledWith( + 'POST /repos/{owner}/{repo}/pages', + { + owner: 'owner', + repo: 'repo', + build_type: 'workflow', + source: { + branch: 'main', + path: '/', + }, + headers: { + 'X-GitHub-Api-Version': '2022-11-28', + }, + }, + ); + }); +}); diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubPages.ts b/plugins/scaffolder-backend-module-github/src/actions/githubPages.ts new file mode 100644 index 0000000000..09910319fe --- /dev/null +++ b/plugins/scaffolder-backend-module-github/src/actions/githubPages.ts @@ -0,0 +1,130 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { InputError } from '@backstage/errors'; +import { + GithubCredentialsProvider, + ScmIntegrationRegistry, +} from '@backstage/integration'; +import { Octokit } from 'octokit'; +import { + createTemplateAction, + parseRepoUrl, +} from '@backstage/plugin-scaffolder-node'; +import { examples } from './githubPages.examples'; +import { getOctokitOptions } from '@backstage/plugin-scaffolder-backend-module-github'; + +/** + * Creates a new action that enables GitHub Pages for a repository. + * + * @public + */ +export function createGithubPagesAction(options: { + integrations: ScmIntegrationRegistry; + githubCredentialsProvider?: GithubCredentialsProvider; +}) { + const { integrations, githubCredentialsProvider } = options; + + return createTemplateAction<{ + repoUrl: string; + buildType?: 'legacy' | 'workflow'; + sourceBranch?: string; + sourcePath?: '/' | '/docs'; + token?: string; + }>({ + id: 'github:pages', + examples, + description: 'Enables GitHub Pages for a repository.', + schema: { + input: { + type: 'object', + required: ['repoUrl'], + 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', + }, + buildType: { + title: 'Build Type', + type: 'string', + description: + 'The GitHub Pages build type - "legacy" or "workflow". Default is "workflow', + }, + sourceBranch: { + title: 'Source Branch', + type: 'string', + description: + 'The the GitHub Pages source branch. Default is "main"', + }, + sourcePath: { + title: 'Source Path', + type: 'string', + description: + 'The the GitHub Pages source path - "/" or "/docs". Default is "/"', + }, + token: { + title: 'Authorization Token', + type: 'string', + description: 'The token to use for authorization to GitHub', + }, + }, + }, + }, + async handler(ctx) { + const { + repoUrl, + buildType = 'workflow', + sourceBranch = 'main', + sourcePath = '/', + token: providedToken, + } = ctx.input; + + const octokitOptions = await getOctokitOptions({ + integrations, + credentialsProvider: githubCredentialsProvider, + token: providedToken, + repoUrl: repoUrl, + }); + const client = new Octokit(octokitOptions); + + const { owner, repo } = parseRepoUrl(repoUrl, integrations); + + if (!owner) { + throw new InputError('Invalid repository owner provided in repoUrl'); + } + + ctx.logger.info( + `Attempting to enable GitHub Pages for ${owner}/${repo} with "${buildType}" build type, on source branch "${sourceBranch}" and source path "${sourcePath}"`, + ); + + await client.request('POST /repos/{owner}/{repo}/pages', { + owner: owner, + repo: repo, + build_type: buildType, + source: { + branch: sourceBranch, + path: sourcePath, + }, + headers: { + 'X-GitHub-Api-Version': '2022-11-28', + }, + }); + + ctx.logger.info('Completed enabling GitHub Pages'); + }, + }); +} diff --git a/plugins/scaffolder-backend-module-github/src/actions/index.ts b/plugins/scaffolder-backend-module-github/src/actions/index.ts index 40a0da5455..e9a11e9377 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/index.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/index.ts @@ -21,12 +21,12 @@ export { createGithubRepoPushAction } from './githubRepoPush'; export { createGithubWebhookAction } from './githubWebhook'; export { createGithubDeployKeyAction } from './githubDeployKey'; export { createGithubEnvironmentAction } from './githubEnvironment'; - export { createPublishGithubPullRequestAction, type CreateGithubPullRequestActionOptions, } from './githubPullRequest'; export { createPublishGithubAction } from './github'; export { createGithubAutolinksAction } from './githubAutolinks'; +export { createGithubPagesAction } from './githubPages'; export { getOctokitOptions } from './helpers'; diff --git a/plugins/scaffolder-backend-module-github/src/module.ts b/plugins/scaffolder-backend-module-github/src/module.ts index 1817a68bfb..a26fdd7d2d 100644 --- a/plugins/scaffolder-backend-module-github/src/module.ts +++ b/plugins/scaffolder-backend-module-github/src/module.ts @@ -29,6 +29,7 @@ import { createGithubWebhookAction, createPublishGithubAction, createPublishGithubPullRequestAction, + createGithubPagesAction, } from './actions'; import { DefaultGithubCredentialsProvider, @@ -91,6 +92,10 @@ export const githubModule = createBackendModule({ githubCredentialsProvider, config, }), + createGithubPagesAction({ + integrations, + githubCredentialsProvider, + }), ); }, }); From 1469ddade4ee796fac4ebee923433594f3c1e72e Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 28 Jun 2024 15:43:55 -0500 Subject: [PATCH 140/510] Rename based on feedback Signed-off-by: Andre Wanlin --- plugins/scaffolder-backend-module-github/api-report.md | 2 +- ....examples.test.ts => githubPagesEnable.examples.test.ts} | 6 +++--- ...ithubPages.examples.ts => githubPagesEnable.examples.ts} | 0 .../{githubPages.test.ts => githubPagesEnable.test.ts} | 4 ++-- .../src/actions/{githubPages.ts => githubPagesEnable.ts} | 6 +++--- .../scaffolder-backend-module-github/src/actions/index.ts | 2 +- plugins/scaffolder-backend-module-github/src/module.ts | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) rename plugins/scaffolder-backend-module-github/src/actions/{githubPages.examples.test.ts => githubPagesEnable.examples.test.ts} (93%) rename plugins/scaffolder-backend-module-github/src/actions/{githubPages.examples.ts => githubPagesEnable.examples.ts} (100%) rename plugins/scaffolder-backend-module-github/src/actions/{githubPages.test.ts => githubPagesEnable.test.ts} (95%) rename plugins/scaffolder-backend-module-github/src/actions/{githubPages.ts => githubPagesEnable.ts} (96%) diff --git a/plugins/scaffolder-backend-module-github/api-report.md b/plugins/scaffolder-backend-module-github/api-report.md index aa4d94dcd6..0572052fd4 100644 --- a/plugins/scaffolder-backend-module-github/api-report.md +++ b/plugins/scaffolder-backend-module-github/api-report.md @@ -108,7 +108,7 @@ export function createGithubIssuesLabelAction(options: { >; // @public -export function createGithubPagesAction(options: { +export function createGithubPagesEnableAction(options: { integrations: ScmIntegrationRegistry; githubCredentialsProvider?: GithubCredentialsProvider; }): TemplateAction< diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubPages.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubPagesEnable.examples.test.ts similarity index 93% rename from plugins/scaffolder-backend-module-github/src/actions/githubPages.examples.test.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubPagesEnable.examples.test.ts index 7480d8d478..ee7b5caa65 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubPages.examples.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubPagesEnable.examples.test.ts @@ -22,8 +22,8 @@ import { GithubCredentialsProvider, ScmIntegrations, } from '@backstage/integration'; -import { createGithubPagesAction } from './githubPages'; -import { examples } from './githubPages.examples'; +import { createGithubPagesEnableAction } from './githubPagesEnable'; +import { examples } from './githubPagesEnable.examples'; import yaml from 'yaml'; const mockOctokit = { @@ -60,7 +60,7 @@ describe('github:pages', () => { beforeEach(() => { githubCredentialsProvider = DefaultGithubCredentialsProvider.fromIntegrations(integrations); - action = createGithubPagesAction({ + action = createGithubPagesEnableAction({ integrations, githubCredentialsProvider, }); diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubPages.examples.ts b/plugins/scaffolder-backend-module-github/src/actions/githubPagesEnable.examples.ts similarity index 100% rename from plugins/scaffolder-backend-module-github/src/actions/githubPages.examples.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubPagesEnable.examples.ts diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubPages.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubPagesEnable.test.ts similarity index 95% rename from plugins/scaffolder-backend-module-github/src/actions/githubPages.test.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubPagesEnable.test.ts index 266f4c5a53..203014b67b 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubPages.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubPagesEnable.test.ts @@ -22,7 +22,7 @@ import { GithubCredentialsProvider, ScmIntegrations, } from '@backstage/integration'; -import { createGithubPagesAction } from './githubPages'; +import { createGithubPagesEnableAction } from './githubPagesEnable'; const mockOctokit = { request: jest.fn(), @@ -63,7 +63,7 @@ describe('github:pages', () => { beforeEach(() => { githubCredentialsProvider = DefaultGithubCredentialsProvider.fromIntegrations(integrations); - action = createGithubPagesAction({ + action = createGithubPagesEnableAction({ integrations, githubCredentialsProvider, }); diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubPages.ts b/plugins/scaffolder-backend-module-github/src/actions/githubPagesEnable.ts similarity index 96% rename from plugins/scaffolder-backend-module-github/src/actions/githubPages.ts rename to plugins/scaffolder-backend-module-github/src/actions/githubPagesEnable.ts index 09910319fe..044005961e 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubPages.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubPagesEnable.ts @@ -24,7 +24,7 @@ import { createTemplateAction, parseRepoUrl, } from '@backstage/plugin-scaffolder-node'; -import { examples } from './githubPages.examples'; +import { examples } from './githubPagesEnable.examples'; import { getOctokitOptions } from '@backstage/plugin-scaffolder-backend-module-github'; /** @@ -32,7 +32,7 @@ import { getOctokitOptions } from '@backstage/plugin-scaffolder-backend-module-g * * @public */ -export function createGithubPagesAction(options: { +export function createGithubPagesEnableAction(options: { integrations: ScmIntegrationRegistry; githubCredentialsProvider?: GithubCredentialsProvider; }) { @@ -45,7 +45,7 @@ export function createGithubPagesAction(options: { sourcePath?: '/' | '/docs'; token?: string; }>({ - id: 'github:pages', + id: 'github:pages:enable', examples, description: 'Enables GitHub Pages for a repository.', schema: { diff --git a/plugins/scaffolder-backend-module-github/src/actions/index.ts b/plugins/scaffolder-backend-module-github/src/actions/index.ts index e9a11e9377..6f37678099 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/index.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/index.ts @@ -27,6 +27,6 @@ export { } from './githubPullRequest'; export { createPublishGithubAction } from './github'; export { createGithubAutolinksAction } from './githubAutolinks'; -export { createGithubPagesAction } from './githubPages'; +export { createGithubPagesEnableAction } from './githubPagesEnable'; export { getOctokitOptions } from './helpers'; diff --git a/plugins/scaffolder-backend-module-github/src/module.ts b/plugins/scaffolder-backend-module-github/src/module.ts index a26fdd7d2d..a5676ab8c9 100644 --- a/plugins/scaffolder-backend-module-github/src/module.ts +++ b/plugins/scaffolder-backend-module-github/src/module.ts @@ -29,7 +29,7 @@ import { createGithubWebhookAction, createPublishGithubAction, createPublishGithubPullRequestAction, - createGithubPagesAction, + createGithubPagesEnableAction, } from './actions'; import { DefaultGithubCredentialsProvider, @@ -92,7 +92,7 @@ export const githubModule = createBackendModule({ githubCredentialsProvider, config, }), - createGithubPagesAction({ + createGithubPagesEnableAction({ integrations, githubCredentialsProvider, }), From 780d994544de0045e8aae211a9ebe85957f3ea26 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 7 Jun 2024 19:35:15 -0500 Subject: [PATCH 141/510] Added `MyGroupsSidebarItem` to the sidebar in the `create-app` template Signed-off-by: Andre Wanlin --- .changeset/bright-fireants-sit.md | 5 +++++ .../default-app/packages/app/src/components/Root/Root.tsx | 7 +++++++ 2 files changed, 12 insertions(+) create mode 100644 .changeset/bright-fireants-sit.md diff --git a/.changeset/bright-fireants-sit.md b/.changeset/bright-fireants-sit.md new file mode 100644 index 0000000000..320bc69ff9 --- /dev/null +++ b/.changeset/bright-fireants-sit.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Added `MyGroupsSidebarItem` to the sidebar in the `create-app` template diff --git a/packages/create-app/templates/default-app/packages/app/src/components/Root/Root.tsx b/packages/create-app/templates/default-app/packages/app/src/components/Root/Root.tsx index 71c04122ae..853d175bae 100644 --- a/packages/create-app/templates/default-app/packages/app/src/components/Root/Root.tsx +++ b/packages/create-app/templates/default-app/packages/app/src/components/Root/Root.tsx @@ -25,6 +25,8 @@ import { } from '@backstage/core-components'; import MenuIcon from '@material-ui/icons/Menu'; import SearchIcon from '@material-ui/icons/Search'; +import { MyGroupsSidebarItem } from '@backstage/plugin-org'; +import GroupIcon from '@material-ui/icons/People'; const useSidebarLogoStyles = makeStyles({ root: { @@ -65,6 +67,11 @@ export const Root = ({ children }: PropsWithChildren<{}>) => ( }> {/* Global nav, not org-specific */} + From e5b5e08374ba687016191e2bc61da878c0ccc41c Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Mon, 6 May 2024 12:37:50 -0500 Subject: [PATCH 142/510] Added Docs Project Area Signed-off-by: Andre Wanlin --- OWNERS.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/OWNERS.md b/OWNERS.md index 9382b38f4f..4a9fdc4ccc 100644 --- a/OWNERS.md +++ b/OWNERS.md @@ -159,6 +159,18 @@ Scope: The Scaffolder frontend and backend plugins, and related tooling. | ------------------- | ------------ | ------------------------------------- | ---------------- | | Bogdan Nechyporenko | Bol.com | [acierto](https://github.com/acierto) | `bogdan_haarlem` | +### Documentation + +Team: @backstage/documentation-maintainers + +Scope: The Backstage Documentation + +| Name | Organization | GitHub | Discord | +| -------------- | ------------ | ----------------------------------------------------- | ----------------- | +| Andre Wanlin | Spotify | [awanlin](https://github.com/awanlin) | `ahhhndre` | +| Aramis Sennyey | | [aramissennyeydd](https://github.com/aramissennyeydd) | `Aramis#7984` | +| Waldir Montoya | Broadcom | [waldirmontoya25](https://github.com/waldirmontoya25) | `waldirmontoya25` | + ## Sponsors | Name | Organization | GitHub | Email | From a8d0b87f1bb6c91c6db6a5fd6c4939bcb6c450df Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Wed, 19 Jun 2024 11:35:56 -0500 Subject: [PATCH 143/510] Updates Signed-off-by: Andre Wanlin --- OWNERS.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/OWNERS.md b/OWNERS.md index 4a9fdc4ccc..16e884e518 100644 --- a/OWNERS.md +++ b/OWNERS.md @@ -165,11 +165,11 @@ Team: @backstage/documentation-maintainers Scope: The Backstage Documentation -| Name | Organization | GitHub | Discord | -| -------------- | ------------ | ----------------------------------------------------- | ----------------- | -| Andre Wanlin | Spotify | [awanlin](https://github.com/awanlin) | `ahhhndre` | -| Aramis Sennyey | | [aramissennyeydd](https://github.com/aramissennyeydd) | `Aramis#7984` | -| Waldir Montoya | Broadcom | [waldirmontoya25](https://github.com/waldirmontoya25) | `waldirmontoya25` | +| Name | Organization | GitHub | Discord | +| --------------- | ------------- | ----------------------------------------------------- | -------------------- | +| Andre Wanlin | Spotify | [awanlin](https://github.com/awanlin) | `ahhhndre` | +| Aramis Sennyey | | [aramissennyeydd](https://github.com/aramissennyeydd) | `Aramis#7984` | +| Peter Macdonald | VodafoneZiggo | [parsifal-m](https://github.com/Parsifal-M) | `Peter "Parsifal-M"` | ## Sponsors From 8def8fec564f38f69fdbd82a567ba52cb0d4dcba Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 28 Jun 2024 15:47:58 -0500 Subject: [PATCH 144/510] Updates Signed-off-by: Andre Wanlin --- OWNERS.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/OWNERS.md b/OWNERS.md index 16e884e518..5012181d21 100644 --- a/OWNERS.md +++ b/OWNERS.md @@ -165,11 +165,11 @@ Team: @backstage/documentation-maintainers Scope: The Backstage Documentation -| Name | Organization | GitHub | Discord | -| --------------- | ------------- | ----------------------------------------------------- | -------------------- | -| Andre Wanlin | Spotify | [awanlin](https://github.com/awanlin) | `ahhhndre` | -| Aramis Sennyey | | [aramissennyeydd](https://github.com/aramissennyeydd) | `Aramis#7984` | -| Peter Macdonald | VodafoneZiggo | [parsifal-m](https://github.com/Parsifal-M) | `Peter "Parsifal-M"` | +| Name | Organization | GitHub | Discord | +| --------------- | ------------- | ----------------------------------------------------- | ------------- | +| Andre Wanlin | Spotify | [awanlin](https://github.com/awanlin) | `ahhhndre` | +| Aramis Sennyey | | [aramissennyeydd](https://github.com/aramissennyeydd) | `Aramis#7984` | +| Peter Macdonald | VodafoneZiggo | [Parsifal-M](https://github.com/Parsifal-M) | `parsifal` | ## Sponsors From 281f44b1e2b3ef4b9bb474a0e935a185773b54c1 Mon Sep 17 00:00:00 2001 From: Jonathan Stevens Date: Fri, 28 Jun 2024 17:51:01 -0600 Subject: [PATCH 145/510] fix(docs): fixing/simplifying new backend system search imports Signed-off-by: Jonathan Stevens --- docs/features/search/how-to-guides.md | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/docs/features/search/how-to-guides.md b/docs/features/search/how-to-guides.md index 6564fd0a44..9ce30da556 100644 --- a/docs/features/search/how-to-guides.md +++ b/docs/features/search/how-to-guides.md @@ -396,21 +396,17 @@ Recently, the Backstage maintainers [announced the new Backend System](https://b In "packages/backend/index.ts", install the search plugin [1], the search engine [2], and the search collators/decorators modules [3]: ```ts -import { searchPlugin } from '@backstage/plugin-search-backend/alpha'; -import { searchModuleElasticsearchEngine } from '@backstage/plugin-search-backend-module-elasticsearch/alpha'; -import { searchModuleCatalogCollator } from '@backstage/plugin-search-backend-module-catalog/alpha'; -import { searchModuleTechDocsCollator } from '@backstage/plugin-search-backend-module-techdocs/alpha'; -import { searchModuleExploreCollator } from '@backstage/plugin-search-backend-module-explore/alpha'; - const backend = createBackend(); // [1] adding the search plugin to the backend -backend.add(searchPlugin()); +backend.add(import('@backstage/plugin-search-backend/alpha')); // [2] (optional) the default search engine is Lunr, if you want to extend the search backend with another search engine. -backend.add(searchModuleElasticsearchEngine()); +backend.add( + import('@backstage/plugin-search-backend-module-elasticsearch/alpha'), +); // [3] extending search with collator modules to start index documents, take in optional schedule parameters. -backend.add(searchModuleCatalogCollator()); -backend.add(searchModuleTechDocsCollator()); -backend.add(searchModuleExploreCollator()); +backend.add(import('@backstage/plugin-search-backend-module-catalog/alpha')); +backend.add(import('@backstage/plugin-search-backend-module-techdocs/alpha')); +backend.add(import('@backstage/plugin-search-backend-module-explore/alpha')); backend.start(); ``` From 84b2516fbb4c00b70b4ab8f42ea509bf466a773a Mon Sep 17 00:00:00 2001 From: aramissennyeydd Date: Sat, 29 Jun 2024 11:18:27 -0400 Subject: [PATCH 146/510] fix(docs): add scheduler to custom provider example Signed-off-by: aramissennyeydd --- .../software-catalog/external-integrations.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/features/software-catalog/external-integrations.md b/docs/features/software-catalog/external-integrations.md index 6eaee2f80d..c77ed51943 100644 --- a/docs/features/software-catalog/external-integrations.md +++ b/docs/features/software-catalog/external-integrations.md @@ -300,9 +300,19 @@ export const catalogModuleFrobsProvider = createBackendModule({ deps: { catalog: catalogProcessingExtensionPoint, reader: coreServices.urlReader, + scheduler: coreServices.scheduler, }, - async init({ catalog, reader }) { - catalog.addEntityProvider(new FrobsProvider('dev', reader)); + async init({ catalog, reader, scheduler }) { + const frobs = new FrobsProvider('dev', reader); + catalog.addEntityProvider(frobs); + await scheduler.scheduleTask({ + id: 'run_frobs_refresh', + fn: async () => { + await frobs.run(); + }, + frequency: { minutes: 30 }, + timeout: { minutes: 10 }, + }); }, }); }, From db2e2d51f612b6cddab9b61ab46527263b8f4aa0 Mon Sep 17 00:00:00 2001 From: Marco Crivellaro Date: Sat, 29 Jun 2024 20:04:46 +0200 Subject: [PATCH 147/510] Config schema to support app.routes.bindings Signed-off-by: Marco Crivellaro --- .changeset/friendly-experts-fail.md | 5 +++++ packages/core-app-api/config.d.ts | 12 ++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 .changeset/friendly-experts-fail.md diff --git a/.changeset/friendly-experts-fail.md b/.changeset/friendly-experts-fail.md new file mode 100644 index 0000000000..df2d2e2b24 --- /dev/null +++ b/.changeset/friendly-experts-fail.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-app-api': patch +--- + +Updated config schema to support app.routes.bindings diff --git a/packages/core-app-api/config.d.ts b/packages/core-app-api/config.d.ts index 22f241fbcf..1a7ccb666f 100644 --- a/packages/core-app-api/config.d.ts +++ b/packages/core-app-api/config.d.ts @@ -65,6 +65,18 @@ export interface Config { }>; }>; }; + + routes?: { + /** + * Maps external route references to regular route references. Both the + * key and the value is expected to be on the form `.`. + * If the value is `false`, the route will be disabled even if it has a + * default mapping. + * + * @deepVisibility frontend + */ + bindings?: { [externalRouteRefId: string]: string | false }; + }; }; /** From 1edd6c27ee943747bd58e0bf35c86944902287e6 Mon Sep 17 00:00:00 2001 From: Tim Klever Date: Sat, 29 Jun 2024 11:29:38 -0700 Subject: [PATCH 148/510] feat: update ConfigSources options to match process.env typings Signed-off-by: Tim Klever --- .changeset/neat-bears-divide.md | 28 +++++++++++++++++++ packages/config-loader/api-report.md | 2 +- .../src/sources/ConfigSources.ts | 2 +- 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 .changeset/neat-bears-divide.md diff --git a/.changeset/neat-bears-divide.md b/.changeset/neat-bears-divide.md new file mode 100644 index 0000000000..b40db6c7bd --- /dev/null +++ b/.changeset/neat-bears-divide.md @@ -0,0 +1,28 @@ +--- +'@backstage/config-loader': major +--- + +**BREAKING** The `env` property on the `ConfigSourcesDefaultOptions` interface allows for undefined members. + +This change makes `ConfigSourcesDefaultOptions.env` consistent with other parts of this package and the wider +`node` ecosystem. Specifically, with this update `ConfigSourcesDefaultOptions.env`'s types match: + +#### EnvConfigSource + +- [`EnvConfigSource.constructor`](https://github.com/backstage/backstage/blob/c780320418b7775f18fc0d2cc279ee7db9c7cb25/packages/config-loader/src/sources/EnvConfigSource.ts#L68) +- [`EnvConfigSourceOptions`](https://github.com/backstage/backstage/blob/c780320418b7775f18fc0d2cc279ee7db9c7cb25/packages/config-loader/src/sources/EnvConfigSource.ts#L31) +- [`readEnvConfig`](https://github.com/backstage/backstage/blob/c780320418b7775f18fc0d2cc279ee7db9c7cb25/packages/config-loader/src/sources/EnvConfigSource.ts#L114) + +#### NodeJS process.env + +- [`ProcessEnv`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/aa121ee3a7a3caa16433b66c1103df5904f612ea/types/node/v18/process.d.ts#L137) + which extends [`Dict`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/aa121ee3a7a3caa16433b66c1103df5904f612ea/types/node/v18/globals.d.ts#L333-L335) + +While this is a somewhat trivial change, it does loosen typings on a public interface, so by definition it's a breaking +change and a major version bump. + +You may meed to update your backstage instance if you have built an implementation of `ConfigSources` or any other +functionality that relies on `ConfigSourcesDefaultOptions`. This change means you'll have to update that code to account +for the possibility of `undefined` values inside `ConfigSourcesDefaultOptions.env`, although it is very likely already +accounted for as the typings for [`process.env`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/aa121ee3a7a3caa16433b66c1103df5904f612ea/types/node/v18/process.d.ts#L137) +already include the possibility of [`undefined`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/aa121ee3a7a3caa16433b66c1103df5904f612ea/types/node/v18/globals.d.ts#L333-L335). diff --git a/packages/config-loader/api-report.md b/packages/config-loader/api-report.md index bc8f217bbb..da836ffd21 100644 --- a/packages/config-loader/api-report.md +++ b/packages/config-loader/api-report.md @@ -87,7 +87,7 @@ export interface ConfigSourcesDefaultOptions extends BaseConfigSourcesOptions { // (undocumented) argv?: string[]; // (undocumented) - env?: Record; + env?: Record; } // @public diff --git a/packages/config-loader/src/sources/ConfigSources.ts b/packages/config-loader/src/sources/ConfigSources.ts index ecff39da2d..15eede736e 100644 --- a/packages/config-loader/src/sources/ConfigSources.ts +++ b/packages/config-loader/src/sources/ConfigSources.ts @@ -102,7 +102,7 @@ export interface ConfigSourcesDefaultForTargetsOptions */ export interface ConfigSourcesDefaultOptions extends BaseConfigSourcesOptions { argv?: string[]; - env?: Record; + env?: Record; } /** From b83fbc00b1c3c262f390236597906be97c7b1a08 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 29 Jun 2024 20:20:56 +0000 Subject: [PATCH 149/510] Update dependency @types/prop-types to v15.7.12 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 8d1c0ecb06..d22cee2a71 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18383,9 +18383,9 @@ __metadata: linkType: hard "@types/prop-types@npm:*, @types/prop-types@npm:^15.0.0, @types/prop-types@npm:^15.7.11, @types/prop-types@npm:^15.7.3": - version: 15.7.11 - resolution: "@types/prop-types@npm:15.7.11" - checksum: 7519ff11d06fbf6b275029fe03fff9ec377b4cb6e864cac34d87d7146c7f5a7560fd164bdc1d2dbe00b60c43713631251af1fd3d34d46c69cd354602bc0c7c54 + version: 15.7.12 + resolution: "@types/prop-types@npm:15.7.12" + checksum: ac16cc3d0a84431ffa5cfdf89579ad1e2269549f32ce0c769321fdd078f84db4fbe1b461ed5a1a496caf09e637c0e367d600c541435716a55b1d9713f5035dfe languageName: node linkType: hard From d26fc8c19f52044f1d4c64e36b853a442c32b872 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 29 Jun 2024 21:16:49 +0000 Subject: [PATCH 150/510] Update dependency grpc-docs to v1.1.4 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/yarn.lock b/yarn.lock index 20a828a69b..b337884121 100644 --- a/yarn.lock +++ b/yarn.lock @@ -20270,6 +20270,16 @@ __metadata: languageName: node linkType: hard +"GendocuPublicApis@https://git.gendocu.com/gendocu/GendocuPublicApis.git#master": + version: 1.0.0 + resolution: "GendocuPublicApis@https://git.gendocu.com/gendocu/GendocuPublicApis.git#commit=6e8d4c1d2342556a2e8e719f19385b266001ebae" + dependencies: + "@improbable-eng/grpc-web": ^0.14.0 + google-protobuf: ^3.15.8 + checksum: 2c8f28cd89e9a71e5f9df819115a89659d98f22d6e7a6b2f3fc0bc24a4ca954c0112070c00401749dcbcdeeb42ca070d6d8a36b3c205fbf13409fb1110b5966e + languageName: node + linkType: hard + "a-sync-waterfall@npm:^1.0.0": version: 1.0.1 resolution: "a-sync-waterfall@npm:1.0.1" @@ -27962,16 +27972,6 @@ __metadata: languageName: node linkType: hard -"gendocu-public-apis@npm:^1.0.0": - version: 1.0.0 - resolution: "gendocu-public-apis@npm:1.0.0" - dependencies: - "@improbable-eng/grpc-web": ^0.14.0 - google-protobuf: ^3.15.8 - checksum: ee1548d1285f9d2dc7ef04c959e620516322314c8aa2f2bfedd25345a6211abf51cdca4d54cca18de8f31a90f2b86ab171ae41f7c2f39dfdd0ac7163f875f719 - languageName: node - linkType: hard - "generate-function@npm:^2.3.1": version: 2.3.1 resolution: "generate-function@npm:2.3.1" @@ -28392,10 +28392,10 @@ __metadata: languageName: node linkType: hard -"google-protobuf@npm:^3.15.8, google-protobuf@npm:^3.19.1": - version: 3.20.1 - resolution: "google-protobuf@npm:3.20.1" - checksum: a440fbc329bb441b253bc421b01540918f4b66921c47a3bc57d154d2677dc917cb1a29126ff35ddc4d8872d1b5843ef1ece60b6dff506ba64a9f5807962d3f61 +"google-protobuf@npm:^3.15.8, google-protobuf@npm:^3.21.2": + version: 3.21.2 + resolution: "google-protobuf@npm:3.21.2" + checksum: 3caa2e1e2654714cc1a201ac5e5faabcaa48f5fba3d8ff9b64ca66fe19e4e0506b94053f32eddc77bf3a7a47ac1660315c6744185c1e2bb27654fd76fe91b988 languageName: node linkType: hard @@ -28593,13 +28593,13 @@ __metadata: linkType: hard "grpc-docs@npm:^1.0.6, grpc-docs@npm:^1.1.2": - version: 1.1.3 - resolution: "grpc-docs@npm:1.1.3" + version: 1.1.4 + resolution: "grpc-docs@npm:1.1.4" dependencies: "@improbable-eng/grpc-web": ^0.15.0 "@types/minimatch": ^3.0.5 - gendocu-public-apis: ^1.0.0 - google-protobuf: ^3.19.1 + GendocuPublicApis: "https://git.gendocu.com/gendocu/GendocuPublicApis.git#master" + google-protobuf: ^3.21.2 grpc-docs: ^1.0.6 js-yaml: ^4.1.0 minimatch: ^3.0.4 @@ -28612,7 +28612,7 @@ __metadata: styled-components: ^5.3.3 peerDependencies: react: ^16.0.0 - checksum: 1bcd3179ce276e8fd34229acc6d3f1024908b7e6734e36ddcc4852c6db0100b900093355652577ab476c9927167cff92b05e560713995803154d4dbd4459f973 + checksum: 55b088011205fe82ced6af763136bb2494eb059445c5776bf29922439b814fa8983774a68910c47898cef5be82bea60801c2f96305e76170cff1df3f890b8d18 languageName: node linkType: hard From e23579b0bb25b2c29940273d8fd0ed8fccb4e951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Sat, 29 Jun 2024 23:37:12 +0200 Subject: [PATCH 151/510] Update .changeset/friendly-bulldogs-pay.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/friendly-bulldogs-pay.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.changeset/friendly-bulldogs-pay.md b/.changeset/friendly-bulldogs-pay.md index 9c7ab8f9cb..d77c739bb0 100644 --- a/.changeset/friendly-bulldogs-pay.md +++ b/.changeset/friendly-bulldogs-pay.md @@ -2,4 +2,6 @@ '@backstage/plugin-catalog-backend-module-ldap': minor --- +**BREAKING**: `readLdapOrg` and the `LdapProviderConfig` type now always accept arrays of user and group configs, not just single items. + Added support for single ldap catalog provider to provide list and undefined user and group bindings next to standard single one. From 85542a9e79543fda5bda36da9495db866654006c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 29 Jun 2024 22:18:21 +0000 Subject: [PATCH 152/510] Update dependency knip to v5.23.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 b337884121..5ec7bb2899 100644 --- a/yarn.lock +++ b/yarn.lock @@ -32067,8 +32067,8 @@ __metadata: linkType: hard "knip@npm:^5.0.0": - version: 5.23.1 - resolution: "knip@npm:5.23.1" + version: 5.23.2 + resolution: "knip@npm:5.23.2" dependencies: "@ericcornelissen/bash-parser": 0.5.3 "@nodelib/fs.walk": 2.0.0 @@ -32094,7 +32094,7 @@ __metadata: bin: knip: bin/knip.js knip-bun: bin/knip-bun.js - checksum: d3c39f266907b2c8f241e4d7d7c4b3a4fa1500c57f7e60f86bd3e9cd2684696e4c84b823d2a461b23cdc729a310ad571eec6ac22acacb5a4b17130d19ef5b866 + checksum: efcfa5bea3848bb6e054cb80a840dbcc718a1c91d8f6c508a686239de5e1fe7775afc05d03fd624f07fb545767b4a08a5c59b7a29a009cbad001cb68a1e92859 languageName: node linkType: hard From 2fb0eb88b7e1105ec9b7a193ab68ce3d66606b77 Mon Sep 17 00:00:00 2001 From: John Redwood Date: Sun, 30 Jun 2024 10:31:15 +1000 Subject: [PATCH 153/510] fix: allow gitlab pipeline triggers to include variables Signed-off-by: John Redwood --- .changeset/three-carpets-smoke.md | 5 ++++ .../api-report.md | 1 + .../actions/gitlabPipelineTrigger.examples.ts | 1 + .../src/actions/gitlabPipelineTrigger.test.ts | 29 +++++++++++++++++++ .../src/actions/gitlabPipelineTrigger.ts | 9 +++++- 5 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 .changeset/three-carpets-smoke.md diff --git a/.changeset/three-carpets-smoke.md b/.changeset/three-carpets-smoke.md new file mode 100644 index 0000000000..e096fe054d --- /dev/null +++ b/.changeset/three-carpets-smoke.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gitlab': minor +--- + +Fixed trigger pipeline accepting input variables diff --git a/plugins/scaffolder-backend-module-gitlab/api-report.md b/plugins/scaffolder-backend-module-gitlab/api-report.md index 4f9239e9b2..b1f240029e 100644 --- a/plugins/scaffolder-backend-module-gitlab/api-report.md +++ b/plugins/scaffolder-backend-module-gitlab/api-report.md @@ -211,6 +211,7 @@ export const createTriggerGitlabPipelineAction: (options: { projectId: number; tokenDescription: string; token?: string | undefined; + variables?: Record | undefined; }, { pipelineUrl: string; diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabPipelineTrigger.examples.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabPipelineTrigger.examples.ts index 4948db908b..d0840030df 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabPipelineTrigger.examples.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabPipelineTrigger.examples.ts @@ -33,6 +33,7 @@ export const examples: TemplateExample[] = [ 'This is the text that will appear in the pipeline token', token: 'glpt-xxxxxxxxxxxx', branch: 'main', + variables: { var_one: 'one', var_two: 'two' }, }, }, ], diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabPipelineTrigger.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabPipelineTrigger.test.ts index a7412032a4..3803198ec8 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabPipelineTrigger.test.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabPipelineTrigger.test.ts @@ -101,6 +101,7 @@ describe('gitlab:pipeline:trigger', () => { 123, 'main', 'glptt-abcdef', + { variables: undefined }, ); expect(mockGitlabClient.PipelineTriggerTokens.remove).toHaveBeenCalledWith( @@ -189,6 +190,7 @@ describe('gitlab:pipeline:trigger', () => { 123, 'main', 'glptt-abcdef', + { variables: undefined }, ); expect(mockGitlabClient.PipelineTriggerTokens.remove).toHaveBeenCalledWith( @@ -196,6 +198,7 @@ describe('gitlab:pipeline:trigger', () => { 42, ); }); + it('should clean up pipeline token on failure', async () => { const mockContext = createMockActionContext({ input: { @@ -232,4 +235,30 @@ describe('gitlab:pipeline:trigger', () => { 42, ); }); + + it('should succeed trigger and pass variables', async () => { + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 123, + tokenDescription: 'My cool pipeline token', + branch: 'main', + variables: { var_one: 'val1', var_two: 'val2' }, + }, + workspacePath: 'seen2much', + }); + + await expect( + action.handler({ + ...mockContext, + }), + ).rejects.toThrow('Failed to trigger pipeline'); + + expect(mockGitlabClient.PipelineTriggerTokens.trigger).toHaveBeenCalledWith( + 123, + 'main', + 'glptt-abcdef', + { variables: { var_one: 'val1', var_two: 'val2' } }, + ); + }); }); diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabPipelineTrigger.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabPipelineTrigger.ts index 6937fe44aa..b9f629edfb 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabPipelineTrigger.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabPipelineTrigger.ts @@ -30,6 +30,12 @@ const pipelineInputProperties = z.object({ projectId: z.number().describe('Project Id'), tokenDescription: z.string().describe('Pipeline token description'), branch: z.string().describe('Project branch'), + variables: z + .record(z.string(), z.string()) + .optional() + .describe( + 'A object/record of key-valued strings containing the pipeline variables.', + ), }); const pipelineOutputProperties = z.object({ @@ -57,7 +63,7 @@ export const createTriggerGitlabPipelineAction = (options: { async handler(ctx) { let pipelineTokenResponse: PipelineTriggerTokenSchema | null = null; - const { repoUrl, projectId, tokenDescription, token, branch } = + const { repoUrl, projectId, tokenDescription, token, branch, variables } = commonGitlabConfig.merge(pipelineInputProperties).parse(ctx.input); const { host } = parseRepoUrl(repoUrl, integrations); @@ -84,6 +90,7 @@ export const createTriggerGitlabPipelineAction = (options: { projectId, branch, pipelineTokenResponse.token, + { variables }, )) as ExpandedPipelineSchema; if (!pipelineTriggerResponse.id) { From b141c20b53082ad16af942c2574040d4b83921c6 Mon Sep 17 00:00:00 2001 From: Stephen Glass Date: Sun, 30 Jun 2024 00:53:24 -0400 Subject: [PATCH 154/510] Move review object explode function into utils Signed-off-by: Stephen Glass --- .../components/ReviewState/ReviewState.tsx | 34 +--- .../next/components/ReviewState/util.test.ts | 187 ++++++++++++++++++ .../src/next/components/ReviewState/util.ts | 49 +++++ 3 files changed, 238 insertions(+), 32 deletions(-) create mode 100644 plugins/scaffolder-react/src/next/components/ReviewState/util.test.ts create mode 100644 plugins/scaffolder-react/src/next/components/ReviewState/util.ts diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx index 22ec54ac26..95f5d76212 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx +++ b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx @@ -15,9 +15,10 @@ */ import React from 'react'; import { StructuredMetadataTable } from '@backstage/core-components'; -import { JsonObject, JsonValue } from '@backstage/types'; +import { JsonObject } from '@backstage/types'; import { Draft07 as JSONSchema } from 'json-schema-library'; import { ParsedTemplateSchema } from '../../hooks/useTemplateSchema'; +import { flattenObject, isJsonObject } from './util'; /** * The props for the {@link ReviewState} component. @@ -28,37 +29,6 @@ export type ReviewStateProps = { formState: JsonObject; }; -function flattenObject( - obj: JsonObject, - prefix: string, - schema: JSONSchema, - formState: JsonObject, -): [string, JsonValue | undefined][] { - return Object.entries(obj).flatMap(([key, value]) => { - const prefixedKey = prefix ? `${prefix}/${key}` : key; - - const definitionInSchema = schema.getSchema({ - pointer: `#/${prefixedKey}`, - data: formState, - }); - - if (definitionInSchema) { - const backstageReviewOptions = definitionInSchema['ui:backstage']?.review; - - // Recurse into nested objects - if (backstageReviewOptions?.explode && isJsonObject(value)) { - return flattenObject(value, prefixedKey, schema, formState); - } - } - - return [[key, value]]; - }); -} - -function isJsonObject(value?: JsonValue): value is JsonObject { - return typeof value === 'object' && value !== null && !Array.isArray(value); -} - /** * The component used by the {@link Stepper} to render the review step. * @alpha diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/util.test.ts b/plugins/scaffolder-react/src/next/components/ReviewState/util.test.ts new file mode 100644 index 0000000000..c468c1a055 --- /dev/null +++ b/plugins/scaffolder-react/src/next/components/ReviewState/util.test.ts @@ -0,0 +1,187 @@ +/* eslint-disable no-console */ +/* + * 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 { flattenObject, isJsonObject } from './util'; +import { Draft07 as JSONSchema } from 'json-schema-library'; +import { ParsedTemplateSchema } from '../../hooks/useTemplateSchema'; + +describe('isJsonObject', () => { + it('should return true for non-null objects', () => { + expect(isJsonObject({})).toBe(true); + expect(isJsonObject({ key: 'value' })).toBe(true); + }); + + it('should return false for null', () => { + expect(isJsonObject(null)).toBe(false); + }); + + it('should return false for arrays', () => { + expect(isJsonObject([])).toBe(false); + expect(isJsonObject([1, 2, 3])).toBe(false); + }); + + it('should return false for non-objects', () => { + expect(isJsonObject('string')).toBe(false); + expect(isJsonObject(123)).toBe(false); + expect(isJsonObject(true)).toBe(false); + expect(isJsonObject(undefined)).toBe(false); + }); +}); + +describe('flattenObject', () => { + it('should handle an empty object', () => { + const schemas: ParsedTemplateSchema[] = [ + { + mergedSchema: { + type: 'object', + properties: { + name: { + type: 'object', + 'ui:backstage': { + review: { + explode: true, + }, + }, + properties: {}, + }, + }, + }, + schema: {}, + title: 'test', + uiSchema: {}, + }, + ]; + + const parsedSchema = new JSONSchema(schemas[0].mergedSchema); + + const result = flattenObject({}, '', parsedSchema, {}); + + expect(result).toEqual([]); + }); + + it('should flatten a simple object', () => { + const formState = { + name: { + foo: 'value1', + bar: 'value2', + }, + }; + + const schemas: ParsedTemplateSchema[] = [ + { + mergedSchema: { + type: 'object', + properties: { + name: { + type: 'object', + 'ui:backstage': { + review: { + explode: true, + }, + }, + properties: { + foo: { + type: 'string', + }, + bar: { + type: 'string', + }, + }, + }, + }, + }, + schema: {}, + title: 'test', + uiSchema: {}, + }, + ]; + + const [key, value] = Object.entries(formState)[0]; + const parsedSchema = new JSONSchema(schemas[0].mergedSchema); + + const result = flattenObject(value, key, parsedSchema, formState); + + expect(result).toEqual([ + ['foo', 'value1'], + ['bar', 'value2'], + ]); + }); + + it('should recurse into a nested object', () => { + const formState = { + name: { + foo: 'value1', + bar: 'value2', + example: { + test: 'value3', + }, + }, + }; + const schemas: ParsedTemplateSchema[] = [ + { + mergedSchema: { + type: 'object', + properties: { + name: { + type: 'object', + 'ui:backstage': { + review: { + explode: true, + }, + }, + properties: { + foo: { + type: 'string', + }, + bar: { + type: 'string', + }, + example: { + type: 'object', + 'ui:backstage': { + review: { + explode: true, + }, + }, + properties: { + test: { + type: 'string', + }, + }, + }, + }, + }, + }, + }, + schema: {}, + title: 'test', + uiSchema: {}, + }, + ]; + + const [key, value] = Object.entries(formState)[0]; + const parsedSchema = new JSONSchema(schemas[0].mergedSchema); + + const result = flattenObject(value, key, parsedSchema, formState); + + expect(result).toEqual([ + ['foo', 'value1'], + ['bar', 'value2'], + ['test', 'value3'], + ]); + }); +}); diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/util.ts b/plugins/scaffolder-react/src/next/components/ReviewState/util.ts new file mode 100644 index 0000000000..0bb6fc08d2 --- /dev/null +++ b/plugins/scaffolder-react/src/next/components/ReviewState/util.ts @@ -0,0 +1,49 @@ +/* + * 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 { JsonObject, JsonValue } from '@backstage/types'; +import { Draft07 as JSONSchema } from 'json-schema-library'; + +export function flattenObject( + obj: JsonObject, + prefix: string, + schema: JSONSchema, + formState: JsonObject, +): [string, JsonValue | undefined][] { + return Object.entries(obj).flatMap(([key, value]) => { + const prefixedKey = prefix ? `${prefix}/${key}` : key; + + const definitionInSchema = schema.getSchema({ + pointer: `#/${prefixedKey}`, + data: formState, + }); + + if (definitionInSchema) { + const backstageReviewOptions = definitionInSchema['ui:backstage']?.review; + + // Recurse into nested objects + if (backstageReviewOptions?.explode && isJsonObject(value)) { + return flattenObject(value, prefixedKey, schema, formState); + } + } + + return [[key, value]]; + }); +} + +export function isJsonObject(value?: JsonValue): value is JsonObject { + return typeof value === 'object' && value !== null && !Array.isArray(value); +} From 08b7c3e1802702b456d4b51c69ddfa5d327e1f13 Mon Sep 17 00:00:00 2001 From: Stephen Glass Date: Sun, 30 Jun 2024 01:29:30 -0400 Subject: [PATCH 155/510] Remove debug code Signed-off-by: Stephen Glass --- .../src/next/components/ReviewState/util.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/util.test.ts b/plugins/scaffolder-react/src/next/components/ReviewState/util.test.ts index c468c1a055..e2a10587dc 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/util.test.ts +++ b/plugins/scaffolder-react/src/next/components/ReviewState/util.test.ts @@ -1,4 +1,3 @@ -/* eslint-disable no-console */ /* * Copyright 2022 The Backstage Authors * From 54429b5cac736d131636fdff4c5b444fe279955a Mon Sep 17 00:00:00 2001 From: Ambarish07 <43902240+Ambarish07@users.noreply.github.com> Date: Mon, 1 Jul 2024 01:20:29 +0530 Subject: [PATCH 156/510] fixed filename and imports for scaffolder-node-test-utils plugin fix: fixed the filename and imports for scaffolder-node-test-utils plugin --------- Signed-off-by: Ambarish07 --- .changeset/yellow-cows-kick.md | 5 +++++ plugins/scaffolder-node-test-utils/src/actions/index.ts | 2 +- .../actions/{mockActionConext.ts => mockActionContext.ts} | 0 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/yellow-cows-kick.md rename plugins/scaffolder-node-test-utils/src/actions/{mockActionConext.ts => mockActionContext.ts} (100%) diff --git a/.changeset/yellow-cows-kick.md b/.changeset/yellow-cows-kick.md new file mode 100644 index 0000000000..93c7e1cff1 --- /dev/null +++ b/.changeset/yellow-cows-kick.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-node-test-utils': patch +--- + +Filename and imports correction for mockActionContext.ts diff --git a/plugins/scaffolder-node-test-utils/src/actions/index.ts b/plugins/scaffolder-node-test-utils/src/actions/index.ts index 161bae8521..aee195cd34 100644 --- a/plugins/scaffolder-node-test-utils/src/actions/index.ts +++ b/plugins/scaffolder-node-test-utils/src/actions/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export { createMockActionContext } from './mockActionConext'; +export { createMockActionContext } from './mockActionContext'; diff --git a/plugins/scaffolder-node-test-utils/src/actions/mockActionConext.ts b/plugins/scaffolder-node-test-utils/src/actions/mockActionContext.ts similarity index 100% rename from plugins/scaffolder-node-test-utils/src/actions/mockActionConext.ts rename to plugins/scaffolder-node-test-utils/src/actions/mockActionContext.ts From cab824fd984f342163a24c1c3bc1faff82fba5a7 Mon Sep 17 00:00:00 2001 From: Ben Lambert Date: Mon, 1 Jul 2024 12:30:40 +0200 Subject: [PATCH 157/510] Update three-carpets-smoke.md Signed-off-by: Ben Lambert --- .changeset/three-carpets-smoke.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/three-carpets-smoke.md b/.changeset/three-carpets-smoke.md index e096fe054d..ab6d857f7d 100644 --- a/.changeset/three-carpets-smoke.md +++ b/.changeset/three-carpets-smoke.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-scaffolder-backend-module-gitlab': minor +'@backstage/plugin-scaffolder-backend-module-gitlab': patch --- -Fixed trigger pipeline accepting input variables +Added support for passing `variables` to `gitlab:pipeline:trigger` From 9a85f1cdaf0fb28e65bdf2958276e528ccad4af5 Mon Sep 17 00:00:00 2001 From: Beth Griggs Date: Mon, 1 Jul 2024 15:41:24 +0100 Subject: [PATCH 158/510] chore: add delay to useGetEntities batches and dedupe Signed-off-by: Beth Griggs --- .../OwnershipCard/useGetEntities.test.ts | 8 +++- .../Cards/OwnershipCard/useGetEntities.ts | 46 ++++++++++--------- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.test.ts b/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.test.ts index 2c223c3f4f..207b01099e 100644 --- a/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.test.ts +++ b/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.test.ts @@ -266,7 +266,9 @@ describe('useGetEntities', () => { }, ); - await waitFor(() => expect(result.current.loading).toBe(false)); + await waitFor(() => expect(result.current.loading).toBe(false), { + timeout: 5000, + }); const callArgs = (catalogApiMock.getEntities as jest.Mock).mock .calls[0][0]; @@ -318,7 +320,9 @@ describe('useGetEntities', () => { }, ); - await waitFor(() => expect(result.current.loading).toBe(false)); + await waitFor(() => expect(result.current.loading).toBe(false), { + timeout: 5000, + }); const callArgs = (catalogApiMock.getEntities as jest.Mock).mock .calls[0][0]; diff --git a/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts b/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts index d919e1d7c5..27fe3019e2 100644 --- a/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts +++ b/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts @@ -32,7 +32,7 @@ import { useApi } from '@backstage/core-plugin-api'; import useAsync from 'react-use/esm/useAsync'; import qs from 'qs'; import { EntityRelationAggregation } from '../types'; -import { uniq } from 'lodash'; +import { uniq, uniqBy } from 'lodash'; const limiter = limiterFactory(5); @@ -143,37 +143,41 @@ const getOwners = async ( return [stringifyEntityRef(entity)]; }; +const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); + const batchGetOwnedEntitiesByOwners = async ( owners: string[], kinds: string[], catalogApi: CatalogApi, batchSize: number = 100, + delayMs: number = 100, ) => { - const batches = []; + const results = []; for (let i = 0; i < owners.length; i += batchSize) { const batch = owners.slice(i, i + batchSize); - batches.push( - catalogApi.getEntities({ - filter: [ - { - kind: kinds, - 'relations.ownedBy': batch, - }, - ], - fields: [ - 'kind', - 'metadata.name', - 'metadata.namespace', - 'spec.type', - 'relations', - ], - }), - ); + const response = await catalogApi.getEntities({ + filter: [ + { + kind: kinds, + 'relations.ownedBy': batch, + }, + ], + fields: [ + 'kind', + 'metadata.name', + 'metadata.namespace', + 'spec.type', + 'relations', + ], + }); + + results.push(...response.items); + + if (i + batchSize < owners.length) await delay(delayMs); } - const results = await Promise.all(batches); - return results.flatMap(result => result.items); + return uniqBy(results, stringifyEntityRef); }; export function useGetEntities( From 8944b8b53762bab1acaa9f93fc12ac86444d9e8f Mon Sep 17 00:00:00 2001 From: Coraly Romero-Principe <34314397+cromero-principe@users.noreply.github.com> Date: Mon, 1 Jul 2024 13:29:43 -0500 Subject: [PATCH 159/510] Update README.md Update the plugin import line in the installation instructions for the new backend Signed-off-by: Coraly Romero-Principe <34314397+cromero-principe@users.noreply.github.com> --- plugins/catalog-backend-module-unprocessed/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog-backend-module-unprocessed/README.md b/plugins/catalog-backend-module-unprocessed/README.md index 6b350e5ef8..f01347912d 100644 --- a/plugins/catalog-backend-module-unprocessed/README.md +++ b/plugins/catalog-backend-module-unprocessed/README.md @@ -17,7 +17,7 @@ yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-unproce In `packages/backend/src/index.ts` add the module: ```ts title="packages/backend/src/index.ts" -backend.add(catalogModuleUnprocessedEntities()); +backend.add(import('@backstage/plugin-catalog-backend-module-unprocessed')); ``` ### Legacy Backend From ff1bb4c39ecf55d801b0c33244e292b6f0949ea7 Mon Sep 17 00:00:00 2001 From: bnechyporenko Date: Mon, 1 Jul 2024 22:17:07 +0200 Subject: [PATCH 160/510] Added a documentation how to use checkpoints + the fix when to clean the workspace Signed-off-by: bnechyporenko --- .changeset/kind-dancers-boil.md | 5 ++++ .../writing-custom-actions.md | 26 ++++++++++++++++++- .../tasks/NunjucksWorkflowRunner.ts | 13 ++++++---- 3 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 .changeset/kind-dancers-boil.md diff --git a/.changeset/kind-dancers-boil.md b/.changeset/kind-dancers-boil.md new file mode 100644 index 0000000000..8e69e830df --- /dev/null +++ b/.changeset/kind-dancers-boil.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Added a documentation how to use checkpoints + the fix when to clean the workspace diff --git a/docs/features/software-templates/writing-custom-actions.md b/docs/features/software-templates/writing-custom-actions.md index e8b354bd45..41bd7d2026 100644 --- a/docs/features/software-templates/writing-custom-actions.md +++ b/docs/features/software-templates/writing-custom-actions.md @@ -145,6 +145,8 @@ When the action `handler` is called, we provide you a `context` as the only argument. It looks like the following: - `ctx.baseUrl` - a string where the template is located +- `ctx.checkpoint` - _Experimental_ allows to implement idempotency of the actions by not re-running the same function again if it was + executed successfully on the previous run. - `ctx.logger` - a Winston logger for additional logging inside your action - `ctx.logStream` - a stream version of the logger if needed - `ctx.workspacePath` - a string of the working directory of the template run @@ -153,7 +155,7 @@ argument. It looks like the following: - `ctx.output` - a function which you can call to set outputs that match the JSON schema or `zod` in `schema.output` for ex. `ctx.output('downloadUrl', myDownloadUrl)` - `createTemporaryDirectory` a function to call to give you a temporary - directory somewhere on the runner so you can store some files there rather + directory somewhere on the runner, so you can store some files there rather than polluting the `workspacePath` - `ctx.metadata` - an object containing a `name` field, indicating the template name. More metadata fields may be added later. @@ -217,6 +219,28 @@ import { }) ``` +### Using Checkpoints in Custom Actions (Experimental) + +Idempotent action could be achieved via the usage of checkpoints. + +Example: + +```ts +const res = await ctx.checkpoint?.('create.projects', async () => { + const projectStgId = createStagingProjectId(); + const projectProId = createProductionProjectId(); + + return { + projectStgId, + projectProId, + }; +}); +``` + +You have to define the unique key in scope of the scaffolder task for your checkpoint. During the execution task engine +will check if the checkpoint with such key was already executed or not, if yes, and the run was successful, the callback +will be skipped and instead the stored value will be returned. + ### Register Custom Actions with the Legacy Backend System Once you have your Custom Action ready for usage with the scaffolder, you'll diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts index 3b88fd0f10..69f17e9dce 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts @@ -508,11 +508,11 @@ export class NunjucksWorkflowRunner implements WorkflowRunner { const output = this.render(task.spec.output, context, renderTemplate); await taskTrack.markSuccessful(); + await task.cleanWorkspace?.(); return { output }; } finally { if (workspacePath) { - await task.cleanWorkspace?.(); await fs.remove(workspacePath); } } @@ -554,10 +554,13 @@ function scaffoldingTracker() { step: TaskStep, action: TemplateAction, ) { - task.emitLog(`Skipping because ${action.id} does not support dry-run`, { - stepId: step.id, - status: 'skipped', - }); + await task.emitLog( + `Skipping because ${action.id} does not support dry-run`, + { + stepId: step.id, + status: 'skipped', + }, + ); } async function markSuccessful() { From b29b39302ca0df2bb4cd97753f60f52e6470d747 Mon Sep 17 00:00:00 2001 From: bnechyporenko Date: Tue, 2 Jul 2024 09:08:29 +0200 Subject: [PATCH 161/510] Excluding the fix from this PR Signed-off-by: bnechyporenko --- .changeset/kind-dancers-boil.md | 2 +- .../src/scaffolder/tasks/NunjucksWorkflowRunner.ts | 13 +++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/.changeset/kind-dancers-boil.md b/.changeset/kind-dancers-boil.md index 8e69e830df..4451cab4f4 100644 --- a/.changeset/kind-dancers-boil.md +++ b/.changeset/kind-dancers-boil.md @@ -2,4 +2,4 @@ '@backstage/plugin-scaffolder-backend': patch --- -Added a documentation how to use checkpoints + the fix when to clean the workspace +Added a documentation how to use checkpoints diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts index 69f17e9dce..3b88fd0f10 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts @@ -508,11 +508,11 @@ export class NunjucksWorkflowRunner implements WorkflowRunner { const output = this.render(task.spec.output, context, renderTemplate); await taskTrack.markSuccessful(); - await task.cleanWorkspace?.(); return { output }; } finally { if (workspacePath) { + await task.cleanWorkspace?.(); await fs.remove(workspacePath); } } @@ -554,13 +554,10 @@ function scaffoldingTracker() { step: TaskStep, action: TemplateAction, ) { - await task.emitLog( - `Skipping because ${action.id} does not support dry-run`, - { - stepId: step.id, - status: 'skipped', - }, - ); + task.emitLog(`Skipping because ${action.id} does not support dry-run`, { + stepId: step.id, + status: 'skipped', + }); } async function markSuccessful() { From 08c63d46ac9ab0987363b5cf314dda81115991f3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 2 Jul 2024 09:03:14 +0000 Subject: [PATCH 162/510] Version Packages (next) --- .changeset/pre.json | 18 + docs/releases/v1.29.0-next.1-changelog.md | 1952 +++++++++++++++++ package.json | 2 +- packages/app-defaults/CHANGELOG.md | 11 + packages/app-defaults/package.json | 2 +- packages/app-next/CHANGELOG.md | 43 + packages/app-next/package.json | 2 +- packages/app/CHANGELOG.md | 41 + packages/app/package.json | 2 +- packages/backend-app-api/CHANGELOG.md | 17 + packages/backend-app-api/package.json | 2 +- packages/backend-common/CHANGELOG.md | 17 + packages/backend-common/package.json | 2 +- packages/backend-defaults/CHANGELOG.md | 21 + packages/backend-defaults/package.json | 2 +- .../CHANGELOG.md | 26 + .../package.json | 2 +- packages/backend-legacy/CHANGELOG.md | 42 + packages/backend-legacy/package.json | 2 +- packages/backend-openapi-utils/CHANGELOG.md | 8 + packages/backend-openapi-utils/package.json | 2 +- packages/backend-plugin-api/CHANGELOG.md | 12 + packages/backend-plugin-api/package.json | 2 +- packages/backend-tasks/CHANGELOG.md | 11 + packages/backend-tasks/package.json | 2 +- packages/backend-test-utils/CHANGELOG.md | 15 + packages/backend-test-utils/package.json | 2 +- packages/backend/CHANGELOG.md | 37 + packages/backend/package.json | 2 +- packages/cli/CHANGELOG.md | 17 + packages/cli/package.json | 2 +- packages/core-app-api/CHANGELOG.md | 11 + packages/core-app-api/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 | 15 + packages/frontend-app-api/package.json | 2 +- packages/frontend-test-utils/CHANGELOG.md | 10 + packages/frontend-test-utils/package.json | 2 +- packages/repo-tools/CHANGELOG.md | 12 + packages/repo-tools/package.json | 2 +- .../techdocs-cli-embedded-app/CHANGELOG.md | 19 + .../techdocs-cli-embedded-app/package.json | 2 +- packages/techdocs-cli/CHANGELOG.md | 11 + packages/techdocs-cli/package.json | 2 +- packages/test-utils/CHANGELOG.md | 13 + packages/test-utils/package.json | 2 +- plugins/api-docs/CHANGELOG.md | 15 + plugins/api-docs/package.json | 2 +- plugins/app-backend/CHANGELOG.md | 14 + plugins/app-backend/package.json | 2 +- plugins/app-node/CHANGELOG.md | 8 + plugins/app-node/package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- plugins/auth-backend/CHANGELOG.md | 30 + plugins/auth-backend/package.json | 2 +- plugins/auth-node/CHANGELOG.md | 13 + plugins/auth-node/package.json | 2 +- .../catalog-backend-module-aws/CHANGELOG.md | 17 + .../catalog-backend-module-aws/package.json | 2 +- .../catalog-backend-module-azure/CHANGELOG.md | 13 + .../catalog-backend-module-azure/package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 17 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../catalog-backend-module-gcp/CHANGELOG.md | 13 + .../catalog-backend-module-gcp/package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 44 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 15 + .../package.json | 2 +- .../CHANGELOG.md | 16 + .../package.json | 2 +- .../catalog-backend-module-ldap/CHANGELOG.md | 20 + .../catalog-backend-module-ldap/package.json | 2 +- .../catalog-backend-module-logs/CHANGELOG.md | 9 + .../catalog-backend-module-logs/package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 15 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- plugins/catalog-backend/CHANGELOG.md | 26 + plugins/catalog-backend/package.json | 2 +- plugins/catalog-graph/CHANGELOG.md | 14 + plugins/catalog-graph/package.json | 2 +- plugins/catalog-import/CHANGELOG.md | 18 + plugins/catalog-import/package.json | 2 +- plugins/catalog-node/CHANGELOG.md | 14 + plugins/catalog-node/package.json | 2 +- plugins/catalog-react/CHANGELOG.md | 19 + plugins/catalog-react/package.json | 2 +- plugins/catalog/CHANGELOG.md | 22 + plugins/catalog/package.json | 2 +- plugins/devtools-backend/CHANGELOG.md | 16 + plugins/devtools-backend/package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../events-backend-module-azure/CHANGELOG.md | 8 + .../events-backend-module-azure/package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../events-backend-module-gerrit/CHANGELOG.md | 8 + .../events-backend-module-gerrit/package.json | 2 +- .../events-backend-module-github/CHANGELOG.md | 9 + .../events-backend-module-github/package.json | 2 +- .../events-backend-module-gitlab/CHANGELOG.md | 9 + .../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 | 10 + plugins/events-backend/package.json | 2 +- plugins/events-node/CHANGELOG.md | 7 + plugins/events-node/package.json | 2 +- .../example-todo-list-backend/CHANGELOG.md | 10 + .../example-todo-list-backend/package.json | 2 +- plugins/home-react/CHANGELOG.md | 12 + plugins/home-react/package.json | 2 +- plugins/home/CHANGELOG.md | 21 + plugins/home/package.json | 2 +- plugins/kubernetes-backend/CHANGELOG.md | 20 + plugins/kubernetes-backend/package.json | 2 +- plugins/kubernetes-cluster/CHANGELOG.md | 12 + plugins/kubernetes-cluster/package.json | 2 +- plugins/kubernetes-node/CHANGELOG.md | 10 + plugins/kubernetes-node/package.json | 2 +- plugins/kubernetes/CHANGELOG.md | 12 + plugins/kubernetes/package.json | 2 +- .../CHANGELOG.md | 15 + .../package.json | 2 +- plugins/notifications-backend/CHANGELOG.md | 17 + plugins/notifications-backend/package.json | 2 +- plugins/notifications-node/CHANGELOG.md | 12 + plugins/notifications-node/package.json | 2 +- plugins/notifications/CHANGELOG.md | 14 + plugins/notifications/package.json | 2 +- plugins/org-react/CHANGELOG.md | 11 + plugins/org-react/package.json | 2 +- plugins/org/CHANGELOG.md | 14 + plugins/org/package.json | 2 +- .../CHANGELOG.md | 10 + .../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/proxy-backend/CHANGELOG.md | 10 + plugins/proxy-backend/package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 17 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- plugins/scaffolder-backend/CHANGELOG.md | 31 + plugins/scaffolder-backend/package.json | 2 +- .../scaffolder-node-test-utils/CHANGELOG.md | 11 + .../scaffolder-node-test-utils/package.json | 2 +- plugins/scaffolder-node/CHANGELOG.md | 13 + plugins/scaffolder-node/package.json | 2 +- plugins/scaffolder-react/CHANGELOG.md | 24 + plugins/scaffolder-react/package.json | 2 +- plugins/scaffolder/CHANGELOG.md | 25 + plugins/scaffolder/package.json | 2 +- .../CHANGELOG.md | 18 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- plugins/search-backend-module-pg/CHANGELOG.md | 12 + plugins/search-backend-module-pg/package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 18 + .../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/CHANGELOG.md | 16 + plugins/search/package.json | 2 +- plugins/signals-backend/CHANGELOG.md | 13 + plugins/signals-backend/package.json | 2 +- plugins/signals-node/CHANGELOG.md | 12 + plugins/signals-node/package.json | 2 +- .../techdocs-addons-test-utils/CHANGELOG.md | 15 + .../techdocs-addons-test-utils/package.json | 2 +- plugins/techdocs-backend/CHANGELOG.md | 18 + plugins/techdocs-backend/package.json | 2 +- plugins/techdocs-node/CHANGELOG.md | 16 + plugins/techdocs-node/package.json | 2 +- plugins/techdocs/CHANGELOG.md | 22 + plugins/techdocs/package.json | 2 +- plugins/user-settings-backend/CHANGELOG.md | 14 + plugins/user-settings-backend/package.json | 2 +- plugins/user-settings/CHANGELOG.md | 17 + plugins/user-settings/package.json | 2 +- 275 files changed, 4055 insertions(+), 137 deletions(-) create mode 100644 docs/releases/v1.29.0-next.1-changelog.md diff --git a/.changeset/pre.json b/.changeset/pre.json index df3592a582..ebf0c6bf22 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -189,6 +189,7 @@ "@backstage/plugin-scaffolder-backend-module-gcp": "0.0.1-next.1" }, "changesets": [ + "bright-fireants-sit", "bright-panthers-leave", "calm-jeans-ring", "chilly-roses-trade", @@ -196,11 +197,16 @@ "create-app-1719320674", "curvy-teachers-smell", "eighty-games-wink", + "fair-fans-flow", "fair-pillows-know", "fair-rockets-leave", "famous-dodos-crash", + "fast-pens-smell", "fifty-pumpkins-smell", + "friendly-bulldogs-pay", + "friendly-experts-fail", "friendly-masks-type", + "friendly-oranges-greet", "friendly-stingrays-occur", "funny-laws-tease", "gentle-avocados-obey", @@ -211,22 +217,34 @@ "light-avocados-worry", "little-games-fail", "metal-jokes-add", + "metal-parents-brush", + "metal-suits-drum", "moody-llamas-breathe", + "neat-dingos-tickle", + "poor-cheetahs-raise", "rare-peas-dream", "renovate-7b61228", + "renovate-ced359b", "rich-bears-march", "selfish-turtles-jog", "serious-kings-trade", "short-flowers-cry", "shy-hounds-battle", "silent-experts-move", + "silent-lobsters-tease", "silent-moose-eat", "soft-clocks-bake", "sour-jokes-sneeze", + "spotty-crabs-shop", + "swift-dots-cough", "ten-dancers-drum", + "ten-nails-hear", "ten-pots-walk", "thick-lizards-divide", + "three-carpets-smoke", "tough-lies-mate", + "weak-boats-float", + "yellow-cows-kick", "young-donuts-swim", "young-fishes-lie", "young-houses-unite" diff --git a/docs/releases/v1.29.0-next.1-changelog.md b/docs/releases/v1.29.0-next.1-changelog.md new file mode 100644 index 0000000000..34cd038f22 --- /dev/null +++ b/docs/releases/v1.29.0-next.1-changelog.md @@ -0,0 +1,1952 @@ +# Release v1.29.0-next.1 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.29.0-next.1](https://backstage.github.io/upgrade-helper/?to=1.29.0-next.1) + +## @backstage/plugin-catalog-backend@1.24.0-next.1 + +### Minor Changes + +- b9ed1bb: bumped better-sqlite3 from ^9.0.0 to ^11.0.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-openapi-utils@0.1.15-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-node@0.7.33-next.1 + - @backstage/plugin-search-backend-module-catalog@0.1.28-next.1 + +## @backstage/plugin-catalog-backend-module-ldap@0.7.0-next.1 + +### Minor Changes + +- cb32ca7: **BREAKING**: `readLdapOrg` and the `LdapProviderConfig` type now always accept arrays of user and group configs, not just single items. + + Added support for single ldap catalog provider to provide list and undefined user and group bindings next to standard single one. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + +## @backstage/plugin-scaffolder-react@1.10.0-next.1 + +### Minor Changes + +- 354e68c: Improve validation error display text in scaffolder + +### Patch Changes + +- cc81579: Updated dependency `@rjsf/utils` to `5.18.5`. + Updated dependency `@rjsf/core` to `5.18.5`. + Updated dependency `@rjsf/material-ui` to `5.18.5`. + Updated dependency `@rjsf/validator-ajv8` to `5.18.5`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-permission-react@0.4.23 + - @backstage/plugin-scaffolder-common@1.5.3 + +## @backstage/app-defaults@1.5.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.13.1-next.1 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-permission-react@0.4.23 + +## @backstage/backend-app-api@0.7.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.6 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-permission-node@0.7.33-next.1 + +## @backstage/backend-common@0.23.3-next.1 + +### Patch Changes + +- b9ed1bb: bumped better-sqlite3 from ^9.0.0 to ^11.0.0 +- Updated dependencies + - @backstage/backend-dev-utils@0.1.4 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + +## @backstage/backend-defaults@0.3.4-next.1 + +### Patch Changes + +- b9ed1bb: bumped better-sqlite3 from ^9.0.0 to ^11.0.0 +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-app-api@0.7.10-next.1 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + - @backstage/plugin-permission-node@0.7.33-next.1 + +## @backstage/backend-dynamic-feature-service@0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.24.0-next.1 + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-app-api@0.7.10-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.6 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-events-backend@0.3.9-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-node@0.7.33-next.1 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + - @backstage/plugin-search-backend-node@1.2.27-next.1 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/backend-openapi-utils@0.1.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/errors@1.2.4 + +## @backstage/backend-plugin-api@0.6.22-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-permission-common@0.7.14 + +## @backstage/backend-tasks@0.5.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/backend-test-utils@0.4.4-next.1 + +### Patch Changes + +- b9ed1bb: bumped better-sqlite3 from ^9.0.0 to ^11.0.0 +- Updated dependencies + - @backstage/backend-defaults@0.3.4-next.1 + - @backstage/backend-app-api@0.7.10-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + +## @backstage/cli@0.26.11-next.1 + +### Patch Changes + +- 4baac0c: The `backendPlugin` and `backendModule` factory now includes a step for automatically adding the new backend plugin/module to the `index.ts` file of the backend. +- Updated dependencies + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.6 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + - @backstage/eslint-plugin@0.1.8 + - @backstage/integration@1.13.0-next.0 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/core-app-api@1.13.1-next.1 + +### Patch Changes + +- db2e2d5: Updated config schema to support app.routes.bindings +- Updated dependencies + - @backstage/core-plugin-api@1.9.3 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/create-app@0.5.17-next.1 + +### Patch Changes + +- 780d994: Added `MyGroupsSidebarItem` to the sidebar in the `create-app` template +- Updated dependencies + - @backstage/cli-common@0.1.14 + +## @backstage/dev-utils@1.0.35-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.13.1-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/app-defaults@1.5.8-next.1 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/theme@0.5.6 + +## @backstage/frontend-app-api@0.7.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.13.1-next.1 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/frontend-test-utils@0.1.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.7.3-next.1 + - @backstage/test-utils@1.5.8-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/types@1.1.1 + +## @backstage/repo-tools@0.9.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.6 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + +## @techdocs/cli@1.8.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.8-next.1 + - @backstage/backend-defaults@0.3.4-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## @backstage/test-utils@1.5.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.13.1-next.1 + - @backstage/core-plugin-api@1.9.3 + - @backstage/config@1.2.0 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-react@0.4.23 + +## @backstage/plugin-api-docs@0.11.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/plugin-catalog@1.21.1-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-react@0.4.23 + +## @backstage/plugin-app-backend@0.3.71-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + +## @backstage/plugin-app-node@0.1.22-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config-loader@1.8.1 + +## @backstage/plugin-auth-backend@0.22.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.2.3-next.1 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.14-next.1 + - @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.1.5-next.1 + - @backstage/plugin-auth-backend-module-bitbucket-provider@0.1.5-next.1 + - @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.1.5-next.1 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.17-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.1.19-next.1 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.19-next.1 + - @backstage/plugin-auth-backend-module-google-provider@0.1.19-next.1 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.1.17-next.1 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.2.3-next.1 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.15-next.1 + - @backstage/plugin-auth-backend-module-oidc-provider@0.2.3-next.1 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.15-next.1 + - @backstage/plugin-auth-backend-module-onelogin-provider@0.1.3-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-catalog-node@1.12.4-next.1 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-backend@0.22.9-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.17-next.1 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.17-next.1 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.1.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.1.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + +## @backstage/plugin-auth-backend-module-google-provider@0.1.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + +## @backstage/plugin-auth-backend-module-guest-provider@0.1.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.17-next.1 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.1.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.17-next.1 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-auth-backend@0.22.9-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + +## @backstage/plugin-auth-backend-module-okta-provider@0.0.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.1.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-auth-node@0.4.17-next.1 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-auth-node@0.4.17-next.1 + +## @backstage/plugin-auth-node@0.4.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog@1.21.1-next.1 + +### Patch Changes + +- 06c0956: Support i18n for catalog and catalog-react plugins +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-react@0.4.23 + - @backstage/plugin-scaffolder-common@1.5.3 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-catalog-backend-module-aws@0.3.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-kubernetes-common@0.8.0 + +## @backstage/plugin-catalog-backend-module-azure@0.1.42-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/config@1.2.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.2.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-openapi-utils@0.1.15-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.4-next.1 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.21-next.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.36-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-node@1.12.4-next.1 + +## @backstage/plugin-catalog-backend-module-gcp@0.1.23-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-kubernetes-common@0.8.0 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.39-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-node@1.12.4-next.1 + +## @backstage/plugin-catalog-backend-module-github@0.6.5-next.1 + +### Patch Changes + +- 9112efc: Adds support for `repository` events. + + The provider adds a subscription to the topic `github.repository`. + + Hereby, it supports events of type `repository` with actions + + - `archived` + - `deleted` + - `edited` + - `renamed` + - `transferred` + - `unarchived` + + Actions skipped as they don't require entity changes: + + - `created` + - `privatized` + - `publicized` + + If the config option `validateLocationsExist` is enabled, an API request + is necessary and will be executed. + This affects the actions `renamed`, `transferred`, and `unarchive` + of event type `repository`. + + Catalog entities related to the `GithubEntityProvider` instance will be adjusted + according to action and its meaning for them. + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.24.0-next.1 + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + +## @backstage/plugin-catalog-backend-module-github-org@0.1.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-github@0.6.5-next.1 + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + +## @backstage/plugin-catalog-backend-module-gitlab@0.3.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.0.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-catalog-backend-module-gitlab@0.3.21-next.1 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.4.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.24.0-next.1 + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + - @backstage/plugin-permission-common@0.7.14 + +## @backstage/plugin-catalog-backend-module-logs@0.0.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.24.0-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + +## @backstage/plugin-catalog-backend-module-msgraph@0.5.30-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.40-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.24.0-next.1 + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.1.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.12.4-next.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-scaffolder-common@1.5.3 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.4.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.2 + - @backstage/plugin-permission-common@0.7.14 + +## @backstage/plugin-catalog-graph@0.4.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-import@0.12.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-catalog-common@1.0.24 + +## @backstage/plugin-catalog-node@1.12.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-node@0.7.33-next.1 + +## @backstage/plugin-catalog-react@1.12.2-next.1 + +### Patch Changes + +- 06c0956: Support i18n for catalog and catalog-react plugins +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-react@0.4.23 + +## @backstage/plugin-devtools-backend@0.3.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.10 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-node@0.7.33-next.1 + +## @backstage/plugin-events-backend@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.8-next.1 + +## @backstage/plugin-events-backend-module-aws-sqs@0.3.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.8-next.1 + +## @backstage/plugin-events-backend-module-azure@0.2.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + +## @backstage/plugin-events-backend-module-gerrit@0.2.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + +## @backstage/plugin-events-backend-module-github@0.2.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.8-next.1 + +## @backstage/plugin-events-backend-module-gitlab@0.2.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.8-next.1 + +## @backstage/plugin-events-backend-test-utils@0.1.32-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.8-next.1 + +## @backstage/plugin-events-node@0.3.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + +## @backstage/plugin-home@0.7.7-next.1 + +### Patch Changes + +- cc81579: Updated dependency `@rjsf/utils` to `5.18.5`. + Updated dependency `@rjsf/core` to `5.18.5`. + Updated dependency `@rjsf/material-ui` to `5.18.5`. + Updated dependency `@rjsf/validator-ajv8` to `5.18.5`. +- Updated dependencies + - @backstage/core-app-api@1.13.1-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/plugin-home-react@0.1.15-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/theme@0.5.6 + +## @backstage/plugin-home-react@0.1.15-next.1 + +### Patch Changes + +- cc81579: Updated dependency `@rjsf/utils` to `5.18.5`. + Updated dependency `@rjsf/core` to `5.18.5`. + Updated dependency `@rjsf/material-ui` to `5.18.5`. + Updated dependency `@rjsf/validator-ajv8` to `5.18.5`. +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-kubernetes@0.11.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-kubernetes-react@0.4.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-kubernetes-common@0.8.0 + +## @backstage/plugin-kubernetes-backend@0.18.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-kubernetes-common@0.8.0 + - @backstage/plugin-kubernetes-node@0.1.16-next.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-node@0.7.33-next.1 + +## @backstage/plugin-kubernetes-cluster@0.0.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-kubernetes-react@0.4.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-kubernetes-common@0.8.0 + +## @backstage/plugin-kubernetes-node@0.1.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.0 + +## @backstage/plugin-notifications@0.2.3-next.1 + +### Patch Changes + +- 3bf0697: The toolbar on the Notifications page is hidden when there are no listed notifications. +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.4 + - @backstage/plugin-signals-react@0.0.4 + +## @backstage/plugin-notifications-backend@0.3.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + - @backstage/plugin-notifications-common@0.0.4 + - @backstage/plugin-notifications-node@0.2.3-next.1 + - @backstage/plugin-signals-node@0.1.8-next.1 + +## @backstage/plugin-notifications-backend-module-email@0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.4 + - @backstage/plugin-notifications-node@0.2.3-next.1 + +## @backstage/plugin-notifications-node@0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-notifications-common@0.0.4 + - @backstage/plugin-signals-node@0.1.8-next.1 + +## @backstage/plugin-org@0.6.27-next.1 + +### Patch Changes + +- 5132d28: The `useGetEntities` hook could result in requests to `/api/catalog/entities` where the headers exceed the default maximum Node.js header size of 16KB. The hook logic has been adjusted to batch the requests. +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/plugin-catalog-common@1.0.24 + +## @backstage/plugin-org-react@0.1.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + +## @backstage/plugin-permission-backend@0.5.46-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-node@0.7.33-next.1 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.1.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-node@0.7.33-next.1 + +## @backstage/plugin-permission-node@0.7.33-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-permission-common@0.7.14 + +## @backstage/plugin-proxy-backend@0.5.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder@1.22.1-next.1 + +### Patch Changes + +- cc81579: Updated dependency `@rjsf/utils` to `5.18.5`. + Updated dependency `@rjsf/core` to `5.18.5`. + Updated dependency `@rjsf/material-ui` to `5.18.5`. + Updated dependency `@rjsf/validator-ajv8` to `5.18.5`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/plugin-scaffolder-react@1.10.0-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-react@0.4.23 + - @backstage/plugin-scaffolder-common@1.5.3 + +## @backstage/plugin-scaffolder-backend@1.23.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-github@0.4.0-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.4.4-next.1 + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-bitbucket-cloud-common@0.2.21-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.20-next.1 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-node@0.7.33-next.1 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.14-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.12-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.12-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.12-next.1 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.14-next.1 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.12-next.1 + - @backstage/plugin-scaffolder-common@1.5.3 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + +## @backstage/plugin-scaffolder-backend-module-azure@0.1.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.12-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.12-next.1 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.21-next.0 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.23-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.46-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.1.0-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.1.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.1.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + +## @backstage/plugin-scaffolder-backend-module-github@0.4.0-next.1 + +### Patch Changes + +- 141f366: Added action to enable GitHub Pages on a repo + +- dfaa28d: Adds `requireLastPushApproval` input property to configure Branch Protection Settings in `github:publish` action + + Adds `requireLastPushApproval` input property to configure Branch Protection Settings in `github:repo:push` action + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.4.4-next.1 + +### Patch Changes + +- 2fb0eb8: Added support for passing `variables` to `gitlab:pipeline:trigger` +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.0.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-notifications-common@0.0.4 + - @backstage/plugin-notifications-node@0.2.3-next.1 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.39-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.1.30-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.3.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node-test-utils@0.1.9-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + +## @backstage/plugin-scaffolder-node@0.4.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.3 + +## @backstage/plugin-scaffolder-node-test-utils@0.1.9-next.1 + +### Patch Changes + +- 54429b5: Filename and imports correction for mockActionContext.ts +- Updated dependencies + - @backstage/backend-test-utils@0.4.4-next.1 + - @backstage/backend-common@0.23.3-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + +## @backstage/plugin-search@1.4.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-search-backend@1.5.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.3.4-next.1 + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-openapi-utils@0.1.15-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-node@0.7.33-next.1 + - @backstage/plugin-search-backend-node@1.2.27-next.1 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-search-backend-module-catalog@0.1.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-search-backend-node@1.2.27-next.1 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-search-backend-module-elasticsearch@1.5.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-backend-node@1.2.27-next.1 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-search-backend-module-explore@0.1.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.2.27-next.1 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-search-backend-module-pg@0.5.32-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-app-api@0.7.10-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.2.27-next.1 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.2.27-next.1 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-search-backend-module-techdocs@0.1.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.8-next.1 + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-search-backend-node@1.2.27-next.1 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-search-backend-node@1.2.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-signals-backend@0.1.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + - @backstage/plugin-signals-node@0.1.8-next.1 + +## @backstage/plugin-signals-node@0.1.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + +## @backstage/plugin-techdocs@1.10.7-next.1 + +### Patch Changes + +- 60caa92: Fix double scrollbar bug in reader +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.4-next.0 + - @backstage/plugin-search-common@1.2.12 + - @backstage/plugin-techdocs-react@1.2.6-next.0 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.35-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.13.1-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/plugin-catalog@1.21.1-next.1 + - @backstage/plugin-techdocs@1.10.7-next.1 + - @backstage/core-plugin-api@1.9.3 + - @backstage/test-utils@1.5.8-next.1 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-techdocs-react@1.2.6-next.0 + +## @backstage/plugin-techdocs-backend@1.10.9-next.1 + +### Patch Changes + +- 9ecf5fd: Adds extension point for publishers to the techdocs backend +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.8-next.1 + - @backstage/backend-common@0.23.3-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.27-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-common@0.7.14 + +## @backstage/plugin-techdocs-node@1.12.8-next.1 + +### Patch Changes + +- 9ecf5fd: Adds extension point for publishers to the techdocs backend +- 4c4d077: Bumps default version of techdocs docker image to latest +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-user-settings@0.8.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.13.1-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.4 + - @backstage/plugin-user-settings-common@0.0.1 + +## @backstage/plugin-user-settings-backend@0.2.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-signals-node@0.1.8-next.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.99-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-org@0.6.27-next.1 + - @backstage/core-app-api@1.13.1-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/plugin-catalog@1.21.1-next.1 + - @backstage/plugin-techdocs@1.10.7-next.1 + - @backstage/plugin-notifications@0.2.3-next.1 + - @backstage/plugin-home@0.7.7-next.1 + - @backstage/plugin-scaffolder-react@1.10.0-next.1 + - @backstage/plugin-scaffolder@1.22.1-next.1 + - @backstage/cli@0.26.11-next.1 + - @backstage/app-defaults@1.5.8-next.1 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/frontend-app-api@0.7.3-next.1 + - @backstage/plugin-api-docs@0.11.7-next.1 + - @backstage/plugin-catalog-graph@0.4.7-next.1 + - @backstage/plugin-catalog-import@0.12.1-next.1 + - @backstage/plugin-search@1.4.13-next.1 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/plugin-signals@0.0.8-next.0 + - @backstage/plugin-user-settings@0.8.9-next.1 + - @backstage/plugin-kubernetes@0.11.12-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.13-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.4-next.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-unprocessed-entities@0.2.6-next.0 + - @backstage/plugin-devtools@0.1.16-next.0 + - @backstage/plugin-permission-react@0.4.23 + - @backstage/plugin-search-common@1.2.12 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.12-next.0 + - @backstage/plugin-techdocs-react@1.2.6-next.0 + +## example-app-next@0.0.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-org@0.6.27-next.1 + - @backstage/core-app-api@1.13.1-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/plugin-catalog@1.21.1-next.1 + - @backstage/plugin-techdocs@1.10.7-next.1 + - @backstage/plugin-notifications@0.2.3-next.1 + - @backstage/plugin-home@0.7.7-next.1 + - @backstage/plugin-scaffolder-react@1.10.0-next.1 + - @backstage/plugin-scaffolder@1.22.1-next.1 + - @backstage/cli@0.26.11-next.1 + - @backstage/app-defaults@1.5.8-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/frontend-app-api@0.7.3-next.1 + - @backstage/plugin-api-docs@0.11.7-next.1 + - @backstage/plugin-catalog-graph@0.4.7-next.1 + - @backstage/plugin-catalog-import@0.12.1-next.1 + - @backstage/plugin-search@1.4.13-next.1 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/plugin-signals@0.0.8-next.0 + - @backstage/plugin-user-settings@0.8.9-next.1 + - @backstage/plugin-kubernetes@0.11.12-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.13-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-app-visualizer@0.1.8-next.0 + - @backstage/plugin-auth-react@0.1.4-next.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-unprocessed-entities@0.2.6-next.0 + - @backstage/plugin-permission-react@0.4.23 + - @backstage/plugin-search-common@1.2.12 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.12-next.0 + - @backstage/plugin-techdocs-react@1.2.6-next.0 + +## example-backend@0.0.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-backend@1.10.9-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.4.0-next.1 + - @backstage/plugin-catalog-backend@1.24.0-next.1 + - @backstage/backend-defaults@0.3.4-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.27-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-app-backend@0.3.71-next.1 + - @backstage/plugin-auth-backend@0.22.9-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.1.19-next.1 + - @backstage/plugin-auth-backend-module-guest-provider@0.1.8-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.2.5-next.1 + - @backstage/plugin-catalog-backend-module-openapi@0.1.40-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.20-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.9-next.1 + - @backstage/plugin-devtools-backend@0.3.8-next.1 + - @backstage/plugin-kubernetes-backend@0.18.3-next.1 + - @backstage/plugin-notifications-backend@0.3.3-next.1 + - @backstage/plugin-permission-backend@0.5.46-next.1 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.19-next.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-node@0.7.33-next.1 + - @backstage/plugin-proxy-backend@0.5.3-next.1 + - @backstage/plugin-scaffolder-backend@1.23.0-next.1 + - @backstage/plugin-search-backend@1.5.14-next.1 + - @backstage/plugin-search-backend-module-catalog@0.1.28-next.1 + - @backstage/plugin-search-backend-module-explore@0.1.28-next.1 + - @backstage/plugin-search-backend-node@1.2.27-next.1 + - @backstage/plugin-signals-backend@0.1.8-next.1 + +## example-backend-legacy@0.2.100-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-backend@1.10.9-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.4.4-next.1 + - @backstage/plugin-catalog-backend@1.24.0-next.1 + - @backstage/backend-common@0.23.3-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.27-next.1 + - example-app@0.2.99-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-app-backend@0.3.71-next.1 + - @backstage/plugin-auth-backend@0.22.9-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.20-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.9-next.1 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-devtools-backend@0.3.8-next.1 + - @backstage/plugin-events-backend@0.3.9-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + - @backstage/plugin-kubernetes-backend@0.18.3-next.1 + - @backstage/plugin-permission-backend@0.5.46-next.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-node@0.7.33-next.1 + - @backstage/plugin-proxy-backend@0.5.3-next.1 + - @backstage/plugin-scaffolder-backend@1.23.0-next.1 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.23-next.1 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.39-next.1 + - @backstage/plugin-search-backend@1.5.14-next.1 + - @backstage/plugin-search-backend-module-catalog@0.1.28-next.1 + - @backstage/plugin-search-backend-module-elasticsearch@1.5.3-next.1 + - @backstage/plugin-search-backend-module-explore@0.1.28-next.1 + - @backstage/plugin-search-backend-module-pg@0.5.32-next.1 + - @backstage/plugin-search-backend-node@1.2.27-next.1 + - @backstage/plugin-signals-backend@0.1.8-next.1 + - @backstage/plugin-signals-node@0.1.8-next.1 + +## e2e-test@0.2.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.17-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + +## techdocs-cli-embedded-app@0.2.98-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.13.1-next.1 + - @backstage/plugin-catalog@1.21.1-next.1 + - @backstage/plugin-techdocs@1.10.7-next.1 + - @backstage/cli@0.26.11-next.1 + - @backstage/app-defaults@1.5.8-next.1 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/test-utils@1.5.8-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-techdocs-react@1.2.6-next.0 + +## @internal/plugin-todo-list-backend@1.0.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.17-next.1 diff --git a/package.json b/package.json index 0946671f12..7de757ff9b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "root", - "version": "1.29.0-next.0", + "version": "1.29.0-next.1", "private": true, "repository": { "type": "git", diff --git a/packages/app-defaults/CHANGELOG.md b/packages/app-defaults/CHANGELOG.md index 40ee32565f..588c59c3e4 100644 --- a/packages/app-defaults/CHANGELOG.md +++ b/packages/app-defaults/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/app-defaults +## 1.5.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.13.1-next.1 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-permission-react@0.4.23 + ## 1.5.7-next.0 ### Patch Changes diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json index 5dc9e3d617..8bb0a707b5 100644 --- a/packages/app-defaults/package.json +++ b/packages/app-defaults/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/app-defaults", - "version": "1.5.7-next.0", + "version": "1.5.8-next.1", "description": "Provides the default wiring of a Backstage App", "backstage": { "role": "web-library" diff --git a/packages/app-next/CHANGELOG.md b/packages/app-next/CHANGELOG.md index 979284c459..6c3d48601f 100644 --- a/packages/app-next/CHANGELOG.md +++ b/packages/app-next/CHANGELOG.md @@ -1,5 +1,48 @@ # example-app-next +## 0.0.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-org@0.6.27-next.1 + - @backstage/core-app-api@1.13.1-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/plugin-catalog@1.21.1-next.1 + - @backstage/plugin-techdocs@1.10.7-next.1 + - @backstage/plugin-notifications@0.2.3-next.1 + - @backstage/plugin-home@0.7.7-next.1 + - @backstage/plugin-scaffolder-react@1.10.0-next.1 + - @backstage/plugin-scaffolder@1.22.1-next.1 + - @backstage/cli@0.26.11-next.1 + - @backstage/app-defaults@1.5.8-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/frontend-app-api@0.7.3-next.1 + - @backstage/plugin-api-docs@0.11.7-next.1 + - @backstage/plugin-catalog-graph@0.4.7-next.1 + - @backstage/plugin-catalog-import@0.12.1-next.1 + - @backstage/plugin-search@1.4.13-next.1 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/plugin-signals@0.0.8-next.0 + - @backstage/plugin-user-settings@0.8.9-next.1 + - @backstage/plugin-kubernetes@0.11.12-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.13-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-app-visualizer@0.1.8-next.0 + - @backstage/plugin-auth-react@0.1.4-next.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-unprocessed-entities@0.2.6-next.0 + - @backstage/plugin-permission-react@0.4.23 + - @backstage/plugin-search-common@1.2.12 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.12-next.0 + - @backstage/plugin-techdocs-react@1.2.6-next.0 + ## 0.0.13-next.0 ### Patch Changes diff --git a/packages/app-next/package.json b/packages/app-next/package.json index 73141946ea..a0f0174753 100644 --- a/packages/app-next/package.json +++ b/packages/app-next/package.json @@ -1,6 +1,6 @@ { "name": "example-app-next", - "version": "0.0.13-next.0", + "version": "0.0.13-next.1", "private": true, "repository": { "type": "git", diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index ca64c31049..3a06dd99fd 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,46 @@ # example-app +## 0.2.99-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-org@0.6.27-next.1 + - @backstage/core-app-api@1.13.1-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/plugin-catalog@1.21.1-next.1 + - @backstage/plugin-techdocs@1.10.7-next.1 + - @backstage/plugin-notifications@0.2.3-next.1 + - @backstage/plugin-home@0.7.7-next.1 + - @backstage/plugin-scaffolder-react@1.10.0-next.1 + - @backstage/plugin-scaffolder@1.22.1-next.1 + - @backstage/cli@0.26.11-next.1 + - @backstage/app-defaults@1.5.8-next.1 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/frontend-app-api@0.7.3-next.1 + - @backstage/plugin-api-docs@0.11.7-next.1 + - @backstage/plugin-catalog-graph@0.4.7-next.1 + - @backstage/plugin-catalog-import@0.12.1-next.1 + - @backstage/plugin-search@1.4.13-next.1 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/plugin-signals@0.0.8-next.0 + - @backstage/plugin-user-settings@0.8.9-next.1 + - @backstage/plugin-kubernetes@0.11.12-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.13-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.4-next.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-unprocessed-entities@0.2.6-next.0 + - @backstage/plugin-devtools@0.1.16-next.0 + - @backstage/plugin-permission-react@0.4.23 + - @backstage/plugin-search-common@1.2.12 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.12-next.0 + - @backstage/plugin-techdocs-react@1.2.6-next.0 + ## 0.2.99-next.0 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index 067b2d84eb..a30c8e15d7 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "example-app", - "version": "0.2.99-next.0", + "version": "0.2.99-next.1", "backstage": { "role": "frontend" }, diff --git a/packages/backend-app-api/CHANGELOG.md b/packages/backend-app-api/CHANGELOG.md index c9fe21c89e..4456d8438b 100644 --- a/packages/backend-app-api/CHANGELOG.md +++ b/packages/backend-app-api/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/backend-app-api +## 0.7.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.6 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-permission-node@0.7.33-next.1 + ## 0.7.9-next.0 ### Patch Changes diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index 51bbca14bc..4d3ffd874f 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-app-api", - "version": "0.7.9-next.0", + "version": "0.7.10-next.1", "description": "Core API used by Backstage backend apps", "backstage": { "role": "node-library" diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md index d635b77c72..d144d461b8 100644 --- a/packages/backend-common/CHANGELOG.md +++ b/packages/backend-common/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/backend-common +## 0.23.3-next.1 + +### Patch Changes + +- b9ed1bb: bumped better-sqlite3 from ^9.0.0 to ^11.0.0 +- Updated dependencies + - @backstage/backend-dev-utils@0.1.4 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + ## 0.23.2-next.0 ### Patch Changes diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 28378f6c41..f23f0d2ce9 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-common", - "version": "0.23.2-next.0", + "version": "0.23.3-next.1", "description": "Common functionality library for Backstage backends", "backstage": { "role": "node-library" diff --git a/packages/backend-defaults/CHANGELOG.md b/packages/backend-defaults/CHANGELOG.md index 7e9788756f..a9b20bfbea 100644 --- a/packages/backend-defaults/CHANGELOG.md +++ b/packages/backend-defaults/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/backend-defaults +## 0.3.4-next.1 + +### Patch Changes + +- b9ed1bb: bumped better-sqlite3 from ^9.0.0 to ^11.0.0 +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-app-api@0.7.10-next.1 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + - @backstage/plugin-permission-node@0.7.33-next.1 + ## 0.3.3-next.0 ### Patch Changes diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index 824f1893bd..0606d942ff 100644 --- a/packages/backend-defaults/package.json +++ b/packages/backend-defaults/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-defaults", - "version": "0.3.3-next.0", + "version": "0.3.4-next.1", "description": "Backend defaults used by Backstage backend apps", "backstage": { "role": "node-library" diff --git a/packages/backend-dynamic-feature-service/CHANGELOG.md b/packages/backend-dynamic-feature-service/CHANGELOG.md index 4ec9489674..02f47ef7b4 100644 --- a/packages/backend-dynamic-feature-service/CHANGELOG.md +++ b/packages/backend-dynamic-feature-service/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/backend-dynamic-feature-service +## 0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.24.0-next.1 + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-app-api@0.7.10-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.6 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-events-backend@0.3.9-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-node@0.7.33-next.1 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + - @backstage/plugin-search-backend-node@1.2.27-next.1 + - @backstage/plugin-search-common@1.2.12 + ## 0.2.14-next.0 ### Patch Changes diff --git a/packages/backend-dynamic-feature-service/package.json b/packages/backend-dynamic-feature-service/package.json index 60ff4d2d4e..3e3e566879 100644 --- a/packages/backend-dynamic-feature-service/package.json +++ b/packages/backend-dynamic-feature-service/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-dynamic-feature-service", "description": "Backstage dynamic feature service", - "version": "0.2.14-next.0", + "version": "0.2.15-next.1", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-legacy/CHANGELOG.md b/packages/backend-legacy/CHANGELOG.md index 9535ba1211..7734d12d4f 100644 --- a/packages/backend-legacy/CHANGELOG.md +++ b/packages/backend-legacy/CHANGELOG.md @@ -1,5 +1,47 @@ # example-backend-legacy +## 0.2.100-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-backend@1.10.9-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.4.4-next.1 + - @backstage/plugin-catalog-backend@1.24.0-next.1 + - @backstage/backend-common@0.23.3-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.27-next.1 + - example-app@0.2.99-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-app-backend@0.3.71-next.1 + - @backstage/plugin-auth-backend@0.22.9-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.20-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.9-next.1 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-devtools-backend@0.3.8-next.1 + - @backstage/plugin-events-backend@0.3.9-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + - @backstage/plugin-kubernetes-backend@0.18.3-next.1 + - @backstage/plugin-permission-backend@0.5.46-next.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-node@0.7.33-next.1 + - @backstage/plugin-proxy-backend@0.5.3-next.1 + - @backstage/plugin-scaffolder-backend@1.23.0-next.1 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.23-next.1 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.39-next.1 + - @backstage/plugin-search-backend@1.5.14-next.1 + - @backstage/plugin-search-backend-module-catalog@0.1.28-next.1 + - @backstage/plugin-search-backend-module-elasticsearch@1.5.3-next.1 + - @backstage/plugin-search-backend-module-explore@0.1.28-next.1 + - @backstage/plugin-search-backend-module-pg@0.5.32-next.1 + - @backstage/plugin-search-backend-node@1.2.27-next.1 + - @backstage/plugin-signals-backend@0.1.8-next.1 + - @backstage/plugin-signals-node@0.1.8-next.1 + ## 0.2.100-next.0 ### Patch Changes diff --git a/packages/backend-legacy/package.json b/packages/backend-legacy/package.json index 6b9bb3523a..384ce61973 100644 --- a/packages/backend-legacy/package.json +++ b/packages/backend-legacy/package.json @@ -1,6 +1,6 @@ { "name": "example-backend-legacy", - "version": "0.2.100-next.0", + "version": "0.2.100-next.1", "backstage": { "role": "backend" }, diff --git a/packages/backend-openapi-utils/CHANGELOG.md b/packages/backend-openapi-utils/CHANGELOG.md index 0040eddc57..43a57f7d8c 100644 --- a/packages/backend-openapi-utils/CHANGELOG.md +++ b/packages/backend-openapi-utils/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/backend-openapi-utils +## 0.1.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/errors@1.2.4 + ## 0.1.14-next.0 ### Patch Changes diff --git a/packages/backend-openapi-utils/package.json b/packages/backend-openapi-utils/package.json index 4b2551eb13..f35863c6e3 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.14-next.0", + "version": "0.1.15-next.1", "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 b36d7a996d..cb341b218e 100644 --- a/packages/backend-plugin-api/CHANGELOG.md +++ b/packages/backend-plugin-api/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/backend-plugin-api +## 0.6.22-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-permission-common@0.7.14 + ## 0.6.21-next.0 ### Patch Changes diff --git a/packages/backend-plugin-api/package.json b/packages/backend-plugin-api/package.json index dbb59f7991..631141a57f 100644 --- a/packages/backend-plugin-api/package.json +++ b/packages/backend-plugin-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-plugin-api", - "version": "0.6.21-next.0", + "version": "0.6.22-next.1", "description": "Core API used by Backstage backend plugins", "backstage": { "role": "node-library" diff --git a/packages/backend-tasks/CHANGELOG.md b/packages/backend-tasks/CHANGELOG.md index 008ae3cb11..590d824635 100644 --- a/packages/backend-tasks/CHANGELOG.md +++ b/packages/backend-tasks/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/backend-tasks +## 0.5.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.5.26-next.0 ### Patch Changes diff --git a/packages/backend-tasks/package.json b/packages/backend-tasks/package.json index 2033be826c..df10190443 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.26-next.0", + "version": "0.5.27-next.1", "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 435d1f8abc..9f3d84a906 100644 --- a/packages/backend-test-utils/CHANGELOG.md +++ b/packages/backend-test-utils/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/backend-test-utils +## 0.4.4-next.1 + +### Patch Changes + +- b9ed1bb: bumped better-sqlite3 from ^9.0.0 to ^11.0.0 +- Updated dependencies + - @backstage/backend-defaults@0.3.4-next.1 + - @backstage/backend-app-api@0.7.10-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + ## 0.4.3-next.0 ### Patch Changes diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index 540b4f9ee4..e975dc01d9 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-test-utils", - "version": "0.4.3-next.0", + "version": "0.4.4-next.1", "description": "Test helpers library for Backstage backends", "backstage": { "role": "node-library" diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index 6e4257b62d..0c91daa13d 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,42 @@ # example-backend +## 0.0.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-backend@1.10.9-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.4.0-next.1 + - @backstage/plugin-catalog-backend@1.24.0-next.1 + - @backstage/backend-defaults@0.3.4-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.27-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-app-backend@0.3.71-next.1 + - @backstage/plugin-auth-backend@0.22.9-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.1.19-next.1 + - @backstage/plugin-auth-backend-module-guest-provider@0.1.8-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.2.5-next.1 + - @backstage/plugin-catalog-backend-module-openapi@0.1.40-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.20-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.9-next.1 + - @backstage/plugin-devtools-backend@0.3.8-next.1 + - @backstage/plugin-kubernetes-backend@0.18.3-next.1 + - @backstage/plugin-notifications-backend@0.3.3-next.1 + - @backstage/plugin-permission-backend@0.5.46-next.1 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.19-next.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-node@0.7.33-next.1 + - @backstage/plugin-proxy-backend@0.5.3-next.1 + - @backstage/plugin-scaffolder-backend@1.23.0-next.1 + - @backstage/plugin-search-backend@1.5.14-next.1 + - @backstage/plugin-search-backend-module-catalog@0.1.28-next.1 + - @backstage/plugin-search-backend-module-explore@0.1.28-next.1 + - @backstage/plugin-search-backend-node@1.2.27-next.1 + - @backstage/plugin-signals-backend@0.1.8-next.1 + ## 0.0.28-next.0 ### Patch Changes diff --git a/packages/backend/package.json b/packages/backend/package.json index f81701a77d..8e6918bfc5 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.0.28-next.0", + "version": "0.0.28-next.1", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 0e65266410..a2fae6e3c0 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/cli +## 0.26.11-next.1 + +### Patch Changes + +- 4baac0c: The `backendPlugin` and `backendModule` factory now includes a step for automatically adding the new backend plugin/module to the `index.ts` file of the backend. +- Updated dependencies + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.6 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + - @backstage/eslint-plugin@0.1.8 + - @backstage/integration@1.13.0-next.0 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + ## 0.26.10-next.0 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index b458cf162f..393f1217e1 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/cli", - "version": "0.26.10-next.0", + "version": "0.26.11-next.1", "description": "CLI for developing Backstage plugins and apps", "backstage": { "role": "cli" diff --git a/packages/core-app-api/CHANGELOG.md b/packages/core-app-api/CHANGELOG.md index 32edc95e49..d80ed2fdcb 100644 --- a/packages/core-app-api/CHANGELOG.md +++ b/packages/core-app-api/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/core-app-api +## 1.13.1-next.1 + +### Patch Changes + +- db2e2d5: Updated config schema to support app.routes.bindings +- Updated dependencies + - @backstage/core-plugin-api@1.9.3 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 1.13.0-next.0 ### Minor Changes diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json index bdd6a1f663..35e32f9726 100644 --- a/packages/core-app-api/package.json +++ b/packages/core-app-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-app-api", "description": "Core app API used by Backstage apps", - "version": "1.13.0-next.0", + "version": "1.13.1-next.1", "publishConfig": { "access": "public" }, diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index d6ccf478a4..3f102c17da 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/create-app +## 0.5.17-next.1 + +### Patch Changes + +- 780d994: Added `MyGroupsSidebarItem` to the sidebar in the `create-app` template +- Updated dependencies + - @backstage/cli-common@0.1.14 + ## 0.5.17-next.0 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index bcbb1c5899..96be1f941c 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.17-next.0", + "version": "0.5.17-next.1", "publishConfig": { "access": "public" }, diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index d44d840187..62a5c2adc2 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/dev-utils +## 1.0.35-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.13.1-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/app-defaults@1.5.8-next.1 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/theme@0.5.6 + ## 1.0.34-next.0 ### Patch Changes diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index 43f05d62ae..3e05873d6c 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/dev-utils", - "version": "1.0.34-next.0", + "version": "1.0.35-next.1", "description": "Utilities for developing Backstage plugins.", "backstage": { "role": "web-library" diff --git a/packages/e2e-test/CHANGELOG.md b/packages/e2e-test/CHANGELOG.md index 74e22bcb63..a11001a2aa 100644 --- a/packages/e2e-test/CHANGELOG.md +++ b/packages/e2e-test/CHANGELOG.md @@ -1,5 +1,14 @@ # e2e-test +## 0.2.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.17-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + ## 0.2.18-next.0 ### Patch Changes diff --git a/packages/e2e-test/package.json b/packages/e2e-test/package.json index d63b93a7ba..d1f42a1d8f 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.18-next.0", + "version": "0.2.18-next.1", "private": true, "backstage": { "role": "cli" diff --git a/packages/frontend-app-api/CHANGELOG.md b/packages/frontend-app-api/CHANGELOG.md index 94fffd0397..fc39807e5b 100644 --- a/packages/frontend-app-api/CHANGELOG.md +++ b/packages/frontend-app-api/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/frontend-app-api +## 0.7.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.13.1-next.1 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 0.7.2-next.0 ### Patch Changes diff --git a/packages/frontend-app-api/package.json b/packages/frontend-app-api/package.json index f4290b70cc..a6c2583fbc 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.7.2-next.0", + "version": "0.7.3-next.1", "backstage": { "role": "web-library" }, diff --git a/packages/frontend-test-utils/CHANGELOG.md b/packages/frontend-test-utils/CHANGELOG.md index 04c896d246..5ece8edb86 100644 --- a/packages/frontend-test-utils/CHANGELOG.md +++ b/packages/frontend-test-utils/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/frontend-test-utils +## 0.1.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.7.3-next.1 + - @backstage/test-utils@1.5.8-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/types@1.1.1 + ## 0.1.9-next.0 ### Patch Changes diff --git a/packages/frontend-test-utils/package.json b/packages/frontend-test-utils/package.json index c7d28e99e3..9856a09367 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.9-next.0", + "version": "0.1.10-next.1", "backstage": { "role": "web-library" }, diff --git a/packages/repo-tools/CHANGELOG.md b/packages/repo-tools/CHANGELOG.md index 204437551d..daa0684e41 100644 --- a/packages/repo-tools/CHANGELOG.md +++ b/packages/repo-tools/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/repo-tools +## 0.9.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.6 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + ## 0.9.3-next.0 ### Patch Changes diff --git a/packages/repo-tools/package.json b/packages/repo-tools/package.json index 4eca696aea..cd1658b417 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.9.3-next.0", + "version": "0.9.4-next.1", "publishConfig": { "access": "public" }, diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md index 99af9b8ad0..343ecf5ccb 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.98-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.13.1-next.1 + - @backstage/plugin-catalog@1.21.1-next.1 + - @backstage/plugin-techdocs@1.10.7-next.1 + - @backstage/cli@0.26.11-next.1 + - @backstage/app-defaults@1.5.8-next.1 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/test-utils@1.5.8-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-techdocs-react@1.2.6-next.0 + ## 0.2.98-next.0 ### Patch Changes diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json index ef762bc3e2..3b234c8f4c 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.98-next.0", + "version": "0.2.98-next.1", "private": true, "backstage": { "role": "frontend" diff --git a/packages/techdocs-cli/CHANGELOG.md b/packages/techdocs-cli/CHANGELOG.md index 9fa6485f0d..0097d35ef6 100644 --- a/packages/techdocs-cli/CHANGELOG.md +++ b/packages/techdocs-cli/CHANGELOG.md @@ -1,5 +1,16 @@ # @techdocs/cli +## 1.8.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.8-next.1 + - @backstage/backend-defaults@0.3.4-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + ## 1.8.15-next.0 ### Patch Changes diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index e1f00726af..d947af0ee8 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.15-next.0", + "version": "1.8.16-next.1", "publishConfig": { "access": "public" }, diff --git a/packages/test-utils/CHANGELOG.md b/packages/test-utils/CHANGELOG.md index c19d0cd4af..6a038fd0d8 100644 --- a/packages/test-utils/CHANGELOG.md +++ b/packages/test-utils/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/test-utils +## 1.5.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.13.1-next.1 + - @backstage/core-plugin-api@1.9.3 + - @backstage/config@1.2.0 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-react@0.4.23 + ## 1.5.7-next.0 ### Patch Changes diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index a1e642dd89..9cf0c7a6a7 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/test-utils", - "version": "1.5.7-next.0", + "version": "1.5.8-next.1", "description": "Utilities to test Backstage plugins and apps.", "backstage": { "role": "web-library" diff --git a/plugins/api-docs/CHANGELOG.md b/plugins/api-docs/CHANGELOG.md index 80aaf0dbc7..f41b4534f1 100644 --- a/plugins/api-docs/CHANGELOG.md +++ b/plugins/api-docs/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-api-docs +## 0.11.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/plugin-catalog@1.21.1-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-react@0.4.23 + ## 0.11.7-next.0 ### Patch Changes diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 5a64e41e19..84e2891bcc 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-api-docs", - "version": "0.11.7-next.0", + "version": "0.11.7-next.1", "description": "A Backstage plugin that helps represent API entities in the frontend", "backstage": { "role": "frontend-plugin", diff --git a/plugins/app-backend/CHANGELOG.md b/plugins/app-backend/CHANGELOG.md index a898805ef2..b472d51f0f 100644 --- a/plugins/app-backend/CHANGELOG.md +++ b/plugins/app-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-app-backend +## 0.3.71-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + ## 0.3.70-next.0 ### Patch Changes diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json index 50c7d98d55..0d44e3dc61 100644 --- a/plugins/app-backend/package.json +++ b/plugins/app-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-app-backend", - "version": "0.3.70-next.0", + "version": "0.3.71-next.1", "description": "A Backstage backend plugin that serves the Backstage frontend app", "backstage": { "role": "backend-plugin", diff --git a/plugins/app-node/CHANGELOG.md b/plugins/app-node/CHANGELOG.md index 71d34825c0..e5ff0eb99f 100644 --- a/plugins/app-node/CHANGELOG.md +++ b/plugins/app-node/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-app-node +## 0.1.22-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config-loader@1.8.1 + ## 0.1.21-next.0 ### Patch Changes diff --git a/plugins/app-node/package.json b/plugins/app-node/package.json index e7d639d620..11ddf46cf8 100644 --- a/plugins/app-node/package.json +++ b/plugins/app-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-app-node", - "version": "0.1.21-next.0", + "version": "0.1.22-next.1", "description": "Node.js library for the app plugin", "backstage": { "role": "node-library", diff --git a/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md b/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md index aadbd252ed..0449bc6933 100644 --- a/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-atlassian-provider +## 0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + ## 0.2.2-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-atlassian-provider/package.json b/plugins/auth-backend-module-atlassian-provider/package.json index 9ceec32602..d938144603 100644 --- a/plugins/auth-backend-module-atlassian-provider/package.json +++ b/plugins/auth-backend-module-atlassian-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-atlassian-provider", - "version": "0.2.2-next.0", + "version": "0.2.3-next.1", "description": "The atlassian-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md b/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md index 747f13b972..f1ae8a4981 100644 --- a/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-auth-backend-module-aws-alb-provider +## 0.1.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-backend@0.22.9-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + ## 0.1.13-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-aws-alb-provider/package.json b/plugins/auth-backend-module-aws-alb-provider/package.json index 500914eb64..6ee5c274c1 100644 --- a/plugins/auth-backend-module-aws-alb-provider/package.json +++ b/plugins/auth-backend-module-aws-alb-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-aws-alb-provider", - "version": "0.1.13-next.0", + "version": "0.1.14-next.1", "description": "The aws-alb provider module for the Backstage auth backend.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md b/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md index 7067eb6b14..5e78ec6abb 100644 --- a/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-azure-easyauth-provider +## 0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.17-next.1 + ## 0.1.4-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-azure-easyauth-provider/package.json b/plugins/auth-backend-module-azure-easyauth-provider/package.json index b505a45804..287059eb8f 100644 --- a/plugins/auth-backend-module-azure-easyauth-provider/package.json +++ b/plugins/auth-backend-module-azure-easyauth-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-azure-easyauth-provider", - "version": "0.1.4-next.0", + "version": "0.1.5-next.1", "description": "The azure-easyauth-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md b/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md index f337ee2c87..33b434f86e 100644 --- a/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-bitbucket-provider +## 0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + ## 0.1.4-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-bitbucket-provider/package.json b/plugins/auth-backend-module-bitbucket-provider/package.json index 70a5265b87..95189d2cea 100644 --- a/plugins/auth-backend-module-bitbucket-provider/package.json +++ b/plugins/auth-backend-module-bitbucket-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-bitbucket-provider", - "version": "0.1.4-next.0", + "version": "0.1.5-next.1", "description": "The bitbucket-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md b/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md index e94bb32963..9754e9a73a 100644 --- a/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-cloudflare-access-provider +## 0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.17-next.1 + ## 0.1.4-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-cloudflare-access-provider/package.json b/plugins/auth-backend-module-cloudflare-access-provider/package.json index 076c94b37c..b0cd52d022 100644 --- a/plugins/auth-backend-module-cloudflare-access-provider/package.json +++ b/plugins/auth-backend-module-cloudflare-access-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-cloudflare-access-provider", - "version": "0.1.4-next.0", + "version": "0.1.5-next.1", "description": "The cloudflare-access-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md b/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md index c593dbacf8..8fe2c331a4 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-gcp-iap-provider +## 0.2.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + ## 0.2.16-next.0 ### 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 bd97b9094d..8e00b9e935 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/package.json +++ b/plugins/auth-backend-module-gcp-iap-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-gcp-iap-provider", - "version": "0.2.16-next.0", + "version": "0.2.17-next.1", "description": "A GCP IAP auth provider module for the Backstage auth backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-github-provider/CHANGELOG.md b/plugins/auth-backend-module-github-provider/CHANGELOG.md index 8461d67843..f73e6adf3c 100644 --- a/plugins/auth-backend-module-github-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-github-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-github-provider +## 0.1.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + ## 0.1.18-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-github-provider/package.json b/plugins/auth-backend-module-github-provider/package.json index 8a813883ce..138aaa4e02 100644 --- a/plugins/auth-backend-module-github-provider/package.json +++ b/plugins/auth-backend-module-github-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-github-provider", - "version": "0.1.18-next.0", + "version": "0.1.19-next.1", "description": "The github-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md b/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md index 5d84c75f92..a8d5844847 100644 --- a/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-gitlab-provider +## 0.1.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + ## 0.1.18-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-gitlab-provider/package.json b/plugins/auth-backend-module-gitlab-provider/package.json index 4dd9548f98..97e680237c 100644 --- a/plugins/auth-backend-module-gitlab-provider/package.json +++ b/plugins/auth-backend-module-gitlab-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-gitlab-provider", - "version": "0.1.18-next.0", + "version": "0.1.19-next.1", "description": "The gitlab-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-google-provider/CHANGELOG.md b/plugins/auth-backend-module-google-provider/CHANGELOG.md index 0cef76c81c..e7eeb2779c 100644 --- a/plugins/auth-backend-module-google-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-google-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-google-provider +## 0.1.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + ## 0.1.18-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-google-provider/package.json b/plugins/auth-backend-module-google-provider/package.json index fdf8eb6728..55b2616502 100644 --- a/plugins/auth-backend-module-google-provider/package.json +++ b/plugins/auth-backend-module-google-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-google-provider", - "version": "0.1.18-next.0", + "version": "0.1.19-next.1", "description": "A Google auth provider module for the Backstage auth backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-guest-provider/CHANGELOG.md b/plugins/auth-backend-module-guest-provider/CHANGELOG.md index 5d9a1ac2c8..fd046e8dca 100644 --- a/plugins/auth-backend-module-guest-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-guest-provider/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-auth-backend-module-guest-provider +## 0.1.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.17-next.1 + ## 0.1.7-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-guest-provider/package.json b/plugins/auth-backend-module-guest-provider/package.json index 7f569c1f74..78fbd098f6 100644 --- a/plugins/auth-backend-module-guest-provider/package.json +++ b/plugins/auth-backend-module-guest-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-guest-provider", - "version": "0.1.7-next.0", + "version": "0.1.8-next.1", "description": "The guest-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md b/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md index 48ea704e10..668047c816 100644 --- a/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-microsoft-provider +## 0.1.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + ## 0.1.16-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-microsoft-provider/package.json b/plugins/auth-backend-module-microsoft-provider/package.json index abdb555bb1..76d3236f8b 100644 --- a/plugins/auth-backend-module-microsoft-provider/package.json +++ b/plugins/auth-backend-module-microsoft-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-microsoft-provider", - "version": "0.1.16-next.0", + "version": "0.1.17-next.1", "description": "The microsoft-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md b/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md index b0d7371bbe..9872a64385 100644 --- a/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-oauth2-provider +## 0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + ## 0.2.2-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-oauth2-provider/package.json b/plugins/auth-backend-module-oauth2-provider/package.json index b3f7d2ddfe..71934913fe 100644 --- a/plugins/auth-backend-module-oauth2-provider/package.json +++ b/plugins/auth-backend-module-oauth2-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-oauth2-provider", - "version": "0.2.2-next.0", + "version": "0.2.3-next.1", "description": "The oauth2-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md b/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md index 52480f24f3..895ada0e6e 100644 --- a/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-oauth2-proxy-provider +## 0.1.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.17-next.1 + ## 0.1.14-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-oauth2-proxy-provider/package.json b/plugins/auth-backend-module-oauth2-proxy-provider/package.json index 717d4ba09a..4123403eb2 100644 --- a/plugins/auth-backend-module-oauth2-proxy-provider/package.json +++ b/plugins/auth-backend-module-oauth2-proxy-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-oauth2-proxy-provider", - "version": "0.1.14-next.0", + "version": "0.1.15-next.1", "description": "The oauth2-proxy-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-oidc-provider/CHANGELOG.md b/plugins/auth-backend-module-oidc-provider/CHANGELOG.md index a9f175f316..b9f8ffc98d 100644 --- a/plugins/auth-backend-module-oidc-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oidc-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-oidc-provider +## 0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-auth-backend@0.22.9-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + ## 0.2.2-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-oidc-provider/package.json b/plugins/auth-backend-module-oidc-provider/package.json index 95c5ff49f8..34e6c6f296 100644 --- a/plugins/auth-backend-module-oidc-provider/package.json +++ b/plugins/auth-backend-module-oidc-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-oidc-provider", - "version": "0.2.2-next.0", + "version": "0.2.3-next.1", "description": "The oidc-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-okta-provider/CHANGELOG.md b/plugins/auth-backend-module-okta-provider/CHANGELOG.md index c2fb212b1c..dfb5f638bf 100644 --- a/plugins/auth-backend-module-okta-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-okta-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-okta-provider +## 0.0.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + ## 0.0.14-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-okta-provider/package.json b/plugins/auth-backend-module-okta-provider/package.json index 16bbb79a44..cf099d40ee 100644 --- a/plugins/auth-backend-module-okta-provider/package.json +++ b/plugins/auth-backend-module-okta-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-okta-provider", - "version": "0.0.14-next.0", + "version": "0.0.15-next.1", "description": "The okta-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md b/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md index ed302347c4..8e21a1868e 100644 --- a/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-onelogin-provider +## 0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + ## 0.1.2-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-onelogin-provider/package.json b/plugins/auth-backend-module-onelogin-provider/package.json index 54606d26f3..ac6a38a4f5 100644 --- a/plugins/auth-backend-module-onelogin-provider/package.json +++ b/plugins/auth-backend-module-onelogin-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-onelogin-provider", - "version": "0.1.2-next.0", + "version": "0.1.3-next.1", "description": "The onelogin-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md b/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md index 175d786367..4435efc501 100644 --- a/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-pinniped-provider +## 0.1.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-auth-node@0.4.17-next.1 + ## 0.1.15-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-pinniped-provider/package.json b/plugins/auth-backend-module-pinniped-provider/package.json index 0b78dc7dd1..2698a56a2e 100644 --- a/plugins/auth-backend-module-pinniped-provider/package.json +++ b/plugins/auth-backend-module-pinniped-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-pinniped-provider", - "version": "0.1.15-next.0", + "version": "0.1.16-next.1", "description": "The pinniped-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md b/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md index c6b724bdd6..edfc30c099 100644 --- a/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-vmware-cloud-provider +## 0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-auth-node@0.4.17-next.1 + ## 0.2.2-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-vmware-cloud-provider/package.json b/plugins/auth-backend-module-vmware-cloud-provider/package.json index 78fbccdd1f..d6b7eaf263 100644 --- a/plugins/auth-backend-module-vmware-cloud-provider/package.json +++ b/plugins/auth-backend-module-vmware-cloud-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-vmware-cloud-provider", - "version": "0.2.2-next.0", + "version": "0.2.3-next.1", "description": "The vmware-cloud-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md index 98454b2c65..2bb083ed66 100644 --- a/plugins/auth-backend/CHANGELOG.md +++ b/plugins/auth-backend/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-auth-backend +## 0.22.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.2.3-next.1 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.14-next.1 + - @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.1.5-next.1 + - @backstage/plugin-auth-backend-module-bitbucket-provider@0.1.5-next.1 + - @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.1.5-next.1 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.17-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.1.19-next.1 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.19-next.1 + - @backstage/plugin-auth-backend-module-google-provider@0.1.19-next.1 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.1.17-next.1 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.2.3-next.1 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.15-next.1 + - @backstage/plugin-auth-backend-module-oidc-provider@0.2.3-next.1 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.15-next.1 + - @backstage/plugin-auth-backend-module-onelogin-provider@0.1.3-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-catalog-node@1.12.4-next.1 + ## 0.22.8-next.0 ### Patch Changes diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index e14d4de6b0..cd31a18064 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend", - "version": "0.22.8-next.0", + "version": "0.22.9-next.1", "description": "A Backstage backend plugin that handles authentication", "backstage": { "role": "backend-plugin", diff --git a/plugins/auth-node/CHANGELOG.md b/plugins/auth-node/CHANGELOG.md index 5c775a6bc3..e931a1c26a 100644 --- a/plugins/auth-node/CHANGELOG.md +++ b/plugins/auth-node/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-auth-node +## 0.4.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.4.16-next.0 ### Patch Changes diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index c9b956def6..ab84eb7fe6 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.16-next.0", + "version": "0.4.17-next.1", "backstage": { "role": "node-library", "pluginId": "auth", diff --git a/plugins/catalog-backend-module-aws/CHANGELOG.md b/plugins/catalog-backend-module-aws/CHANGELOG.md index bd5663758a..15f944de19 100644 --- a/plugins/catalog-backend-module-aws/CHANGELOG.md +++ b/plugins/catalog-backend-module-aws/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-catalog-backend-module-aws +## 0.3.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-kubernetes-common@0.8.0 + ## 0.3.16-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-aws/package.json b/plugins/catalog-backend-module-aws/package.json index 3b75c3cfcd..7081b09d2b 100644 --- a/plugins/catalog-backend-module-aws/package.json +++ b/plugins/catalog-backend-module-aws/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-aws", - "version": "0.3.16-next.0", + "version": "0.3.17-next.1", "description": "A Backstage catalog backend module that helps integrate towards AWS", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-azure/CHANGELOG.md b/plugins/catalog-backend-module-azure/CHANGELOG.md index 598636a239..1f672302ac 100644 --- a/plugins/catalog-backend-module-azure/CHANGELOG.md +++ b/plugins/catalog-backend-module-azure/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-azure +## 0.1.42-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/config@1.2.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + ## 0.1.41-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-azure/package.json b/plugins/catalog-backend-module-azure/package.json index bf0b69f177..1159aff6db 100644 --- a/plugins/catalog-backend-module-azure/package.json +++ b/plugins/catalog-backend-module-azure/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-azure", - "version": "0.1.41-next.0", + "version": "0.1.42-next.1", "description": "A Backstage catalog backend module that helps integrate towards Azure", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md b/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md index fa23d67c67..125778b4b6 100644 --- a/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-backstage-openapi +## 0.2.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-openapi-utils@0.1.15-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.4-next.1 + ## 0.2.4-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-backstage-openapi/package.json b/plugins/catalog-backend-module-backstage-openapi/package.json index 4d06de5ddb..fad1dc47c9 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.2.4-next.0", + "version": "0.2.5-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "catalog", diff --git a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md index 2a977a4f7b..4ad56f2aa3 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-catalog-backend-module-bitbucket-cloud +## 0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.21-next.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + ## 0.2.8-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-cloud/package.json b/plugins/catalog-backend-module-bitbucket-cloud/package.json index d0261ad01f..e691c2a3c3 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/package.json +++ b/plugins/catalog-backend-module-bitbucket-cloud/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-cloud", - "version": "0.2.8-next.0", + "version": "0.2.9-next.1", "description": "A Backstage catalog backend module that helps integrate towards Bitbucket Cloud", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md index f395e731ec..a5901702ff 100644 --- a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-bitbucket-server +## 0.1.36-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-node@1.12.4-next.1 + ## 0.1.35-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-server/package.json b/plugins/catalog-backend-module-bitbucket-server/package.json index 4d2e0a1e78..4e47fcbdcc 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.35-next.0", + "version": "0.1.36-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "catalog", diff --git a/plugins/catalog-backend-module-gcp/CHANGELOG.md b/plugins/catalog-backend-module-gcp/CHANGELOG.md index 5948b92338..b76bc9d7a9 100644 --- a/plugins/catalog-backend-module-gcp/CHANGELOG.md +++ b/plugins/catalog-backend-module-gcp/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-gcp +## 0.1.23-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-kubernetes-common@0.8.0 + ## 0.1.22-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-gcp/package.json b/plugins/catalog-backend-module-gcp/package.json index 5cfcca3ba9..0888a9eb03 100644 --- a/plugins/catalog-backend-module-gcp/package.json +++ b/plugins/catalog-backend-module-gcp/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gcp", - "version": "0.1.22-next.0", + "version": "0.1.23-next.1", "description": "A Backstage catalog backend module that helps integrate towards GCP", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-gerrit/CHANGELOG.md b/plugins/catalog-backend-module-gerrit/CHANGELOG.md index 5cab7509bc..6492e65ffa 100644 --- a/plugins/catalog-backend-module-gerrit/CHANGELOG.md +++ b/plugins/catalog-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-gerrit +## 0.1.39-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-node@1.12.4-next.1 + ## 0.1.38-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-gerrit/package.json b/plugins/catalog-backend-module-gerrit/package.json index 7bac2566da..b99347e6f5 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.38-next.0", + "version": "0.1.39-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "catalog", diff --git a/plugins/catalog-backend-module-github-org/CHANGELOG.md b/plugins/catalog-backend-module-github-org/CHANGELOG.md index 950185b415..0236b1d30c 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.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-github@0.6.5-next.1 + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + ## 0.1.16-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-github-org/package.json b/plugins/catalog-backend-module-github-org/package.json index 31daeea5ee..abd92889a0 100644 --- a/plugins/catalog-backend-module-github-org/package.json +++ b/plugins/catalog-backend-module-github-org/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-github-org", - "version": "0.1.16-next.0", + "version": "0.1.17-next.1", "description": "The github-org backend module for the catalog plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-github/CHANGELOG.md b/plugins/catalog-backend-module-github/CHANGELOG.md index d9dc710268..02975d2b68 100644 --- a/plugins/catalog-backend-module-github/CHANGELOG.md +++ b/plugins/catalog-backend-module-github/CHANGELOG.md @@ -1,5 +1,49 @@ # @backstage/plugin-catalog-backend-module-github +## 0.6.5-next.1 + +### Patch Changes + +- 9112efc: Adds support for `repository` events. + + The provider adds a subscription to the topic `github.repository`. + + Hereby, it supports events of type `repository` with actions + + - `archived` + - `deleted` + - `edited` + - `renamed` + - `transferred` + - `unarchived` + + Actions skipped as they don't require entity changes: + + - `created` + - `privatized` + - `publicized` + + If the config option `validateLocationsExist` is enabled, an API request + is necessary and will be executed. + This affects the actions `renamed`, `transferred`, and `unarchive` + of event type `repository`. + + Catalog entities related to the `GithubEntityProvider` instance will be adjusted + according to action and its meaning for them. + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.24.0-next.1 + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + ## 0.6.4-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-github/package.json b/plugins/catalog-backend-module-github/package.json index 3528786e6d..c8b78c5e92 100644 --- a/plugins/catalog-backend-module-github/package.json +++ b/plugins/catalog-backend-module-github/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-github", - "version": "0.6.4-next.0", + "version": "0.6.5-next.1", "description": "A Backstage catalog backend module that helps integrate towards GitHub", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md b/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md index 3ce5fef0b4..d86cb76c24 100644 --- a/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md +++ b/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-catalog-backend-module-gitlab-org +## 0.0.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-catalog-backend-module-gitlab@0.3.21-next.1 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + ## 0.0.4-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-gitlab-org/package.json b/plugins/catalog-backend-module-gitlab-org/package.json index 0861d4ec92..a08a42d1f3 100644 --- a/plugins/catalog-backend-module-gitlab-org/package.json +++ b/plugins/catalog-backend-module-gitlab-org/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gitlab-org", - "version": "0.0.4-next.0", + "version": "0.0.5-next.1", "description": "The gitlab-org backend module for the catalog plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-gitlab/CHANGELOG.md b/plugins/catalog-backend-module-gitlab/CHANGELOG.md index 6fd86bb15d..8d6eb4bfef 100644 --- a/plugins/catalog-backend-module-gitlab/CHANGELOG.md +++ b/plugins/catalog-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-backend-module-gitlab +## 0.3.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + ## 0.3.20-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-gitlab/package.json b/plugins/catalog-backend-module-gitlab/package.json index 51538cc178..0780ccdd6a 100644 --- a/plugins/catalog-backend-module-gitlab/package.json +++ b/plugins/catalog-backend-module-gitlab/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gitlab", - "version": "0.3.20-next.0", + "version": "0.3.21-next.1", "description": "A Backstage catalog backend module that helps integrate towards GitLab", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md index 04da7cc46e..9cd19e259e 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md +++ b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-catalog-backend-module-incremental-ingestion +## 0.4.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.24.0-next.1 + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + - @backstage/plugin-permission-common@0.7.14 + ## 0.4.26-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-incremental-ingestion/package.json b/plugins/catalog-backend-module-incremental-ingestion/package.json index 2941fcd3f4..c9cf1f5a82 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/package.json +++ b/plugins/catalog-backend-module-incremental-ingestion/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-incremental-ingestion", - "version": "0.4.26-next.0", + "version": "0.4.27-next.1", "description": "An entity provider for streaming large asset sources into the catalog", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-ldap/CHANGELOG.md b/plugins/catalog-backend-module-ldap/CHANGELOG.md index b975322d0d..6842b99282 100644 --- a/plugins/catalog-backend-module-ldap/CHANGELOG.md +++ b/plugins/catalog-backend-module-ldap/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-catalog-backend-module-ldap +## 0.7.0-next.1 + +### Minor Changes + +- cb32ca7: **BREAKING**: `readLdapOrg` and the `LdapProviderConfig` type now always accept arrays of user and group configs, not just single items. + + Added support for single ldap catalog provider to provide list and undefined user and group bindings next to standard single one. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + ## 0.6.2-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-ldap/package.json b/plugins/catalog-backend-module-ldap/package.json index f719673682..411f168fd8 100644 --- a/plugins/catalog-backend-module-ldap/package.json +++ b/plugins/catalog-backend-module-ldap/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-ldap", - "version": "0.6.2-next.0", + "version": "0.7.0-next.1", "description": "A Backstage catalog backend module that helps integrate towards LDAP", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-logs/CHANGELOG.md b/plugins/catalog-backend-module-logs/CHANGELOG.md index 7e5ae51a99..c609fc369d 100644 --- a/plugins/catalog-backend-module-logs/CHANGELOG.md +++ b/plugins/catalog-backend-module-logs/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-catalog-backend-module-logs +## 0.0.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.24.0-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + ## 0.0.1-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-logs/package.json b/plugins/catalog-backend-module-logs/package.json index e0d2e46c78..fe3f09c29c 100644 --- a/plugins/catalog-backend-module-logs/package.json +++ b/plugins/catalog-backend-module-logs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-logs", - "version": "0.0.1-next.0", + "version": "0.0.1-next.1", "description": "A module that subscribes to catalog releated events and logs them.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-msgraph/CHANGELOG.md b/plugins/catalog-backend-module-msgraph/CHANGELOG.md index 0f74e4591b..eb3591241f 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.30-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + ## 0.5.29-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json index 7ba2b7e1e6..b04cd8788c 100644 --- a/plugins/catalog-backend-module-msgraph/package.json +++ b/plugins/catalog-backend-module-msgraph/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-msgraph", - "version": "0.5.29-next.0", + "version": "0.5.30-next.1", "description": "A Backstage catalog backend module that helps integrate towards Microsoft Graph", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-openapi/CHANGELOG.md b/plugins/catalog-backend-module-openapi/CHANGELOG.md index 8003dc39ac..bf35045dcc 100644 --- a/plugins/catalog-backend-module-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-openapi/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-backend-module-openapi +## 0.1.40-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.24.0-next.1 + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + ## 0.1.39-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-openapi/package.json b/plugins/catalog-backend-module-openapi/package.json index 7016701fc0..b37cb09b15 100644 --- a/plugins/catalog-backend-module-openapi/package.json +++ b/plugins/catalog-backend-module-openapi/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-openapi", - "version": "0.1.39-next.0", + "version": "0.1.40-next.1", "description": "A Backstage catalog backend module that helps with OpenAPI specifications", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-puppetdb/CHANGELOG.md b/plugins/catalog-backend-module-puppetdb/CHANGELOG.md index 4e5b25479a..ead44a56aa 100644 --- a/plugins/catalog-backend-module-puppetdb/CHANGELOG.md +++ b/plugins/catalog-backend-module-puppetdb/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-puppetdb +## 0.1.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.12.4-next.1 + ## 0.1.27-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-puppetdb/package.json b/plugins/catalog-backend-module-puppetdb/package.json index 1759eebb14..114daa45e8 100644 --- a/plugins/catalog-backend-module-puppetdb/package.json +++ b/plugins/catalog-backend-module-puppetdb/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-puppetdb", - "version": "0.1.27-next.0", + "version": "0.1.28-next.1", "description": "A Backstage catalog backend module that helps integrate towards PuppetDB", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md b/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md index df4e93de73..758d59c7c0 100644 --- a/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md +++ b/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-catalog-backend-module-scaffolder-entity-model +## 0.1.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-scaffolder-common@1.5.3 + ## 0.1.19-next.0 ### 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 a2891d2d4d..58bcdc6fb5 100644 --- a/plugins/catalog-backend-module-scaffolder-entity-model/package.json +++ b/plugins/catalog-backend-module-scaffolder-entity-model/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-scaffolder-entity-model", - "version": "0.1.19-next.0", + "version": "0.1.20-next.1", "description": "Adds support for the scaffolder specific entity model (e.g. the Template kind) to the catalog backend plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-unprocessed/CHANGELOG.md b/plugins/catalog-backend-module-unprocessed/CHANGELOG.md index 6940a04db9..afac0ebeed 100644 --- a/plugins/catalog-backend-module-unprocessed/CHANGELOG.md +++ b/plugins/catalog-backend-module-unprocessed/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-unprocessed +## 0.4.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.2 + - @backstage/plugin-permission-common@0.7.14 + ## 0.4.8-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-unprocessed/package.json b/plugins/catalog-backend-module-unprocessed/package.json index 582be2ffe8..c49a3d700d 100644 --- a/plugins/catalog-backend-module-unprocessed/package.json +++ b/plugins/catalog-backend-module-unprocessed/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-unprocessed", - "version": "0.4.8-next.0", + "version": "0.4.9-next.1", "description": "Backstage Catalog module to view unprocessed entities", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md index 16442df3c1..65ed28cb6d 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-catalog-backend +## 1.24.0-next.1 + +### Minor Changes + +- b9ed1bb: bumped better-sqlite3 from ^9.0.0 to ^11.0.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-openapi-utils@0.1.15-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-node@0.7.33-next.1 + - @backstage/plugin-search-backend-module-catalog@0.1.28-next.1 + ## 1.23.2-next.0 ### Patch Changes diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 596e51435e..e554f0a334 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend", - "version": "1.23.2-next.0", + "version": "1.24.0-next.1", "description": "The Backstage backend plugin that provides the Backstage catalog", "backstage": { "role": "backend-plugin", diff --git a/plugins/catalog-graph/CHANGELOG.md b/plugins/catalog-graph/CHANGELOG.md index c632769632..fd2b0477e0 100644 --- a/plugins/catalog-graph/CHANGELOG.md +++ b/plugins/catalog-graph/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-graph +## 0.4.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/types@1.1.1 + ## 0.4.7-next.0 ### Patch Changes diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json index 82f3e5d171..22e30e3406 100644 --- a/plugins/catalog-graph/package.json +++ b/plugins/catalog-graph/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-graph", - "version": "0.4.7-next.0", + "version": "0.4.7-next.1", "backstage": { "role": "frontend-plugin", "pluginId": "catalog-graph", diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md index bbb56b6f08..bebc0c5240 100644 --- a/plugins/catalog-import/CHANGELOG.md +++ b/plugins/catalog-import/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-catalog-import +## 0.12.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-catalog-common@1.0.24 + ## 0.12.1-next.0 ### Patch Changes diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index 1082f08113..704fdae2e6 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-import", - "version": "0.12.1-next.0", + "version": "0.12.1-next.1", "description": "A Backstage plugin the helps you import entities into your catalog", "backstage": { "role": "frontend-plugin", diff --git a/plugins/catalog-node/CHANGELOG.md b/plugins/catalog-node/CHANGELOG.md index f23bfa9917..54f39e9e51 100644 --- a/plugins/catalog-node/CHANGELOG.md +++ b/plugins/catalog-node/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-node +## 1.12.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-node@0.7.33-next.1 + ## 1.12.3-next.0 ### Patch Changes diff --git a/plugins/catalog-node/package.json b/plugins/catalog-node/package.json index 293b915eea..575a1c65f5 100644 --- a/plugins/catalog-node/package.json +++ b/plugins/catalog-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-node", - "version": "1.12.3-next.0", + "version": "1.12.4-next.1", "description": "The plugin-catalog-node module for @backstage/plugin-catalog-backend", "backstage": { "role": "node-library", diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md index 892bfe306d..68febf6b12 100644 --- a/plugins/catalog-react/CHANGELOG.md +++ b/plugins/catalog-react/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-catalog-react +## 1.12.2-next.1 + +### Patch Changes + +- 06c0956: Support i18n for catalog and catalog-react plugins +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-react@0.4.23 + ## 1.12.2-next.0 ### Patch Changes diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index 8267047b2d..99eb8af013 100644 --- a/plugins/catalog-react/package.json +++ b/plugins/catalog-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-react", - "version": "1.12.2-next.0", + "version": "1.12.2-next.1", "description": "A frontend library that helps other Backstage plugins interact with the catalog", "backstage": { "role": "web-library", diff --git a/plugins/catalog/CHANGELOG.md b/plugins/catalog/CHANGELOG.md index 9c6031799c..d003afccf1 100644 --- a/plugins/catalog/CHANGELOG.md +++ b/plugins/catalog/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-catalog +## 1.21.1-next.1 + +### Patch Changes + +- 06c0956: Support i18n for catalog and catalog-react plugins +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-react@0.4.23 + - @backstage/plugin-scaffolder-common@1.5.3 + - @backstage/plugin-search-common@1.2.12 + ## 1.21.1-next.0 ### Patch Changes diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index 7cafc9cf92..5cf63e86ab 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog", - "version": "1.21.1-next.0", + "version": "1.21.1-next.1", "description": "The Backstage plugin for browsing the Backstage catalog", "backstage": { "role": "frontend-plugin", diff --git a/plugins/devtools-backend/CHANGELOG.md b/plugins/devtools-backend/CHANGELOG.md index 94c827d2f3..cc0dc806c8 100644 --- a/plugins/devtools-backend/CHANGELOG.md +++ b/plugins/devtools-backend/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-devtools-backend +## 0.3.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.10 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-node@0.7.33-next.1 + ## 0.3.7-next.0 ### Patch Changes diff --git a/plugins/devtools-backend/package.json b/plugins/devtools-backend/package.json index f15e205bca..bd3b61f22d 100644 --- a/plugins/devtools-backend/package.json +++ b/plugins/devtools-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-devtools-backend", - "version": "0.3.7-next.0", + "version": "0.3.8-next.1", "backstage": { "role": "backend-plugin", "pluginId": "devtools", diff --git a/plugins/events-backend-module-aws-sqs/CHANGELOG.md b/plugins/events-backend-module-aws-sqs/CHANGELOG.md index 677cdddcfc..399ed2689d 100644 --- a/plugins/events-backend-module-aws-sqs/CHANGELOG.md +++ b/plugins/events-backend-module-aws-sqs/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-events-backend-module-aws-sqs +## 0.3.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.8-next.1 + ## 0.3.7-next.0 ### Patch Changes diff --git a/plugins/events-backend-module-aws-sqs/package.json b/plugins/events-backend-module-aws-sqs/package.json index 9cba8e76e3..b2c09d3b8a 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.3.7-next.0", + "version": "0.3.8-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-azure/CHANGELOG.md b/plugins/events-backend-module-azure/CHANGELOG.md index cea3fab2b6..5e5ccffc2a 100644 --- a/plugins/events-backend-module-azure/CHANGELOG.md +++ b/plugins/events-backend-module-azure/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-events-backend-module-azure +## 0.2.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + ## 0.2.7-next.0 ### Patch Changes diff --git a/plugins/events-backend-module-azure/package.json b/plugins/events-backend-module-azure/package.json index 74573116d7..8bb6ac4f6b 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.2.7-next.0", + "version": "0.2.8-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md index eac1919f41..1a339c3807 100644 --- a/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-events-backend-module-bitbucket-cloud +## 0.2.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + ## 0.2.7-next.0 ### Patch Changes diff --git a/plugins/events-backend-module-bitbucket-cloud/package.json b/plugins/events-backend-module-bitbucket-cloud/package.json index 471ecb4ae2..7efffdd361 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.2.7-next.0", + "version": "0.2.8-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-gerrit/CHANGELOG.md b/plugins/events-backend-module-gerrit/CHANGELOG.md index cb5ac5662f..78963fbbaf 100644 --- a/plugins/events-backend-module-gerrit/CHANGELOG.md +++ b/plugins/events-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-events-backend-module-gerrit +## 0.2.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + ## 0.2.7-next.0 ### Patch Changes diff --git a/plugins/events-backend-module-gerrit/package.json b/plugins/events-backend-module-gerrit/package.json index dbff36987a..f1bea2868c 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.2.7-next.0", + "version": "0.2.8-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-github/CHANGELOG.md b/plugins/events-backend-module-github/CHANGELOG.md index e2511f76ba..a095cf4ab3 100644 --- a/plugins/events-backend-module-github/CHANGELOG.md +++ b/plugins/events-backend-module-github/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-events-backend-module-github +## 0.2.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.8-next.1 + ## 0.2.7-next.0 ### Patch Changes diff --git a/plugins/events-backend-module-github/package.json b/plugins/events-backend-module-github/package.json index 126da9f29c..3b37f29022 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.2.7-next.0", + "version": "0.2.8-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-gitlab/CHANGELOG.md b/plugins/events-backend-module-gitlab/CHANGELOG.md index 89d2f47c10..dc8470bd7a 100644 --- a/plugins/events-backend-module-gitlab/CHANGELOG.md +++ b/plugins/events-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-events-backend-module-gitlab +## 0.2.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.8-next.1 + ## 0.2.7-next.0 ### Patch Changes diff --git a/plugins/events-backend-module-gitlab/package.json b/plugins/events-backend-module-gitlab/package.json index 45a9637a24..21c95448b1 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.2.7-next.0", + "version": "0.2.8-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-test-utils/CHANGELOG.md b/plugins/events-backend-test-utils/CHANGELOG.md index e0f42a6f24..967ffc80da 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.32-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.8-next.1 + ## 0.1.31-next.0 ### Patch Changes diff --git a/plugins/events-backend-test-utils/package.json b/plugins/events-backend-test-utils/package.json index 931cb89248..120c7f5fa6 100644 --- a/plugins/events-backend-test-utils/package.json +++ b/plugins/events-backend-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-test-utils", - "version": "0.1.31-next.0", + "version": "0.1.32-next.1", "description": "The plugin-events-backend-test-utils for @backstage/plugin-events-node", "backstage": { "role": "node-library", diff --git a/plugins/events-backend/CHANGELOG.md b/plugins/events-backend/CHANGELOG.md index a0e1f91a23..a4b4b550bb 100644 --- a/plugins/events-backend/CHANGELOG.md +++ b/plugins/events-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-events-backend +## 0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.8-next.1 + ## 0.3.8-next.0 ### Patch Changes diff --git a/plugins/events-backend/package.json b/plugins/events-backend/package.json index b176044bf9..82066d5a91 100644 --- a/plugins/events-backend/package.json +++ b/plugins/events-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend", - "version": "0.3.8-next.0", + "version": "0.3.9-next.1", "backstage": { "role": "backend-plugin", "pluginId": "events", diff --git a/plugins/events-node/CHANGELOG.md b/plugins/events-node/CHANGELOG.md index 1c5025b788..022d50fdd1 100644 --- a/plugins/events-node/CHANGELOG.md +++ b/plugins/events-node/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-events-node +## 0.3.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + ## 0.3.7-next.0 ### Patch Changes diff --git a/plugins/events-node/package.json b/plugins/events-node/package.json index 58790c4e02..f89617dd14 100644 --- a/plugins/events-node/package.json +++ b/plugins/events-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-node", - "version": "0.3.7-next.0", + "version": "0.3.8-next.1", "description": "The plugin-events-node module for @backstage/plugin-events-backend", "backstage": { "role": "node-library", diff --git a/plugins/example-todo-list-backend/CHANGELOG.md b/plugins/example-todo-list-backend/CHANGELOG.md index f42ba59723..d1553258ed 100644 --- a/plugins/example-todo-list-backend/CHANGELOG.md +++ b/plugins/example-todo-list-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @internal/plugin-todo-list-backend +## 1.0.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.17-next.1 + ## 1.0.29-next.0 ### Patch Changes diff --git a/plugins/example-todo-list-backend/package.json b/plugins/example-todo-list-backend/package.json index ec37ce2843..3d46a9f5f7 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.29-next.0", + "version": "1.0.29-next.1", "backstage": { "role": "backend-plugin", "pluginId": "todo-list", diff --git a/plugins/home-react/CHANGELOG.md b/plugins/home-react/CHANGELOG.md index 62f3d98623..8353571dd8 100644 --- a/plugins/home-react/CHANGELOG.md +++ b/plugins/home-react/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-home-react +## 0.1.15-next.1 + +### Patch Changes + +- cc81579: Updated dependency `@rjsf/utils` to `5.18.5`. + Updated dependency `@rjsf/core` to `5.18.5`. + Updated dependency `@rjsf/material-ui` to `5.18.5`. + Updated dependency `@rjsf/validator-ajv8` to `5.18.5`. +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + ## 0.1.15-next.0 ### Patch Changes diff --git a/plugins/home-react/package.json b/plugins/home-react/package.json index 9c7667b4d0..b5dcaae83e 100644 --- a/plugins/home-react/package.json +++ b/plugins/home-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-home-react", - "version": "0.1.15-next.0", + "version": "0.1.15-next.1", "description": "A Backstage plugin that contains react components helps you build a home page", "backstage": { "role": "web-library", diff --git a/plugins/home/CHANGELOG.md b/plugins/home/CHANGELOG.md index b6ff8061f2..b475b7f764 100644 --- a/plugins/home/CHANGELOG.md +++ b/plugins/home/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-home +## 0.7.7-next.1 + +### Patch Changes + +- cc81579: Updated dependency `@rjsf/utils` to `5.18.5`. + Updated dependency `@rjsf/core` to `5.18.5`. + Updated dependency `@rjsf/material-ui` to `5.18.5`. + Updated dependency `@rjsf/validator-ajv8` to `5.18.5`. +- Updated dependencies + - @backstage/core-app-api@1.13.1-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/plugin-home-react@0.1.15-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/theme@0.5.6 + ## 0.7.6-next.0 ### Patch Changes diff --git a/plugins/home/package.json b/plugins/home/package.json index 2bc646b417..928417145b 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-home", - "version": "0.7.6-next.0", + "version": "0.7.7-next.1", "description": "A Backstage plugin that helps you build a home page", "backstage": { "role": "frontend-plugin", diff --git a/plugins/kubernetes-backend/CHANGELOG.md b/plugins/kubernetes-backend/CHANGELOG.md index ea2049d73c..7b8d3fb534 100644 --- a/plugins/kubernetes-backend/CHANGELOG.md +++ b/plugins/kubernetes-backend/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-kubernetes-backend +## 0.18.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-kubernetes-common@0.8.0 + - @backstage/plugin-kubernetes-node@0.1.16-next.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-node@0.7.33-next.1 + ## 0.18.2-next.0 ### Patch Changes diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index d0de031d9d..c9d8733319 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-backend", - "version": "0.18.2-next.0", + "version": "0.18.3-next.1", "description": "A Backstage backend plugin that integrates towards Kubernetes", "backstage": { "role": "backend-plugin", diff --git a/plugins/kubernetes-cluster/CHANGELOG.md b/plugins/kubernetes-cluster/CHANGELOG.md index cef2c059d1..0d8596888a 100644 --- a/plugins/kubernetes-cluster/CHANGELOG.md +++ b/plugins/kubernetes-cluster/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-kubernetes-cluster +## 0.0.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-kubernetes-react@0.4.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-kubernetes-common@0.8.0 + ## 0.0.13-next.0 ### Patch Changes diff --git a/plugins/kubernetes-cluster/package.json b/plugins/kubernetes-cluster/package.json index ce1fa2bc63..40a6d33dd2 100644 --- a/plugins/kubernetes-cluster/package.json +++ b/plugins/kubernetes-cluster/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-cluster", - "version": "0.0.13-next.0", + "version": "0.0.13-next.1", "description": "A Backstage plugin that shows details of Kubernetes clusters", "backstage": { "role": "frontend-plugin", diff --git a/plugins/kubernetes-node/CHANGELOG.md b/plugins/kubernetes-node/CHANGELOG.md index 6f6306cda6..4a6514a2d0 100644 --- a/plugins/kubernetes-node/CHANGELOG.md +++ b/plugins/kubernetes-node/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-kubernetes-node +## 0.1.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.0 + ## 0.1.15-next.0 ### Patch Changes diff --git a/plugins/kubernetes-node/package.json b/plugins/kubernetes-node/package.json index 2b4d061ba7..461bf1bbbe 100644 --- a/plugins/kubernetes-node/package.json +++ b/plugins/kubernetes-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-node", - "version": "0.1.15-next.0", + "version": "0.1.16-next.1", "description": "Node.js library for the kubernetes plugin", "backstage": { "role": "node-library", diff --git a/plugins/kubernetes/CHANGELOG.md b/plugins/kubernetes/CHANGELOG.md index 5c8c4d6d4b..2d92f6b026 100644 --- a/plugins/kubernetes/CHANGELOG.md +++ b/plugins/kubernetes/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-kubernetes +## 0.11.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-kubernetes-react@0.4.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-kubernetes-common@0.8.0 + ## 0.11.12-next.0 ### Patch Changes diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index 998bae3626..eef4da08bc 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes", - "version": "0.11.12-next.0", + "version": "0.11.12-next.1", "description": "A Backstage plugin that integrates towards Kubernetes", "backstage": { "role": "frontend-plugin", diff --git a/plugins/notifications-backend-module-email/CHANGELOG.md b/plugins/notifications-backend-module-email/CHANGELOG.md index 60725d15ee..c536369352 100644 --- a/plugins/notifications-backend-module-email/CHANGELOG.md +++ b/plugins/notifications-backend-module-email/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-notifications-backend-module-email +## 0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.4 + - @backstage/plugin-notifications-node@0.2.3-next.1 + ## 0.1.2-next.0 ### Patch Changes diff --git a/plugins/notifications-backend-module-email/package.json b/plugins/notifications-backend-module-email/package.json index 76bf5432e2..c47a65d4f4 100644 --- a/plugins/notifications-backend-module-email/package.json +++ b/plugins/notifications-backend-module-email/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications-backend-module-email", - "version": "0.1.2-next.0", + "version": "0.1.3-next.1", "description": "The email backend module for the notifications plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/notifications-backend/CHANGELOG.md b/plugins/notifications-backend/CHANGELOG.md index c42aa95a2e..a4be935628 100644 --- a/plugins/notifications-backend/CHANGELOG.md +++ b/plugins/notifications-backend/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-notifications-backend +## 0.3.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + - @backstage/plugin-notifications-common@0.0.4 + - @backstage/plugin-notifications-node@0.2.3-next.1 + - @backstage/plugin-signals-node@0.1.8-next.1 + ## 0.3.2-next.0 ### Patch Changes diff --git a/plugins/notifications-backend/package.json b/plugins/notifications-backend/package.json index 63b3b263b1..bfa1f2f0bd 100644 --- a/plugins/notifications-backend/package.json +++ b/plugins/notifications-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications-backend", - "version": "0.3.2-next.0", + "version": "0.3.3-next.1", "backstage": { "role": "backend-plugin", "pluginId": "notifications", diff --git a/plugins/notifications-node/CHANGELOG.md b/plugins/notifications-node/CHANGELOG.md index 041d0c355f..69e594b513 100644 --- a/plugins/notifications-node/CHANGELOG.md +++ b/plugins/notifications-node/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-notifications-node +## 0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-notifications-common@0.0.4 + - @backstage/plugin-signals-node@0.1.8-next.1 + ## 0.2.2-next.0 ### Patch Changes diff --git a/plugins/notifications-node/package.json b/plugins/notifications-node/package.json index e79b457965..f18ce420f7 100644 --- a/plugins/notifications-node/package.json +++ b/plugins/notifications-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications-node", - "version": "0.2.2-next.0", + "version": "0.2.3-next.1", "description": "Node.js library for the notifications plugin", "backstage": { "role": "node-library", diff --git a/plugins/notifications/CHANGELOG.md b/plugins/notifications/CHANGELOG.md index ebcacf97f6..9f532b3698 100644 --- a/plugins/notifications/CHANGELOG.md +++ b/plugins/notifications/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-notifications +## 0.2.3-next.1 + +### Patch Changes + +- 3bf0697: The toolbar on the Notifications page is hidden when there are no listed notifications. +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.4 + - @backstage/plugin-signals-react@0.0.4 + ## 0.2.3-next.0 ### Patch Changes diff --git a/plugins/notifications/package.json b/plugins/notifications/package.json index bc868c56a1..2e2c67e891 100644 --- a/plugins/notifications/package.json +++ b/plugins/notifications/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications", - "version": "0.2.3-next.0", + "version": "0.2.3-next.1", "backstage": { "role": "frontend-plugin", "pluginId": "notifications", diff --git a/plugins/org-react/CHANGELOG.md b/plugins/org-react/CHANGELOG.md index 8c2ea470da..1ce749fede 100644 --- a/plugins/org-react/CHANGELOG.md +++ b/plugins/org-react/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-org-react +## 0.1.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + ## 0.1.26-next.0 ### Patch Changes diff --git a/plugins/org-react/package.json b/plugins/org-react/package.json index 7bde5d9e9a..327e27662f 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.26-next.0", + "version": "0.1.26-next.1", "backstage": { "role": "web-library", "pluginId": "org", diff --git a/plugins/org/CHANGELOG.md b/plugins/org/CHANGELOG.md index fe82d2c948..5ca788557f 100644 --- a/plugins/org/CHANGELOG.md +++ b/plugins/org/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-org +## 0.6.27-next.1 + +### Patch Changes + +- 5132d28: The `useGetEntities` hook could result in requests to `/api/catalog/entities` where the headers exceed the default maximum Node.js header size of 16KB. The hook logic has been adjusted to batch the requests. +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/plugin-catalog-common@1.0.24 + ## 0.6.27-next.0 ### Patch Changes diff --git a/plugins/org/package.json b/plugins/org/package.json index 5b749ac215..5c62ffa99f 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-org", - "version": "0.6.27-next.0", + "version": "0.6.27-next.1", "description": "A Backstage plugin that helps you create entity pages for your organization", "backstage": { "role": "frontend-plugin", diff --git a/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md b/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md index 9192850893..616c6acda2 100644 --- a/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md +++ b/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-permission-backend-module-allow-all-policy +## 0.1.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-node@0.7.33-next.1 + ## 0.1.18-next.0 ### 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 62a3f6d101..60e11825f4 100644 --- a/plugins/permission-backend-module-policy-allow-all/package.json +++ b/plugins/permission-backend-module-policy-allow-all/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-backend-module-allow-all-policy", - "version": "0.1.18-next.0", + "version": "0.1.19-next.1", "description": "Allow all policy backend module for the permission plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/permission-backend/CHANGELOG.md b/plugins/permission-backend/CHANGELOG.md index d7190f15ee..39ae10e557 100644 --- a/plugins/permission-backend/CHANGELOG.md +++ b/plugins/permission-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-permission-backend +## 0.5.46-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-node@0.7.33-next.1 + ## 0.5.45-next.0 ### Patch Changes diff --git a/plugins/permission-backend/package.json b/plugins/permission-backend/package.json index 24b62d1358..43a57407e1 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.45-next.0", + "version": "0.5.46-next.1", "backstage": { "role": "backend-plugin", "pluginId": "permission", diff --git a/plugins/permission-node/CHANGELOG.md b/plugins/permission-node/CHANGELOG.md index 7255dbe266..a63abb1d95 100644 --- a/plugins/permission-node/CHANGELOG.md +++ b/plugins/permission-node/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-permission-node +## 0.7.33-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-permission-common@0.7.14 + ## 0.7.32-next.0 ### Patch Changes diff --git a/plugins/permission-node/package.json b/plugins/permission-node/package.json index 695e28f30b..db3c067088 100644 --- a/plugins/permission-node/package.json +++ b/plugins/permission-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-node", - "version": "0.7.32-next.0", + "version": "0.7.33-next.1", "description": "Common permission and authorization utilities for backend plugins", "backstage": { "role": "node-library", diff --git a/plugins/proxy-backend/CHANGELOG.md b/plugins/proxy-backend/CHANGELOG.md index d57f4936fb..a6c1ef02d2 100644 --- a/plugins/proxy-backend/CHANGELOG.md +++ b/plugins/proxy-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-proxy-backend +## 0.5.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + ## 0.5.2-next.0 ### Patch Changes diff --git a/plugins/proxy-backend/package.json b/plugins/proxy-backend/package.json index 18ad338131..23acc935f3 100644 --- a/plugins/proxy-backend/package.json +++ b/plugins/proxy-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-proxy-backend", - "version": "0.5.2-next.0", + "version": "0.5.3-next.1", "description": "A Backstage backend plugin that helps you set up proxy endpoints in the backend", "backstage": { "role": "backend-plugin", diff --git a/plugins/scaffolder-backend-module-azure/CHANGELOG.md b/plugins/scaffolder-backend-module-azure/CHANGELOG.md index 99ff7bd723..c634d8c8ca 100644 --- a/plugins/scaffolder-backend-module-azure/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-azure/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-scaffolder-backend-module-azure +## 0.1.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + ## 0.1.13-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-azure/package.json b/plugins/scaffolder-backend-module-azure/package.json index 672689ef73..c0e00e8ffe 100644 --- a/plugins/scaffolder-backend-module-azure/package.json +++ b/plugins/scaffolder-backend-module-azure/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-azure", - "version": "0.1.13-next.0", + "version": "0.1.14-next.1", "description": "The azure module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md index f4453bab7a..4e1e2b9531 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder-backend-module-bitbucket-cloud +## 0.1.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.21-next.0 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + ## 0.1.11-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/package.json b/plugins/scaffolder-backend-module-bitbucket-cloud/package.json index d4432ee3d5..5ce826ff1a 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/package.json +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud", - "version": "0.1.11-next.0", + "version": "0.1.12-next.1", "description": "The Bitbucket Cloud module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md b/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md index f614b16994..3443242e91 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-scaffolder-backend-module-bitbucket-server +## 0.1.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + ## 0.1.11-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-bitbucket-server/package.json b/plugins/scaffolder-backend-module-bitbucket-server/package.json index 16ce106570..b396faa5e5 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/package.json +++ b/plugins/scaffolder-backend-module-bitbucket-server/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-bitbucket-server", - "version": "0.1.11-next.0", + "version": "0.1.12-next.1", "description": "The Bitbucket Server module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md b/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md index dc3a0f1597..35f5382652 100644 --- a/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-backend-module-bitbucket +## 0.2.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.12-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.12-next.1 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + ## 0.2.11-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-bitbucket/package.json b/plugins/scaffolder-backend-module-bitbucket/package.json index 35b23e39d9..bca6e94878 100644 --- a/plugins/scaffolder-backend-module-bitbucket/package.json +++ b/plugins/scaffolder-backend-module-bitbucket/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-bitbucket", - "version": "0.2.11-next.0", + "version": "0.2.12-next.1", "description": "The bitbucket module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md b/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md index d24746f67a..b3c7bfbe36 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.23-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + ## 0.2.22-next.0 ### 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 34e49f740f..f607696136 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/package.json +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown", - "version": "0.2.22-next.0", + "version": "0.2.23-next.1", "description": "The confluence-to-markdown module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md index dfa740b4a6..5854e9ff47 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-backend-module-cookiecutter +## 0.2.46-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + ## 0.2.45-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-cookiecutter/package.json b/plugins/scaffolder-backend-module-cookiecutter/package.json index ea0a7fad77..43a7e348a4 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/package.json +++ b/plugins/scaffolder-backend-module-cookiecutter/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-cookiecutter", - "version": "0.2.45-next.0", + "version": "0.2.46-next.1", "description": "A module for the scaffolder backend that lets you template projects using cookiecutter", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-gcp/CHANGELOG.md b/plugins/scaffolder-backend-module-gcp/CHANGELOG.md index 5afcde9965..e32c2ef08f 100644 --- a/plugins/scaffolder-backend-module-gcp/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gcp/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-scaffolder-backend-module-gcp +## 0.1.0-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + ## 0.1.0-next.2 ### Minor Changes diff --git a/plugins/scaffolder-backend-module-gcp/package.json b/plugins/scaffolder-backend-module-gcp/package.json index 2f8f130d39..c441acb21a 100644 --- a/plugins/scaffolder-backend-module-gcp/package.json +++ b/plugins/scaffolder-backend-module-gcp/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gcp", - "version": "0.1.0-next.2", + "version": "0.1.0-next.3", "description": "The GCP Bucket module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md b/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md index cc4d9612a1..dd26e1d5a8 100644 --- a/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-scaffolder-backend-module-gerrit +## 0.1.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + ## 0.1.13-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gerrit/package.json b/plugins/scaffolder-backend-module-gerrit/package.json index 06c5d063d4..31a30c3f7e 100644 --- a/plugins/scaffolder-backend-module-gerrit/package.json +++ b/plugins/scaffolder-backend-module-gerrit/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gerrit", - "version": "0.1.13-next.0", + "version": "0.1.14-next.1", "description": "The gerrit module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-gitea/CHANGELOG.md b/plugins/scaffolder-backend-module-gitea/CHANGELOG.md index 5f26aa6a2d..f3ceb7ce8c 100644 --- a/plugins/scaffolder-backend-module-gitea/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gitea/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-scaffolder-backend-module-gitea +## 0.1.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + ## 0.1.11-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gitea/package.json b/plugins/scaffolder-backend-module-gitea/package.json index f6563795cd..3cacbc66db 100644 --- a/plugins/scaffolder-backend-module-gitea/package.json +++ b/plugins/scaffolder-backend-module-gitea/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gitea", - "version": "0.1.11-next.0", + "version": "0.1.12-next.1", "description": "The gitea module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-github/CHANGELOG.md b/plugins/scaffolder-backend-module-github/CHANGELOG.md index e3cd0904aa..2d3c6ff0f2 100644 --- a/plugins/scaffolder-backend-module-github/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-github/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-scaffolder-backend-module-github +## 0.4.0-next.1 + +### Patch Changes + +- 141f366: Added action to enable GitHub Pages on a repo +- dfaa28d: Adds `requireLastPushApproval` input property to configure Branch Protection Settings in `github:publish` action + + Adds `requireLastPushApproval` input property to configure Branch Protection Settings in `github:repo:push` action + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + ## 0.4.0-next.0 ### Minor Changes diff --git a/plugins/scaffolder-backend-module-github/package.json b/plugins/scaffolder-backend-module-github/package.json index 1fd404c6f9..500ec86f9f 100644 --- a/plugins/scaffolder-backend-module-github/package.json +++ b/plugins/scaffolder-backend-module-github/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-github", - "version": "0.4.0-next.0", + "version": "0.4.0-next.1", "description": "The github module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md b/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md index c64aa0ca32..0c8f0529a6 100644 --- a/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-backend-module-gitlab +## 0.4.4-next.1 + +### Patch Changes + +- 2fb0eb8: Added support for passing `variables` to `gitlab:pipeline:trigger` +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + ## 0.4.3-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gitlab/package.json b/plugins/scaffolder-backend-module-gitlab/package.json index 7444bde77d..499cfd6872 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.4.3-next.0", + "version": "0.4.4-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "scaffolder", diff --git a/plugins/scaffolder-backend-module-notifications/CHANGELOG.md b/plugins/scaffolder-backend-module-notifications/CHANGELOG.md index 948770e600..6371124957 100644 --- a/plugins/scaffolder-backend-module-notifications/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-notifications/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-scaffolder-backend-module-notifications +## 0.0.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/plugin-notifications-common@0.0.4 + - @backstage/plugin-notifications-node@0.2.3-next.1 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + ## 0.0.4-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-notifications/package.json b/plugins/scaffolder-backend-module-notifications/package.json index bb8b7807e8..7c983c36ce 100644 --- a/plugins/scaffolder-backend-module-notifications/package.json +++ b/plugins/scaffolder-backend-module-notifications/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-notifications", - "version": "0.0.4-next.0", + "version": "0.0.5-next.1", "description": "The notifications backend module for the scaffolder plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-rails/CHANGELOG.md b/plugins/scaffolder-backend-module-rails/CHANGELOG.md index afaebde648..0db7584509 100644 --- a/plugins/scaffolder-backend-module-rails/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-rails/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-backend-module-rails +## 0.4.39-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + ## 0.4.38-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-rails/package.json b/plugins/scaffolder-backend-module-rails/package.json index a736106df1..c15815d2fa 100644 --- a/plugins/scaffolder-backend-module-rails/package.json +++ b/plugins/scaffolder-backend-module-rails/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-rails", - "version": "0.4.38-next.0", + "version": "0.4.39-next.1", "description": "A module for the scaffolder backend that lets you template projects using Rails", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-sentry/CHANGELOG.md b/plugins/scaffolder-backend-module-sentry/CHANGELOG.md index fa7712e500..29e8c17b04 100644 --- a/plugins/scaffolder-backend-module-sentry/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-sentry/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-scaffolder-backend-module-sentry +## 0.1.30-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + ## 0.1.29-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-sentry/package.json b/plugins/scaffolder-backend-module-sentry/package.json index 7943de9b5c..c0866f979d 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.29-next.0", + "version": "0.1.30-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "scaffolder", diff --git a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md index c3c2322b9a..4e99b51284 100644 --- a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-scaffolder-backend-module-yeoman +## 0.3.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node-test-utils@0.1.9-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + ## 0.3.5-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-yeoman/package.json b/plugins/scaffolder-backend-module-yeoman/package.json index 70133616ef..76158fdc01 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.3.5-next.0", + "version": "0.3.6-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "scaffolder", diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md index 5737dc0165..97cd859856 100644 --- a/plugins/scaffolder-backend/CHANGELOG.md +++ b/plugins/scaffolder-backend/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/plugin-scaffolder-backend +## 1.23.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-github@0.4.0-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.4.4-next.1 + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-bitbucket-cloud-common@0.2.21-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.20-next.1 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-node@0.7.33-next.1 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.14-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.12-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.12-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.12-next.1 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.14-next.1 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.12-next.1 + - @backstage/plugin-scaffolder-common@1.5.3 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + ## 1.23.0-next.0 ### Minor Changes diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index c9c19d9983..71857e245b 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend", - "version": "1.23.0-next.0", + "version": "1.23.0-next.1", "description": "The Backstage backend plugin that helps you create new things", "backstage": { "role": "backend-plugin", diff --git a/plugins/scaffolder-node-test-utils/CHANGELOG.md b/plugins/scaffolder-node-test-utils/CHANGELOG.md index 1136cce04b..9104fbcb26 100644 --- a/plugins/scaffolder-node-test-utils/CHANGELOG.md +++ b/plugins/scaffolder-node-test-utils/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-scaffolder-node-test-utils +## 0.1.9-next.1 + +### Patch Changes + +- 54429b5: Filename and imports correction for mockActionContext.ts +- Updated dependencies + - @backstage/backend-test-utils@0.4.4-next.1 + - @backstage/backend-common@0.23.3-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.8-next.1 + ## 0.1.8-next.0 ### Patch Changes diff --git a/plugins/scaffolder-node-test-utils/package.json b/plugins/scaffolder-node-test-utils/package.json index 87f895efc3..d361d0ae1d 100644 --- a/plugins/scaffolder-node-test-utils/package.json +++ b/plugins/scaffolder-node-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-node-test-utils", - "version": "0.1.8-next.0", + "version": "0.1.9-next.1", "backstage": { "role": "node-library", "pluginId": "scaffolder", diff --git a/plugins/scaffolder-node/CHANGELOG.md b/plugins/scaffolder-node/CHANGELOG.md index f0deb319ff..f67c8c8cda 100644 --- a/plugins/scaffolder-node/CHANGELOG.md +++ b/plugins/scaffolder-node/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-node +## 0.4.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.3 + ## 0.4.7-next.0 ### Patch Changes diff --git a/plugins/scaffolder-node/package.json b/plugins/scaffolder-node/package.json index 2568809647..079eebfb00 100644 --- a/plugins/scaffolder-node/package.json +++ b/plugins/scaffolder-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-node", - "version": "0.4.7-next.0", + "version": "0.4.8-next.1", "description": "The plugin-scaffolder-node module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "node-library", diff --git a/plugins/scaffolder-react/CHANGELOG.md b/plugins/scaffolder-react/CHANGELOG.md index baa34dbc5b..6cbdb781f3 100644 --- a/plugins/scaffolder-react/CHANGELOG.md +++ b/plugins/scaffolder-react/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-scaffolder-react +## 1.10.0-next.1 + +### Minor Changes + +- 354e68c: Improve validation error display text in scaffolder + +### Patch Changes + +- cc81579: Updated dependency `@rjsf/utils` to `5.18.5`. + Updated dependency `@rjsf/core` to `5.18.5`. + Updated dependency `@rjsf/material-ui` to `5.18.5`. + Updated dependency `@rjsf/validator-ajv8` to `5.18.5`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-permission-react@0.4.23 + - @backstage/plugin-scaffolder-common@1.5.3 + ## 1.10.0-next.0 ### Minor Changes diff --git a/plugins/scaffolder-react/package.json b/plugins/scaffolder-react/package.json index d5fe7ca9cb..6bdc263b3d 100644 --- a/plugins/scaffolder-react/package.json +++ b/plugins/scaffolder-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-react", - "version": "1.10.0-next.0", + "version": "1.10.0-next.1", "description": "A frontend library that helps other Backstage plugins interact with the Scaffolder", "backstage": { "role": "web-library", diff --git a/plugins/scaffolder/CHANGELOG.md b/plugins/scaffolder/CHANGELOG.md index 55d7271807..566411b9bd 100644 --- a/plugins/scaffolder/CHANGELOG.md +++ b/plugins/scaffolder/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-scaffolder +## 1.22.1-next.1 + +### Patch Changes + +- cc81579: Updated dependency `@rjsf/utils` to `5.18.5`. + Updated dependency `@rjsf/core` to `5.18.5`. + Updated dependency `@rjsf/material-ui` to `5.18.5`. + Updated dependency `@rjsf/validator-ajv8` to `5.18.5`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/plugin-scaffolder-react@1.10.0-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-react@0.4.23 + - @backstage/plugin-scaffolder-common@1.5.3 + ## 1.22.0-next.0 ### Minor Changes diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 33cf7be16f..0db796359a 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder", - "version": "1.22.0-next.0", + "version": "1.22.1-next.1", "description": "The Backstage plugin that helps you create new things", "backstage": { "role": "frontend-plugin", diff --git a/plugins/search-backend-module-catalog/CHANGELOG.md b/plugins/search-backend-module-catalog/CHANGELOG.md index e2d6440c94..d064814ecb 100644 --- a/plugins/search-backend-module-catalog/CHANGELOG.md +++ b/plugins/search-backend-module-catalog/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-search-backend-module-catalog +## 0.1.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-search-backend-node@1.2.27-next.1 + - @backstage/plugin-search-common@1.2.12 + ## 0.1.27-next.0 ### Patch Changes diff --git a/plugins/search-backend-module-catalog/package.json b/plugins/search-backend-module-catalog/package.json index d46e220029..0f45f3ce43 100644 --- a/plugins/search-backend-module-catalog/package.json +++ b/plugins/search-backend-module-catalog/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-catalog", - "version": "0.1.27-next.0", + "version": "0.1.28-next.1", "description": "A module for the search backend that exports catalog modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-elasticsearch/CHANGELOG.md b/plugins/search-backend-module-elasticsearch/CHANGELOG.md index 16cf473283..f0628d0254 100644 --- a/plugins/search-backend-module-elasticsearch/CHANGELOG.md +++ b/plugins/search-backend-module-elasticsearch/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-search-backend-module-elasticsearch +## 1.5.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-backend-node@1.2.27-next.1 + - @backstage/plugin-search-common@1.2.12 + ## 1.5.2-next.0 ### Patch Changes diff --git a/plugins/search-backend-module-elasticsearch/package.json b/plugins/search-backend-module-elasticsearch/package.json index 57414ec6e5..9cb61ee97b 100644 --- a/plugins/search-backend-module-elasticsearch/package.json +++ b/plugins/search-backend-module-elasticsearch/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-elasticsearch", - "version": "1.5.2-next.0", + "version": "1.5.3-next.1", "description": "A module for the search backend that implements search using ElasticSearch", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-explore/CHANGELOG.md b/plugins/search-backend-module-explore/CHANGELOG.md index 4b75d163f9..888be119be 100644 --- a/plugins/search-backend-module-explore/CHANGELOG.md +++ b/plugins/search-backend-module-explore/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-search-backend-module-explore +## 0.1.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.2.27-next.1 + - @backstage/plugin-search-common@1.2.12 + ## 0.1.27-next.0 ### Patch Changes diff --git a/plugins/search-backend-module-explore/package.json b/plugins/search-backend-module-explore/package.json index 13cba189e5..f37c4d55d3 100644 --- a/plugins/search-backend-module-explore/package.json +++ b/plugins/search-backend-module-explore/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-explore", - "version": "0.1.27-next.0", + "version": "0.1.28-next.1", "description": "A module for the search backend that exports explore modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-pg/CHANGELOG.md b/plugins/search-backend-module-pg/CHANGELOG.md index 376d266f8f..3fe18213bb 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.32-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-app-api@0.7.10-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.2.27-next.1 + - @backstage/plugin-search-common@1.2.12 + ## 0.5.31-next.0 ### Patch Changes diff --git a/plugins/search-backend-module-pg/package.json b/plugins/search-backend-module-pg/package.json index 3319d85dbb..ec6782535f 100644 --- a/plugins/search-backend-module-pg/package.json +++ b/plugins/search-backend-module-pg/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-pg", - "version": "0.5.31-next.0", + "version": "0.5.32-next.1", "description": "A module for the search backend that implements search using PostgreSQL", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md b/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md index 91652d5543..96214102b7 100644 --- a/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md +++ b/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-search-backend-module-stack-overflow-collator +## 0.1.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.2.27-next.1 + - @backstage/plugin-search-common@1.2.12 + ## 0.1.14-next.0 ### 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 60b658a34a..dd09d75b11 100644 --- a/plugins/search-backend-module-stack-overflow-collator/package.json +++ b/plugins/search-backend-module-stack-overflow-collator/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-stack-overflow-collator", - "version": "0.1.14-next.0", + "version": "0.1.15-next.1", "description": "A module for the search backend that exports stack overflow modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-techdocs/CHANGELOG.md b/plugins/search-backend-module-techdocs/CHANGELOG.md index 4e7e3c4baa..706d178601 100644 --- a/plugins/search-backend-module-techdocs/CHANGELOG.md +++ b/plugins/search-backend-module-techdocs/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-search-backend-module-techdocs +## 0.1.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.8-next.1 + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-node@1.12.4-next.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-search-backend-node@1.2.27-next.1 + - @backstage/plugin-search-common@1.2.12 + ## 0.1.26-next.0 ### Patch Changes diff --git a/plugins/search-backend-module-techdocs/package.json b/plugins/search-backend-module-techdocs/package.json index 1650012d93..b26065cc60 100644 --- a/plugins/search-backend-module-techdocs/package.json +++ b/plugins/search-backend-module-techdocs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-techdocs", - "version": "0.1.26-next.0", + "version": "0.1.27-next.1", "description": "A module for the search backend that exports techdocs modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-node/CHANGELOG.md b/plugins/search-backend-node/CHANGELOG.md index 5209cb8753..26cd8e91eb 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.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/backend-tasks@0.5.27-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-search-common@1.2.12 + ## 1.2.26-next.0 ### Patch Changes diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index ef655ac566..e8cc89d117 100644 --- a/plugins/search-backend-node/package.json +++ b/plugins/search-backend-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-node", - "version": "1.2.26-next.0", + "version": "1.2.27-next.1", "description": "A library for Backstage backend plugins that want to interact with the search backend plugin", "backstage": { "role": "node-library", diff --git a/plugins/search-backend/CHANGELOG.md b/plugins/search-backend/CHANGELOG.md index ea4142e583..2de90e3960 100644 --- a/plugins/search-backend/CHANGELOG.md +++ b/plugins/search-backend/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-search-backend +## 1.5.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.3.4-next.1 + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-openapi-utils@0.1.15-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-node@0.7.33-next.1 + - @backstage/plugin-search-backend-node@1.2.27-next.1 + - @backstage/plugin-search-common@1.2.12 + ## 1.5.13-next.0 ### Patch Changes diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index c1d536d4d4..8d266c63a8 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend", - "version": "1.5.13-next.0", + "version": "1.5.14-next.1", "description": "The Backstage backend plugin that provides your backstage app with search", "backstage": { "role": "backend-plugin", diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md index effe205170..dac2074373 100644 --- a/plugins/search/CHANGELOG.md +++ b/plugins/search/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-search +## 1.4.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-search-common@1.2.12 + ## 1.4.13-next.0 ### Patch Changes diff --git a/plugins/search/package.json b/plugins/search/package.json index f25bff3e26..3b08790026 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search", - "version": "1.4.13-next.0", + "version": "1.4.13-next.1", "description": "The Backstage plugin that provides your backstage app with search", "backstage": { "role": "frontend-plugin", diff --git a/plugins/signals-backend/CHANGELOG.md b/plugins/signals-backend/CHANGELOG.md index 1e9c57e1da..aaf4a0c15f 100644 --- a/plugins/signals-backend/CHANGELOG.md +++ b/plugins/signals-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-signals-backend +## 0.1.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + - @backstage/plugin-signals-node@0.1.8-next.1 + ## 0.1.7-next.0 ### Patch Changes diff --git a/plugins/signals-backend/package.json b/plugins/signals-backend/package.json index 9501878d87..0bded11c2e 100644 --- a/plugins/signals-backend/package.json +++ b/plugins/signals-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals-backend", - "version": "0.1.7-next.0", + "version": "0.1.8-next.1", "backstage": { "role": "backend-plugin", "pluginId": "signals", diff --git a/plugins/signals-node/CHANGELOG.md b/plugins/signals-node/CHANGELOG.md index 28db4b57fa..cbcdea7a98 100644 --- a/plugins/signals-node/CHANGELOG.md +++ b/plugins/signals-node/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-signals-node +## 0.1.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-events-node@0.3.8-next.1 + ## 0.1.7-next.0 ### Patch Changes diff --git a/plugins/signals-node/package.json b/plugins/signals-node/package.json index 8185c27d6b..033dcb8246 100644 --- a/plugins/signals-node/package.json +++ b/plugins/signals-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals-node", - "version": "0.1.7-next.0", + "version": "0.1.8-next.1", "description": "Node.js library for the signals plugin", "backstage": { "role": "node-library", diff --git a/plugins/techdocs-addons-test-utils/CHANGELOG.md b/plugins/techdocs-addons-test-utils/CHANGELOG.md index 93552868b9..0695f7e1f4 100644 --- a/plugins/techdocs-addons-test-utils/CHANGELOG.md +++ b/plugins/techdocs-addons-test-utils/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-techdocs-addons-test-utils +## 1.0.35-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.13.1-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/plugin-catalog@1.21.1-next.1 + - @backstage/plugin-techdocs@1.10.7-next.1 + - @backstage/core-plugin-api@1.9.3 + - @backstage/test-utils@1.5.8-next.1 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-techdocs-react@1.2.6-next.0 + ## 1.0.34-next.0 ### Patch Changes diff --git a/plugins/techdocs-addons-test-utils/package.json b/plugins/techdocs-addons-test-utils/package.json index a18bfea16f..fd1c806414 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.34-next.0", + "version": "1.0.35-next.1", "backstage": { "role": "web-library", "pluginId": "techdocs-addons", diff --git a/plugins/techdocs-backend/CHANGELOG.md b/plugins/techdocs-backend/CHANGELOG.md index 286ea77341..d50062c744 100644 --- a/plugins/techdocs-backend/CHANGELOG.md +++ b/plugins/techdocs-backend/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-techdocs-backend +## 1.10.9-next.1 + +### Patch Changes + +- 9ecf5fd: Adds extension point for publishers to the techdocs backend +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.8-next.1 + - @backstage/backend-common@0.23.3-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.27-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-common@0.7.14 + ## 1.10.8-next.0 ### Patch Changes diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index 01891b83d4..1533cdc3fe 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-backend", - "version": "1.10.8-next.0", + "version": "1.10.9-next.1", "description": "The Backstage backend plugin that renders technical documentation for your components", "backstage": { "role": "backend-plugin", diff --git a/plugins/techdocs-node/CHANGELOG.md b/plugins/techdocs-node/CHANGELOG.md index 0093f6a1eb..99240bd9d4 100644 --- a/plugins/techdocs-node/CHANGELOG.md +++ b/plugins/techdocs-node/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-techdocs-node +## 1.12.8-next.1 + +### Patch Changes + +- 9ecf5fd: Adds extension point for publishers to the techdocs backend +- 4c4d077: Bumps default version of techdocs docker image to latest +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.13.0-next.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.12 + ## 1.12.7-next.0 ### Patch Changes diff --git a/plugins/techdocs-node/package.json b/plugins/techdocs-node/package.json index ae11fcb1df..70d10aeed4 100644 --- a/plugins/techdocs-node/package.json +++ b/plugins/techdocs-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-node", - "version": "1.12.7-next.0", + "version": "1.12.8-next.1", "description": "Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", "backstage": { "role": "node-library", diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index fd35205da8..a14559de1e 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-techdocs +## 1.10.7-next.1 + +### Patch Changes + +- 60caa92: Fix double scrollbar bug in reader +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.4-next.0 + - @backstage/plugin-search-common@1.2.12 + - @backstage/plugin-techdocs-react@1.2.6-next.0 + ## 1.10.7-next.0 ### Patch Changes diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 8212246aab..2a404551be 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs", - "version": "1.10.7-next.0", + "version": "1.10.7-next.1", "description": "The Backstage plugin that renders technical documentation for your components", "backstage": { "role": "frontend-plugin", diff --git a/plugins/user-settings-backend/CHANGELOG.md b/plugins/user-settings-backend/CHANGELOG.md index cbd2ab7536..c830df43e5 100644 --- a/plugins/user-settings-backend/CHANGELOG.md +++ b/plugins/user-settings-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-user-settings-backend +## 0.2.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.17-next.1 + - @backstage/plugin-signals-node@0.1.8-next.1 + - @backstage/plugin-user-settings-common@0.0.1 + ## 0.2.20-next.0 ### Patch Changes diff --git a/plugins/user-settings-backend/package.json b/plugins/user-settings-backend/package.json index d8dc0770a5..e975b38c08 100644 --- a/plugins/user-settings-backend/package.json +++ b/plugins/user-settings-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-user-settings-backend", - "version": "0.2.20-next.0", + "version": "0.2.21-next.1", "description": "The Backstage backend plugin to manage user settings", "backstage": { "role": "backend-plugin", diff --git a/plugins/user-settings/CHANGELOG.md b/plugins/user-settings/CHANGELOG.md index 20ef229a2d..5b86011ba8 100644 --- a/plugins/user-settings/CHANGELOG.md +++ b/plugins/user-settings/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-user-settings +## 0.8.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.13.1-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.4 + - @backstage/plugin-user-settings-common@0.0.1 + ## 0.8.8-next.0 ### Patch Changes diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index 3257de8072..a549c7cdd2 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-user-settings", - "version": "0.8.8-next.0", + "version": "0.8.9-next.1", "description": "A Backstage plugin that provides a settings page", "backstage": { "role": "frontend-plugin", From 3b118003a93d9f4954b45386e52c05870195a5c9 Mon Sep 17 00:00:00 2001 From: aramissennyeydd Date: Tue, 2 Jul 2024 09:23:33 -0400 Subject: [PATCH 163/510] update to use taskRunner and show how to use config Signed-off-by: aramissennyeydd --- .../software-catalog/external-integrations.md | 106 ++++++++++++++---- 1 file changed, 85 insertions(+), 21 deletions(-) diff --git a/docs/features/software-catalog/external-integrations.md b/docs/features/software-catalog/external-integrations.md index c77ed51943..c269030f29 100644 --- a/docs/features/software-catalog/external-integrations.md +++ b/docs/features/software-catalog/external-integrations.md @@ -84,6 +84,7 @@ import { EntityProvider, EntityProviderConnection, } from '@backstage/plugin-catalog-node'; +import { SchedulerServiceTaskRunner } from '@backstage/backend-plugin-api'; /** * Provides entities from fictional frobs service. @@ -92,11 +93,17 @@ export class FrobsProvider implements EntityProvider { private readonly env: string; private readonly reader: UrlReader; private connection?: EntityProviderConnection; + private taskRunner: SchedulerServiceTaskRunner; /** [1] */ - constructor(env: string, reader: UrlReader) { + constructor( + env: string, + reader: UrlReader, + taskRunner: SchedulerServiceTaskRunner, + ) { this.env = env; this.reader = reader; + this.taskRunner = taskRunner; } /** [2] */ @@ -107,6 +114,12 @@ export class FrobsProvider implements EntityProvider { /** [3] */ async connect(connection: EntityProviderConnection): Promise { this.connection = connection; + this.taskRunner.run({ + id: this.getProviderName(), + fn: async () => { + await this.run(); + }, + }); } /** [4] */ @@ -248,24 +261,17 @@ export default async function createPlugin( ): Promise { const builder = CatalogBuilder.create(env); /* highlight-add-start */ - const frobs = new FrobsProvider('production', env.reader); + const taskRunner = env.scheduler.createScheduledTaskRunner({ + frequency: { minutes: 30 }, + timeout: { minutes: 10 }, + }); + const frobs = new FrobsProvider('production', env.reader, taskRunner); builder.addEntityProvider(frobs); /* highlight-add-end */ const { processingEngine, router } = await builder.build(); await processingEngine.start(); - /* highlight-add-start */ - await env.scheduler.scheduleTask({ - id: 'run_frobs_refresh', - fn: async () => { - await frobs.run(); - }, - frequency: { minutes: 30 }, - timeout: { minutes: 10 }, - }); - /* highlight-add-end */ - // .. } ``` @@ -300,19 +306,17 @@ export const catalogModuleFrobsProvider = createBackendModule({ deps: { catalog: catalogProcessingExtensionPoint, reader: coreServices.urlReader, + /* highlight-add-start */ scheduler: coreServices.scheduler, + /* highlight-add-end */ }, - async init({ catalog, reader, scheduler }) { - const frobs = new FrobsProvider('dev', reader); - catalog.addEntityProvider(frobs); - await scheduler.scheduleTask({ - id: 'run_frobs_refresh', - fn: async () => { - await frobs.run(); - }, + async init({ catalog, reader, scheduler, config }) { + const taskRunner = scheduler.createScheduledTaskRunner({ frequency: { minutes: 30 }, timeout: { minutes: 10 }, }); + const frobs = new FrobsProvider('dev', reader, taskRunner); + catalog.addEntityProvider(frobs); }, }); }, @@ -328,6 +332,66 @@ backend.add(catalogModuleFrobsProvider); backend.start(); ``` +#### Follow-up: Config Defined Schedule + +If you want to go a step further and increase the configurability of your new `FrobsProvider`, you can define the schedule that the task runs at in `app-config.yaml` instead of requiring code changes to adjust. + +```yaml +catalog: + providers: + frobs-provider: + schedule: + initialDelay: { seconds: 30 } + frequency: { hours: 1 } + timeout: { minutes: 50 } +``` + +This approach will also allow you to customize the schedule per environment + +#### New Backend + +```ts +import { + SchedulerServiceTaskScheduleDefinition, + /* highlight-add-start */ + readSchedulerServiceTaskScheduleDefinitionFromConfig, + /* highlight-add-end */ +} from '@backstage/backend-plugin-api'; + +export const catalogModuleFrobsProvider = createBackendModule({ + pluginId: 'catalog', + moduleId: 'frobs-provider', + register(env) { + env.registerInit({ + deps: { + // ... other deps + /* highlight-add-start */ + rootConfig: coreServices.rootConfig, + /* highlight-add-end */ + }, + async init({ catalog, reader, scheduler, rootConfig }) { + /* highlight-add-start */ + const config = rootConfig.getConfig('catalog.providers.frobs-provider'); // Generally, catalog config goes under catalog.providers.pluginId + // Add a default schedule if you don't define one in config. + const schedule = config.has('schedule') + ? readSchedulerServiceTaskScheduleDefinitionFromConfig( + config.getConfig('schedule'), + ) + : { + frequency: { minutes: 30 }, + timeout: { minutes: 10 }, + }; + const taskRunner: SchedulerServiceTaskRunner = + scheduler.createScheduledTaskRunner(schedule); + /* highlight-add-end */ + + // rest of your code + }, + }); + }, +}); +``` + ### Example User Entity Provider If you have a 3rd party entity provider such as an internal HR system that you wish to use you are not limited to using our entity providers, (or simply wish to add to existing entity providers with your own data). From fc221e0e57a52d52398140a5d7e4e93eb089e154 Mon Sep 17 00:00:00 2001 From: Aramis Sennyey <159921952+aramissennyeydd@users.noreply.github.com> Date: Tue, 2 Jul 2024 09:24:29 -0400 Subject: [PATCH 164/510] Update docs/features/software-catalog/external-integrations.md Signed-off-by: Aramis Sennyey <159921952+aramissennyeydd@users.noreply.github.com> --- docs/features/software-catalog/external-integrations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/software-catalog/external-integrations.md b/docs/features/software-catalog/external-integrations.md index c269030f29..c9fed03e23 100644 --- a/docs/features/software-catalog/external-integrations.md +++ b/docs/features/software-catalog/external-integrations.md @@ -310,7 +310,7 @@ export const catalogModuleFrobsProvider = createBackendModule({ scheduler: coreServices.scheduler, /* highlight-add-end */ }, - async init({ catalog, reader, scheduler, config }) { + async init({ catalog, reader, scheduler }) { const taskRunner = scheduler.createScheduledTaskRunner({ frequency: { minutes: 30 }, timeout: { minutes: 10 }, From 82d14dd868f6701673f56e80a8a88dcda21945c4 Mon Sep 17 00:00:00 2001 From: aramissennyeydd Date: Tue, 2 Jul 2024 09:29:01 -0400 Subject: [PATCH 165/510] show how to do it for the old backend as well Signed-off-by: aramissennyeydd --- .../software-catalog/external-integrations.md | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/docs/features/software-catalog/external-integrations.md b/docs/features/software-catalog/external-integrations.md index c9fed03e23..56423c9392 100644 --- a/docs/features/software-catalog/external-integrations.md +++ b/docs/features/software-catalog/external-integrations.md @@ -336,7 +336,7 @@ backend.start(); If you want to go a step further and increase the configurability of your new `FrobsProvider`, you can define the schedule that the task runs at in `app-config.yaml` instead of requiring code changes to adjust. -```yaml +```yaml title="app-config.yaml" catalog: providers: frobs-provider: @@ -350,7 +350,7 @@ This approach will also allow you to customize the schedule per environment #### New Backend -```ts +```ts title="packages/backend/src/index.ts" import { SchedulerServiceTaskScheduleDefinition, /* highlight-add-start */ @@ -392,6 +392,38 @@ export const catalogModuleFrobsProvider = createBackendModule({ }); ``` +#### Old Backend + +```ts title="packages/backend/src/plugins/catalog.ts" +/* highlight-add-next-line */ +import { FrobsProvider } from '../path/to/class'; +import { + /* highlight-add-start */ + readSchedulerServiceTaskScheduleDefinitionFromConfig, + /* highlight-add-end */ +} from '@backstage/backend-plugin-api'; + +export default async function createPlugin( + env: PluginEnvironment, +): Promise { + /* highlight-add-start */ + const config = env.config.getConfig('catalog.providers.frobs-provider'); // Generally, catalog config goes under catalog.providers.pluginId + // Add a default schedule if you don't define one in config. + const schedule = config.has('schedule') + ? readSchedulerServiceTaskScheduleDefinitionFromConfig( + config.getConfig('schedule'), + ) + : { + frequency: { minutes: 30 }, + timeout: { minutes: 10 }, + }; + const taskRunner = env.scheduler.createScheduledTaskRunner(schedule); + /* highlight-add-end */ + + // .. +} +``` + ### Example User Entity Provider If you have a 3rd party entity provider such as an internal HR system that you wish to use you are not limited to using our entity providers, (or simply wish to add to existing entity providers with your own data). From a36e90ef56069029fcdee38fd990aea6aaab12c9 Mon Sep 17 00:00:00 2001 From: Debabrata Panigrahi <50622005+Debanitrkl@users.noreply.github.com> Date: Tue, 2 Jul 2024 13:39:12 +0000 Subject: [PATCH 166/510] Signed-off-by: Debabrata Panigrahi <50622005+Debanitrkl@users.noreply.github.com> Added the harness iacm plugin info to microsite --- microsite/data/plugins/harness-iacm.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 microsite/data/plugins/harness-iacm.yaml diff --git a/microsite/data/plugins/harness-iacm.yaml b/microsite/data/plugins/harness-iacm.yaml new file mode 100644 index 0000000000..4463bab371 --- /dev/null +++ b/microsite/data/plugins/harness-iacm.yaml @@ -0,0 +1,13 @@ +--- +title: Harness Infrastructure as Code Management +author: harness.io +authorUrl: https://github.com/harness/backstage-plugins +category: Infrastructure +description: This plugin provides an overview of all the resources provisioned through information on active workspaces in your account +documentation: https://github.com/harness/backstage-plugins/tree/main/plugins/harness-iacm#harness-iacm-plugin +iconUrl: https://static.harness.io/ng-static/images/favicon.png +npmPackageName: '@harnessio/backstage-plugin-harness-iacm' +tags: + - infrastrucure-as-code + - resource-management +addedDate: '2024-07-03' From e3cb6abeec2e4a9861890cea9f9f29450b6134aa Mon Sep 17 00:00:00 2001 From: Ilias Van Peer <1038427+zwilias@users.noreply.github.com> Date: Tue, 2 Jul 2024 16:47:10 +0200 Subject: [PATCH 167/510] Add namespace label to argo rollouts in kubernetes (#25467) * Create fixture for rollouts Since rollouts have customized support, having a fixture for them can help in maintaining their rendering. Signed-off-by: ilias * Show namespace on Argo Rollout drawers Signed-off-by: ilias * Add changeset Signed-off-by: ilias * Check namespace shows up on rollouts Signed-off-by: ilias --------- Signed-off-by: ilias --- .changeset/sharp-rice-tickle.md | 5 + .../ArgoRollouts/Rollout.test.tsx | 4 + .../ArgoRollouts/RolloutDrawer.tsx | 7 + plugins/kubernetes/dev/index.tsx | 14 + .../src/__fixtures__/1-rollouts.json | 2908 +++++++++++++++++ 5 files changed, 2938 insertions(+) create mode 100644 .changeset/sharp-rice-tickle.md create mode 100644 plugins/kubernetes/src/__fixtures__/1-rollouts.json diff --git a/.changeset/sharp-rice-tickle.md b/.changeset/sharp-rice-tickle.md new file mode 100644 index 0000000000..6104e11e75 --- /dev/null +++ b/.changeset/sharp-rice-tickle.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kubernetes-react': patch +--- + +Add a namespace label to RolloutDrawer diff --git a/plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/Rollout.test.tsx b/plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/Rollout.test.tsx index 00063afa99..a4748cdae7 100644 --- a/plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/Rollout.test.tsx +++ b/plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/Rollout.test.tsx @@ -35,6 +35,7 @@ describe('Rollout', () => { expect(screen.getByText('dice-roller')).toBeInTheDocument(); expect(screen.getByText('Rollout')).toBeInTheDocument(); + expect(screen.getByText('namespace: default')).toBeInTheDocument(); expect(screen.getByText('2 pods')).toBeInTheDocument(); expect(screen.getByText('No pods with errors')).toBeInTheDocument(); expect(screen.queryByText('Paused')).toBeNull(); @@ -52,6 +53,7 @@ describe('Rollout', () => { expect(screen.getByText('dice-roller')).toBeInTheDocument(); expect(screen.getByText('Rollout')).toBeInTheDocument(); + expect(screen.getByText('namespace: default')).toBeInTheDocument(); expect(screen.getByText('2 pods')).toBeInTheDocument(); expect(screen.getByText('1 pod with errors')).toBeInTheDocument(); expect(screen.queryByText('Paused')).toBeNull(); @@ -71,6 +73,7 @@ describe('Rollout', () => { expect(screen.getByText('dice-roller')).toBeInTheDocument(); expect(screen.getByText('Rollout')).toBeInTheDocument(); + expect(screen.getByText('namespace: default')).toBeInTheDocument(); expect(screen.getByText('2 pods')).toBeInTheDocument(); expect(screen.getByText('No pods with errors')).toBeInTheDocument(); expect(screen.getByText('Paused (45 minutes ago)')).toBeInTheDocument(); @@ -90,6 +93,7 @@ describe('Rollout', () => { expect(screen.getByText('dice-roller')).toBeInTheDocument(); expect(screen.getByText('Rollout')).toBeInTheDocument(); + expect(screen.getByText('namespace: default')).toBeInTheDocument(); expect(screen.getByText('2 pods')).toBeInTheDocument(); expect(screen.getByText('No pods with errors')).toBeInTheDocument(); expect(screen.queryByText('Paused')).toBeNull(); diff --git a/plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/RolloutDrawer.tsx b/plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/RolloutDrawer.tsx index 304c8bdf78..65d4840bf0 100644 --- a/plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/RolloutDrawer.tsx +++ b/plugins/kubernetes-react/src/components/CustomResources/ArgoRollouts/RolloutDrawer.tsx @@ -18,6 +18,7 @@ import React from 'react'; import { KubernetesStructuredMetadataTableDrawer } from '../../KubernetesDrawer'; import Typography from '@material-ui/core/Typography'; import Grid from '@material-ui/core/Grid'; +import Chip from '@material-ui/core/Chip'; export const RolloutDrawer = ({ rollout, @@ -26,6 +27,7 @@ export const RolloutDrawer = ({ rollout: any; expanded?: boolean; }) => { + const namespace = rollout.metadata?.namespace; return ( + {namespace && ( + + + + )} ); diff --git a/plugins/kubernetes/dev/index.tsx b/plugins/kubernetes/dev/index.tsx index fbc666ae13..2de5a17f25 100644 --- a/plugins/kubernetes/dev/index.tsx +++ b/plugins/kubernetes/dev/index.tsx @@ -33,6 +33,7 @@ import fixture1 from '../src/__fixtures__/1-deployments.json'; import fixture2 from '../src/__fixtures__/2-deployments.json'; import fixture3 from '../src/__fixtures__/1-cronjobs.json'; import fixture4 from '../src/__fixtures__/2-cronjobs.json'; +import fixture5 from '../src/__fixtures__/1-rollouts.json'; import { TestApiProvider } from '@backstage/test-utils'; const mockEntity: Entity = { @@ -186,5 +187,18 @@ createDevApp()
    ), }) + .addPage({ + path: '/fixture-5', + title: 'Fixture 5', + element: ( + + + + + + ), + }) .registerPlugin(kubernetesPlugin) .render(); diff --git a/plugins/kubernetes/src/__fixtures__/1-rollouts.json b/plugins/kubernetes/src/__fixtures__/1-rollouts.json new file mode 100644 index 0000000000..66929b9129 --- /dev/null +++ b/plugins/kubernetes/src/__fixtures__/1-rollouts.json @@ -0,0 +1,2908 @@ +{ + "pods": [ + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.11\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-2m5hv", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593216", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-2m5hv", + "uid": "aadb71c0-36fa-43e3-b38a-162f134d4359" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://aa4489297c34c48bb33c18474a8d2b33854a82ed42155680b259f635f556ce70", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.11", + "podIPs": [ + { + "ip": "172.17.0.11" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.7\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-4v6s8", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593221", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-4v6s8", + "uid": "32e56490-6f20-4757-991f-a0c7fb407358" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://d91cc76c41249b8d3dfcf538d180b471b2a7966aae0d17a818307c8a9b4af897", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.7", + "podIPs": [ + { + "ip": "172.17.0.7" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-24T11:39:26.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-24T11:39:26.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.6\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-24T11:39:27.000Z" + } + ], + "name": "dice-roller-6c8646bfd-b9zt5", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "503886", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-b9zt5", + "uid": "8b6601b6-469e-4e89-8fd0-abb2f1a567e4" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:26.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:27.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:27.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:26.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://c50e0d0fa96f09a2ed5df7dd5a7f7de88e6b7c7addb8f002f299d6afc52d82ce", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-24T11:39:27.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.6", + "podIPs": [ + { + "ip": "172.17.0.6" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-24T11:39:26.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.13\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-cfxqc", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593211", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-cfxqc", + "uid": "e87e1776-0ca7-41fb-aeea-e1f648387545" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:51.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://c1641d986aae424429b7c2c1117baeb17d3794f73206bd57292cdf8264f929b2", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.13", + "podIPs": [ + { + "ip": "172.17.0.13" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:51.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.15\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:54.000Z" + } + ], + "name": "dice-roller-6c8646bfd-dtv5z", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593190", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-dtv5z", + "uid": "1638a41b-e47e-4c17-a1f7-7b447df248b6" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:51.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://e62c32db58dbfe0a74b2d2cba0e0a97b7f222693c68e930037ac8738c4758ca3", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.15", + "podIPs": [ + { + "ip": "172.17.0.15" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:51.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.12\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:53.000Z" + } + ], + "name": "dice-roller-6c8646bfd-hhts2", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593186", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-hhts2", + "uid": "ea0b147a-c56a-46e6-9445-7a0b1b0ed3c0" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://bcdbc153630f90556d57ff0d62f04d847ca63a5f0a7e5d9230683623d33d4b8d", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.12", + "podIPs": [ + { + "ip": "172.17.0.12" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.14\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-j68lm", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593226", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-j68lm", + "uid": "b230ff1d-7a13-479b-9c7b-77c26bd79f62" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://30fa8a3429f86ab8e9a4cec472b79d74266609082703f48950f4aae021e9d6a2", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.14", + "podIPs": [ + { + "ip": "172.17.0.14" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.9\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:53.000Z" + } + ], + "name": "dice-roller-6c8646bfd-m6f9w", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593181", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-m6f9w", + "uid": "9b0079f6-ff29-4619-bf6e-71cc10199ac5" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:53.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://f78767ee90eedffe46ff64bfe76d7f69426800dd89f3df012daf0baf3a9c5bdd", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.9", + "podIPs": [ + { + "ip": "172.17.0.9" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-24T11:39:27.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-24T11:39:27.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.4\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-24T11:39:28.000Z" + } + ], + "name": "dice-roller-6c8646bfd-nv9pk", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "503918", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-nv9pk", + "uid": "acf7f77f-78c6-4d4b-bc73-637211770ffc" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:27.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:28.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:28.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-24T11:39:27.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://63dec9b32942c4b09ae43d09d6978261f674a3ee623823b8f1d20da8044c12ac", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-24T11:39:28.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.4", + "podIPs": [ + { + "ip": "172.17.0.4" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-24T11:39:27.000Z" + } + }, + { + "metadata": { + "creationTimestamp": "2020-09-25T09:58:50.000Z", + "generateName": "dice-roller-6c8646bfd-", + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:generateName": {}, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"5126c354-4310-4e23-a9e4-c9b87cb69792\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:conditions": { + "k:{\"type\":\"ContainersReady\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Initialized\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Ready\"}": { + ".": {}, + "f:lastProbeTime": {}, + "f:lastTransitionTime": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:containerStatuses": {}, + "f:hostIP": {}, + "f:phase": {}, + "f:podIP": {}, + "f:podIPs": { + ".": {}, + "k:{\"ip\":\"172.17.0.10\"}": { + ".": {}, + "f:ip": {} + } + }, + "f:startTime": {} + } + }, + "manager": "kubelet", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd-pjhfj", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "ReplicaSet", + "name": "dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + } + ], + "resourceVersion": "593205", + "selfLink": "/api/v1/namespaces/default/pods/dice-roller-6c8646bfd-pjhfj", + "uid": "78775c3a-7af2-4ebe-a676-bc2e5dfa2bcc" + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", + "name": "default-token-5gctn", + "readOnly": true + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "enableServiceLinks": true, + "nodeName": "minikube", + "priority": 0, + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + "tolerations": [ + { + "effect": "NoExecute", + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "tolerationSeconds": 300 + }, + { + "effect": "NoExecute", + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "tolerationSeconds": 300 + } + ], + "volumes": [ + { + "name": "default-token-5gctn", + "secret": { + "defaultMode": 420, + "secretName": "default-token-5gctn" + } + } + ] + }, + "status": { + "conditions": [ + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "Initialized" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "Ready" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "status": "True", + "type": "ContainersReady" + }, + { + "lastProbeTime": null, + "lastTransitionTime": "2020-09-25T09:58:50.000Z", + "status": "True", + "type": "PodScheduled" + } + ], + "containerStatuses": [ + { + "containerID": "docker://cbb83dda250db74285dcbe0b81bd0896acf402bac9710af090311f7360f824aa", + "image": "nginx:1.14.2", + "imageID": "docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d", + "lastState": {}, + "name": "nginx", + "ready": true, + "restartCount": 0, + "started": true, + "state": { + "running": { + "startedAt": "2020-09-25T09:58:53.000Z" + } + } + } + ], + "hostIP": "192.168.64.2", + "phase": "Running", + "podIP": "172.17.0.10", + "podIPs": [ + { + "ip": "172.17.0.10" + } + ], + "qosClass": "BestEffort", + "startTime": "2020-09-25T09:58:50.000Z" + } + } + ], + "replicaSets": [ + { + "metadata": { + "annotations": { + "deployment.kubernetes.io/desired-replicas": "10", + "deployment.kubernetes.io/max-replicas": "13", + "deployment.kubernetes.io/revision": "2" + }, + "creationTimestamp": "2020-09-24T11:39:26.000Z", + "generation": 3, + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + }, + "managedFields": [ + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:deployment.kubernetes.io/desired-replicas": {}, + "f:deployment.kubernetes.io/max-replicas": {}, + "f:deployment.kubernetes.io/revision": {} + }, + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"7551e949-42d1-4061-83c5-9da107186e47\"}": { + ".": {}, + "f:apiVersion": {}, + "f:blockOwnerDeletion": {}, + "f:controller": {}, + "f:kind": {}, + "f:name": {}, + "f:uid": {} + } + } + }, + "f:spec": { + "f:replicas": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {}, + "f:pod-template-hash": {} + } + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {}, + "f:pod-template-hash": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + } + }, + "f:status": { + "f:availableReplicas": {}, + "f:fullyLabeledReplicas": {}, + "f:observedGeneration": {}, + "f:readyReplicas": {}, + "f:replicas": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller-6c8646bfd", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "Deployment", + "name": "dice-roller", + "uid": "7551e949-42d1-4061-83c5-9da107186e47" + } + ], + "resourceVersion": "593228", + "selfLink": "/apis/apps/v1/namespaces/default/replicasets/dice-roller-6c8646bfd", + "uid": "5126c354-4310-4e23-a9e4-c9b87cb69792" + }, + "spec": { + "replicas": 10, + "selector": { + "matchLabels": { + "app": "dice-roller", + "pod-template-hash": "6c8646bfd" + } + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller", + "pod-template-hash": "6c8646bfd" + } + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "terminationGracePeriodSeconds": 30 + } + } + }, + "status": { + "availableReplicas": 10, + "fullyLabeledReplicas": 10, + "observedGeneration": 3, + "readyReplicas": 10, + "replicas": 10 + } + } + ], + "customResources": [ + { + "apiVersion": "argoproj.io/v1alpha1", + "kind": "Rollout", + "metadata": { + "annotations": { + "deployment.kubernetes.io/revision": "2", + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"metadata\":{\"annotations\":{},\"labels\":{\"backstage.io/kubernetes-id\":\"dice-roller\"},\"name\":\"dice-roller\",\"namespace\":\"default\"},\"spec\":{\"replicas\":10,\"selector\":{\"matchLabels\":{\"app\":\"dice-roller\"}},\"template\":{\"metadata\":{\"labels\":{\"app\":\"dice-roller\",\"backstage.io/kubernetes-id\":\"dice-roller\"}},\"spec\":{\"containers\":[{\"image\":\"nginx:1.14.2\",\"name\":\"nginx\",\"ports\":[{\"containerPort\":80}]}]}}}}\n" + }, + "creationTimestamp": "2020-09-23T12:00:55.000Z", + "generation": 3, + "labels": { + "backstage.io/kubernetes-id": "dice-roller" + }, + "managedFields": [ + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubectl.kubernetes.io/last-applied-configuration": {} + }, + "f:labels": { + ".": {}, + "f:backstage.io/kubernetes-id": {} + } + }, + "f:spec": { + "f:progressDeadlineSeconds": {}, + "f:replicas": {}, + "f:revisionHistoryLimit": {}, + "f:selector": { + "f:matchLabels": { + ".": {}, + "f:app": {} + } + }, + "f:strategy": { + "f:rollingUpdate": { + ".": {}, + "f:maxSurge": {}, + "f:maxUnavailable": {} + }, + "f:type": {} + }, + "f:template": { + "f:metadata": { + "f:labels": { + ".": {}, + "f:app": {}, + "f:backstage.io/kubernetes-id": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:ports": { + ".": {}, + "k:{\"containerPort\":80,\"protocol\":\"TCP\"}": { + ".": {}, + "f:containerPort": {}, + "f:protocol": {} + } + }, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {} + } + } + } + }, + "manager": "kubectl", + "operation": "Update", + "time": "2020-09-25T09:58:50.000Z" + }, + { + "apiVersion": "apps/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + "f:deployment.kubernetes.io/revision": {} + } + }, + "f:status": { + "f:availableReplicas": {}, + "f:conditions": { + ".": {}, + "k:{\"type\":\"Available\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + }, + "k:{\"type\":\"Progressing\"}": { + ".": {}, + "f:lastTransitionTime": {}, + "f:lastUpdateTime": {}, + "f:message": {}, + "f:reason": {}, + "f:status": {}, + "f:type": {} + } + }, + "f:observedGeneration": {}, + "f:readyReplicas": {}, + "f:replicas": {}, + "f:updatedReplicas": {} + } + }, + "manager": "kube-controller-manager", + "operation": "Update", + "time": "2020-09-25T09:58:55.000Z" + } + ], + "name": "dice-roller", + "namespace": "default", + "resourceVersion": "593230", + "selfLink": "/apis/apps/v1/namespaces/default/deployments/dice-roller", + "uid": "7551e949-42d1-4061-83c5-9da107186e47" + }, + "spec": { + "progressDeadlineSeconds": 600, + "replicas": 10, + "revisionHistoryLimit": 10, + "selector": { + "matchLabels": { + "app": "dice-roller" + } + }, + "strategy": { + "rollingUpdate": { + "maxSurge": "25%", + "maxUnavailable": "25%" + }, + "type": "RollingUpdate" + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "dice-roller", + "backstage.io/kubernetes-id": "dice-roller" + } + }, + "spec": { + "containers": [ + { + "image": "nginx:1.14.2", + "imagePullPolicy": "IfNotPresent", + "name": "nginx", + "ports": [ + { + "containerPort": 80, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File" + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "schedulerName": "default-scheduler", + "securityContext": {}, + "terminationGracePeriodSeconds": 30 + } + } + }, + "status": { + "availableReplicas": 10, + "conditions": [ + { + "lastTransitionTime": "2020-09-23T12:00:55.000Z", + "lastUpdateTime": "2020-09-24T11:39:28.000Z", + "message": "ReplicaSet \"dice-roller-6c8646bfd\" has successfully progressed.", + "reason": "NewReplicaSetAvailable", + "status": "True", + "type": "Progressing" + }, + { + "lastTransitionTime": "2020-09-25T09:58:55.000Z", + "lastUpdateTime": "2020-09-25T09:58:55.000Z", + "message": "Deployment has minimum availability.", + "reason": "MinimumReplicasAvailable", + "status": "True", + "type": "Available" + } + ], + "observedGeneration": 3, + "readyReplicas": 10, + "replicas": 10, + "updatedReplicas": 10 + } + } + ], + "horizontalPodAutoscalers": [ + { + "apiVersion": "autoscaling/v2", + "kind": "HorizontalPodAutoscaler", + "metadata": { + "annotations": {}, + "creationTimestamp": "2024-02-13T20:13:52Z", + "labels": { + "backstage.io/kubernetes-id": "dice-roller" + }, + "name": "dice-roller", + "namespace": "default", + "resourceVersion": "6717s736", + "uid": "a34c90e1-8e8f-407f-b4c5-b4543bd56c1b" + }, + "spec": { + "maxReplicas": 2, + "metrics": [ + { + "resource": { + "name": "cpu", + "target": { + "averageUtilization": 50, + "type": "Utilization" + } + }, + "type": "Resource" + } + ], + "minReplicas": 1, + "scaleTargetRef": { + "apiVersion": "apps/v1", + "kind": "Deployment", + "name": "dice-roller" + } + }, + "status": { + "conditions": [ + { + "lastTransitionTime": "2024-05-17T19:50:35Z", + "message": "recent recommendations were higher than current one, applying the highest recent recommendation", + "reason": "ScaleDownStabilized", + "status": "True", + "type": "AbleToScale" + }, + { + "lastTransitionTime": "2024-05-16T06:21:01Z", + "message": "the HPA was able to successfully calculate a replica count from cpu resource utilization (percentage of request)", + "reason": "ValidMetricFound", + "status": "True", + "type": "ScalingActive" + }, + { + "lastTransitionTime": "2024-05-16T06:21:01Z", + "message": "the desired replica count is more than the maximum replica count", + "reason": "TooManyReplicas", + "status": "True", + "type": "ScalingLimited" + } + ], + "currentMetrics": [ + { + "resource": { + "current": { + "averageUtilization": 100, + "averageValue": "50m", + "value": "100m" + }, + "name": "cpu" + }, + "type": "Resource" + } + ], + "currentReplicas": 2, + "desiredReplicas": 2, + "lastScaleTime": "2024-02-13T20:14:23Z" + } + } + ] +} From 9182cb074f2933291ef72443b43c5d386db1093d Mon Sep 17 00:00:00 2001 From: bnechyporenko Date: Tue, 2 Jul 2024 19:19:56 +0200 Subject: [PATCH 168/510] Feedback Signed-off-by: bnechyporenko --- docs/features/software-templates/writing-custom-actions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/features/software-templates/writing-custom-actions.md b/docs/features/software-templates/writing-custom-actions.md index 41bd7d2026..3b5843e795 100644 --- a/docs/features/software-templates/writing-custom-actions.md +++ b/docs/features/software-templates/writing-custom-actions.md @@ -146,7 +146,7 @@ argument. It looks like the following: - `ctx.baseUrl` - a string where the template is located - `ctx.checkpoint` - _Experimental_ allows to implement idempotency of the actions by not re-running the same function again if it was - executed successfully on the previous run. + executed successfully on the previous run. More information [here](https://github.com/backstage/backstage/tree/master/beps/0004-scaffolder-task-idempotency#checkpoints) - `ctx.logger` - a Winston logger for additional logging inside your action - `ctx.logStream` - a stream version of the logger if needed - `ctx.workspacePath` - a string of the working directory of the template run @@ -225,7 +225,7 @@ Idempotent action could be achieved via the usage of checkpoints. Example: -```ts +```ts title="plugins/my-company-scaffolder-actions-plugin/src/vendor/my-custom-action.ts" const res = await ctx.checkpoint?.('create.projects', async () => { const projectStgId = createStagingProjectId(); const projectProId = createProductionProjectId(); From 920d0f9c96c0e92275f5566a6a9e495b03aa1f12 Mon Sep 17 00:00:00 2001 From: bnechyporenko Date: Tue, 2 Jul 2024 19:20:54 +0200 Subject: [PATCH 169/510] Feedback Signed-off-by: bnechyporenko --- docs/features/software-templates/writing-custom-actions.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/features/software-templates/writing-custom-actions.md b/docs/features/software-templates/writing-custom-actions.md index 3b5843e795..6c1ea573db 100644 --- a/docs/features/software-templates/writing-custom-actions.md +++ b/docs/features/software-templates/writing-custom-actions.md @@ -145,8 +145,10 @@ When the action `handler` is called, we provide you a `context` as the only argument. It looks like the following: - `ctx.baseUrl` - a string where the template is located -- `ctx.checkpoint` - _Experimental_ allows to implement idempotency of the actions by not re-running the same function again if it was - executed successfully on the previous run. More information [here](https://github.com/backstage/backstage/tree/master/beps/0004-scaffolder-task-idempotency#checkpoints) +- `ctx.checkpoint` - _Experimental_ allows to + implement [idempotency of the actions](https://github.com/backstage/backstage/tree/master/beps/0004-scaffolder-task-idempotency) + by not re-running the same function again if it was + executed successfully on the previous run. - `ctx.logger` - a Winston logger for additional logging inside your action - `ctx.logStream` - a stream version of the logger if needed - `ctx.workspacePath` - a string of the working directory of the template run From 44ecd6d5eebb51613deb6e921234b097452a52c9 Mon Sep 17 00:00:00 2001 From: aramissennyeydd Date: Tue, 2 Jul 2024 18:47:10 -0400 Subject: [PATCH 170/510] docs: add a link to config definition Signed-off-by: aramissennyeydd --- docs/features/software-catalog/external-integrations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/software-catalog/external-integrations.md b/docs/features/software-catalog/external-integrations.md index 56423c9392..98fae5a95e 100644 --- a/docs/features/software-catalog/external-integrations.md +++ b/docs/features/software-catalog/external-integrations.md @@ -346,7 +346,7 @@ catalog: timeout: { minutes: 50 } ``` -This approach will also allow you to customize the schedule per environment +This approach will also allow you to customize the schedule per environment. You can also [add a schema to your config](../../conf/defining.md). #### New Backend From 72143aa7d65a743ec521536a64b1b1164c254136 Mon Sep 17 00:00:00 2001 From: Tavi Nolan Date: Wed, 3 Jul 2024 11:03:11 +0100 Subject: [PATCH 171/510] Changing to original link Signed-off-by: Tavi Nolan --- docs/features/software-catalog/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/software-catalog/configuration.md b/docs/features/software-catalog/configuration.md index 9524886a49..3c875d90c4 100644 --- a/docs/features/software-catalog/configuration.md +++ b/docs/features/software-catalog/configuration.md @@ -47,7 +47,7 @@ action is logged for further investigation. ### Local File (`type: file`) Configurations In addition to url locations, you can use the `file` location type to bring in content from the local file system. You should only use this for local development, test setups, and example data, not for production data. -You are also not able to use placeholders in them like `$text`, `$json` or `$yaml`. You can however reference other files relative to the current file. See the full [catalog example data set here](https://github.com/backstage/backstage/blob/master/packages/create-app/templates/default-app/app-config.yaml.hbs) for an extensive example. +You are also not able to use placeholders in them like `$text`, `$json` or `$yaml`. You can however reference other files relative to the current file. See the full [catalog example data set here](https://github.com/backstage/backstage/tree/master/packages/catalog-model/examples) for an extensive example. Here is an example pulling in the `all.yaml` file from the examples folder. Note the use of `../../` to go up two levels from the current execution path of the backend. This is typically `packages/backend/`. From 25ff80427472fb11658a992bdad4cfa69a0f515e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Edstr=C3=B6m?= Date: Wed, 3 Jul 2024 12:20:45 +0200 Subject: [PATCH 172/510] Modified propname to be data-test and added unit test for custom data-testid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Simon Edström --- .../core-components/src/components/Select/Select.test.tsx | 8 ++++++++ packages/core-components/src/components/Select/Select.tsx | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/core-components/src/components/Select/Select.test.tsx b/packages/core-components/src/components/Select/Select.test.tsx index 71159150e4..3c05c6bcaf 100644 --- a/packages/core-components/src/components/Select/Select.test.tsx +++ b/packages/core-components/src/components/Select/Select.test.tsx @@ -66,4 +66,12 @@ describe(', + ); + const input = getByTestId('custom-select'); + expect(input.textContent).toBe('All results'); + }); }); diff --git a/packages/core-components/src/components/Select/Select.tsx b/packages/core-components/src/components/Select/Select.tsx index 9c0d4e4dfe..b78693213f 100644 --- a/packages/core-components/src/components/Select/Select.tsx +++ b/packages/core-components/src/components/Select/Select.tsx @@ -136,7 +136,7 @@ export type SelectProps = { native?: boolean; disabled?: boolean; margin?: 'dense' | 'none'; - testid?: string; + 'data-testid'?: string; }; /** @public */ @@ -152,7 +152,7 @@ export function SelectComponent(props: SelectProps) { native = false, disabled = false, margin, - testid = 'select', + 'data-testid': dataTestId = 'select', } = props; const classes = useStyles(); const [value, setValue] = useState( @@ -205,7 +205,7 @@ export function SelectComponent(props: SelectProps) { value={value} native={native} disabled={disabled} - data-testid={testid} + data-testid={dataTestId} displayEmpty multiple={multiple} margin={margin} From f0426dc9f5e50faf40d24b076506fbf47e9032fd Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 3 Jul 2024 14:04:11 +0200 Subject: [PATCH 173/510] Update .changeset/new-sheep-arrive.md Signed-off-by: Camila Belo --- .changeset/new-sheep-arrive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/new-sheep-arrive.md b/.changeset/new-sheep-arrive.md index 9ae0af93aa..00e759a187 100644 --- a/.changeset/new-sheep-arrive.md +++ b/.changeset/new-sheep-arrive.md @@ -2,4 +2,4 @@ '@backstage/core-components': patch --- -Modified the Select component to take in a testid parameter that sets the data-testid of the material ui Select sub-component, ensuring backwards compatibility with default value corresponding to previously hardcoded data-testid of "select". +Modified the `Select` component to take in a `data-testid` parameter ensuring backwards compatibility with default value corresponding to previously hardcoded `data-testid` of "select". From ece2dae403e80c3d01a326cb6fe3da8eb8f84d2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Edstr=C3=B6m?= Date: Wed, 3 Jul 2024 14:25:21 +0200 Subject: [PATCH 174/510] Fixed RepoUrlPickerHost having incorrect testid in test, data-testid was specified (but did nothing) and the test expected the hardcoded 'select' testid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Simon Edström --- .../fields/RepoUrlPicker/RepoUrlPickerHost.test.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPickerHost.test.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPickerHost.test.tsx index 0c7ca75990..a070e0c6e4 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPickerHost.test.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPickerHost.test.tsx @@ -64,7 +64,7 @@ describe('RepoUrlPickerHostField', () => { , ); - fireEvent.mouseDown(getByTestId('select')); + fireEvent.mouseDown(getByTestId('host-select')); expect(getByText('gitlab.com')).toBeInTheDocument(); const listbox = within(getByRole('combobox')); @@ -93,7 +93,7 @@ describe('RepoUrlPickerHostField', () => { , ); - fireEvent.mouseDown(getByTestId('select')); + fireEvent.mouseDown(getByTestId('host-select')); expect(getByText('gitlab.com')).toBeInTheDocument(); const listbox = within(getByRole('combobox')); From fad1b903a8e166492837c003916adb1f59be788e Mon Sep 17 00:00:00 2001 From: ElaineDeMattosSilvaB Date: Wed, 3 Jul 2024 19:47:37 +0200 Subject: [PATCH 175/510] feat: allow the oauth token to be used in the gitlab:projectVariableAction:create action Signed-off-by: ElaineDeMattosSilvaB --- .changeset/grumpy-owls-suffer.md | 5 ++ ...tlabProjectVariableCreate.examples.test.ts | 61 ++++++++++--------- .../actions/gitlabProjectVariableCreate.ts | 27 ++++---- 3 files changed, 49 insertions(+), 44 deletions(-) create mode 100644 .changeset/grumpy-owls-suffer.md diff --git a/.changeset/grumpy-owls-suffer.md b/.changeset/grumpy-owls-suffer.md new file mode 100644 index 0000000000..977055eb33 --- /dev/null +++ b/.changeset/grumpy-owls-suffer.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gitlab': patch +--- + +Allow the `createGitlabProjectVariableAction` to use oauth tokens diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectVariableCreate.examples.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectVariableCreate.examples.test.ts index 1eeb01ca91..99b26682d8 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectVariableCreate.examples.test.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectVariableCreate.examples.test.ts @@ -26,7 +26,7 @@ const mockGitlabClient = { create: jest.fn(), }, }; -jest.mock('@gitbeaker/node', () => ({ +jest.mock('@gitbeaker/rest', () => ({ Gitlab: class { constructor() { return mockGitlabClient; @@ -41,7 +41,7 @@ describe('gitlab:projectVariableAction: create examples', () => { { host: 'gitlab.com', token: 'tokenlols', - apiBaseUrl: 'https://api.gitlab.com', + apiBaseUrl: 'https://api.gitlab.com/api/v4', }, { host: 'hosted.gitlab.com', @@ -79,17 +79,18 @@ describe('gitlab:projectVariableAction: create examples', () => { expect(mockGitlabClient.ProjectVariables.create).toHaveBeenCalledWith( '123', + 'MY_VARIABLE', + 'my_value', { - key: 'MY_VARIABLE', - value: 'my_value', - variable_type: 'env_var', - environment_scope: '*', + variableType: 'env_var', // Correctly using variableType + environmentScope: '*', masked: false, protected: false, raw: false, }, ); }); + it(`Should ${examples[1].description}`, async () => { mockGitlabClient.ProjectVariables.create.mockResolvedValue({ token: 'TOKEN', @@ -102,14 +103,14 @@ describe('gitlab:projectVariableAction: create examples', () => { expect(mockGitlabClient.ProjectVariables.create).toHaveBeenCalledWith( '123', + 'MY_VARIABLE', + 'my-file-content', { - key: 'MY_VARIABLE', - value: 'my-file-content', + variableType: 'file', // Correctly using variableType protected: false, masked: false, raw: false, - environment_scope: '*', - variable_type: 'file', + environmentScope: '*', }, ); }); @@ -126,13 +127,13 @@ describe('gitlab:projectVariableAction: create examples', () => { expect(mockGitlabClient.ProjectVariables.create).toHaveBeenCalledWith( '456', + 'MY_VARIABLE', + 'my_value', { - key: 'MY_VARIABLE', - value: 'my_value', masked: false, raw: false, - environment_scope: '*', - variable_type: 'env_var', + environmentScope: '*', + variableType: 'env_var', // Correctly using variableType protected: true, }, ); @@ -150,13 +151,13 @@ describe('gitlab:projectVariableAction: create examples', () => { expect(mockGitlabClient.ProjectVariables.create).toHaveBeenCalledWith( '789', + 'DB_PASSWORD', + 'password123', { - key: 'DB_PASSWORD', - value: 'password123', protected: false, raw: false, - environment_scope: '*', - variable_type: 'env_var', + environmentScope: '*', + variableType: 'env_var', // Correctly using variableType masked: true, }, ); @@ -174,12 +175,12 @@ describe('gitlab:projectVariableAction: create examples', () => { expect(mockGitlabClient.ProjectVariables.create).toHaveBeenCalledWith( '123', + 'MY_VARIABLE', + 'my_value', { - key: 'MY_VARIABLE', - value: 'my_value', protected: false, - environment_scope: '*', - variable_type: 'env_var', + environmentScope: '*', + variableType: 'env_var', // Correctly using variableType masked: false, raw: true, }, @@ -198,14 +199,14 @@ describe('gitlab:projectVariableAction: create examples', () => { expect(mockGitlabClient.ProjectVariables.create).toHaveBeenCalledWith( '123', + 'MY_VARIABLE', + 'my_value', { - key: 'MY_VARIABLE', - value: 'my_value', protected: false, - variable_type: 'env_var', + variableType: 'env_var', // Correctly using variableType masked: false, raw: false, - environment_scope: 'production', + environmentScope: 'production', }, ); }); @@ -222,14 +223,14 @@ describe('gitlab:projectVariableAction: create examples', () => { expect(mockGitlabClient.ProjectVariables.create).toHaveBeenCalledWith( '123', + 'MY_VARIABLE', + 'my_value', { - key: 'MY_VARIABLE', - value: 'my_value', protected: false, - variable_type: 'env_var', + variableType: 'env_var', // Correctly using variableType masked: false, raw: false, - environment_scope: '*', + environmentScope: '*', }, ); }); diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectVariableCreate.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectVariableCreate.ts index a07ec747fa..3a9eeec0a1 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectVariableCreate.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectVariableCreate.ts @@ -16,10 +16,10 @@ import { ScmIntegrationRegistry } from '@backstage/integration'; import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; -import { Gitlab } from '@gitbeaker/node'; +import { VariableType } from '@gitbeaker/rest'; import { z } from 'zod'; import commonGitlabConfig from '../commonGitlabConfig'; -import { getToken } from '../util'; +import { getClient, parseRepoUrl } from '../util'; import { examples } from './gitlabProjectVariableCreate.examples'; /** @@ -72,6 +72,7 @@ export const createGitlabProjectVariableAction = (options: { }, async handler(ctx) { const { + repoUrl, projectId, key, value, @@ -80,21 +81,19 @@ export const createGitlabProjectVariableAction = (options: { masked = false, raw = false, environmentScope = '*', + token, } = ctx.input; - const { token, integrationConfig } = getToken(ctx.input, integrations); - const api = new Gitlab({ - host: integrationConfig.config.baseUrl, - token: token, - }); - await api.ProjectVariables.create(projectId, { - key: key, - value: value, - variable_type: variableType, + const { host } = parseRepoUrl(repoUrl, integrations); + + const api = getClient({ host, integrations, token }); + + await api.ProjectVariables.create(projectId, key, value, { + variableType: variableType as VariableType, protected: variableProtected, - masked: masked, - raw: raw, - environment_scope: environmentScope, + masked, + raw, + environmentScope, }); }, }); From 1ba55321bfea5911cec426452868f8d7e50edb2c Mon Sep 17 00:00:00 2001 From: "Stephen A. Wilson" Date: Wed, 3 Jul 2024 20:17:30 -0400 Subject: [PATCH 176/510] Fix linting errors Signed-off-by: Stephen A. Wilson --- plugins/techdocs/src/home/components/Tables/DocsTable.tsx | 2 +- plugins/techdocs/src/home/components/Tables/columns.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/techdocs/src/home/components/Tables/DocsTable.tsx b/plugins/techdocs/src/home/components/Tables/DocsTable.tsx index e2904374a0..b1537affdb 100644 --- a/plugins/techdocs/src/home/components/Tables/DocsTable.tsx +++ b/plugins/techdocs/src/home/components/Tables/DocsTable.tsx @@ -58,7 +58,7 @@ const defaultColumns: TableColumn[] = [ columnFactories.createKindColumn(), columnFactories.createTypeColumn(), ]; - + /** * Component which renders a table documents * diff --git a/plugins/techdocs/src/home/components/Tables/columns.tsx b/plugins/techdocs/src/home/components/Tables/columns.tsx index 08c190c26b..ef22f6d288 100644 --- a/plugins/techdocs/src/home/components/Tables/columns.tsx +++ b/plugins/techdocs/src/home/components/Tables/columns.tsx @@ -31,12 +31,12 @@ function customTitle(entity: Entity): string { */ export const columnFactories = { createTitleColumn(options?: { hidden?: boolean }): TableColumn { - const nameCol = columnFactories.createNameColumn() + const nameCol = columnFactories.createNameColumn(); return { ...nameCol, field: 'entity.metadata.title', hidden: options?.hidden, - } + }; }, createNameColumn(): TableColumn { return { From 3c2659e721086903d5bdad60778775950cbadee8 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Thu, 4 Jul 2024 10:40:23 +0200 Subject: [PATCH 177/510] add fetch api to deps Signed-off-by: Emma Indal --- plugins/search/src/alpha.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/search/src/alpha.tsx b/plugins/search/src/alpha.tsx index 5c85d097d4..c202d58712 100644 --- a/plugins/search/src/alpha.tsx +++ b/plugins/search/src/alpha.tsx @@ -33,7 +33,7 @@ import { useApi, DiscoveryApi, discoveryApiRef, - identityApiRef, + fetchApiRef, FetchApi, } from '@backstage/core-plugin-api'; @@ -79,7 +79,7 @@ import { export const searchApi = createApiExtension({ factory: { api: searchApiRef, - deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef }, + deps: { discoveryApi: discoveryApiRef, fetchApi: fetchApiRef }, factory: ({ fetchApi, discoveryApi, From 1117aba4bfc7ce64b85d6aaeef9f2639dac70492 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Thu, 4 Jul 2024 10:51:47 +0200 Subject: [PATCH 178/510] add changeset Signed-off-by: Emma Indal --- .changeset/thick-moose-decide.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/thick-moose-decide.md diff --git a/.changeset/thick-moose-decide.md b/.changeset/thick-moose-decide.md new file mode 100644 index 0000000000..194932979d --- /dev/null +++ b/.changeset/thick-moose-decide.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search': patch +--- + +Update deps in search api extension to include fetch api From 5351b8c6bd0b26d5da70dcb9587e72bae818c9c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 4 Jul 2024 11:53:18 +0200 Subject: [PATCH 179/510] Update publishing.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- docs/publishing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/publishing.md b/docs/publishing.md index d7a4f65008..50d78ebf09 100644 --- a/docs/publishing.md +++ b/docs/publishing.md @@ -75,7 +75,7 @@ Given one or more PRs towards master that we want to create a patch release for, ./scripts/patch-release-for-pr.js ... ``` -Wait until the script has finished executing, at the end of the output you will find a link of the format `https://github.com/backstage/backstage/compare/patch/...`. Open this link in your browser to create a PR for the patch release. Finish the sentence "This release fixes an issue where..." and create the PR. +Wait until the script has finished executing, at the end of the output you will find a link of the format `https://github.com/backstage/backstage/pull/new/patch-release-pr-...`. Open this link in your browser to create a PR for the patch release. Finish the sentence "This release fixes an issue where..." and create the PR. Once the PR has been approved and merged, the patch release will be automatically created. The patch release is complete when a notification has been posted to Discord in the `#announcements` channel. Keep an eye on "Deploy Packages" workflow and re-trigger if it fails. It is safe to re-trigger any part of this workflow, including the release step. From 031f07d470782a116b7de613173c426ec33703be Mon Sep 17 00:00:00 2001 From: Adem Simsek Date: Thu, 4 Jul 2024 16:50:26 +0200 Subject: [PATCH 180/510] docs: Use correct Application Link Setup for Bitbucket Server Signed-off-by: Adem Simsek --- docs/auth/bitbucketServer/provider.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/auth/bitbucketServer/provider.md b/docs/auth/bitbucketServer/provider.md index 96c7db263e..eef934ca60 100644 --- a/docs/auth/bitbucketServer/provider.md +++ b/docs/auth/bitbucketServer/provider.md @@ -10,8 +10,8 @@ users using Bitbucket Server. This does **NOT** work with Bitbucket Cloud. ## Create an Application Link in Bitbucket Server -To add Bitbucket Server authentication, you must create an outgoing application link. Follow the steps described in -the [Bitbucket Server documentation](https://confluence.atlassian.com/bitbucketserver/configure-an-outgoing-link-1108483656.html) +To add Bitbucket Server authentication, you must create an incoming application link. Follow the steps described in +the [Bitbucket Server documentation](https://confluence.atlassian.com/bitbucketserver/configure-an-incoming-link-1108483657.html) to create one. ## Configuration From e90a2cdc0578b32edc532185ab2babaa7623260b Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 5 Jul 2024 10:22:05 -0500 Subject: [PATCH 181/510] Added the Catalog logs module to the `create-app` template Signed-off-by: Andre Wanlin --- .changeset/fair-spoons-work.md | 5 +++++ packages/create-app/src/lib/versions.ts | 3 +++ .../templates/default-app/packages/backend/package.json.hbs | 1 + .../templates/default-app/packages/backend/src/index.ts | 3 +++ 4 files changed, 12 insertions(+) create mode 100644 .changeset/fair-spoons-work.md diff --git a/.changeset/fair-spoons-work.md b/.changeset/fair-spoons-work.md new file mode 100644 index 0000000000..e4b94625db --- /dev/null +++ b/.changeset/fair-spoons-work.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Added the Catalog logs module to the `create-app` template diff --git a/packages/create-app/src/lib/versions.ts b/packages/create-app/src/lib/versions.ts index febc68102c..25fd7b7c3c 100644 --- a/packages/create-app/src/lib/versions.ts +++ b/packages/create-app/src/lib/versions.ts @@ -58,6 +58,7 @@ import { version as pluginCatalog } from '../../../../plugins/catalog/package.js import { version as pluginCatalogCommon } from '../../../../plugins/catalog-common/package.json'; import { version as pluginCatalogReact } from '../../../../plugins/catalog-react/package.json'; import { version as pluginCatalogBackend } from '../../../../plugins/catalog-backend/package.json'; +import { version as pluginCatalogBackendModuleLogs } from '../../../../plugins/catalog-backend-module-logs/package.json'; import { version as pluginCatalogBackendModuleScaffolderEntityModel } from '../../../../plugins/catalog-backend-module-scaffolder-entity-model/package.json'; import { version as pluginCatalogGraph } from '../../../../plugins/catalog-graph/package.json'; import { version as pluginCatalogImport } from '../../../../plugins/catalog-import/package.json'; @@ -111,6 +112,8 @@ export const packageVersions = { '@backstage/plugin-catalog-common': pluginCatalogCommon, '@backstage/plugin-catalog-react': pluginCatalogReact, '@backstage/plugin-catalog-backend': pluginCatalogBackend, + '@backstage/plugin-catalog-backend-module-logs': + pluginCatalogBackendModuleLogs, '@backstage/plugin-catalog-backend-module-scaffolder-entity-model': pluginCatalogBackendModuleScaffolderEntityModel, '@backstage/plugin-catalog-graph': pluginCatalogGraph, diff --git a/packages/create-app/templates/default-app/packages/backend/package.json.hbs b/packages/create-app/templates/default-app/packages/backend/package.json.hbs index 8d95ee60a5..e26c788496 100644 --- a/packages/create-app/templates/default-app/packages/backend/package.json.hbs +++ b/packages/create-app/templates/default-app/packages/backend/package.json.hbs @@ -26,6 +26,7 @@ "@backstage/plugin-auth-backend-module-guest-provider": "^{{version '@backstage/plugin-auth-backend-module-guest-provider'}}", "@backstage/plugin-auth-node": "^{{version '@backstage/plugin-auth-node'}}", "@backstage/plugin-catalog-backend": "^{{version '@backstage/plugin-catalog-backend'}}", + "@backstage/plugin-catalog-backend-module-logs": "^{{version '@backstage/plugin-catalog-backend-module-logs'}}", "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "^{{version '@backstage/plugin-catalog-backend-module-scaffolder-entity-model'}}", "@backstage/plugin-permission-backend": "^{{version '@backstage/plugin-permission-backend'}}", "@backstage/plugin-permission-backend-module-allow-all-policy": "^{{version '@backstage/plugin-permission-backend-module-allow-all-policy'}}", diff --git a/packages/create-app/templates/default-app/packages/backend/src/index.ts b/packages/create-app/templates/default-app/packages/backend/src/index.ts index 1c442a8d95..239269288e 100644 --- a/packages/create-app/templates/default-app/packages/backend/src/index.ts +++ b/packages/create-app/templates/default-app/packages/backend/src/index.ts @@ -27,6 +27,9 @@ backend.add( import('@backstage/plugin-catalog-backend-module-scaffolder-entity-model'), ); +// See https://backstage.io/docs/features/software-catalog/configuration#subscribing-to-catalog-errors +backend.add(import('@backstage/plugin-catalog-backend-module-logs')); + // permission plugin backend.add(import('@backstage/plugin-permission-backend/alpha')); backend.add( From 0976bbd15238533f72038a66d0ec2696adb2daf2 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 5 Jul 2024 12:07:22 -0500 Subject: [PATCH 182/510] Added backend install steps for various auth providers Signed-off-by: Andre Wanlin --- docs/auth/atlassian/provider.md | 17 +++ docs/auth/aws-alb/provider.md | 67 +++++----- docs/auth/bitbucket/provider.md | 77 ++++++------ docs/auth/cloudflare/access.md | 174 -------------------------- docs/auth/cloudflare/provider.md | 82 ++++++++++++ docs/auth/github/provider.md | 33 +++-- docs/auth/gitlab/provider.md | 17 +++ docs/auth/google/gcp-iap-auth.md | 95 ++------------ docs/auth/google/provider.md | 21 +++- docs/auth/identity-resolver.md | 2 + docs/auth/microsoft/azure-easyauth.md | 137 +++++++++----------- docs/auth/microsoft/provider.md | 41 ++++-- docs/auth/oauth2-proxy/provider.md | 38 +++--- docs/auth/okta/provider.md | 17 +++ docs/auth/onelogin/provider.md | 39 ++++++ docs/auth/vmware-cloud/provider.md | 133 +++++--------------- 16 files changed, 439 insertions(+), 551 deletions(-) delete mode 100644 docs/auth/cloudflare/access.md create mode 100644 docs/auth/cloudflare/provider.md diff --git a/docs/auth/atlassian/provider.md b/docs/auth/atlassian/provider.md index c8db009805..44f6d097b9 100644 --- a/docs/auth/atlassian/provider.md +++ b/docs/auth/atlassian/provider.md @@ -79,6 +79,23 @@ The resolvers will be tried in order, but will only be skipped if they throw a ` If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. +## Backend Installation + +To add the provider to the backend we will first need to install the package by running this command: + +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-atlassian-provider +``` + +Then we will need to this line: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-auth-backend')); +/* highlight-add-start */ +backend.add(import('@backstage/plugin-auth-backend-module-atlassian-provider')); +/* highlight-add-end */ +``` + ## Adding the provider to the Backstage frontend To add the provider to the frontend, add the `atlassianAuthApi` reference and diff --git a/docs/auth/aws-alb/provider.md b/docs/auth/aws-alb/provider.md index dc878e8971..8f21b7dbf0 100644 --- a/docs/auth/aws-alb/provider.md +++ b/docs/auth/aws-alb/provider.md @@ -8,37 +8,6 @@ description: Adding AWS ALB as an authentication provider in Backstage Backstage can de deployed behind [AWS Application Load Balancer](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html) and get the user seamlessly authenticated. -## Installation - -### Backend - -:::note -These instructions are written for the [new backend system](../../backend-system/index.md). -::: - -Add the `@backstage/plugin-auth-backend-module-aws-alb-provider` to your backend installation. - -```sh -# From your Backstage root directory -yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-aws-alb-provider -``` - -Then, add it to your backend's source, - -```ts title="packages/backend/src/index.ts" -const backend = createBackend(); - -backend.add(import('@backstage/plugin-auth-backend')); -// highlight-add-next-line -backend.add(import('@backstage/plugin-auth-backend-module-aws-alb-provider')); - -await backend.start(); -``` - -### Frontend - -See [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) for pointers on how to set up the sign-in page, and to also make it work smoothly for local development. - ## Configuration The provider configuration can be added to your `app-config.yaml` under the root @@ -57,4 +26,40 @@ auth: - resolver: emailLocalPartMatchingUserEntityName ``` +### Resolvers + +This provider includes several resolvers out of the box that you can use: + +- `emailMatchingUserEntityProfileEmail`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will throw a `NotFoundError`. +- `emailLocalPartMatchingUserEntityName`: Matches the [local part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the email address from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`. + +:::note Note + +The resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + +::: + +If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. + +## Backend Installation + +To add the provider to the backend we will first need to install the package by running this command: + +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-aws-alb-provider +``` + +Then we will need to add this line: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-auth-backend')); +/* highlight-add-start */ +backend.add(import('@backstage/plugin-auth-backend-module-aws-alb-provider')); +/* highlight-add-end */ +``` + +## Adding the provider to the Backstage frontend + +See [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) for pointers on how to set up the sign-in page, and to also make it work smoothly for local development. You'll use `awsalb` as the provider name. + If you [provide a custom sign in resolver](https://backstage.io/docs/auth/identity-resolver#building-custom-resolvers), you can skip the `signIn` block entirely. diff --git a/docs/auth/bitbucket/provider.md b/docs/auth/bitbucket/provider.md index b03201893c..163647c790 100644 --- a/docs/auth/bitbucket/provider.md +++ b/docs/auth/bitbucket/provider.md @@ -37,6 +37,13 @@ auth: development: clientId: ${AUTH_BITBUCKET_CLIENT_ID} clientSecret: ${AUTH_BITBUCKET_CLIENT_SECRET} + signIn: + resolvers: + # typically you would pick one of these + - resolver: emailMatchingUserEntityProfileEmail + - resolver: emailLocalPartMatchingUserEntityName + - resolver: userIdMatchingUserEntityAnnotation + - resolver: usernameMatchingUserEntityAnnotation ``` The Bitbucket provider is a structure with two configuration keys: @@ -45,44 +52,42 @@ The Bitbucket provider is a structure with two configuration keys: `b59241722e3c3b4816e2` - `clientSecret`: The Secret tied to the generated Key. +### Resolvers + +This provider includes several resolvers out of the box that you can use: + +- `emailMatchingUserEntityProfileEmail`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will throw a `NotFoundError`. +- `emailLocalPartMatchingUserEntityName`: Matches the [local part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the email address from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`. +- `userIdMatchingUserEntityAnnotation`: Matches the `userId` from the auth provider with the User entity that has a matching `bitbucket.org/user-id` annotation. If no match is found it will throw a `NotFoundError`. +- `usernameMatchingUserEntityAnnotation`: Matches the `username` from the auth provider with the User entity that has a matching `bitbucket.org/username` annotation. If no match is found it will throw a `NotFoundError`. + +:::note Note + +The resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + +::: + +If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. + +## Backend Installation + +To add the provider to the backend we will first need to install the package by running this command: + +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-bitbucket-provider +``` + +Then we will need to add this line: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-auth-backend')); +/* highlight-add-start */ +backend.add(import('@backstage/plugin-auth-backend-module-bitbucket-provider')); +/* highlight-add-end */ +``` + ## Adding the provider to the Backstage frontend To add the provider to the frontend, add the `bitbucketAuthApi` reference and `SignInPage` component as shown in [Adding the provider to the sign-in page](../index.md#adding-the-provider-to-the-sign-in-page). - -## Using Bitbucket for sign-in - -In order to use the Bitbucket provider for sign-in, you must configure it with a -`signIn.resolver`. See the -[Sign-In Resolver documentation](../identity-resolver.md) for more details on -how this is done. Note that for the Bitbucket provider, you'll want to use -`bitbucket` as the provider ID, and `providers.bitbucket.create` for the provider -factory. - -The `@backstage/plugin-auth-backend` plugin also comes with two built-in -resolvers that can be used if desired. The first one is the -`bitbucketUsernameSignInResolver`, which identifies users by matching their -Bitbucket username to `bitbucket.org/username` annotations of `User` entities in -the catalog. Note that you must populate your catalog with matching entities or -users will not be able to sign in. - -The second resolver is the `bitbucketUserIdSignInResolver`, which works the -same way, but uses the Bitbucket user ID instead, and matches on the -`bitbucket.org/user-id` annotation. - -The following is an example of how to use one of the built-in resolvers: - -```ts -import { providers } from '@backstage/plugin-auth-backend'; - -// ... - providerFactories: { - bitbucket: providers.bitbucket.create({ - signIn: { - resolver: - providers.bitbucket.resolvers.usernameMatchingUserEntityAnnotation(), - }, - }), - }, -``` diff --git a/docs/auth/cloudflare/access.md b/docs/auth/cloudflare/access.md deleted file mode 100644 index 52d9fdfc21..0000000000 --- a/docs/auth/cloudflare/access.md +++ /dev/null @@ -1,174 +0,0 @@ ---- -id: provider -title: Cloudflare Access Provider -sidebar_label: Cloudflare Access -description: Adding Cloudflare Access as an authentication provider in Backstage ---- - -Similar to GCP IAP Proxy Provider or AWS ALB provider, developers can offload authentication -support to Cloudflare Access. - -This tutorial shows how to use authentication on Cloudflare Access sitting in -front of Backstage. - -It is assumed a Cloudflare tunnel is already serving traffic in front of a -Backstage instance configured to serve the frontend app from the backend and is -already gated using Cloudflare Access. - -## Configuration - -Let's start by adding the following `auth` configuration in your -`app-config.yaml` or `app-config.production.yaml` or similar: - -```yaml -auth: - providers: - cfaccess: - # You can find the team name in the Cloudflare Zero Trust dashboard. - teamName: - # This service tokens section is optional -- you only need it if you have - # some Cloudflare Service Tokens that you want to be able to log in to your - # Backstage instance. - serviceTokens: - - token: '1uh2fh19efvfh129f1f919u21f2f19jf2.access' - subject: 'bot-user@your-company.com' - # This picks what sign in resolver(s) you want to use. - signIn: - resolvers: - - resolver: emailMatchingUserEntityProfileEmail -``` - -This config section must be in place for the provider to load at all. - -The `signIn` section picks what sign-in resolver(s) to use for sign-in attempts. -It is responsible for matching the upstream provider's sign-in result to a -corresponding Backstage identity, or to throw an error if the attempt should be -rejected for any reason. The `emailMatchingUserEntityProfileEmail` is a common -choice: it tries to match the email of the signed-in user to a `User` kind -entity in the catalog whose profile email matches that. - -If the builtin sign in resolvers do not match your needs, you can skip the -`signIn` section and instead [provide a custom resolver](#advanced-custom-sign-in-resolver). - -## Backend Changes - -We need to add the provider package as a dependency to our backend: - -```bash title="from your Backstage root directory" -yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-cloudflare-access-provider -``` - -And to tell the backend to load it: - -```ts title="in packages/backend/src/index.ts" -backend.add(import('@backstage/plugin-auth-backend')); -/* highlight-add-start */ -backend.add( - import('@backstage/plugin-auth-backend-module-cloudflare-access-provider'), -); -/* highlight-add-end */ -``` - -Now the backend is ready to serve auth requests on the -`/api/auth/cfaccess/refresh` endpoint. All that's left is to update the frontend -sign-in mechanism to poll that endpoint through Cloudflare Access, on the user's -behalf. - -## Frontend Changes - -It is recommended to use the `ProxiedSignInPage` for this provider, which is -installed in your app like this: - -```tsx title="in packages/app/src/App.tsx" -/* highlight-add-next-line */ -import { ProxiedSignInPage } from '@backstage/core-components'; - -const app = createApp({ - /* highlight-add-start */ - components: { - SignInPage: props => , - }, - /* highlight-add-end */ - // ... -}); -``` - -See [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) for -pointers on how to set up the sign-in page to also work smoothly for local -development. - -## Advanced: Custom Sign-in Resolver - -If none of the built-in sign in resolvers fit your needs, you need to provide a -customized version of the module. Now you should _not_ -`backend.add(import(...))`, instead you will do the following. - -```ts title="in packages/backend/plugin/auth.ts" -/* highlight-add-start */ -import { createCloudflareAccessAuthenticator } from '@backstage/plugin-auth-backend-module-cloudflare-access-provider'; -import { - coreServices, - createBackendModule, -} from '@backstage/backend-plugin-api'; -import { - authProvidersExtensionPoint, - createProxyAuthProviderFactory, -} from '@backstage/plugin-auth-node'; - -const customAuth = createBackendModule({ - // This ID must be exactly "auth" because that's the plugin it targets - pluginId: 'auth', - // This ID must be unique, but can be anything - moduleId: 'custom-auth-provider', - register(reg) { - reg.registerInit({ - deps: { - providers: authProvidersExtensionPoint, - cache: coreServices.cache, - }, - async init({ providers, cache }) { - providers.registerProvider({ - // This ID must match the actual provider config, e.g. addressing - // auth.providers.github means that this must be "github". - providerId: 'cfaccess', - // Use createProxyAuthProviderFactory instead if it's one of the proxy - // based providers rather than an OAuth based one - factory: createProxyAuthProviderFactory({ - authenticator: createCloudflareAccessAuthenticator({ cache }), - async signInResolver(info, ctx) { - // This is where the body of the sign-in resolver goes! - const { profile } = info; - if (!profile.email) { - throw new Error( - 'Login failed, user profile does not contain an email', - ); - } - return ctx.signInWithCatalogUser({ - filter: { - 'spec.profile.email': profile.email, - }, - }); - }, - }), - }); - }, - }); - }, -}); -/* highlight-add-end */ - -backend.add(import('@backstage/plugin-auth-backend')); -/* highlight-remove-start */ -backend.add( - import('@backstage/plugin-auth-backend-module-cloudflare-access-provider'), -); -/* highlight-remove-end */ -/* highlight-add-next-line */ -backend.add(customAuth); -``` - -The body of the sign-in resolver is up to you to write! The example code above -is just a copy of what `emailMatchingUserEntityProfileEmail` does. The `info` -parameter contains all of the results of the sign-in attempt so far. The `ctx` -context [has several useful functions](https://backstage.io/docs/reference/plugin-auth-node.authresolvercontext/) -for issuing tokens in various ways. diff --git a/docs/auth/cloudflare/provider.md b/docs/auth/cloudflare/provider.md new file mode 100644 index 0000000000..516ea9d647 --- /dev/null +++ b/docs/auth/cloudflare/provider.md @@ -0,0 +1,82 @@ +--- +id: provider +title: Cloudflare Access Provider +sidebar_label: Cloudflare Access +description: Adding Cloudflare Access as an authentication provider in Backstage +--- + +Similar to GCP IAP Proxy Provider or AWS ALB provider, developers can offload authentication +support to Cloudflare Access. + +This tutorial shows how to use authentication on Cloudflare Access sitting in +front of Backstage. + +It is assumed a Cloudflare tunnel is already serving traffic in front of a +Backstage instance configured to serve the frontend app from the backend and is +already gated using Cloudflare Access. + +## Configuration + +Let's start by adding the following `auth` configuration in your +`app-config.yaml` or `app-config.production.yaml` or similar: + +```yaml +auth: + providers: + cfaccess: + # You can find the team name in the Cloudflare Zero Trust dashboard. + teamName: + # This service tokens section is optional -- you only need it if you have + # some Cloudflare Service Tokens that you want to be able to log in to your + # Backstage instance. + serviceTokens: + - token: '1uh2fh19efvfh129f1f919u21f2f19jf2.access' + subject: 'bot-user@your-company.com' + # This picks what sign in resolver(s) you want to use. + signIn: + resolvers: + - resolver: emailMatchingUserEntityProfileEmail + - resolver: emailLocalPartMatchingUserEntityName +``` + +This config section must be in place for the provider to load at all. + +### Resolvers + +This provider includes several resolvers out of the box that you can use: + +- `emailMatchingUserEntityProfileEmail`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will throw a `NotFoundError`. +- `emailLocalPartMatchingUserEntityName`: Matches the [local part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the email address from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`. + +:::note Note + +The resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + +::: + +If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. + +## Backend Installation + +To add the provider to the backend we will first need to install the package by running this command: + +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-cloudflare-access-provider +``` + +Then we will need to add this line: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-auth-backend')); +/* highlight-add-start */ +backend.add( + import('@backstage/plugin-auth-backend-module-cloudflare-access-provider'), +); +/* highlight-add-end */ +``` + +## Adding the provider to the Backstage frontend + +See [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) for pointers on how to set up the sign-in page, and to also make it work smoothly for local development. You'll use `cfaccess` as the provider name. + +If you [provide a custom sign in resolver](https://backstage.io/docs/auth/identity-resolver#building-custom-resolvers), you can skip the `signIn` block entirely. diff --git a/docs/auth/github/provider.md b/docs/auth/github/provider.md index 1873730bd6..801320299b 100644 --- a/docs/auth/github/provider.md +++ b/docs/auth/github/provider.md @@ -26,6 +26,14 @@ Settings for local development: - Homepage URL: `http://localhost:3000` - Authorization callback URL: `http://localhost:7007/api/auth/github/handler/frame` +### Difference between GitHub Apps and GitHub OAuth Apps + +GitHub Apps handle OAuth scope at the app installation level, meaning that the +`scope` parameter for the call to `getAccessToken` in the frontend has no +effect. When calling `getAccessToken` in open source plugins, one should still +include the appropriate scope, but also document in the plugin README what +scopes are required for GitHub Apps. + ## Configuration The provider configuration can then be added to your `app-config.yaml` under the @@ -79,16 +87,25 @@ The resolvers will be tried in order, but will only be skipped if they throw a ` If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. +## Backend Installation + +To add the provider to the backend we will first need to install the package by running this command: + +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-github-provider +``` + +Then we will need to add this line: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-auth-backend')); +/* highlight-add-start */ +backend.add(import('@backstage/plugin-auth-backend-module-github-provider')); +/* highlight-add-end */ +``` + ## Adding the provider to the Backstage frontend To add the provider to the frontend, add the `githubAuthApi` reference and `SignInPage` component as shown in [Adding the provider to the sign-in page](../index.md#adding-the-provider-to-the-sign-in-page). - -## Difference between GitHub Apps and GitHub OAuth Apps - -GitHub Apps handle OAuth scope at the app installation level, meaning that the -`scope` parameter for the call to `getAccessToken` in the frontend has no -effect. When calling `getAccessToken` in open source plugins, one should still -include the appropriate scope, but also document in the plugin README what -scopes are required for GitHub Apps. diff --git a/docs/auth/gitlab/provider.md b/docs/auth/gitlab/provider.md index f5613582fd..e70953e11d 100644 --- a/docs/auth/gitlab/provider.md +++ b/docs/auth/gitlab/provider.md @@ -78,6 +78,23 @@ The resolvers will be tried in order, but will only be skipped if they throw a ` If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. +## Backend Installation + +To add the provider to the backend we will first need to install the package by running this command: + +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-gitlab-provider +``` + +Then we will need to add this line: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-auth-backend')); +/* highlight-add-start */ +backend.add(import('@backstage/plugin-auth-backend-module-gitlab-provider')); +/* highlight-add-end */ +``` + ## Adding the provider to the Backstage frontend To add the provider to the frontend, add the `gitlabAuthApi` reference and diff --git a/docs/auth/google/gcp-iap-auth.md b/docs/auth/google/gcp-iap-auth.md index 7e6178154c..6479ac7268 100644 --- a/docs/auth/google/gcp-iap-auth.md +++ b/docs/auth/google/gcp-iap-auth.md @@ -58,102 +58,25 @@ The resolvers will be tried in order, but will only be skipped if they throw a ` If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. -## Backend Changes +## Backend Installation -There is a module for this provider that you will need to add to your backend. +To add the provider to the backend we will first need to install the package by running this command: -First you'll want to run this command to add the module: - -```sh - yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-gcp-iap-provider +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-gcp-iap-provider ``` -Then you will need to add this to your backend: - -```ts title="packages/backend/src/index.ts" -const backend = createBackend(); +Then we will need to add this line: +```ts title="in packages/backend/src/index.ts" backend.add(import('@backstage/plugin-auth-backend')); /* highlight-add-start */ backend.add(import('@backstage/plugin-auth-backend-module-gcp-iap-provider')); /* highlight-add-end */ ``` -### Legacy Backend Changes +## Adding the provider to the Backstage frontend -If you are still using the legacy backend you will need to make the changes outlined here. +See [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) for pointers on how to set up the sign-in page, and to also make it work smoothly for local development. You'll use `gcp-iap` as the provider name. -This provider is not enabled by default in the auth backend code, because besides the config section above, it also needs to be given one or more callbacks in actual code as well as described below. - -Add a `providerFactories` entry to the router in -`packages/backend/src/plugins/auth.ts`. - -```ts title="packages/backend/src/plugins/auth.ts" -import { providers } from '@backstage/plugin-auth-backend'; -import { stringifyEntityRef } from '@backstage/catalog-model'; - -export default async function createPlugin( - env: PluginEnvironment, -): Promise { - return await createRouter({ - logger: env.logger, - config: env.config, - database: env.database, - discovery: env.discovery, - providerFactories: { - 'gcp-iap': providers.gcpIap.create({ - // Replace the auth handler if you want to customize the returned user - // profile info (can be left out; the default implementation is shown - // below which only returns the email). You may want to amend this code - // with something that loads additional user profile data out of e.g. - // GSuite or LDAP or similar. - async authHandler({ iapToken }) { - return { profile: { email: iapToken.email } }; - }, - signIn: { - // You need to supply an identity resolver, that takes the profile - // and the IAP token and produces the Backstage token with the - // relevant user info. - async resolver({ profile, result: { iapToken } }, ctx) { - // Somehow compute the Backstage token claims. Just some sample code - // shown here, but you may want to query your LDAP server, or - // GSuite or similar, based on the IAP token sub/email claims - const id = iapToken.email.split('@')[0]; - const sub = stringifyEntityRef({ kind: 'User', name: id }); - const ent = [ - sub, - stringifyEntityRef({ kind: 'Group', name: 'team-name' }), - ]; - return ctx.issueToken({ claims: { sub, ent } }); - }, - }, - }), - }, - }); -} -``` - -Now the backend is ready to serve auth requests on the -`/api/auth/gcp-iap/refresh` endpoint. All that's left is to update the frontend -sign-in mechanism to poll that endpoint through the IAP, on the user's behalf. - -## Frontend Changes - -It is recommended to use the `ProxiedSignInPage` for this provider, which is -installed in `packages/app/src/App.tsx` like this: - -```tsx title="packages/app/src/App.tsx" -/* highlight-add-next-line */ -import { ProxiedSignInPage } from '@backstage/core-components'; - -const app = createApp({ - /* highlight-add-start */ - components: { - SignInPage: props => , - }, - /* highlight-add-end */ - // .. -}); -``` - -See the [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) section for more information. +If you [provide a custom sign in resolver](https://backstage.io/docs/auth/identity-resolver#building-custom-resolvers), you can skip the `signIn` block entirely. diff --git a/docs/auth/google/provider.md b/docs/auth/google/provider.md index f7802d43f7..e2efacfed2 100644 --- a/docs/auth/google/provider.md +++ b/docs/auth/google/provider.md @@ -24,9 +24,9 @@ To support Google authentication, you must create OAuth credentials: - Add yourself as a test user, if using External user type 6. Set **Application Type** to `Web Application` with these settings: - `Name`: Backstage (or your custom app name) - - `Authorized JavaScript origins`: http://localhost:3000 + - `Authorized JavaScript origins`: - `Authorized Redirect URIs`: - http://localhost:7007/api/auth/google/handler/frame + 7. Click Create ## Configuration @@ -72,6 +72,23 @@ The resolvers will be tried in order, but will only be skipped if they throw a ` If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. +## Backend Installation + +To add the provider to the backend we will first need to install the package by running this command: + +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-google-provider +``` + +Then we will need to add this line: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-auth-backend')); +/* highlight-add-start */ +backend.add(import('@backstage/plugin-auth-backend-module-google-provider')); +/* highlight-add-end */ +``` + ## Adding the provider to the Backstage frontend To add the provider to the frontend, add the `googleAuthApi` reference and diff --git a/docs/auth/identity-resolver.md b/docs/auth/identity-resolver.md index 4140276df8..5efb592270 100644 --- a/docs/auth/identity-resolver.md +++ b/docs/auth/identity-resolver.md @@ -124,6 +124,8 @@ The list of available resolvers is different for each provider, since they often depend on the information model returned from the upstream provider service. Consult the documentation of the respective provider to find the list. +In the example above `emailMatchingUserEntityProfileEmail` and `emailLocalPartMatchingUserEntityName` are common to all auth providers and `usernameMatchingUserEntityName` is specific to GitHub. + ### Building Custom Resolvers If the builtins don't work for you, you can also provide a completely custom diff --git a/docs/auth/microsoft/azure-easyauth.md b/docs/auth/microsoft/azure-easyauth.md index 5fec3354d7..e8d6f2f105 100644 --- a/docs/auth/microsoft/azure-easyauth.md +++ b/docs/auth/microsoft/azure-easyauth.md @@ -7,87 +7,6 @@ description: Adding Azure's EasyAuth Proxy as an authentication provider in Back The Backstage `core-plugin-api` package comes with a Microsoft authentication provider that can authenticate users using Microsoft Entra ID (formerly Azure Active Directory) for PaaS service hosted in Azure that support Easy Auth, such as Azure App Services. -## Backend Changes - -Add the following into your `app-config.yaml` under the root `auth` configuration: - -```yaml title="app-config.yaml" -auth: - providers: - azureEasyAuth: - signIn: - resolvers: - - resolver: idMatchingUserEntityAnnotation - - resolver: emailMatchingUserEntityProfileEmail - - resolver: emailLocalPartMatchingUserEntityName -``` - -The `idMatchingUserEntityAnnotation` is -[a builtin sign-in resolver](../identity-resolver.md#using-builtin-resolvers) from `azureEasyAuth` provider. -It tries to find a user entity with [a `graph.microsoft.com/user-id` annotation](../../features/software-catalog/well-known-annotations.md#graphmicrosoftcomtenant-id-graphmicrosoftcomgroup-id-graphmicrosoftcomuser-id) -which matches the object ID of the user attempting to sign in. -If you want to provide your own sign-in resolver, -see [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers). - -Add the `@backstage/plugin-auth-backend-module-azure-easyauth-provider` to your backend installation. - -```sh -# From your Backstage root directory -yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-azure-easyauth-provider -``` - -Then, add it to your backend's source, - -```ts title="packages/backend/src/index.ts" -const backend = createBackend(); - -backend.add(import('@backstage/plugin-auth-backend')); -// highlight-add-next-line -backend.add( - import('@backstage/plugin-auth-backend-module-azure-easyauth-provider'), -); - -await backend.start(); -``` - -Now the backend is ready to serve auth requests on the -`/api/auth/azureEasyAuth/refresh` endpoint. All that's left is to update the frontend -sign-in mechanism to poll that endpoint through the Easy Auth proxy, on the user's behalf. - -## Frontend Changes - -To use this component, you'll need to configure the app's `SignInPage`. -It is recommended to use the `ProxiedSignInPage` for this provider when running in Azure, However for local development (or any other scenario running outside of Azure), you'll want to set up something different. -For the closest experience to Easy Auth, you could set up the `microsoft` provider locally, but that will requires setting up App Registrations & secrets which may be locked down by your organisation, in which case it may be easier to use guest login locally. -See [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) for more details. - -```tsx title="packages/app/src/App.tsx" -/* highlight-add-next-line */ -import { ProxiedSignInPage } from '@backstage/core-components'; - -const app = createApp({ - /* highlight-add-start */ - components: { - SignInPage: props => { - const configApi = useApi(configApiRef); - if (configApi.getString('auth.environment') !== 'development') { - return ; - } - return ( - - ); - }, - }, - /* highlight-add-end */ - // .. -}); -``` - ## Azure Configuration How to configure azure depends on the Azure service you're using to host Backstage. @@ -136,3 +55,59 @@ resource webApp 'Microsoft.Web/sites@2022-03-01' existing = { } } ``` + +## Configuration + +Add the following into your `app-config.yaml` under the root `auth` configuration: + +```yaml title="app-config.yaml" +auth: + providers: + azureEasyAuth: + signIn: + resolvers: + - resolver: emailMatchingUserEntityProfileEmail + - resolver: emailLocalPartMatchingUserEntityName + - resolver: idMatchingUserEntityAnnotation +``` + +### Resolvers + +This provider includes several resolvers out of the box that you can use: + +- `emailMatchingUserEntityProfileEmail`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will throw a `NotFoundError`. +- `emailLocalPartMatchingUserEntityName`: Matches the [local part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the email address from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`. +- `idMatchingUserEntityAnnotation`: Matches the user Id from the auth provider with the User entity that has a matching `graph.microsoft.com/user-id` annotation. If no match is found it will throw a `NotFoundError`. + +:::note Note + +The resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + +::: + +If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. + +## Backend Installation + +To add the provider to the backend we will first need to install the package by running this command: + +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-azure-easyauth-provider +``` + +Then we will need to this line: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-auth-backend')); +/* highlight-add-start */ +backend.add( + import('@backstage/plugin-auth-backend-module-azure-easyauth-provider'), +); +/* highlight-add-end */ +``` + +## Adding the provider to the Backstage frontend + +See [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) for pointers on how to set up the sign-in page, and to also make it work smoothly for local development. You'll use `azureEasyAuth` as the provider name. + +If you [provide a custom sign in resolver](https://backstage.io/docs/auth/identity-resolver#building-custom-resolvers), you can skip the `signIn` block entirely. diff --git a/docs/auth/microsoft/provider.md b/docs/auth/microsoft/provider.md index b96f175183..aeec71213f 100644 --- a/docs/auth/microsoft/provider.md +++ b/docs/auth/microsoft/provider.md @@ -40,6 +40,18 @@ If you're using an existing app registration, and backstage already has a client If not, go to the **Certificates & Secrets** page, then the **Client secrets** tab and create a new client secret. Make a note of this value as you'll need it in the next section. +## Outbound Network Access + +If your environment has restrictions on outgoing access (e.g. through +firewall rules), make sure your Backstage backend has access to the following +hosts: + +- `login.microsoftonline.com`, to get and exchange authorization codes and access + tokens +- `graph.microsoft.com`, to fetch user profile information (as seen + in [this source code](https://github.com/seanfisher/passport-microsoft/blob/0456aa9bce05579c18e77f51330176eb26373658/lib/strategy.js#L93-L95)). + If this host is unreachable, users may see an `Authentication failed, failed to fetch user profile` error when they attempt to log in. + ## Configuration The provider configuration can then be added to your `app-config.yaml` under the @@ -92,20 +104,25 @@ The resolvers will be tried in order, but will only be skipped if they throw a ` If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. +## Backend Installation + +To add the provider to the backend we will first need to install the package by running this command: + +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-microsoft-provider +``` + +Then we will need to this line: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-auth-backend')); +/* highlight-add-start */ +backend.add(import('@backstage/plugin-auth-backend-module-microsoft-provider')); +/* highlight-add-end */ +``` + ## Adding the provider to the Backstage frontend To add the provider to the frontend, add the `microsoftAuthApiRef` reference and `SignInPage` component as shown in [Adding the provider to the sign-in page](../index.md#adding-the-provider-to-the-sign-in-page). - -## Outbound Network Access - -If your environment has restrictions on outgoing access (e.g. through -firewall rules), make sure your Backstage backend has access to the following -hosts: - -- `login.microsoftonline.com`, to get and exchange authorization codes and access - tokens -- `graph.microsoft.com`, to fetch user profile information (as seen - in [this source code](https://github.com/seanfisher/passport-microsoft/blob/0456aa9bce05579c18e77f51330176eb26373658/lib/strategy.js#L93-L95)). - If this host is unreachable, users may see an `Authentication failed, failed to fetch user profile` error when they attempt to log in. diff --git a/docs/auth/oauth2-proxy/provider.md b/docs/auth/oauth2-proxy/provider.md index dca074cc7d..0901685b2f 100644 --- a/docs/auth/oauth2-proxy/provider.md +++ b/docs/auth/oauth2-proxy/provider.md @@ -47,25 +47,27 @@ The resolvers will be tried in order, but will only be skipped if they throw a ` If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. -## Adding the provider to the Backstage frontend +## Backend Installation -It is recommended to use the `ProxiedSignInPage` for this provider, which is -installed in `packages/app/src/App.tsx` like this: +To add the provider to the backend we will first need to install the package by running this command: -```tsx title="packages/app/src/App.tsx" -/* highlight-add-next-line */ -import { ProxiedSignInPage } from '@backstage/core-components'; - -const app = createApp({ - /* highlight-add-start */ - components: { - SignInPage: props => ( - - ), - }, - /* highlight-add-end */ - // .. -}); +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-oauth2-proxy-provider ``` -See [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) for pointers on how to set up the sign-in page to also work smoothly for local development. +Then we will need to this line: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-auth-backend')); +/* highlight-add-start */ +backend.add( + import('@backstage/plugin-auth-backend-module-oauth2-proxy-provider'), +); +/* highlight-add-end */ +``` + +## Adding the provider to the Backstage frontend + +See [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) for pointers on how to set up the sign-in page, and to also make it work smoothly for local development. You'll use `oauth2Proxy` as the provider name. + +If you [provide a custom sign in resolver](https://backstage.io/docs/auth/identity-resolver#building-custom-resolvers), you can skip the `signIn` block entirely. diff --git a/docs/auth/okta/provider.md b/docs/auth/okta/provider.md index 6fe7a8b992..77dace2289 100644 --- a/docs/auth/okta/provider.md +++ b/docs/auth/okta/provider.md @@ -83,6 +83,23 @@ The resolvers will be tried in order, but will only be skipped if they throw a ` If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. +## Backend Installation + +To add the provider to the backend we will first need to install the package by running this command: + +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-okta-provider +``` + +Then we will need to add this line: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-auth-backend')); +/* highlight-add-start */ +backend.add(import('@backstage/plugin-auth-backend-module-okta-provider')); +/* highlight-add-end */ +``` + ## Adding the provider to the Backstage frontend To add the provider to the frontend, add the `oktaAuthApi` reference and diff --git a/docs/auth/onelogin/provider.md b/docs/auth/onelogin/provider.md index c3572367d2..9330a20332 100644 --- a/docs/auth/onelogin/provider.md +++ b/docs/auth/onelogin/provider.md @@ -38,6 +38,12 @@ auth: clientId: ${AUTH_ONELOGIN_CLIENT_ID} clientSecret: ${AUTH_ONELOGIN_CLIENT_SECRET} issuer: https://.onelogin.com/oidc/2 + signIn: + resolvers: + # typically you would pick one of these + - resolver: emailMatchingUserEntityProfileEmail + - resolver: emailLocalPartMatchingUserEntityName + - resolver: usernameMatchingUserEntityName ``` The OneLogin provider is a structure with three configuration keys; **these are @@ -47,6 +53,39 @@ found on the SSO tab** for the OneLogin Application: - `clientSecret`: The client secret - `issuer`: The issuer URL +### Resolvers + +This provider includes several resolvers out of the box that you can use: + +- `emailMatchingUserEntityProfileEmail`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will throw a `NotFoundError`. +- `emailLocalPartMatchingUserEntityName`: Matches the [local part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the email address from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`. +- `usernameMatchingUserEntityName`: Matches the username from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`. + +:::note Note + +The resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + +::: + +If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. + +## Backend Installation + +To add the provider to the backend we will first need to install the package by running this command: + +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-onelogin-provider +``` + +Then we will need to add this line: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-auth-backend')); +/* highlight-add-start */ +backend.add(import('@backstage/plugin-auth-backend-module-onelogin-provider')); +/* highlight-add-end */ +``` + ## Adding the provider to the Backstage frontend To add the provider to the frontend, add the `oneloginAuthApi` reference and diff --git a/docs/auth/vmware-cloud/provider.md b/docs/auth/vmware-cloud/provider.md index dd7c32f700..d79c84534a 100644 --- a/docs/auth/vmware-cloud/provider.md +++ b/docs/auth/vmware-cloud/provider.md @@ -33,108 +33,6 @@ Cloud Console and within a Backstage app required to enable this capability. 1. Take note of the `App ID` in the resulting modal; this is the client ID to be used by Backstage. -## Install the provider in the backend - -### New backend system - -Apps using the [new backend system](../../backend-system/index.md), -can enable the VMware Cloud provider with a small modification like: - -```ts title="packages/backend/src/index.ts" -import { createBackend } from '@backstage/backend-defaults'; - -const backend = createBackend(); -backend.add(import('@backstage/plugin-auth-backend')); -/* highlight-add-start */ -backend.add( - import('@backstage/plugin-auth-backend-module-vmware-cloud-provider'), -); -/* highlight-add-end */ -backend.start(); -``` - -### Old backend system - -This provider was added after the migration of the auth-backend plugin to the -new backend system, so no default provider factory was added. Because of this, -the installation procedure for old-style backends is slightly more involved: - -```ts title="packages/backend/src/plugins/auth.ts" -import { - DEFAULT_NAMESPACE, - stringifyEntityRef, -} from '@backstage/catalog-model'; -import { - createRouter, - providers, - defaultAuthProviderFactories, -} from '@backstage/plugin-auth-backend'; -import { Router } from 'express'; -import { PluginEnvironment } from '../types'; -/* highlight-add-start */ -import { - commonSignInResolvers, - createOAuthProviderFactory, -} from '@backstage/plugin-auth-node'; -import { - vmwareCloudAuthenticator, -} from '@backstage/plugin-auth-backend-module-vmware-cloud-provider'; -/* highlight-add-end */ - -export default async function createPlugin( - env: PluginEnvironment, -): Promise { - return await createRouter({ - logger: env.logger, - config: env.config, - database: env.database, - discovery: env.discovery, - tokenManager: env.tokenManager, - providerFactories: { - ...defaultAuthProviderFactories, - /* highlight-add-start */ - vmwareCloudServices: createOAuthProviderFactory({ - authenticator: vmwareCloudAuthenticator, - signInResolver: - commonSignInResolvers.emailLocalPartMatchingUserEntityName(), - }), - /* highlight-add-end */ -``` - -In the above, `commonSignInResolvers.emailLocalPartMatchingUserEntityName()` -can be replaced with a more suitable resolver for the app in question. - -## Add to Sign-in Page - -See the [Sign-In Configuration](../index.md#sign-in-configuration) docs for -general guidance, but as an example: - -```tsx title="packages/app/src/App.tsx" -/* highlight-add-start */ -import { vmwareCloudAuthApiRef } from '@backstage/core-plugin-api'; -import { SignInPage } from '@backstage/core-components'; -/* highlight-add-end */ - -const app = createApp({ - /* highlight-add-start */ - components: { - SignInPage: props => ( - - ), - }, - /* highlight-add-end */ - // .. -}); -``` - ## Configuration Add the following to your `app-config.yaml` under the root `auth` configuration: @@ -161,13 +59,17 @@ Where `APP_ID` refers to the ID retrieved when creating the OAuth App, and `ORG_ID` is the [long ID of the Organization](https://docs.vmware.com/en/VMware-Cloud-services/services/Using-VMware-Cloud-Services/GUID-CF9E9318-B811-48CF-8499-9419997DC1F8.html#view-the-organization-id-1) in VMware Cloud for which you wish to enable sign-in. -Note that VMware Cloud requires OAuth Apps to use +:::note Note + +VMware Cloud requires OAuth Apps to use [PKCE](https://oauth.net/2/pkce/) when performing authorization code flows; the library used by this provider requires the use of Express session middleware to do this. Therefore the value `your session secret` under `auth.session.secret` should be replaced with a long, complex and unique string which will act as a key for signing session cookies set by Backstage. +::: + ### Resolvers This provider includes several resolvers out of the box that you can use: @@ -183,3 +85,28 @@ The resolvers will be tried in order, but will only be skipped if they throw a ` ::: If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. + +## Backend Installation + +To add the provider to the backend we will first need to install the package by running this command: + +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-vmware-cloud-provider +``` + +Then we will need to this line: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-auth-backend')); +/* highlight-add-start */ +backend.add( + import('@backstage/plugin-auth-backend-module-vmware-cloud-provider'), +); +/* highlight-add-end */ +``` + +## Adding the provider to the Backstage frontend + +To add the provider to the frontend, add the `vmwareCloudAuthApiRef` reference and +`SignInPage` component as shown in +[Adding the provider to the sign-in page](../index.md#adding-the-provider-to-the-sign-in-page). From 3e71b19711948fc4fb2de70423ef6c90b11da3aa Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 5 Jul 2024 12:14:38 -0500 Subject: [PATCH 183/510] Fixed tests Signed-off-by: Andre Wanlin --- packages/create-app/src/lib/tasks.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/create-app/src/lib/tasks.test.ts b/packages/create-app/src/lib/tasks.test.ts index 38a09f7ac6..1f507b95ed 100644 --- a/packages/create-app/src/lib/tasks.test.ts +++ b/packages/create-app/src/lib/tasks.test.ts @@ -62,6 +62,7 @@ jest.mock('./versions', () => ({ '@backstage/plugin-auth-backend-module-github-provider': '1.0.0', '@backstage/plugin-auth-backend-module-guest-provider': '1.0.0', '@backstage/plugin-catalog-backend': '1.0.0', + '@backstage/plugin-catalog-backend-module-logs': '1.0.0', '@backstage/plugin-catalog-backend-module-scaffolder-entity-model': '1.0.0', '@backstage/plugin-permission-common': '1.0.0', '@backstage/plugin-permission-node': '1.0.0', From b4e401fd9ed99f379c6a2a5a3277cad3cab1d568 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 5 Jul 2024 13:32:46 -0500 Subject: [PATCH 184/510] Fixed links and MkDocs config Signed-off-by: Andre Wanlin --- docs/auth/atlassian/provider.md | 2 +- docs/auth/auth0/provider.md | 2 +- docs/auth/bitbucket/provider.md | 2 +- docs/auth/bitbucketServer/provider.md | 2 +- docs/auth/github/provider.md | 2 +- docs/auth/gitlab/provider.md | 2 +- docs/auth/google/provider.md | 2 +- docs/auth/microsoft/provider.md | 2 +- docs/auth/okta/provider.md | 2 +- docs/auth/onelogin/provider.md | 2 +- docs/auth/vmware-cloud/provider.md | 2 +- mkdocs.yml | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/auth/atlassian/provider.md b/docs/auth/atlassian/provider.md index 44f6d097b9..96271f04a0 100644 --- a/docs/auth/atlassian/provider.md +++ b/docs/auth/atlassian/provider.md @@ -100,4 +100,4 @@ backend.add(import('@backstage/plugin-auth-backend-module-atlassian-provider')); To add the provider to the frontend, add the `atlassianAuthApi` reference and `SignInPage` component as shown in -[Adding the provider to the sign-in page](../index.md#adding-the-provider-to-the-sign-in-page). +[Adding the provider to the sign-in page](../index.md#sign-in-configuration). diff --git a/docs/auth/auth0/provider.md b/docs/auth/auth0/provider.md index dcd02d226f..ae44114906 100644 --- a/docs/auth/auth0/provider.md +++ b/docs/auth/auth0/provider.md @@ -64,4 +64,4 @@ Auth0 requires a session, so you need to give the session a secret key. To add the provider to the frontend, add the `auth0AuthApi` reference and `SignInPage` component as shown in -[Adding the provider to the sign-in page](../index.md#adding-the-provider-to-the-sign-in-page). +[Adding the provider to the sign-in page](../index.md#sign-in-configuration). diff --git a/docs/auth/bitbucket/provider.md b/docs/auth/bitbucket/provider.md index 163647c790..1ca35437ba 100644 --- a/docs/auth/bitbucket/provider.md +++ b/docs/auth/bitbucket/provider.md @@ -90,4 +90,4 @@ backend.add(import('@backstage/plugin-auth-backend-module-bitbucket-provider')); To add the provider to the frontend, add the `bitbucketAuthApi` reference and `SignInPage` component as shown in -[Adding the provider to the sign-in page](../index.md#adding-the-provider-to-the-sign-in-page). +[Adding the provider to the sign-in page](../index.md#sign-in-configuration). diff --git a/docs/auth/bitbucketServer/provider.md b/docs/auth/bitbucketServer/provider.md index eef934ca60..82aebc20b2 100644 --- a/docs/auth/bitbucketServer/provider.md +++ b/docs/auth/bitbucketServer/provider.md @@ -37,7 +37,7 @@ The Bitbucket Server provider is a structure with two configuration keys: ## Adding the provider to the Backstage frontend To add the provider to the frontend, add the `bitbucketServerAuthApi` reference and `SignInPage` component as shown -in [Adding the provider to the sign-in page](../index.md#adding-the-provider-to-the-sign-in-page). +in [Adding the provider to the sign-in page](../index.md#sign-in-configuration). ## Using Bitbucket Server for sign-in diff --git a/docs/auth/github/provider.md b/docs/auth/github/provider.md index 801320299b..76b63c6617 100644 --- a/docs/auth/github/provider.md +++ b/docs/auth/github/provider.md @@ -108,4 +108,4 @@ backend.add(import('@backstage/plugin-auth-backend-module-github-provider')); To add the provider to the frontend, add the `githubAuthApi` reference and `SignInPage` component as shown in -[Adding the provider to the sign-in page](../index.md#adding-the-provider-to-the-sign-in-page). +[Adding the provider to the sign-in page](../index.md#sign-in-configuration). diff --git a/docs/auth/gitlab/provider.md b/docs/auth/gitlab/provider.md index e70953e11d..73546411bf 100644 --- a/docs/auth/gitlab/provider.md +++ b/docs/auth/gitlab/provider.md @@ -99,4 +99,4 @@ backend.add(import('@backstage/plugin-auth-backend-module-gitlab-provider')); To add the provider to the frontend, add the `gitlabAuthApi` reference and `SignInPage` component as shown in -[Adding the provider to the sign-in page](../index.md#adding-the-provider-to-the-sign-in-page). +[Adding the provider to the sign-in page](../index.md#sign-in-configuration). diff --git a/docs/auth/google/provider.md b/docs/auth/google/provider.md index e2efacfed2..b19d21d63f 100644 --- a/docs/auth/google/provider.md +++ b/docs/auth/google/provider.md @@ -93,4 +93,4 @@ backend.add(import('@backstage/plugin-auth-backend-module-google-provider')); To add the provider to the frontend, add the `googleAuthApi` reference and `SignInPage` component as shown in -[Adding the provider to the sign-in page](../index.md#adding-the-provider-to-the-sign-in-page). +[Adding the provider to the sign-in page](../index.md#sign-in-configuration). diff --git a/docs/auth/microsoft/provider.md b/docs/auth/microsoft/provider.md index aeec71213f..f799eeb627 100644 --- a/docs/auth/microsoft/provider.md +++ b/docs/auth/microsoft/provider.md @@ -125,4 +125,4 @@ backend.add(import('@backstage/plugin-auth-backend-module-microsoft-provider')); To add the provider to the frontend, add the `microsoftAuthApiRef` reference and `SignInPage` component as shown in -[Adding the provider to the sign-in page](../index.md#adding-the-provider-to-the-sign-in-page). +[Adding the provider to the sign-in page](../index.md#sign-in-configuration). diff --git a/docs/auth/okta/provider.md b/docs/auth/okta/provider.md index 77dace2289..83352aaa0d 100644 --- a/docs/auth/okta/provider.md +++ b/docs/auth/okta/provider.md @@ -104,4 +104,4 @@ backend.add(import('@backstage/plugin-auth-backend-module-okta-provider')); To add the provider to the frontend, add the `oktaAuthApi` reference and `SignInPage` component as shown in -[Adding the provider to the sign-in page](../index.md#adding-the-provider-to-the-sign-in-page). +[Adding the provider to the sign-in page](../index.md#sign-in-configuration). diff --git a/docs/auth/onelogin/provider.md b/docs/auth/onelogin/provider.md index 9330a20332..002445a9d1 100644 --- a/docs/auth/onelogin/provider.md +++ b/docs/auth/onelogin/provider.md @@ -90,4 +90,4 @@ backend.add(import('@backstage/plugin-auth-backend-module-onelogin-provider')); To add the provider to the frontend, add the `oneloginAuthApi` reference and `SignInPage` component as shown in -[Adding the provider to the sign-in page](../index.md#adding-the-provider-to-the-sign-in-page). +[Adding the provider to the sign-in page](../index.md#sign-in-configuration). diff --git a/docs/auth/vmware-cloud/provider.md b/docs/auth/vmware-cloud/provider.md index d79c84534a..ac2cf3ee92 100644 --- a/docs/auth/vmware-cloud/provider.md +++ b/docs/auth/vmware-cloud/provider.md @@ -109,4 +109,4 @@ backend.add( To add the provider to the frontend, add the `vmwareCloudAuthApiRef` reference and `SignInPage` component as shown in -[Adding the provider to the sign-in page](../index.md#adding-the-provider-to-the-sign-in-page). +[Adding the provider to the sign-in page](../index.md#sign-in-configuration). diff --git a/mkdocs.yml b/mkdocs.yml index b9f6d41d46..f163005377 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -158,7 +158,7 @@ nav: - Azure EasyAuth: 'auth/microsoft/azure-easyauth.md' - Bitbucket: 'auth/bitbucket/provider.md' - Bitbucket Server: 'auth/bitbucketServer/provider.md' - - Cloudflare Access: 'auth/cloudflare/access.md' + - Cloudflare Access: 'auth/cloudflare/provider.md' - GitHub: 'auth/github/provider.md' - GitLab: 'auth/gitlab/provider.md' - Google: 'auth/google/provider.md' From 401e892bafc3927acd87213b69712144dbef1603 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 5 Jul 2024 13:49:45 -0500 Subject: [PATCH 185/510] Fixed more links Signed-off-by: Andre Wanlin --- docs/auth/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/auth/index.md b/docs/auth/index.md index f925e52917..4a0e56a36e 100644 --- a/docs/auth/index.md +++ b/docs/auth/index.md @@ -31,7 +31,7 @@ Backstage comes with many common authentication providers in the core library: - [Azure Easy Auth](microsoft/azure-easyauth.md) - [Bitbucket](bitbucket/provider.md) - [Bitbucket Server](bitbucketServer/provider.md) -- [Cloudflare Access](cloudflare/access.md) +- [Cloudflare Access](cloudflare/provider.md) - [GitHub](github/provider.md) - [GitLab](gitlab/provider.md) - [Google](google/provider.md) @@ -158,7 +158,7 @@ Some auth providers are so-called "proxy" providers, meaning they're meant to be behind an authentication proxy. Examples of these are [Amazon Application Load Balancer](https://github.com/backstage/backstage/blob/master/contrib/docs/tutorials/aws-alb-aad-oidc-auth.md), [Azure EasyAuth](./microsoft/azure-easyauth.md), -[Cloudflare Access](./cloudflare/access.md), +[Cloudflare Access](./cloudflare/provider.md), [Google Identity-Aware Proxy](./google/gcp-iap-auth.md) and [OAuth2 Proxy](./oauth2-proxy/provider.md). From a835d6f644d10fb7b7334e7749e7824f34bb8e46 Mon Sep 17 00:00:00 2001 From: Adam Harvey <33203301+adamdmharvey@users.noreply.github.com> Date: Fri, 5 Jul 2024 22:40:33 -0400 Subject: [PATCH 186/510] chore(docs): Fix broken Note admonition Signed-off-by: Adam Harvey <33203301+adamdmharvey@users.noreply.github.com> --- docs/integrations/github/github-apps.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/integrations/github/github-apps.md b/docs/integrations/github/github-apps.md index b5e252be74..298eba26e3 100644 --- a/docs/integrations/github/github-apps.md +++ b/docs/integrations/github/github-apps.md @@ -109,8 +109,8 @@ integrations: webhookSecret: ${AUTH_ORG_WEBHOOK_SECRET} ``` -:::Note -Note that in both examples above `apps` is an array which means you can add multiple GitHub Apps using `$include` or environment variables as long as they are each for a different GitHub Org as mentioned under the [Caveats](#caveats) section +:::note +Note that in both examples above `apps` is an array which means you can add multiple GitHub Apps using `$include` or environment variables as long as they are each for a different GitHub Org as mentioned under the [Caveats](#caveats) section. ::: ## Limiting the GitHub App installations From 583715dbbe375fe54d9feb8fee3153e5876ecd33 Mon Sep 17 00:00:00 2001 From: Adam Harvey <33203301+adamdmharvey@users.noreply.github.com> Date: Fri, 5 Jul 2024 23:33:03 -0400 Subject: [PATCH 187/510] chore: Fix comment typo Signed-off-by: Adam Harvey <33203301+adamdmharvey@users.noreply.github.com> --- packages/repo-tools/src/commands/api-reports/api-extractor.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 6a523af6a9..c3054dffe9 100644 --- a/packages/repo-tools/src/commands/api-reports/api-extractor.ts +++ b/packages/repo-tools/src/commands/api-reports/api-extractor.ts @@ -145,7 +145,7 @@ ApiReportGenerator.generateReviewFileContent = if (!localName) { // Sometimes the symbol name is suffixed with a number to disambiguate, // e.g. "Props_14" instead of "Props" if there are multiple Props interfaces - // so we tyry to strip that suffix and look up the symbol again. + // so we try to strip that suffix and look up the symbol again. const [, trimmedSymbolName] = symbolName.match(/(.*)_\d+/) || []; localName = (sourceFile as any).identifiers?.get(trimmedSymbolName); } @@ -1101,6 +1101,7 @@ export async function buildDocs({ switch (hierarchyItem.kind) { case ApiItemKind.Model: case ApiItemKind.EntryPoint: + case ApiItemKind.None: // We don't show the model as part of the breadcrumb because it is the root-level container. // We don't show the entry point because today API Extractor doesn't support multiple entry points; // this may change in the future. From c3837fb3fca523d296b9024c5dd8c80a5f207e1f Mon Sep 17 00:00:00 2001 From: Adam Harvey <33203301+adamdmharvey@users.noreply.github.com> Date: Fri, 5 Jul 2024 23:34:33 -0400 Subject: [PATCH 188/510] chore: Fix invalid API docs cross-reference Signed-off-by: Adam Harvey <33203301+adamdmharvey@users.noreply.github.com> --- plugins/permission-node/src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/permission-node/src/types.ts b/plugins/permission-node/src/types.ts index 36e30714f6..0a7e06ed91 100644 --- a/plugins/permission-node/src/types.ts +++ b/plugins/permission-node/src/types.ts @@ -23,7 +23,7 @@ import { NoInfer } from './integration/util'; /** * A conditional rule that can be provided in an - * {@link @backstage/permission-common#AuthorizeDecision} response to an authorization request. + * {@link @backstage/plugin-permission-common#AuthorizeDecision} response to an authorization request. * * @remarks * From 09086e8d0ae82ca18f1e2a476bff60278af872f6 Mon Sep 17 00:00:00 2001 From: Adam Harvey <33203301+adamdmharvey@users.noreply.github.com> Date: Fri, 5 Jul 2024 23:34:53 -0400 Subject: [PATCH 189/510] chore: Add packageDocumentation for API Docs Index Signed-off-by: Adam Harvey <33203301+adamdmharvey@users.noreply.github.com> --- plugins/permission-react/api-report.md | 2 -- plugins/permission-react/src/index.ts | 5 +++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/permission-react/api-report.md b/plugins/permission-react/api-report.md index 3c1961c92c..4c51d16b80 100644 --- a/plugins/permission-react/api-report.md +++ b/plugins/permission-react/api-report.md @@ -100,6 +100,4 @@ export function usePermission( resourceRef: string | undefined; }, ): AsyncPermissionResult; - -// (No @packageDocumentation comment for this package) ``` diff --git a/plugins/permission-react/src/index.ts b/plugins/permission-react/src/index.ts index 57352c5cdd..de6958b3e5 100644 --- a/plugins/permission-react/src/index.ts +++ b/plugins/permission-react/src/index.ts @@ -14,6 +14,11 @@ * limitations under the License. */ +/** + * Components and hooks to help implement permissions in Backstage frontend plugins. + * + * @packageDocumentation + */ export * from './components'; export * from './hooks'; export * from './apis'; From 28b2cfb08cf1bc88107ef61d344b687febfd2bed Mon Sep 17 00:00:00 2001 From: Adam Harvey <33203301+adamdmharvey@users.noreply.github.com> Date: Fri, 5 Jul 2024 23:37:30 -0400 Subject: [PATCH 190/510] chore: Add changesets Signed-off-by: Adam Harvey <33203301+adamdmharvey@users.noreply.github.com> --- .changeset/famous-clocks-visit.md | 5 +++++ .changeset/tender-turkeys-begin.md | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 .changeset/famous-clocks-visit.md create mode 100644 .changeset/tender-turkeys-begin.md diff --git a/.changeset/famous-clocks-visit.md b/.changeset/famous-clocks-visit.md new file mode 100644 index 0000000000..66c2048872 --- /dev/null +++ b/.changeset/famous-clocks-visit.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-permission-node': patch +--- + +Fix invalid cross-reference in API Reference docs diff --git a/.changeset/tender-turkeys-begin.md b/.changeset/tender-turkeys-begin.md new file mode 100644 index 0000000000..26e376cecf --- /dev/null +++ b/.changeset/tender-turkeys-begin.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-permission-react': patch +--- + +Improve API Reference documentation From 518616d4c9f13eeaef816a9dfa8ce9b95a07e773 Mon Sep 17 00:00:00 2001 From: Adam Harvey <33203301+adamdmharvey@users.noreply.github.com> Date: Sat, 6 Jul 2024 00:14:44 -0400 Subject: [PATCH 191/510] chore: Remove testing Signed-off-by: Adam Harvey <33203301+adamdmharvey@users.noreply.github.com> --- packages/repo-tools/src/commands/api-reports/api-extractor.ts | 1 - 1 file changed, 1 deletion(-) 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 c3054dffe9..122f04cc7e 100644 --- a/packages/repo-tools/src/commands/api-reports/api-extractor.ts +++ b/packages/repo-tools/src/commands/api-reports/api-extractor.ts @@ -1101,7 +1101,6 @@ export async function buildDocs({ switch (hierarchyItem.kind) { case ApiItemKind.Model: case ApiItemKind.EntryPoint: - case ApiItemKind.None: // We don't show the model as part of the breadcrumb because it is the root-level container. // We don't show the entry point because today API Extractor doesn't support multiple entry points; // this may change in the future. From ad8f60b1f74761558f65b777f593db6ba2d88c47 Mon Sep 17 00:00:00 2001 From: Benjamin Janssens Date: Mon, 8 Jul 2024 10:59:17 +0200 Subject: [PATCH 192/510] chore: add DPG Media as an adopter Signed-off-by: Benjamin Janssens --- ADOPTERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ADOPTERS.md b/ADOPTERS.md index 3ff0c5e1b5..c1b1686ccc 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -272,3 +272,4 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [Senora.dev](https://senora.dev) | [Shaked Braimok Yosef](https://github.com/ShakedBraimok) | We are using Backstage as a service catalog for our costumers. | | [Covestro](https://www.covestro.com) | [Julien Gedeon](https://github.com/cvvcv1) | We use Backstage as our Internal developer portal for the Digital R&D department. | | [Grupo OLX](https://www.olx.com.br/) | [@marciorgb](https://github.com/marciorgb), [@jeffbraga](https://github.com/jeffbraga), [@rogerfernandes](https://github.com/rogerfernandes), [@stockrt](https://github.com/stockrt) | At Grupo OLX, we are using Backstage to reduce friction and enhance developer autonomy by creating Golden Paths, which automate previously manual processes. Additionally, Backstage's catalog integrates various views of our organizational structure and workflows, offering a comprehensive overview of how different components interconnect. | +| [DPG Media](https://www.dpgmediagroup.com) | [@benjidotsh](https://github.com/benjidotsh), [@lvstb](https://github.com/lvstb), [@ssliman](https://github.com/ssliman), [@edewel-beep](https://github.com/edewel-beep) | Access to infrastructure, documentation and internal tooling | From bc2700cbf962e3f3a4554d664a193943224b3f27 Mon Sep 17 00:00:00 2001 From: Chap Ambrose Date: Mon, 8 Jul 2024 08:26:47 -0500 Subject: [PATCH 193/510] recommend updating config in app-config.production.yaml Co-authored-by: Andre Wanlin <67169551+awanlin@users.noreply.github.com> Signed-off-by: Chap Ambrose --- docs/deployment/heroku.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/deployment/heroku.md b/docs/deployment/heroku.md index a70ff66ca5..23dff683f8 100644 --- a/docs/deployment/heroku.md +++ b/docs/deployment/heroku.md @@ -32,7 +32,7 @@ $ heroku domains -a .herokuapp.com ``` -Update `baseUrl` and `port` in `app-config.yaml`. The core [app-backend plugin](https://www.npmjs.com/package/@backstage/plugin-app-backend) allows a single Heroku app to serve the frontend and backend: +The core [app-backend plugin](https://www.npmjs.com/package/@backstage/plugin-app-backend) allows a single Heroku app to serve the frontend and backend. To make this work you need to update the `baseUrl` and `port` in `app-config.production.yaml`: ```yaml app: baseUrl: https://.herokuapp.com From fb6a5d5f6ba90edb6152c20d4c111b93a9182d16 Mon Sep 17 00:00:00 2001 From: Chap Ambrose Date: Mon, 8 Jul 2024 08:27:20 -0500 Subject: [PATCH 194/510] Typo in docs Co-authored-by: Andre Wanlin <67169551+awanlin@users.noreply.github.com> Signed-off-by: Chap Ambrose --- docs/deployment/heroku.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/deployment/heroku.md b/docs/deployment/heroku.md index 23dff683f8..5e6eb59a82 100644 --- a/docs/deployment/heroku.md +++ b/docs/deployment/heroku.md @@ -9,7 +9,7 @@ Heroku is a Platform as a Service (PaaS) designed to simplify application deploy ## Create App -Start with an exisiting Backstage app or follow the [getting started guide](https://backstage.io/docs/getting-started/) to create a new one: +Starting with an existing Backstage app or follow the [getting started guide](https://backstage.io/docs/getting-started/) to create a new one: ```shell $ npx @backstage/create-app@latest From 6b56a1921925517006e8cbdecffccc3f74814916 Mon Sep 17 00:00:00 2001 From: Chap Ambrose Date: Mon, 8 Jul 2024 08:27:45 -0500 Subject: [PATCH 195/510] add app-config.production to build script Co-authored-by: Andre Wanlin <67169551+awanlin@users.noreply.github.com> Signed-off-by: Chap Ambrose --- docs/deployment/heroku.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/deployment/heroku.md b/docs/deployment/heroku.md index 5e6eb59a82..c5042c732c 100644 --- a/docs/deployment/heroku.md +++ b/docs/deployment/heroku.md @@ -51,7 +51,7 @@ backend: Add a build script in `package.json` to compile frontend during deployment: ```json "scripts": { - "build": "yarn build:backend --config ../../app-config.yaml" + "build": "yarn build:backend --config ../../app-config.yaml --config app-config.production.yaml" ``` ## Start Command From 32b73f957c7ee8379e190f66640a4a9ec7ced9ab Mon Sep 17 00:00:00 2001 From: Chap Ambrose Date: Mon, 8 Jul 2024 08:32:26 -0500 Subject: [PATCH 196/510] remove command to create new backstage app Signed-off-by: Chap Ambrose --- docs/deployment/heroku.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/docs/deployment/heroku.md b/docs/deployment/heroku.md index c5042c732c..9629dbb212 100644 --- a/docs/deployment/heroku.md +++ b/docs/deployment/heroku.md @@ -9,12 +9,7 @@ Heroku is a Platform as a Service (PaaS) designed to simplify application deploy ## Create App -Starting with an existing Backstage app or follow the [getting started guide](https://backstage.io/docs/getting-started/) to create a new one: - -```shell -$ npx @backstage/create-app@latest - Enter a name -``` +Starting with an existing Backstage app or follow the [getting started guide](https://backstage.io/docs/getting-started/) to create a new one. Install the [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli) and create a new Heroku app: From e80a94f5c31aad63840c36bf592a072310d787c2 Mon Sep 17 00:00:00 2001 From: Chap Ambrose Date: Mon, 8 Jul 2024 09:50:17 -0500 Subject: [PATCH 197/510] add docker instructions to heroku.md Signed-off-by: Chap Ambrose --- docs/deployment/heroku.md | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/docs/deployment/heroku.md b/docs/deployment/heroku.md index 9629dbb212..8f173578c5 100644 --- a/docs/deployment/heroku.md +++ b/docs/deployment/heroku.md @@ -46,14 +46,14 @@ backend: Add a build script in `package.json` to compile frontend during deployment: ```json "scripts": { - "build": "yarn build:backend --config ../../app-config.yaml --config app-config.production.yaml" + "build": "yarn build:backend --config ../../app-config.yaml --config ../../app-config.production.yaml" ``` ## Start Command Create a [Procfile](https://devcenter.heroku.com/articles/procfile) in the app's root: ```shell -$ echo "web: yarn workspace backend start --config ../../app-config.yaml" > Procfile +$ echo "web: yarn workspace backend start --config ../../app-config.yaml --config ../../app-config.production.yaml" > Procfile ``` ## Database @@ -63,7 +63,7 @@ Provision a [Heroku Postgres](https://elements.heroku.com/addons/heroku-postgres $ heroku addons:create heroku-postgresql -a ``` -Update `database` in `app-config.yaml`: +Update `database` in `app-config.production.yaml`: ```yaml backend: database: @@ -99,3 +99,33 @@ View logs: ```shell $ heroku heroku -a ``` + +## Docker + +As an alternative to git deploys, Heroku also [supports container images](https://devcenter.heroku.com/articles/container-registry-and-runtime). + +Login to Heroku's container registry: + +```shell +$ heroku container:login +``` + +Configure the Heroku app to run a container image: + +```shell +$ heroku stack:set container -a +``` + +Locally run the [host build command](https://backstage.io/docs/deployment/docker/#host-build): +```shell +$ yarn build:backend --config ../../app-config.yaml --config ../../app-config.production.yaml +``` + +Build, push, and release the container image: +```shell +$ docker image build . -f packages/backend/Dockerfile --tag registry.heroku.com//web + +$ docker push registry.heroku.com//web + +$ heroku container:release web -a +``` From 9ddbd8c729bf96a36d6642459e3a326e7f8bb6d5 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 8 Jul 2024 17:09:53 +0200 Subject: [PATCH 198/510] search: add missing createApiFactory Signed-off-by: Patrik Oldsberg --- plugins/search/src/alpha.tsx | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/plugins/search/src/alpha.tsx b/plugins/search/src/alpha.tsx index c202d58712..838fb95046 100644 --- a/plugins/search/src/alpha.tsx +++ b/plugins/search/src/alpha.tsx @@ -31,10 +31,9 @@ import { } from '@backstage/core-components'; import { useApi, - DiscoveryApi, discoveryApiRef, fetchApiRef, - FetchApi, + createApiFactory, } from '@backstage/core-plugin-api'; import { @@ -77,17 +76,12 @@ import { /** @alpha */ export const searchApi = createApiExtension({ - factory: { + factory: createApiFactory({ api: searchApiRef, deps: { discoveryApi: discoveryApiRef, fetchApi: fetchApiRef }, - factory: ({ - fetchApi, - discoveryApi, - }: { - fetchApi: FetchApi; - discoveryApi: DiscoveryApi; - }) => new SearchClient({ discoveryApi, fetchApi }), - }, + factory: ({ discoveryApi, fetchApi }) => + new SearchClient({ discoveryApi, fetchApi }), + }), }); const useSearchPageStyles = makeStyles((theme: Theme) => ({ From dc41795dd508275e8d95a89b81861dd1ea636500 Mon Sep 17 00:00:00 2001 From: Chap Ambrose Date: Mon, 8 Jul 2024 11:15:28 -0500 Subject: [PATCH 199/510] prettier fixes Signed-off-by: Chap Ambrose --- docs/deployment/heroku.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/deployment/heroku.md b/docs/deployment/heroku.md index 8f173578c5..74732bb431 100644 --- a/docs/deployment/heroku.md +++ b/docs/deployment/heroku.md @@ -22,12 +22,14 @@ $ heroku apps:create ## Domain Get Heroku app URL: + ```shell $ heroku domains -a .herokuapp.com ``` The core [app-backend plugin](https://www.npmjs.com/package/@backstage/plugin-app-backend) allows a single Heroku app to serve the frontend and backend. To make this work you need to update the `baseUrl` and `port` in `app-config.production.yaml`: + ```yaml app: baseUrl: https://.herokuapp.com @@ -44,6 +46,7 @@ backend: ## Build Script Add a build script in `package.json` to compile frontend during deployment: + ```json "scripts": { "build": "yarn build:backend --config ../../app-config.yaml --config ../../app-config.production.yaml" @@ -52,6 +55,7 @@ Add a build script in `package.json` to compile frontend during deployment: ## Start Command Create a [Procfile](https://devcenter.heroku.com/articles/procfile) in the app's root: + ```shell $ echo "web: yarn workspace backend start --config ../../app-config.yaml --config ../../app-config.production.yaml" > Procfile ``` @@ -59,11 +63,13 @@ $ echo "web: yarn workspace backend start --config ../../app-config.yaml --confi ## Database Provision a [Heroku Postgres](https://elements.heroku.com/addons/heroku-postgresql) database: + ```shell $ heroku addons:create heroku-postgresql -a ``` Update `database` in `app-config.production.yaml`: + ```yaml backend: database: @@ -75,6 +81,7 @@ backend: ``` Allow postgres self-signed certificates: + ```shell $ heroku config:set PGSSLMODE=no-verify -a ``` @@ -117,11 +124,13 @@ $ heroku stack:set container -a ``` Locally run the [host build command](https://backstage.io/docs/deployment/docker/#host-build): + ```shell $ yarn build:backend --config ../../app-config.yaml --config ../../app-config.production.yaml ``` Build, push, and release the container image: + ```shell $ docker image build . -f packages/backend/Dockerfile --tag registry.heroku.com//web From 0b6d31a56b530d92a6881174b91ed7036e4ea169 Mon Sep 17 00:00:00 2001 From: David Weber Date: Mon, 8 Jul 2024 18:55:40 +0200 Subject: [PATCH 200/510] docs: add Baloise as adaptor Signed-off-by: David Weber Signed-off-by: David Weber --- ADOPTERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ADOPTERS.md b/ADOPTERS.md index c1b1686ccc..870b4c93d4 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -273,3 +273,4 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [Covestro](https://www.covestro.com) | [Julien Gedeon](https://github.com/cvvcv1) | We use Backstage as our Internal developer portal for the Digital R&D department. | | [Grupo OLX](https://www.olx.com.br/) | [@marciorgb](https://github.com/marciorgb), [@jeffbraga](https://github.com/jeffbraga), [@rogerfernandes](https://github.com/rogerfernandes), [@stockrt](https://github.com/stockrt) | At Grupo OLX, we are using Backstage to reduce friction and enhance developer autonomy by creating Golden Paths, which automate previously manual processes. Additionally, Backstage's catalog integrates various views of our organizational structure and workflows, offering a comprehensive overview of how different components interconnect. | | [DPG Media](https://www.dpgmediagroup.com) | [@benjidotsh](https://github.com/benjidotsh), [@lvstb](https://github.com/lvstb), [@ssliman](https://github.com/ssliman), [@edewel-beep](https://github.com/edewel-beep) | Access to infrastructure, documentation and internal tooling | +| [Baloise](https://www.baloise.ch) | [@dweber019](https://github.com/dweber019), [@mikevader](https://github.com/mikevader) | We are using Backstage as internal developer protal for use cases like software catalog, documentation, infrastructure. | From b9832aee3d57c40de8e77e35275eff5acfe8d1de Mon Sep 17 00:00:00 2001 From: Olivier Liechti Date: Tue, 9 Jul 2024 09:55:58 +0200 Subject: [PATCH 201/510] Fix issues described in #25551 Signed-off-by: Olivier Liechti --- .changeset/chilly-rabbits-sneeze.md | 5 +++ .../src/authenticator.test.ts | 40 +++++++++++++++++ .../src/authenticator.ts | 44 +++++++++++++++---- .../src/types.d.ts | 3 +- 4 files changed, 83 insertions(+), 9 deletions(-) create mode 100644 .changeset/chilly-rabbits-sneeze.md create mode 100644 plugins/auth-backend-module-atlassian-provider/src/authenticator.test.ts diff --git a/.changeset/chilly-rabbits-sneeze.md b/.changeset/chilly-rabbits-sneeze.md new file mode 100644 index 0000000000..cbce80ebbc --- /dev/null +++ b/.changeset/chilly-rabbits-sneeze.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend-module-atlassian-provider': patch +--- + +Fix several issues with the Atlassian auth provider (type definition, profile url, profile transformation, scopes) diff --git a/plugins/auth-backend-module-atlassian-provider/src/authenticator.test.ts b/plugins/auth-backend-module-atlassian-provider/src/authenticator.test.ts new file mode 100644 index 0000000000..b8e9e1ad75 --- /dev/null +++ b/plugins/auth-backend-module-atlassian-provider/src/authenticator.test.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Strategy from 'passport-atlassian-oauth2'; + +describe('Strategy', () => { + it('should be an instance of', () => { + try { + console.log(Strategy); + const strategy = new Strategy( + { + authorizationURL: 'https://auth.atlassian.com/authorize', + tokenURL: 'https://auth.atlassian.com/oauth/token', + clientID: 'my-client-id', + clientSecret: 'my-client-secret', + scope: ['offline_access', 'read:jira-work', 'read:jira-user'], + }, + () => {}, + ); + console.log(strategy.name); + expect(strategy).toBeInstanceOf(Strategy); + + expect((strategy as any).name).toBe('atlassian'); + } catch (e) { + console.error(e); + } + }); +}); diff --git a/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts b/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts index 0ced9cf831..ab2cd3f94a 100644 --- a/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts +++ b/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts @@ -20,14 +20,35 @@ import { PassportOAuthDoneCallback, PassportProfile, } from '@backstage/plugin-auth-node'; -import { Strategy as AtlassianStrategy } from 'passport-atlassian-oauth2'; +import AtlassianStrategy from 'passport-atlassian-oauth2'; + +export type AtlassianPassportProfile = { + id: string; + displayName: string; + email: string; + photo: string; + provider: string; + _json: any; +}; /** @public */ -export const atlassianAuthenticator = createOAuthAuthenticator({ - defaultProfileTransform: - PassportOAuthAuthenticatorHelper.defaultProfileTransform, +export const atlassianAuthenticator = createOAuthAuthenticator< + any, + AtlassianPassportProfile +>({ + defaultProfileTransform: async (input, context) => { + // const result = await PassportOAuthAuthenticatorHelper.defaultProfileTransform(input, context); + + return { + profile: { + displayName: input.fullProfile.displayName, + email: input.fullProfile.email, + picture: input.fullProfile.photo, + }, + }; + }, scopes: { - required: ['offline_access', 'read:jira-work', 'read:jira-user'], + required: ['offline_access', 'read:me', 'read:jira-work', 'read:jira-user'], }, initialize({ callbackUrl, config }) { const clientId = config.getString('clientId'); @@ -49,18 +70,25 @@ export const atlassianAuthenticator = createOAuthAuthenticator({ baseURL: baseUrl, authorizationURL: `${baseUrl}/authorize`, tokenURL: `${baseUrl}/oauth/token`, - profileURL: `${baseUrl}/api/v4/user`, + // profileURL: `${baseUrl}/api/v4/user`, + profileURL: 'https://api.atlassian.com/me', + scope: config.getOptionalString('additionalScopes')?.split(' ') || [], }, ( accessToken: string, refreshToken: string, params: any, - fullProfile: PassportProfile, + fullProfile: PassportProfile & { email: string; photo: string }, done: PassportOAuthDoneCallback, ) => { + const fullProfileWithEmails = { + ...fullProfile, + // avatarUrl: fullProfile.photo, + // emails: [{ value: fullProfile.email }], + }; done( undefined, - { fullProfile, params, accessToken }, + { fullProfile: fullProfileWithEmails, params, accessToken }, { refreshToken }, ); }, diff --git a/plugins/auth-backend-module-atlassian-provider/src/types.d.ts b/plugins/auth-backend-module-atlassian-provider/src/types.d.ts index 5fd47bf885..aa945f3705 100644 --- a/plugins/auth-backend-module-atlassian-provider/src/types.d.ts +++ b/plugins/auth-backend-module-atlassian-provider/src/types.d.ts @@ -18,8 +18,9 @@ declare module 'passport-atlassian-oauth2' { import { Request } from 'express'; import { StrategyCreated } from 'passport'; - export class Strategy { + export default class Strategy { constructor(options: any, verify: any); + name?: string; authenticate(this: StrategyCreated, req: Request, options?: any): any; } } From be5f08f3a8474cb428ddaf0f6b2fe6b61b27fdaa Mon Sep 17 00:00:00 2001 From: Olivier Liechti Date: Tue, 9 Jul 2024 10:20:17 +0200 Subject: [PATCH 202/510] Cleaning up details Signed-off-by: Olivier Liechti --- .../src/authenticator.test.ts | 3 --- .../src/authenticator.ts | 8 +------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/plugins/auth-backend-module-atlassian-provider/src/authenticator.test.ts b/plugins/auth-backend-module-atlassian-provider/src/authenticator.test.ts index b8e9e1ad75..cb723ecece 100644 --- a/plugins/auth-backend-module-atlassian-provider/src/authenticator.test.ts +++ b/plugins/auth-backend-module-atlassian-provider/src/authenticator.test.ts @@ -29,9 +29,6 @@ describe('Strategy', () => { }, () => {}, ); - console.log(strategy.name); - expect(strategy).toBeInstanceOf(Strategy); - expect((strategy as any).name).toBe('atlassian'); } catch (e) { console.error(e); diff --git a/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts b/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts index ab2cd3f94a..ff020f131d 100644 --- a/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts +++ b/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts @@ -70,7 +70,6 @@ export const atlassianAuthenticator = createOAuthAuthenticator< baseURL: baseUrl, authorizationURL: `${baseUrl}/authorize`, tokenURL: `${baseUrl}/oauth/token`, - // profileURL: `${baseUrl}/api/v4/user`, profileURL: 'https://api.atlassian.com/me', scope: config.getOptionalString('additionalScopes')?.split(' ') || [], }, @@ -81,14 +80,9 @@ export const atlassianAuthenticator = createOAuthAuthenticator< fullProfile: PassportProfile & { email: string; photo: string }, done: PassportOAuthDoneCallback, ) => { - const fullProfileWithEmails = { - ...fullProfile, - // avatarUrl: fullProfile.photo, - // emails: [{ value: fullProfile.email }], - }; done( undefined, - { fullProfile: fullProfileWithEmails, params, accessToken }, + { fullProfile, params, accessToken }, { refreshToken }, ); }, From f7cf3a2a875f833c63dbab687b77b28eeb991f67 Mon Sep 17 00:00:00 2001 From: Olivier Liechti Date: Tue, 9 Jul 2024 10:30:26 +0200 Subject: [PATCH 203/510] Cleaning up details Signed-off-by: Olivier Liechti --- .../auth-backend-module-atlassian-provider/src/authenticator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts b/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts index ff020f131d..1e7b631493 100644 --- a/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts +++ b/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts @@ -77,7 +77,7 @@ export const atlassianAuthenticator = createOAuthAuthenticator< accessToken: string, refreshToken: string, params: any, - fullProfile: PassportProfile & { email: string; photo: string }, + fullProfile: AtlassianPassportProfile, done: PassportOAuthDoneCallback, ) => { done( From 3cdea7aa1e38893c239d71b2ac073457ffe059ff Mon Sep 17 00:00:00 2001 From: Olivier Liechti Date: Tue, 9 Jul 2024 12:12:58 +0200 Subject: [PATCH 204/510] Fix typescript typing issues Signed-off-by: Olivier Liechti --- .../src/authenticator.ts | 32 +++++++++++-------- .../src/module.ts | 7 ++-- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts b/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts index 1e7b631493..8a1b952d15 100644 --- a/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts +++ b/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts @@ -16,9 +16,10 @@ import { createOAuthAuthenticator, + OAuthAuthenticatorResult, PassportOAuthAuthenticatorHelper, PassportOAuthDoneCallback, - PassportProfile, + ProfileInfo, } from '@backstage/plugin-auth-node'; import AtlassianStrategy from 'passport-atlassian-oauth2'; @@ -32,19 +33,20 @@ export type AtlassianPassportProfile = { }; /** @public */ -export const atlassianAuthenticator = createOAuthAuthenticator< - any, - AtlassianPassportProfile ->({ - defaultProfileTransform: async (input, context) => { - // const result = await PassportOAuthAuthenticatorHelper.defaultProfileTransform(input, context); +export const atlassianAuthenticator = createOAuthAuthenticator({ + defaultProfileTransform: async ( + input: OAuthAuthenticatorResult, + ) => { + const atlassianProfile = input.fullProfile as AtlassianPassportProfile; + + const profile: ProfileInfo = { + displayName: atlassianProfile.displayName, + email: atlassianProfile.email, + picture: atlassianProfile.photo, + }; return { - profile: { - displayName: input.fullProfile.displayName, - email: input.fullProfile.email, - picture: input.fullProfile.photo, - }, + profile, }; }, scopes: { @@ -98,10 +100,12 @@ export const atlassianAuthenticator = createOAuthAuthenticator< }, async authenticate(input, helper) { - return helper.authenticate(input); + const result = await helper.authenticate(input); + return result as OAuthAuthenticatorResult; }, async refresh(input, helper) { - return helper.refresh(input); + const result = await helper.refresh(input); + return result as OAuthAuthenticatorResult; }, }); diff --git a/plugins/auth-backend-module-atlassian-provider/src/module.ts b/plugins/auth-backend-module-atlassian-provider/src/module.ts index 9acb665ede..2080da3065 100644 --- a/plugins/auth-backend-module-atlassian-provider/src/module.ts +++ b/plugins/auth-backend-module-atlassian-provider/src/module.ts @@ -19,7 +19,10 @@ import { commonSignInResolvers, createOAuthProviderFactory, } from '@backstage/plugin-auth-node'; -import { atlassianAuthenticator } from './authenticator'; +import { + AtlassianPassportProfile, + atlassianAuthenticator, +} from './authenticator'; import { atlassianSignInResolvers } from './resolvers'; /** @public */ @@ -34,7 +37,7 @@ export const authModuleAtlassianProvider = createBackendModule({ async init({ providers }) { providers.registerProvider({ providerId: 'atlassian', - factory: createOAuthProviderFactory({ + factory: createOAuthProviderFactory({ authenticator: atlassianAuthenticator, signInResolverFactories: { ...atlassianSignInResolvers, From a6acc4c2ea28965e0d695972b0eecb9f78be4373 Mon Sep 17 00:00:00 2001 From: Lorenzo Davis <118796878+lorrrrrrrenzo@users.noreply.github.com> Date: Tue, 9 Jul 2024 15:24:35 +0400 Subject: [PATCH 205/510] Export `defaultEksClusterEntityTransformer` from `catalog-backend-module-aws` Signed-off-by: Lorenzo Davis <118796878+lorrrrrrrenzo@users.noreply.github.com> --- plugins/catalog-backend-module-aws/src/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/catalog-backend-module-aws/src/index.ts b/plugins/catalog-backend-module-aws/src/index.ts index 72ddc6386a..de8f9fd7b2 100644 --- a/plugins/catalog-backend-module-aws/src/index.ts +++ b/plugins/catalog-backend-module-aws/src/index.ts @@ -24,3 +24,4 @@ export * from './processors'; export * from './providers'; export * from './types'; export * from './constants'; +export { defaultEksClusterEntityTransformer } from './lib'; From 4afa050758b60b81ad978b6a293dbb94fcc05c4e Mon Sep 17 00:00:00 2001 From: Lorenzo Davis <118796878+lorrrrrrrenzo@users.noreply.github.com> Date: Tue, 9 Jul 2024 15:31:17 +0400 Subject: [PATCH 206/510] Add changeset Signed-off-by: Lorenzo Davis <118796878+lorrrrrrrenzo@users.noreply.github.com> --- .changeset/mighty-keys-bow.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/mighty-keys-bow.md diff --git a/.changeset/mighty-keys-bow.md b/.changeset/mighty-keys-bow.md new file mode 100644 index 0000000000..5f1bb408c9 --- /dev/null +++ b/.changeset/mighty-keys-bow.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-aws': patch +--- + +Export `defaultEksClusterEntityTransformer` to allow library consumers to layer additional changes on top of the default transformer. From baaf9977730807c67602324c02941000eb759fd6 Mon Sep 17 00:00:00 2001 From: Lorenzo Davis <118796878+lorrrrrrrenzo@users.noreply.github.com> Date: Tue, 9 Jul 2024 16:17:40 +0400 Subject: [PATCH 207/510] Update API Report in light of the change Signed-off-by: Lorenzo Davis <118796878+lorrrrrrrenzo@users.noreply.github.com> --- plugins/catalog-backend-module-aws/api-report.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/catalog-backend-module-aws/api-report.md b/plugins/catalog-backend-module-aws/api-report.md index 5098ab5c32..428a39d934 100644 --- a/plugins/catalog-backend-module-aws/api-report.md +++ b/plugins/catalog-backend-module-aws/api-report.md @@ -106,6 +106,9 @@ export class AwsS3EntityProvider implements EntityProvider { refresh(logger: LoggerService): Promise; } +// @public +export const defaultEksClusterEntityTransformer: EksClusterEntityTransformer; + // @public export type EksClusterEntityTransformer = ( cluster: Cluster, From 9d9a391cfb92796faf192a0f60fdba01bb7ce5f0 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 9 Jul 2024 14:21:33 +0200 Subject: [PATCH 208/510] beps/0009: move to implemented Signed-off-by: Patrik Oldsberg --- beps/0009-plugin-metadata/README.md | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/beps/0009-plugin-metadata/README.md b/beps/0009-plugin-metadata/README.md index c0ae487daa..59101f121c 100644 --- a/beps/0009-plugin-metadata/README.md +++ b/beps/0009-plugin-metadata/README.md @@ -1,6 +1,6 @@ --- title: Plugin Metadata -status: implementable +status: implemented authors: - '@Rugvip' owners: @@ -10,16 +10,8 @@ project-areas: creation-date: yyyy-mm-dd --- - - # BEP: Plugin Metadata - - [**Discussion Issue**](https://github.com/backstage/backstage/issues/25076) - [Summary](#summary) From e583b476870481d92c16e951ad0ab357cb8ad093 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 9 Jul 2024 12:58:58 +0000 Subject: [PATCH 209/510] Version Packages (next) --- .changeset/pre.json | 6 + docs/releases/v1.29.0-next.2-changelog.md | 446 ++++++++++++++++++ package.json | 2 +- packages/app-defaults/CHANGELOG.md | 7 + 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 | 35 ++ packages/app-next/package.json | 2 +- packages/app/CHANGELOG.md | 33 ++ packages/app/package.json | 2 +- packages/backend-legacy/CHANGELOG.md | 8 + packages/backend-legacy/package.json | 2 +- packages/backend/CHANGELOG.md | 7 + packages/backend/package.json | 2 +- packages/core-compat-api/CHANGELOG.md | 7 + packages/core-compat-api/package.json | 2 +- packages/core-components/CHANGELOG.md | 6 + packages/core-components/package.json | 2 +- packages/create-app/CHANGELOG.md | 6 + packages/create-app/package.json | 2 +- packages/dev-utils/CHANGELOG.md | 10 + packages/dev-utils/package.json | 2 +- packages/e2e-test/CHANGELOG.md | 7 + packages/e2e-test/package.json | 2 +- packages/frontend-app-api/CHANGELOG.md | 8 + packages/frontend-app-api/package.json | 2 +- packages/frontend-plugin-api/CHANGELOG.md | 7 + packages/frontend-plugin-api/package.json | 2 +- packages/frontend-test-utils/CHANGELOG.md | 8 + packages/frontend-test-utils/package.json | 2 +- .../techdocs-cli-embedded-app/CHANGELOG.md | 13 + .../techdocs-cli-embedded-app/package.json | 2 +- plugins/api-docs/CHANGELOG.md | 11 + plugins/api-docs/package.json | 2 +- plugins/app-visualizer/CHANGELOG.md | 8 + plugins/app-visualizer/package.json | 2 +- plugins/auth-react/CHANGELOG.md | 7 + plugins/auth-react/package.json | 2 +- plugins/catalog-graph/CHANGELOG.md | 10 + plugins/catalog-graph/package.json | 2 +- plugins/catalog-import/CHANGELOG.md | 11 + plugins/catalog-import/package.json | 2 +- plugins/catalog-react/CHANGELOG.md | 9 + plugins/catalog-react/package.json | 2 +- .../catalog-unprocessed-entities/CHANGELOG.md | 7 + .../catalog-unprocessed-entities/package.json | 2 +- plugins/catalog/CHANGELOG.md | 12 + plugins/catalog/package.json | 2 +- plugins/config-schema/CHANGELOG.md | 7 + plugins/config-schema/package.json | 2 +- plugins/devtools/CHANGELOG.md | 9 + plugins/devtools/package.json | 2 +- plugins/example-todo-list/CHANGELOG.md | 7 + plugins/example-todo-list/package.json | 2 +- plugins/home-react/CHANGELOG.md | 7 + plugins/home-react/package.json | 2 +- plugins/home/CHANGELOG.md | 11 + plugins/home/package.json | 2 +- plugins/kubernetes-cluster/CHANGELOG.md | 9 + plugins/kubernetes-cluster/package.json | 2 +- plugins/kubernetes-react/CHANGELOG.md | 8 + plugins/kubernetes-react/package.json | 2 +- plugins/kubernetes/CHANGELOG.md | 9 + plugins/kubernetes/package.json | 2 +- plugins/notifications/CHANGELOG.md | 7 + plugins/notifications/package.json | 2 +- plugins/org-react/CHANGELOG.md | 8 + plugins/org-react/package.json | 2 +- plugins/org/CHANGELOG.md | 10 + plugins/org/package.json | 2 +- plugins/scaffolder-backend/CHANGELOG.md | 6 + plugins/scaffolder-backend/package.json | 2 +- plugins/scaffolder-react/CHANGELOG.md | 8 + plugins/scaffolder-react/package.json | 2 +- plugins/scaffolder/CHANGELOG.md | 12 + plugins/scaffolder/package.json | 2 +- plugins/search-react/CHANGELOG.md | 8 + plugins/search-react/package.json | 2 +- plugins/search/CHANGELOG.md | 12 + plugins/search/package.json | 2 +- plugins/signals/CHANGELOG.md | 7 + plugins/signals/package.json | 2 +- .../techdocs-addons-test-utils/CHANGELOG.md | 12 + .../techdocs-addons-test-utils/package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- plugins/techdocs-react/CHANGELOG.md | 7 + plugins/techdocs-react/package.json | 2 +- plugins/techdocs/CHANGELOG.md | 15 + plugins/techdocs/package.json | 2 +- plugins/user-settings/CHANGELOG.md | 10 + plugins/user-settings/package.json | 2 +- 93 files changed, 941 insertions(+), 46 deletions(-) create mode 100644 docs/releases/v1.29.0-next.2-changelog.md diff --git a/.changeset/pre.json b/.changeset/pre.json index ebf0c6bf22..acd37c2559 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -197,9 +197,11 @@ "create-app-1719320674", "curvy-teachers-smell", "eighty-games-wink", + "eleven-radios-begin", "fair-fans-flow", "fair-pillows-know", "fair-rockets-leave", + "fair-spoons-work", "famous-dodos-crash", "fast-pens-smell", "fifty-pumpkins-smell", @@ -214,6 +216,7 @@ "heavy-moose-pull", "honest-pears-run", "khaki-rivers-obey", + "kind-dancers-boil", "light-avocados-worry", "little-games-fail", "metal-jokes-add", @@ -221,6 +224,7 @@ "metal-suits-drum", "moody-llamas-breathe", "neat-dingos-tickle", + "new-sheep-arrive", "poor-cheetahs-raise", "rare-peas-dream", "renovate-7b61228", @@ -228,6 +232,7 @@ "rich-bears-march", "selfish-turtles-jog", "serious-kings-trade", + "sharp-rice-tickle", "short-flowers-cry", "shy-hounds-battle", "silent-experts-move", @@ -241,6 +246,7 @@ "ten-nails-hear", "ten-pots-walk", "thick-lizards-divide", + "thick-moose-decide", "three-carpets-smoke", "tough-lies-mate", "weak-boats-float", diff --git a/docs/releases/v1.29.0-next.2-changelog.md b/docs/releases/v1.29.0-next.2-changelog.md new file mode 100644 index 0000000000..f6269407cf --- /dev/null +++ b/docs/releases/v1.29.0-next.2-changelog.md @@ -0,0 +1,446 @@ +# Release v1.29.0-next.2 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.29.0-next.2](https://backstage.github.io/upgrade-helper/?to=1.29.0-next.2) + +## @backstage/app-defaults@1.5.8-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + +## @backstage/core-compat-api@0.2.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.7-next.1 + +## @backstage/core-components@0.14.9-next.1 + +### Patch Changes + +- 99d672d: Modified the `Select` component to take in a `data-testid` parameter ensuring backwards compatibility with default value corresponding to previously hardcoded `data-testid` of "select". + +## @backstage/create-app@0.5.17-next.2 + +### Patch Changes + +- e90a2cd: Added the Catalog logs module to the `create-app` template + +## @backstage/dev-utils@1.0.35-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/app-defaults@1.5.8-next.2 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.2 + +## @backstage/frontend-app-api@0.7.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + +## @backstage/frontend-plugin-api@0.6.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + +## @backstage/frontend-test-utils@0.1.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.7.3-next.2 + - @backstage/frontend-plugin-api@0.6.7-next.1 + +## @backstage/plugin-api-docs@0.11.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/plugin-catalog@1.21.1-next.2 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/core-compat-api@0.2.7-next.1 + +## @backstage/plugin-app-visualizer@0.1.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + +## @backstage/plugin-auth-react@0.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + +## @backstage/plugin-catalog@1.21.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/plugin-search-react@1.7.13-next.1 + - @backstage/core-compat-api@0.2.7-next.1 + +## @backstage/plugin-catalog-graph@0.4.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/core-compat-api@0.2.7-next.1 + +## @backstage/plugin-catalog-import@0.12.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/core-compat-api@0.2.7-next.1 + +## @backstage/plugin-catalog-react@1.12.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/integration-react@1.1.29-next.0 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + +## @backstage/plugin-config-schema@0.1.57-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + +## @backstage/plugin-devtools@0.1.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/core-compat-api@0.2.7-next.1 + +## @backstage/plugin-home@0.7.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/plugin-home-react@0.1.15-next.2 + - @backstage/core-compat-api@0.2.7-next.1 + +## @backstage/plugin-home-react@0.1.15-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + +## @backstage/plugin-kubernetes@0.11.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/plugin-kubernetes-react@0.4.1-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.2 + +## @backstage/plugin-kubernetes-cluster@0.0.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/plugin-kubernetes-react@0.4.1-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.2 + +## @backstage/plugin-kubernetes-react@0.4.1-next.1 + +### Patch Changes + +- e3cb6ab: Add a namespace label to RolloutDrawer +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + +## @backstage/plugin-notifications@0.2.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + +## @backstage/plugin-org@0.6.27-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/core-compat-api@0.2.7-next.1 + +## @backstage/plugin-org-react@0.1.26-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.2 + +## @backstage/plugin-scaffolder@1.22.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/plugin-scaffolder-react@1.10.0-next.2 + - @backstage/core-compat-api@0.2.7-next.1 + +## @backstage/plugin-scaffolder-backend@1.23.0-next.2 + +### Patch Changes + +- ff1bb4c: Added a documentation how to use checkpoints + +## @backstage/plugin-scaffolder-react@1.10.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.2 + +## @backstage/plugin-search@1.4.14-next.2 + +### Patch Changes + +- 1117aba: Update deps in search api extension to include fetch api +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/plugin-search-react@1.7.13-next.1 + - @backstage/core-compat-api@0.2.7-next.1 + +## @backstage/plugin-search-react@1.7.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + +## @backstage/plugin-signals@0.0.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + +## @backstage/plugin-techdocs@1.10.7-next.2 + +### Patch Changes + +- 6fa652c: Improve default sorting of docs table +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-auth-react@0.1.4-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/plugin-search-react@1.7.13-next.1 + - @backstage/plugin-techdocs-react@1.2.6-next.1 + - @backstage/core-compat-api@0.2.7-next.1 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.35-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.7-next.2 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-catalog@1.21.1-next.2 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/plugin-search-react@1.7.13-next.1 + - @backstage/plugin-techdocs-react@1.2.6-next.1 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-techdocs-react@1.2.6-next.1 + +## @backstage/plugin-techdocs-react@1.2.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + +## @backstage/plugin-user-settings@0.8.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/core-compat-api@0.2.7-next.1 + +## example-app@0.2.99-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.7-next.2 + - @backstage/core-components@0.14.9-next.1 + - @backstage/plugin-search@1.4.14-next.2 + - @backstage/app-defaults@1.5.8-next.2 + - @backstage/cli@0.26.11-next.1 + - @backstage/frontend-app-api@0.7.3-next.2 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-api-docs@0.11.7-next.2 + - @backstage/plugin-auth-react@0.1.4-next.1 + - @backstage/plugin-catalog@1.21.1-next.2 + - @backstage/plugin-catalog-graph@0.4.7-next.2 + - @backstage/plugin-catalog-import@0.12.1-next.2 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.2.6-next.1 + - @backstage/plugin-devtools@0.1.16-next.1 + - @backstage/plugin-home@0.7.7-next.2 + - @backstage/plugin-kubernetes@0.11.12-next.2 + - @backstage/plugin-kubernetes-cluster@0.0.13-next.2 + - @backstage/plugin-notifications@0.2.3-next.2 + - @backstage/plugin-org@0.6.27-next.2 + - @backstage/plugin-scaffolder@1.22.1-next.2 + - @backstage/plugin-scaffolder-react@1.10.0-next.2 + - @backstage/plugin-search-react@1.7.13-next.1 + - @backstage/plugin-signals@0.0.8-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.12-next.1 + - @backstage/plugin-techdocs-react@1.2.6-next.1 + - @backstage/plugin-user-settings@0.8.9-next.2 + +## example-app-next@0.0.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.7-next.2 + - @backstage/core-components@0.14.9-next.1 + - @backstage/plugin-search@1.4.14-next.2 + - @backstage/app-defaults@1.5.8-next.2 + - @backstage/cli@0.26.11-next.1 + - @backstage/frontend-app-api@0.7.3-next.2 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-api-docs@0.11.7-next.2 + - @backstage/plugin-app-visualizer@0.1.8-next.1 + - @backstage/plugin-auth-react@0.1.4-next.1 + - @backstage/plugin-catalog@1.21.1-next.2 + - @backstage/plugin-catalog-graph@0.4.7-next.2 + - @backstage/plugin-catalog-import@0.12.1-next.2 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.2.6-next.1 + - @backstage/plugin-home@0.7.7-next.2 + - @backstage/plugin-kubernetes@0.11.12-next.2 + - @backstage/plugin-kubernetes-cluster@0.0.13-next.2 + - @backstage/plugin-notifications@0.2.3-next.2 + - @backstage/plugin-org@0.6.27-next.2 + - @backstage/plugin-scaffolder@1.22.1-next.2 + - @backstage/plugin-scaffolder-react@1.10.0-next.2 + - @backstage/plugin-search-react@1.7.13-next.1 + - @backstage/plugin-signals@0.0.8-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.12-next.1 + - @backstage/plugin-techdocs-react@1.2.6-next.1 + - @backstage/plugin-user-settings@0.8.9-next.2 + - @backstage/core-compat-api@0.2.7-next.1 + +## app-next-example-plugin@0.0.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + +## example-backend@0.0.28-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.23.0-next.2 + +## example-backend-legacy@0.2.100-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.23.0-next.2 + - example-app@0.2.99-next.2 + +## e2e-test@0.2.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.17-next.2 + +## techdocs-cli-embedded-app@0.2.98-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.7-next.2 + - @backstage/core-components@0.14.9-next.1 + - @backstage/app-defaults@1.5.8-next.2 + - @backstage/cli@0.26.11-next.1 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-catalog@1.21.1-next.2 + - @backstage/plugin-techdocs-react@1.2.6-next.1 + +## @internal/plugin-todo-list@1.0.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 diff --git a/package.json b/package.json index 7de757ff9b..d3d042c2f5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "root", - "version": "1.29.0-next.1", + "version": "1.29.0-next.2", "private": true, "repository": { "type": "git", diff --git a/packages/app-defaults/CHANGELOG.md b/packages/app-defaults/CHANGELOG.md index 588c59c3e4..21fe959edb 100644 --- a/packages/app-defaults/CHANGELOG.md +++ b/packages/app-defaults/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/app-defaults +## 1.5.8-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + ## 1.5.8-next.1 ### Patch Changes diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json index 8bb0a707b5..4393164fcd 100644 --- a/packages/app-defaults/package.json +++ b/packages/app-defaults/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/app-defaults", - "version": "1.5.8-next.1", + "version": "1.5.8-next.2", "description": "Provides the default wiring of a Backstage App", "backstage": { "role": "web-library" diff --git a/packages/app-next-example-plugin/CHANGELOG.md b/packages/app-next-example-plugin/CHANGELOG.md index e6788c8566..5456da237c 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.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + ## 0.0.13-next.0 ### Patch Changes diff --git a/packages/app-next-example-plugin/package.json b/packages/app-next-example-plugin/package.json index 9d2e76c418..c3faec66d6 100644 --- a/packages/app-next-example-plugin/package.json +++ b/packages/app-next-example-plugin/package.json @@ -1,6 +1,6 @@ { "name": "app-next-example-plugin", - "version": "0.0.13-next.0", + "version": "0.0.13-next.1", "description": "Backstage internal example plugin", "backstage": { "role": "frontend-plugin", diff --git a/packages/app-next/CHANGELOG.md b/packages/app-next/CHANGELOG.md index 6c3d48601f..22d53e4c78 100644 --- a/packages/app-next/CHANGELOG.md +++ b/packages/app-next/CHANGELOG.md @@ -1,5 +1,40 @@ # example-app-next +## 0.0.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.7-next.2 + - @backstage/core-components@0.14.9-next.1 + - @backstage/plugin-search@1.4.14-next.2 + - @backstage/app-defaults@1.5.8-next.2 + - @backstage/cli@0.26.11-next.1 + - @backstage/frontend-app-api@0.7.3-next.2 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-api-docs@0.11.7-next.2 + - @backstage/plugin-app-visualizer@0.1.8-next.1 + - @backstage/plugin-auth-react@0.1.4-next.1 + - @backstage/plugin-catalog@1.21.1-next.2 + - @backstage/plugin-catalog-graph@0.4.7-next.2 + - @backstage/plugin-catalog-import@0.12.1-next.2 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.2.6-next.1 + - @backstage/plugin-home@0.7.7-next.2 + - @backstage/plugin-kubernetes@0.11.12-next.2 + - @backstage/plugin-kubernetes-cluster@0.0.13-next.2 + - @backstage/plugin-notifications@0.2.3-next.2 + - @backstage/plugin-org@0.6.27-next.2 + - @backstage/plugin-scaffolder@1.22.1-next.2 + - @backstage/plugin-scaffolder-react@1.10.0-next.2 + - @backstage/plugin-search-react@1.7.13-next.1 + - @backstage/plugin-signals@0.0.8-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.12-next.1 + - @backstage/plugin-techdocs-react@1.2.6-next.1 + - @backstage/plugin-user-settings@0.8.9-next.2 + - @backstage/core-compat-api@0.2.7-next.1 + ## 0.0.13-next.1 ### Patch Changes diff --git a/packages/app-next/package.json b/packages/app-next/package.json index a0f0174753..c38eacfcd5 100644 --- a/packages/app-next/package.json +++ b/packages/app-next/package.json @@ -1,6 +1,6 @@ { "name": "example-app-next", - "version": "0.0.13-next.1", + "version": "0.0.13-next.2", "private": true, "repository": { "type": "git", diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index 3a06dd99fd..4977cc1d6d 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,38 @@ # example-app +## 0.2.99-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.7-next.2 + - @backstage/core-components@0.14.9-next.1 + - @backstage/plugin-search@1.4.14-next.2 + - @backstage/app-defaults@1.5.8-next.2 + - @backstage/cli@0.26.11-next.1 + - @backstage/frontend-app-api@0.7.3-next.2 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-api-docs@0.11.7-next.2 + - @backstage/plugin-auth-react@0.1.4-next.1 + - @backstage/plugin-catalog@1.21.1-next.2 + - @backstage/plugin-catalog-graph@0.4.7-next.2 + - @backstage/plugin-catalog-import@0.12.1-next.2 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.2.6-next.1 + - @backstage/plugin-devtools@0.1.16-next.1 + - @backstage/plugin-home@0.7.7-next.2 + - @backstage/plugin-kubernetes@0.11.12-next.2 + - @backstage/plugin-kubernetes-cluster@0.0.13-next.2 + - @backstage/plugin-notifications@0.2.3-next.2 + - @backstage/plugin-org@0.6.27-next.2 + - @backstage/plugin-scaffolder@1.22.1-next.2 + - @backstage/plugin-scaffolder-react@1.10.0-next.2 + - @backstage/plugin-search-react@1.7.13-next.1 + - @backstage/plugin-signals@0.0.8-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.12-next.1 + - @backstage/plugin-techdocs-react@1.2.6-next.1 + - @backstage/plugin-user-settings@0.8.9-next.2 + ## 0.2.99-next.1 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index a30c8e15d7..f15dbac9db 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "example-app", - "version": "0.2.99-next.1", + "version": "0.2.99-next.2", "backstage": { "role": "frontend" }, diff --git a/packages/backend-legacy/CHANGELOG.md b/packages/backend-legacy/CHANGELOG.md index 7734d12d4f..35ed7a6c93 100644 --- a/packages/backend-legacy/CHANGELOG.md +++ b/packages/backend-legacy/CHANGELOG.md @@ -1,5 +1,13 @@ # example-backend-legacy +## 0.2.100-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.23.0-next.2 + - example-app@0.2.99-next.2 + ## 0.2.100-next.1 ### Patch Changes diff --git a/packages/backend-legacy/package.json b/packages/backend-legacy/package.json index 384ce61973..a537361746 100644 --- a/packages/backend-legacy/package.json +++ b/packages/backend-legacy/package.json @@ -1,6 +1,6 @@ { "name": "example-backend-legacy", - "version": "0.2.100-next.1", + "version": "0.2.100-next.2", "backstage": { "role": "backend" }, diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index 0c91daa13d..4ceb786f2a 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,12 @@ # example-backend +## 0.0.28-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.23.0-next.2 + ## 0.0.28-next.1 ### Patch Changes diff --git a/packages/backend/package.json b/packages/backend/package.json index 8e6918bfc5..459db3c317 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.0.28-next.1", + "version": "0.0.28-next.2", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/core-compat-api/CHANGELOG.md b/packages/core-compat-api/CHANGELOG.md index 8bcedca9c4..3ad2bd654e 100644 --- a/packages/core-compat-api/CHANGELOG.md +++ b/packages/core-compat-api/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/core-compat-api +## 0.2.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.7-next.1 + ## 0.2.7-next.0 ### Patch Changes diff --git a/packages/core-compat-api/package.json b/packages/core-compat-api/package.json index 954cd6deb3..0f164a6187 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.2.7-next.0", + "version": "0.2.7-next.1", "backstage": { "role": "web-library" }, diff --git a/packages/core-components/CHANGELOG.md b/packages/core-components/CHANGELOG.md index f42b6396ce..163406bbca 100644 --- a/packages/core-components/CHANGELOG.md +++ b/packages/core-components/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/core-components +## 0.14.9-next.1 + +### Patch Changes + +- 99d672d: Modified the `Select` component to take in a `data-testid` parameter ensuring backwards compatibility with default value corresponding to previously hardcoded `data-testid` of "select". + ## 0.14.9-next.0 ### Patch Changes diff --git a/packages/core-components/package.json b/packages/core-components/package.json index 72f733e1a9..21c4a19dbf 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.14.9-next.0", + "version": "0.14.9-next.1", "publishConfig": { "access": "public" }, diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index 3f102c17da..708a9b33f8 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/create-app +## 0.5.17-next.2 + +### Patch Changes + +- e90a2cd: Added the Catalog logs module to the `create-app` template + ## 0.5.17-next.1 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 96be1f941c..c1ca92f87b 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.17-next.1", + "version": "0.5.17-next.2", "publishConfig": { "access": "public" }, diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index 62a5c2adc2..ee9f56dec7 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/dev-utils +## 1.0.35-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/app-defaults@1.5.8-next.2 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.2 + ## 1.0.35-next.1 ### Patch Changes diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index 3e05873d6c..50220c36e1 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/dev-utils", - "version": "1.0.35-next.1", + "version": "1.0.35-next.2", "description": "Utilities for developing Backstage plugins.", "backstage": { "role": "web-library" diff --git a/packages/e2e-test/CHANGELOG.md b/packages/e2e-test/CHANGELOG.md index a11001a2aa..5144d9fd86 100644 --- a/packages/e2e-test/CHANGELOG.md +++ b/packages/e2e-test/CHANGELOG.md @@ -1,5 +1,12 @@ # e2e-test +## 0.2.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.17-next.2 + ## 0.2.18-next.1 ### Patch Changes diff --git a/packages/e2e-test/package.json b/packages/e2e-test/package.json index d1f42a1d8f..1d65314e83 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.18-next.1", + "version": "0.2.18-next.2", "private": true, "backstage": { "role": "cli" diff --git a/packages/frontend-app-api/CHANGELOG.md b/packages/frontend-app-api/CHANGELOG.md index fc39807e5b..dde282a831 100644 --- a/packages/frontend-app-api/CHANGELOG.md +++ b/packages/frontend-app-api/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/frontend-app-api +## 0.7.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + ## 0.7.3-next.1 ### Patch Changes diff --git a/packages/frontend-app-api/package.json b/packages/frontend-app-api/package.json index a6c2583fbc..68c2fd8fab 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.7.3-next.1", + "version": "0.7.3-next.2", "backstage": { "role": "web-library" }, diff --git a/packages/frontend-plugin-api/CHANGELOG.md b/packages/frontend-plugin-api/CHANGELOG.md index 15e3c06bd6..dda46968a4 100644 --- a/packages/frontend-plugin-api/CHANGELOG.md +++ b/packages/frontend-plugin-api/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/frontend-plugin-api +## 0.6.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + ## 0.6.7-next.0 ### Patch Changes diff --git a/packages/frontend-plugin-api/package.json b/packages/frontend-plugin-api/package.json index be603e2611..b62fe36059 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.6.7-next.0", + "version": "0.6.7-next.1", "backstage": { "role": "web-library" }, diff --git a/packages/frontend-test-utils/CHANGELOG.md b/packages/frontend-test-utils/CHANGELOG.md index 5ece8edb86..34d9b28143 100644 --- a/packages/frontend-test-utils/CHANGELOG.md +++ b/packages/frontend-test-utils/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/frontend-test-utils +## 0.1.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.7.3-next.2 + - @backstage/frontend-plugin-api@0.6.7-next.1 + ## 0.1.10-next.1 ### Patch Changes diff --git a/packages/frontend-test-utils/package.json b/packages/frontend-test-utils/package.json index 9856a09367..2a366fa152 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.10-next.1", + "version": "0.1.10-next.2", "backstage": { "role": "web-library" }, diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md index 343ecf5ccb..123e82edf7 100644 --- a/packages/techdocs-cli-embedded-app/CHANGELOG.md +++ b/packages/techdocs-cli-embedded-app/CHANGELOG.md @@ -1,5 +1,18 @@ # techdocs-cli-embedded-app +## 0.2.98-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.7-next.2 + - @backstage/core-components@0.14.9-next.1 + - @backstage/app-defaults@1.5.8-next.2 + - @backstage/cli@0.26.11-next.1 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-catalog@1.21.1-next.2 + - @backstage/plugin-techdocs-react@1.2.6-next.1 + ## 0.2.98-next.1 ### Patch Changes diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json index 3b234c8f4c..979d18620f 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.98-next.1", + "version": "0.2.98-next.2", "private": true, "backstage": { "role": "frontend" diff --git a/plugins/api-docs/CHANGELOG.md b/plugins/api-docs/CHANGELOG.md index f41b4534f1..58d69f516d 100644 --- a/plugins/api-docs/CHANGELOG.md +++ b/plugins/api-docs/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-api-docs +## 0.11.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/plugin-catalog@1.21.1-next.2 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/core-compat-api@0.2.7-next.1 + ## 0.11.7-next.1 ### Patch Changes diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 84e2891bcc..5a6d97b7ce 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-api-docs", - "version": "0.11.7-next.1", + "version": "0.11.7-next.2", "description": "A Backstage plugin that helps represent API entities in the frontend", "backstage": { "role": "frontend-plugin", diff --git a/plugins/app-visualizer/CHANGELOG.md b/plugins/app-visualizer/CHANGELOG.md index d4a23d79f2..cdb8bab69e 100644 --- a/plugins/app-visualizer/CHANGELOG.md +++ b/plugins/app-visualizer/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-app-visualizer +## 0.1.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + ## 0.1.8-next.0 ### Patch Changes diff --git a/plugins/app-visualizer/package.json b/plugins/app-visualizer/package.json index 31c7dfd87e..95df128040 100644 --- a/plugins/app-visualizer/package.json +++ b/plugins/app-visualizer/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-app-visualizer", - "version": "0.1.8-next.0", + "version": "0.1.8-next.1", "description": "Visualizes the Backstage app structure", "backstage": { "role": "frontend-plugin", diff --git a/plugins/auth-react/CHANGELOG.md b/plugins/auth-react/CHANGELOG.md index 668f751352..84bfadc98c 100644 --- a/plugins/auth-react/CHANGELOG.md +++ b/plugins/auth-react/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-auth-react +## 0.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + ## 0.1.4-next.0 ### Patch Changes diff --git a/plugins/auth-react/package.json b/plugins/auth-react/package.json index 114ecd1d55..8af97a0b04 100644 --- a/plugins/auth-react/package.json +++ b/plugins/auth-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-react", - "version": "0.1.4-next.0", + "version": "0.1.4-next.1", "description": "Web library for the auth plugin", "backstage": { "role": "web-library", diff --git a/plugins/catalog-graph/CHANGELOG.md b/plugins/catalog-graph/CHANGELOG.md index fd2b0477e0..f397955e1c 100644 --- a/plugins/catalog-graph/CHANGELOG.md +++ b/plugins/catalog-graph/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-catalog-graph +## 0.4.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/core-compat-api@0.2.7-next.1 + ## 0.4.7-next.1 ### Patch Changes diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json index 22e30e3406..eb27725d45 100644 --- a/plugins/catalog-graph/package.json +++ b/plugins/catalog-graph/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-graph", - "version": "0.4.7-next.1", + "version": "0.4.7-next.2", "backstage": { "role": "frontend-plugin", "pluginId": "catalog-graph", diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md index bebc0c5240..455f094a86 100644 --- a/plugins/catalog-import/CHANGELOG.md +++ b/plugins/catalog-import/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-catalog-import +## 0.12.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/core-compat-api@0.2.7-next.1 + ## 0.12.1-next.1 ### Patch Changes diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index 704fdae2e6..f41d239792 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-import", - "version": "0.12.1-next.1", + "version": "0.12.1-next.2", "description": "A Backstage plugin the helps you import entities into your catalog", "backstage": { "role": "frontend-plugin", diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md index 68febf6b12..b29a49e47d 100644 --- a/plugins/catalog-react/CHANGELOG.md +++ b/plugins/catalog-react/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-catalog-react +## 1.12.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/integration-react@1.1.29-next.0 + ## 1.12.2-next.1 ### Patch Changes diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index 99eb8af013..f522a4f111 100644 --- a/plugins/catalog-react/package.json +++ b/plugins/catalog-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-react", - "version": "1.12.2-next.1", + "version": "1.12.2-next.2", "description": "A frontend library that helps other Backstage plugins interact with the catalog", "backstage": { "role": "web-library", diff --git a/plugins/catalog-unprocessed-entities/CHANGELOG.md b/plugins/catalog-unprocessed-entities/CHANGELOG.md index ab22634257..fefeffe9d2 100644 --- a/plugins/catalog-unprocessed-entities/CHANGELOG.md +++ b/plugins/catalog-unprocessed-entities/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-catalog-unprocessed-entities +## 0.2.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + ## 0.2.6-next.0 ### Patch Changes diff --git a/plugins/catalog-unprocessed-entities/package.json b/plugins/catalog-unprocessed-entities/package.json index f32ff293df..142b850bd3 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.2.6-next.0", + "version": "0.2.6-next.1", "backstage": { "role": "frontend-plugin", "pluginId": "catalog-unprocessed-entities", diff --git a/plugins/catalog/CHANGELOG.md b/plugins/catalog/CHANGELOG.md index d003afccf1..08a70d4956 100644 --- a/plugins/catalog/CHANGELOG.md +++ b/plugins/catalog/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-catalog +## 1.21.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/plugin-search-react@1.7.13-next.1 + - @backstage/core-compat-api@0.2.7-next.1 + ## 1.21.1-next.1 ### Patch Changes diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index 5cf63e86ab..0d101af3df 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog", - "version": "1.21.1-next.1", + "version": "1.21.1-next.2", "description": "The Backstage plugin for browsing the Backstage catalog", "backstage": { "role": "frontend-plugin", diff --git a/plugins/config-schema/CHANGELOG.md b/plugins/config-schema/CHANGELOG.md index 76472b69b4..8458a50aa3 100644 --- a/plugins/config-schema/CHANGELOG.md +++ b/plugins/config-schema/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-config-schema +## 0.1.57-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + ## 0.1.57-next.0 ### Patch Changes diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index 38db6a21d5..9a1971d80b 100644 --- a/plugins/config-schema/package.json +++ b/plugins/config-schema/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-config-schema", - "version": "0.1.57-next.0", + "version": "0.1.57-next.1", "description": "A Backstage plugin that lets you browse the configuration schema of your app", "backstage": { "role": "frontend-plugin", diff --git a/plugins/devtools/CHANGELOG.md b/plugins/devtools/CHANGELOG.md index 977e9cd73f..5bc6220aa3 100644 --- a/plugins/devtools/CHANGELOG.md +++ b/plugins/devtools/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-devtools +## 0.1.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/core-compat-api@0.2.7-next.1 + ## 0.1.16-next.0 ### Patch Changes diff --git a/plugins/devtools/package.json b/plugins/devtools/package.json index 2749bbeef2..90d724692c 100644 --- a/plugins/devtools/package.json +++ b/plugins/devtools/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-devtools", - "version": "0.1.16-next.0", + "version": "0.1.16-next.1", "backstage": { "role": "frontend-plugin", "pluginId": "devtools", diff --git a/plugins/example-todo-list/CHANGELOG.md b/plugins/example-todo-list/CHANGELOG.md index 2f392e6c33..f61f8b8d0a 100644 --- a/plugins/example-todo-list/CHANGELOG.md +++ b/plugins/example-todo-list/CHANGELOG.md @@ -1,5 +1,12 @@ # @internal/plugin-todo-list +## 1.0.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + ## 1.0.29-next.0 ### Patch Changes diff --git a/plugins/example-todo-list/package.json b/plugins/example-todo-list/package.json index c0ef80b3de..d008b73538 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.29-next.0", + "version": "1.0.29-next.1", "backstage": { "role": "frontend-plugin", "pluginId": "todo-list", diff --git a/plugins/home-react/CHANGELOG.md b/plugins/home-react/CHANGELOG.md index 8353571dd8..1f1c9a0e2e 100644 --- a/plugins/home-react/CHANGELOG.md +++ b/plugins/home-react/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-home-react +## 0.1.15-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + ## 0.1.15-next.1 ### Patch Changes diff --git a/plugins/home-react/package.json b/plugins/home-react/package.json index b5dcaae83e..ec05852818 100644 --- a/plugins/home-react/package.json +++ b/plugins/home-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-home-react", - "version": "0.1.15-next.1", + "version": "0.1.15-next.2", "description": "A Backstage plugin that contains react components helps you build a home page", "backstage": { "role": "web-library", diff --git a/plugins/home/CHANGELOG.md b/plugins/home/CHANGELOG.md index b475b7f764..e65b3dec1c 100644 --- a/plugins/home/CHANGELOG.md +++ b/plugins/home/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-home +## 0.7.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/plugin-home-react@0.1.15-next.2 + - @backstage/core-compat-api@0.2.7-next.1 + ## 0.7.7-next.1 ### Patch Changes diff --git a/plugins/home/package.json b/plugins/home/package.json index 928417145b..01dd27a295 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-home", - "version": "0.7.7-next.1", + "version": "0.7.7-next.2", "description": "A Backstage plugin that helps you build a home page", "backstage": { "role": "frontend-plugin", diff --git a/plugins/kubernetes-cluster/CHANGELOG.md b/plugins/kubernetes-cluster/CHANGELOG.md index 0d8596888a..8932454b3c 100644 --- a/plugins/kubernetes-cluster/CHANGELOG.md +++ b/plugins/kubernetes-cluster/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-kubernetes-cluster +## 0.0.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/plugin-kubernetes-react@0.4.1-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.2 + ## 0.0.13-next.1 ### Patch Changes diff --git a/plugins/kubernetes-cluster/package.json b/plugins/kubernetes-cluster/package.json index 40a6d33dd2..3c6e6c8f1b 100644 --- a/plugins/kubernetes-cluster/package.json +++ b/plugins/kubernetes-cluster/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-cluster", - "version": "0.0.13-next.1", + "version": "0.0.13-next.2", "description": "A Backstage plugin that shows details of Kubernetes clusters", "backstage": { "role": "frontend-plugin", diff --git a/plugins/kubernetes-react/CHANGELOG.md b/plugins/kubernetes-react/CHANGELOG.md index 81b5c62fad..3755d259a8 100644 --- a/plugins/kubernetes-react/CHANGELOG.md +++ b/plugins/kubernetes-react/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-kubernetes-react +## 0.4.1-next.1 + +### Patch Changes + +- e3cb6ab: Add a namespace label to RolloutDrawer +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + ## 0.4.1-next.0 ### Patch Changes diff --git a/plugins/kubernetes-react/package.json b/plugins/kubernetes-react/package.json index 0cc34da7db..fc6f382d3d 100644 --- a/plugins/kubernetes-react/package.json +++ b/plugins/kubernetes-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-react", - "version": "0.4.1-next.0", + "version": "0.4.1-next.1", "description": "Web library for the kubernetes-react plugin", "backstage": { "role": "web-library", diff --git a/plugins/kubernetes/CHANGELOG.md b/plugins/kubernetes/CHANGELOG.md index 2d92f6b026..a6d07dc706 100644 --- a/plugins/kubernetes/CHANGELOG.md +++ b/plugins/kubernetes/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-kubernetes +## 0.11.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/plugin-kubernetes-react@0.4.1-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.2 + ## 0.11.12-next.1 ### Patch Changes diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index eef4da08bc..d0ee97a882 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes", - "version": "0.11.12-next.1", + "version": "0.11.12-next.2", "description": "A Backstage plugin that integrates towards Kubernetes", "backstage": { "role": "frontend-plugin", diff --git a/plugins/notifications/CHANGELOG.md b/plugins/notifications/CHANGELOG.md index 9f532b3698..97e6c50b44 100644 --- a/plugins/notifications/CHANGELOG.md +++ b/plugins/notifications/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-notifications +## 0.2.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + ## 0.2.3-next.1 ### Patch Changes diff --git a/plugins/notifications/package.json b/plugins/notifications/package.json index 2e2c67e891..4ef28f9508 100644 --- a/plugins/notifications/package.json +++ b/plugins/notifications/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications", - "version": "0.2.3-next.1", + "version": "0.2.3-next.2", "backstage": { "role": "frontend-plugin", "pluginId": "notifications", diff --git a/plugins/org-react/CHANGELOG.md b/plugins/org-react/CHANGELOG.md index 1ce749fede..d13578fd32 100644 --- a/plugins/org-react/CHANGELOG.md +++ b/plugins/org-react/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-org-react +## 0.1.26-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.2 + ## 0.1.26-next.1 ### Patch Changes diff --git a/plugins/org-react/package.json b/plugins/org-react/package.json index 327e27662f..e6494eaa28 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.26-next.1", + "version": "0.1.26-next.2", "backstage": { "role": "web-library", "pluginId": "org", diff --git a/plugins/org/CHANGELOG.md b/plugins/org/CHANGELOG.md index 5ca788557f..aa4bd9a93f 100644 --- a/plugins/org/CHANGELOG.md +++ b/plugins/org/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-org +## 0.6.27-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/core-compat-api@0.2.7-next.1 + ## 0.6.27-next.1 ### Patch Changes diff --git a/plugins/org/package.json b/plugins/org/package.json index 5c62ffa99f..c2d43bc5ed 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-org", - "version": "0.6.27-next.1", + "version": "0.6.27-next.2", "description": "A Backstage plugin that helps you create entity pages for your organization", "backstage": { "role": "frontend-plugin", diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md index 97cd859856..a4df9e72e9 100644 --- a/plugins/scaffolder-backend/CHANGELOG.md +++ b/plugins/scaffolder-backend/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/plugin-scaffolder-backend +## 1.23.0-next.2 + +### Patch Changes + +- ff1bb4c: Added a documentation how to use checkpoints + ## 1.23.0-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 71857e245b..10d827762e 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend", - "version": "1.23.0-next.1", + "version": "1.23.0-next.2", "description": "The Backstage backend plugin that helps you create new things", "backstage": { "role": "backend-plugin", diff --git a/plugins/scaffolder-react/CHANGELOG.md b/plugins/scaffolder-react/CHANGELOG.md index 6cbdb781f3..a1ed542bd5 100644 --- a/plugins/scaffolder-react/CHANGELOG.md +++ b/plugins/scaffolder-react/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-scaffolder-react +## 1.10.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.2 + ## 1.10.0-next.1 ### Minor Changes diff --git a/plugins/scaffolder-react/package.json b/plugins/scaffolder-react/package.json index 6bdc263b3d..36ee0870fc 100644 --- a/plugins/scaffolder-react/package.json +++ b/plugins/scaffolder-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-react", - "version": "1.10.0-next.1", + "version": "1.10.0-next.2", "description": "A frontend library that helps other Backstage plugins interact with the Scaffolder", "backstage": { "role": "web-library", diff --git a/plugins/scaffolder/CHANGELOG.md b/plugins/scaffolder/CHANGELOG.md index 566411b9bd..3c4cfe54ab 100644 --- a/plugins/scaffolder/CHANGELOG.md +++ b/plugins/scaffolder/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder +## 1.22.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/plugin-scaffolder-react@1.10.0-next.2 + - @backstage/core-compat-api@0.2.7-next.1 + ## 1.22.1-next.1 ### Patch Changes diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 0db796359a..95dd5bff08 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder", - "version": "1.22.1-next.1", + "version": "1.22.1-next.2", "description": "The Backstage plugin that helps you create new things", "backstage": { "role": "frontend-plugin", diff --git a/plugins/search-react/CHANGELOG.md b/plugins/search-react/CHANGELOG.md index 19ace29f0c..494ce07772 100644 --- a/plugins/search-react/CHANGELOG.md +++ b/plugins/search-react/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-search-react +## 1.7.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + ## 1.7.13-next.0 ### Patch Changes diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index 25bc946bd4..a0701e1f3b 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.13-next.0", + "version": "1.7.13-next.1", "backstage": { "role": "web-library", "pluginId": "search", diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md index dac2074373..a6cab671b5 100644 --- a/plugins/search/CHANGELOG.md +++ b/plugins/search/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-search +## 1.4.14-next.2 + +### Patch Changes + +- 1117aba: Update deps in search api extension to include fetch api +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/plugin-search-react@1.7.13-next.1 + - @backstage/core-compat-api@0.2.7-next.1 + ## 1.4.13-next.1 ### Patch Changes diff --git a/plugins/search/package.json b/plugins/search/package.json index 3b08790026..ad8210df4c 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search", - "version": "1.4.13-next.1", + "version": "1.4.14-next.2", "description": "The Backstage plugin that provides your backstage app with search", "backstage": { "role": "frontend-plugin", diff --git a/plugins/signals/CHANGELOG.md b/plugins/signals/CHANGELOG.md index f5992789c5..9ccdff8b97 100644 --- a/plugins/signals/CHANGELOG.md +++ b/plugins/signals/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-signals +## 0.0.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + ## 0.0.8-next.0 ### Patch Changes diff --git a/plugins/signals/package.json b/plugins/signals/package.json index 18345295b5..58b82fab7a 100644 --- a/plugins/signals/package.json +++ b/plugins/signals/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals", - "version": "0.0.8-next.0", + "version": "0.0.8-next.1", "backstage": { "role": "frontend-plugin", "pluginId": "signals", diff --git a/plugins/techdocs-addons-test-utils/CHANGELOG.md b/plugins/techdocs-addons-test-utils/CHANGELOG.md index 0695f7e1f4..5b247addab 100644 --- a/plugins/techdocs-addons-test-utils/CHANGELOG.md +++ b/plugins/techdocs-addons-test-utils/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-techdocs-addons-test-utils +## 1.0.35-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.7-next.2 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-catalog@1.21.1-next.2 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/plugin-search-react@1.7.13-next.1 + - @backstage/plugin-techdocs-react@1.2.6-next.1 + ## 1.0.35-next.1 ### Patch Changes diff --git a/plugins/techdocs-addons-test-utils/package.json b/plugins/techdocs-addons-test-utils/package.json index fd1c806414..966308ee94 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.35-next.1", + "version": "1.0.35-next.2", "backstage": { "role": "web-library", "pluginId": "techdocs-addons", diff --git a/plugins/techdocs-module-addons-contrib/CHANGELOG.md b/plugins/techdocs-module-addons-contrib/CHANGELOG.md index da76210708..2cc99a8158 100644 --- a/plugins/techdocs-module-addons-contrib/CHANGELOG.md +++ b/plugins/techdocs-module-addons-contrib/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-techdocs-module-addons-contrib +## 1.1.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-techdocs-react@1.2.6-next.1 + ## 1.1.12-next.0 ### Patch Changes diff --git a/plugins/techdocs-module-addons-contrib/package.json b/plugins/techdocs-module-addons-contrib/package.json index f0b2301dfb..f68df2a883 100644 --- a/plugins/techdocs-module-addons-contrib/package.json +++ b/plugins/techdocs-module-addons-contrib/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-module-addons-contrib", - "version": "1.1.12-next.0", + "version": "1.1.12-next.1", "description": "Plugin module for contributed TechDocs Addons", "backstage": { "role": "frontend-plugin-module", diff --git a/plugins/techdocs-react/CHANGELOG.md b/plugins/techdocs-react/CHANGELOG.md index d07ed27eb0..97677352df 100644 --- a/plugins/techdocs-react/CHANGELOG.md +++ b/plugins/techdocs-react/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-techdocs-react +## 1.2.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + ## 1.2.6-next.0 ### Patch Changes diff --git a/plugins/techdocs-react/package.json b/plugins/techdocs-react/package.json index d002db68d1..1686b176ca 100644 --- a/plugins/techdocs-react/package.json +++ b/plugins/techdocs-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-react", - "version": "1.2.6-next.0", + "version": "1.2.6-next.1", "description": "Shared frontend utilities for TechDocs and Addons", "backstage": { "role": "web-library", diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index a14559de1e..34dc9a310f 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-techdocs +## 1.10.7-next.2 + +### Patch Changes + +- 6fa652c: Improve default sorting of docs table +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-auth-react@0.1.4-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/plugin-search-react@1.7.13-next.1 + - @backstage/plugin-techdocs-react@1.2.6-next.1 + - @backstage/core-compat-api@0.2.7-next.1 + ## 1.10.7-next.1 ### Patch Changes diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 2a404551be..cbf1f828ce 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs", - "version": "1.10.7-next.1", + "version": "1.10.7-next.2", "description": "The Backstage plugin that renders technical documentation for your components", "backstage": { "role": "frontend-plugin", diff --git a/plugins/user-settings/CHANGELOG.md b/plugins/user-settings/CHANGELOG.md index 5b86011ba8..8d886aee80 100644 --- a/plugins/user-settings/CHANGELOG.md +++ b/plugins/user-settings/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-user-settings +## 0.8.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/core-compat-api@0.2.7-next.1 + ## 0.8.9-next.1 ### Patch Changes diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index a549c7cdd2..34c719d9df 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-user-settings", - "version": "0.8.9-next.1", + "version": "0.8.9-next.2", "description": "A Backstage plugin that provides a settings page", "backstage": { "role": "frontend-plugin", From efda5a301dbe9a4c40e9194559d32cc606734aeb Mon Sep 17 00:00:00 2001 From: Olivier Liechti Date: Tue, 9 Jul 2024 15:08:24 +0200 Subject: [PATCH 210/510] Export Atlassian OAuth Profile type Signed-off-by: Olivier Liechti --- .changeset/nasty-balloons-attack.md | 5 +++++ plugins/auth-backend-module-atlassian-provider/src/index.ts | 3 +-- plugins/auth-backend/src/providers/atlassian/provider.ts | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 .changeset/nasty-balloons-attack.md diff --git a/.changeset/nasty-balloons-attack.md b/.changeset/nasty-balloons-attack.md new file mode 100644 index 0000000000..60229b4a25 --- /dev/null +++ b/.changeset/nasty-balloons-attack.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': patch +--- + +Use new Atlassian Passport profile in type definition diff --git a/plugins/auth-backend-module-atlassian-provider/src/index.ts b/plugins/auth-backend-module-atlassian-provider/src/index.ts index cc71c9b7e3..224037b868 100644 --- a/plugins/auth-backend-module-atlassian-provider/src/index.ts +++ b/plugins/auth-backend-module-atlassian-provider/src/index.ts @@ -13,13 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - /** * The atlassian-provider backend module for the auth plugin. * * @packageDocumentation */ - export { atlassianAuthenticator } from './authenticator'; +export type { AtlassianPassportProfile } from './authenticator'; export { authModuleAtlassianProvider as default } from './module'; export { atlassianSignInResolvers } from './resolvers'; diff --git a/plugins/auth-backend/src/providers/atlassian/provider.ts b/plugins/auth-backend/src/providers/atlassian/provider.ts index 22db26fd85..d30164bd6e 100644 --- a/plugins/auth-backend/src/providers/atlassian/provider.ts +++ b/plugins/auth-backend/src/providers/atlassian/provider.ts @@ -26,6 +26,7 @@ import { import { OAuthResult } from '../../lib/oauth'; import { createAuthProviderIntegration } from '../createAuthProviderIntegration'; import { AuthHandler } from '../types'; +import { AtlassianPassportProfile } from '@backstage/plugin-auth-backend-module-atlassian-provider'; /** * Auth provider integration for Atlassian auth @@ -47,7 +48,7 @@ export const atlassian = createAuthProviderIntegration({ resolver: SignInResolver; }; }) { - return createOAuthProviderFactory({ + return createOAuthProviderFactory({ authenticator: atlassianAuthenticator, profileTransform: adaptLegacyOAuthHandler(options?.authHandler), signInResolver: adaptLegacyOAuthSignInResolver(options?.signIn?.resolver), From 55c1a729ac4cdd84afd9ac4bb081b9b1c2ad7274 Mon Sep 17 00:00:00 2001 From: Olivier Liechti Date: Tue, 9 Jul 2024 16:29:50 +0200 Subject: [PATCH 211/510] Simplify the bug fix, by implementing logic in the PassportHelper Signed-off-by: Olivier Liechti --- .changeset/stale-beds-sneeze.md | 6 +++ .../src/authenticator.ts | 37 +++---------------- .../src/index.ts | 1 - .../src/providers/atlassian/provider.ts | 3 +- .../auth-node/src/passport/PassportHelpers.ts | 7 ++++ plugins/auth-node/src/passport/types.ts | 2 + 6 files changed, 22 insertions(+), 34 deletions(-) create mode 100644 .changeset/stale-beds-sneeze.md diff --git a/.changeset/stale-beds-sneeze.md b/.changeset/stale-beds-sneeze.md new file mode 100644 index 0000000000..e2fc5acdf2 --- /dev/null +++ b/.changeset/stale-beds-sneeze.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-auth-backend-module-atlassian-provider': patch +'@backstage/plugin-auth-node': patch +--- + +Fix issues with Atlassian OAuth provider diff --git a/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts b/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts index 8a1b952d15..23a4a52197 100644 --- a/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts +++ b/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts @@ -16,39 +16,16 @@ import { createOAuthAuthenticator, - OAuthAuthenticatorResult, PassportOAuthAuthenticatorHelper, PassportOAuthDoneCallback, - ProfileInfo, + PassportProfile, } from '@backstage/plugin-auth-node'; import AtlassianStrategy from 'passport-atlassian-oauth2'; -export type AtlassianPassportProfile = { - id: string; - displayName: string; - email: string; - photo: string; - provider: string; - _json: any; -}; - /** @public */ export const atlassianAuthenticator = createOAuthAuthenticator({ - defaultProfileTransform: async ( - input: OAuthAuthenticatorResult, - ) => { - const atlassianProfile = input.fullProfile as AtlassianPassportProfile; - - const profile: ProfileInfo = { - displayName: atlassianProfile.displayName, - email: atlassianProfile.email, - picture: atlassianProfile.photo, - }; - - return { - profile, - }; - }, + defaultProfileTransform: + PassportOAuthAuthenticatorHelper.defaultProfileTransform, scopes: { required: ['offline_access', 'read:me', 'read:jira-work', 'read:jira-user'], }, @@ -79,7 +56,7 @@ export const atlassianAuthenticator = createOAuthAuthenticator({ accessToken: string, refreshToken: string, params: any, - fullProfile: AtlassianPassportProfile, + fullProfile: PassportProfile, done: PassportOAuthDoneCallback, ) => { done( @@ -100,12 +77,10 @@ export const atlassianAuthenticator = createOAuthAuthenticator({ }, async authenticate(input, helper) { - const result = await helper.authenticate(input); - return result as OAuthAuthenticatorResult; + return helper.authenticate(input); }, async refresh(input, helper) { - const result = await helper.refresh(input); - return result as OAuthAuthenticatorResult; + return helper.refresh(input); }, }); diff --git a/plugins/auth-backend-module-atlassian-provider/src/index.ts b/plugins/auth-backend-module-atlassian-provider/src/index.ts index 224037b868..8f090b76d4 100644 --- a/plugins/auth-backend-module-atlassian-provider/src/index.ts +++ b/plugins/auth-backend-module-atlassian-provider/src/index.ts @@ -19,6 +19,5 @@ * @packageDocumentation */ export { atlassianAuthenticator } from './authenticator'; -export type { AtlassianPassportProfile } from './authenticator'; export { authModuleAtlassianProvider as default } from './module'; export { atlassianSignInResolvers } from './resolvers'; diff --git a/plugins/auth-backend/src/providers/atlassian/provider.ts b/plugins/auth-backend/src/providers/atlassian/provider.ts index d30164bd6e..22db26fd85 100644 --- a/plugins/auth-backend/src/providers/atlassian/provider.ts +++ b/plugins/auth-backend/src/providers/atlassian/provider.ts @@ -26,7 +26,6 @@ import { import { OAuthResult } from '../../lib/oauth'; import { createAuthProviderIntegration } from '../createAuthProviderIntegration'; import { AuthHandler } from '../types'; -import { AtlassianPassportProfile } from '@backstage/plugin-auth-backend-module-atlassian-provider'; /** * Auth provider integration for Atlassian auth @@ -48,7 +47,7 @@ export const atlassian = createAuthProviderIntegration({ resolver: SignInResolver; }; }) { - return createOAuthProviderFactory({ + return createOAuthProviderFactory({ authenticator: atlassianAuthenticator, profileTransform: adaptLegacyOAuthHandler(options?.authHandler), signInResolver: adaptLegacyOAuthSignInResolver(options?.signIn?.resolver), diff --git a/plugins/auth-node/src/passport/PassportHelpers.ts b/plugins/auth-node/src/passport/PassportHelpers.ts index d7b554d56a..8531309917 100644 --- a/plugins/auth-node/src/passport/PassportHelpers.ts +++ b/plugins/auth-node/src/passport/PassportHelpers.ts @@ -42,12 +42,19 @@ export class PassportHelpers { email = firstEmail.value; } + // This is the case for Atlassian + if (profile.email) { + email = profile.email; + } + let picture: string | undefined = undefined; if (profile.avatarUrl) { picture = profile.avatarUrl; } else if (profile.photos && profile.photos.length > 0) { const [firstPhoto] = profile.photos; picture = firstPhoto.value; + } else if (profile.photo) { + picture = profile.photo; // This is the case for Atlassian } let displayName: string | undefined = diff --git a/plugins/auth-node/src/passport/types.ts b/plugins/auth-node/src/passport/types.ts index 4a3f41b6b2..d5681fa9e3 100644 --- a/plugins/auth-node/src/passport/types.ts +++ b/plugins/auth-node/src/passport/types.ts @@ -19,6 +19,8 @@ import { Profile } from 'passport'; /** @public */ export type PassportProfile = Profile & { avatarUrl?: string; + email?: string; + photo?: string; }; /** @public */ From 487c100100365db39a89814f9dd127f8c17ec40e Mon Sep 17 00:00:00 2001 From: Olivier Liechti Date: Tue, 9 Jul 2024 16:41:18 +0200 Subject: [PATCH 212/510] Simplify the bug fix, by implementing logic in the PassportHelper Signed-off-by: Olivier Liechti --- .../auth-backend-module-atlassian-provider/src/module.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/plugins/auth-backend-module-atlassian-provider/src/module.ts b/plugins/auth-backend-module-atlassian-provider/src/module.ts index 2080da3065..9acb665ede 100644 --- a/plugins/auth-backend-module-atlassian-provider/src/module.ts +++ b/plugins/auth-backend-module-atlassian-provider/src/module.ts @@ -19,10 +19,7 @@ import { commonSignInResolvers, createOAuthProviderFactory, } from '@backstage/plugin-auth-node'; -import { - AtlassianPassportProfile, - atlassianAuthenticator, -} from './authenticator'; +import { atlassianAuthenticator } from './authenticator'; import { atlassianSignInResolvers } from './resolvers'; /** @public */ @@ -37,7 +34,7 @@ export const authModuleAtlassianProvider = createBackendModule({ async init({ providers }) { providers.registerProvider({ providerId: 'atlassian', - factory: createOAuthProviderFactory({ + factory: createOAuthProviderFactory({ authenticator: atlassianAuthenticator, signInResolverFactories: { ...atlassianSignInResolvers, From e1eda89df32a9d2b6987c87e8351288379332210 Mon Sep 17 00:00:00 2001 From: Olivier Liechti Date: Tue, 9 Jul 2024 18:58:55 +0200 Subject: [PATCH 213/510] Add api-report.md Signed-off-by: Olivier Liechti --- plugins/auth-node/api-report.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/auth-node/api-report.md b/plugins/auth-node/api-report.md index dc1d86308a..a3750819f9 100644 --- a/plugins/auth-node/api-report.md +++ b/plugins/auth-node/api-report.md @@ -552,6 +552,8 @@ export type PassportOAuthResult = { // @public (undocumented) export type PassportProfile = Profile & { avatarUrl?: string; + email?: string; + photo?: string; }; // @public From 9076843ffd67153f71b1ff9df0eb9af68ba96236 Mon Sep 17 00:00:00 2001 From: Olivier Liechti Date: Tue, 9 Jul 2024 19:48:38 +0200 Subject: [PATCH 214/510] Adatp test to the payload returned by the actual Atlassian strategy (vs its parent) Signed-off-by: Olivier Liechti --- .../src/module.test.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/plugins/auth-backend-module-atlassian-provider/src/module.test.ts b/plugins/auth-backend-module-atlassian-provider/src/module.test.ts index 7b92218d56..7e83aed179 100644 --- a/plugins/auth-backend-module-atlassian-provider/src/module.test.ts +++ b/plugins/auth-backend-module-atlassian-provider/src/module.test.ts @@ -64,10 +64,12 @@ describe('authModuleAtlassianProvider', () => { expect(startUrl.pathname).toBe('/authorize'); expect(Object.fromEntries(startUrl.searchParams)).toEqual({ response_type: 'code', + audience: 'api.atlassian.com', client_id: 'my-client-id', + prompt: 'consent', redirect_uri: `http://localhost:${server.port()}/api/auth/atlassian/handler/frame`, state: expect.any(String), - scope: 'offline_access read:jira-work read:jira-user', + scope: 'offline_access read:me read:jira-work read:jira-user', }); expect(decodeOAuthState(startUrl.searchParams.get('state')!)).toEqual({ @@ -92,10 +94,7 @@ describe('authModuleAtlassianProvider', () => { development: { clientId: 'my-client-id', clientSecret: 'my-client-secret', - additionalScopes: [ - 'read:filter:jira', - 'read:jira-work', // already required - ], + additionalScopes: 'read:filter:jira read:jira-work', // 2nd is already required }, }, }, @@ -123,11 +122,14 @@ describe('authModuleAtlassianProvider', () => { expect(startUrl.origin).toBe('https://auth.atlassian.com'); expect(startUrl.pathname).toBe('/authorize'); expect(Object.fromEntries(startUrl.searchParams)).toEqual({ + audience: 'api.atlassian.com', response_type: 'code', client_id: 'my-client-id', + prompt: 'consent', redirect_uri: `http://localhost:${server.port()}/api/auth/atlassian/handler/frame`, state: expect.any(String), - scope: 'offline_access read:jira-work read:jira-user read:filter:jira', + scope: + 'offline_access read:me read:jira-work read:jira-user read:filter:jira', }); expect(decodeOAuthState(startUrl.searchParams.get('state')!)).toEqual({ From aca86a6a007fa8c9c431f92b685f58c591f25c73 Mon Sep 17 00:00:00 2001 From: Olivier Liechti Date: Wed, 10 Jul 2024 08:11:02 +0200 Subject: [PATCH 215/510] Address review comments Signed-off-by: Olivier Liechti --- .changeset/nasty-balloons-attack.md | 5 ----- .changeset/stale-beds-sneeze.md | 3 +-- plugins/auth-node/src/passport/PassportHelpers.ts | 9 ++++----- 3 files changed, 5 insertions(+), 12 deletions(-) delete mode 100644 .changeset/nasty-balloons-attack.md diff --git a/.changeset/nasty-balloons-attack.md b/.changeset/nasty-balloons-attack.md deleted file mode 100644 index 60229b4a25..0000000000 --- a/.changeset/nasty-balloons-attack.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend': patch ---- - -Use new Atlassian Passport profile in type definition diff --git a/.changeset/stale-beds-sneeze.md b/.changeset/stale-beds-sneeze.md index e2fc5acdf2..695e09a624 100644 --- a/.changeset/stale-beds-sneeze.md +++ b/.changeset/stale-beds-sneeze.md @@ -1,6 +1,5 @@ --- -'@backstage/plugin-auth-backend-module-atlassian-provider': patch '@backstage/plugin-auth-node': patch --- -Fix issues with Atlassian OAuth provider +Fix issues with Atlassian OAuth provider: retrieve the email and photo that were not in arrays but rather in single props. diff --git a/plugins/auth-node/src/passport/PassportHelpers.ts b/plugins/auth-node/src/passport/PassportHelpers.ts index 8531309917..d1ddee20a7 100644 --- a/plugins/auth-node/src/passport/PassportHelpers.ts +++ b/plugins/auth-node/src/passport/PassportHelpers.ts @@ -40,10 +40,8 @@ export class PassportHelpers { if (profile.emails && profile.emails.length > 0) { const [firstEmail] = profile.emails; email = firstEmail.value; - } - - // This is the case for Atlassian - if (profile.email) { + } else if (profile.email) { + // This is the case for Atlassian email = profile.email; } @@ -54,7 +52,8 @@ export class PassportHelpers { const [firstPhoto] = profile.photos; picture = firstPhoto.value; } else if (profile.photo) { - picture = profile.photo; // This is the case for Atlassian + // This is the case for Atlassian + picture = profile.photo; } let displayName: string | undefined = From c48f2cc68df4065d1d19fbbf09e167fe89492600 Mon Sep 17 00:00:00 2001 From: Olivier Liechti Date: Wed, 10 Jul 2024 10:42:16 +0200 Subject: [PATCH 216/510] Cleanup test Signed-off-by: Olivier Liechti --- .../src/authenticator.test.ts | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/plugins/auth-backend-module-atlassian-provider/src/authenticator.test.ts b/plugins/auth-backend-module-atlassian-provider/src/authenticator.test.ts index cb723ecece..ab0a4840f9 100644 --- a/plugins/auth-backend-module-atlassian-provider/src/authenticator.test.ts +++ b/plugins/auth-backend-module-atlassian-provider/src/authenticator.test.ts @@ -17,21 +17,16 @@ import Strategy from 'passport-atlassian-oauth2'; describe('Strategy', () => { it('should be an instance of', () => { - try { - console.log(Strategy); - const strategy = new Strategy( - { - authorizationURL: 'https://auth.atlassian.com/authorize', - tokenURL: 'https://auth.atlassian.com/oauth/token', - clientID: 'my-client-id', - clientSecret: 'my-client-secret', - scope: ['offline_access', 'read:jira-work', 'read:jira-user'], - }, - () => {}, - ); - expect((strategy as any).name).toBe('atlassian'); - } catch (e) { - console.error(e); - } + const strategy = new Strategy( + { + authorizationURL: 'https://auth.atlassian.com/authorize', + tokenURL: 'https://auth.atlassian.com/oauth/token', + clientID: 'my-client-id', + clientSecret: 'my-client-secret', + scope: ['offline_access', 'read:jira-work', 'read:jira-user'], + }, + () => {}, + ); + expect((strategy as any).name).toBe('atlassian'); }); }); From 3d9abab684c528f9547814713bf1a93531059417 Mon Sep 17 00:00:00 2001 From: Olivier Liechti Date: Wed, 10 Jul 2024 11:10:56 +0200 Subject: [PATCH 217/510] Pass an empty array to the 'scope' prop required by Atlassian strategy, but which value is not actually used Signed-off-by: Olivier Liechti --- .../auth-backend-module-atlassian-provider/src/authenticator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts b/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts index 23a4a52197..d4f46b5a8c 100644 --- a/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts +++ b/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts @@ -50,7 +50,7 @@ export const atlassianAuthenticator = createOAuthAuthenticator({ authorizationURL: `${baseUrl}/authorize`, tokenURL: `${baseUrl}/oauth/token`, profileURL: 'https://api.atlassian.com/me', - scope: config.getOptionalString('additionalScopes')?.split(' ') || [], + scope: [], // the Atlassian strategy requires a scope, but Backstage passes the right set of scopes when calling OAuth2Strategy.prototype.authenticate }, ( accessToken: string, From 1cb84d7085cf9be7b5255d26e2a7c4317e9d8da7 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 10 Jul 2024 11:19:10 +0200 Subject: [PATCH 218/510] backend-defaults: removed the deprecated getPath option from httpRouterServiceFactory Signed-off-by: Patrik Oldsberg --- .changeset/cold-jars-punch.md | 6 ++ packages/backend-app-api/api-report.md | 12 +-- .../httpRouter/httpRouterServiceFactory.ts | 11 +-- .../implementations/httpRouter/index.ts | 1 - .../backend-defaults/api-report-httpRouter.md | 12 +-- .../httpRouterServiceFactory.test.ts | 26 ------ .../httpRouter/httpRouterServiceFactory.ts | 92 +++++++------------ .../src/entrypoints/httpRouter/index.ts | 1 - packages/backend-test-utils/api-report.md | 5 +- 9 files changed, 48 insertions(+), 118 deletions(-) create mode 100644 .changeset/cold-jars-punch.md diff --git a/.changeset/cold-jars-punch.md b/.changeset/cold-jars-punch.md new file mode 100644 index 0000000000..8708e1f670 --- /dev/null +++ b/.changeset/cold-jars-punch.md @@ -0,0 +1,6 @@ +--- +'@backstage/backend-defaults': minor +'@backstage/backend-app-api': minor +--- + +**BREAKING**: Removed the depreacted `getPath` option from `httpRouterServiceFactory`, as well as the `HttpRouterFactoryOptions` type. diff --git a/packages/backend-app-api/api-report.md b/packages/backend-app-api/api-report.md index 7518f8e2cc..c577084a58 100644 --- a/packages/backend-app-api/api-report.md +++ b/packages/backend-app-api/api-report.md @@ -146,15 +146,11 @@ export const httpAuthServiceFactory: () => ServiceFactory< 'plugin' >; -// Warning: (ae-forgotten-export) The symbol "HttpRouterFactoryOptions_2" needs to be exported by the entry point index.d.ts -// -// @public @deprecated (undocumented) -export type HttpRouterFactoryOptions = HttpRouterFactoryOptions_2; - // @public @deprecated -export const httpRouterServiceFactory: ( - options?: HttpRouterFactoryOptions_2 | undefined, -) => ServiceFactory; +export const httpRouterServiceFactory: () => ServiceFactory< + HttpRouterService, + 'plugin' +>; // Warning: (ae-forgotten-export) The symbol "HttpServerCertificateOptions_2" needs to be exported by the entry point index.d.ts // diff --git a/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.ts b/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.ts index 9d2b74fb43..0088e53f98 100644 --- a/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.ts @@ -15,16 +15,7 @@ */ // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { - httpRouterServiceFactory as _httpRouterServiceFactory, - type HttpRouterFactoryOptions as _HttpRouterFactoryOptions, -} from '../../../../../backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory'; - -/** - * @public - * @deprecated Please import from `@backstage/backend-defaults/httpRouter` instead. - */ -export type HttpRouterFactoryOptions = _HttpRouterFactoryOptions; +import { httpRouterServiceFactory as _httpRouterServiceFactory } from '../../../../../backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory'; /** * HTTP route registration for plugins. diff --git a/packages/backend-app-api/src/services/implementations/httpRouter/index.ts b/packages/backend-app-api/src/services/implementations/httpRouter/index.ts index 928a232131..bc12480ae8 100644 --- a/packages/backend-app-api/src/services/implementations/httpRouter/index.ts +++ b/packages/backend-app-api/src/services/implementations/httpRouter/index.ts @@ -15,6 +15,5 @@ */ export { httpRouterServiceFactory } from './httpRouterServiceFactory'; -export type { HttpRouterFactoryOptions } from './httpRouterServiceFactory'; export { createLifecycleMiddleware } from './createLifecycleMiddleware'; export type { LifecycleMiddlewareOptions } from './createLifecycleMiddleware'; diff --git a/packages/backend-defaults/api-report-httpRouter.md b/packages/backend-defaults/api-report-httpRouter.md index a7ca2c8dd3..f191a5a847 100644 --- a/packages/backend-defaults/api-report-httpRouter.md +++ b/packages/backend-defaults/api-report-httpRouter.md @@ -14,15 +14,11 @@ export function createLifecycleMiddleware( options: LifecycleMiddlewareOptions, ): RequestHandler; -// @public (undocumented) -export interface HttpRouterFactoryOptions { - getPath?(pluginId: string): string; -} - // @public -export const httpRouterServiceFactory: ( - options?: HttpRouterFactoryOptions | undefined, -) => ServiceFactory; +export const httpRouterServiceFactory: () => ServiceFactory< + HttpRouterService, + 'plugin' +>; // @public export interface LifecycleMiddlewareOptions { diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.test.ts b/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.test.ts index 58c074f985..17665a176a 100644 --- a/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.test.ts +++ b/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.test.ts @@ -52,32 +52,6 @@ describe('httpRouterFactory', () => { ); }); - it('should use custom path generator', async () => { - const rootHttpRouter = mockServices.rootHttpRouter.mock(); - const tester = ServiceFactoryTester.from( - httpRouterServiceFactory({ - getPath: id => `/some/${id}/path`, - }), - { dependencies: [rootHttpRouter.factory] }, - ); - - const router1 = await tester.get('test1'); - router1.use(() => {}); - expect(rootHttpRouter.use).toHaveBeenCalledTimes(1); - expect(rootHttpRouter.use).toHaveBeenCalledWith( - '/some/test1/path', - expect.any(Function), - ); - - const router2 = await tester.get('test2'); - router2.use(() => {}); - expect(rootHttpRouter.use).toHaveBeenCalledTimes(2); - expect(rootHttpRouter.use).toHaveBeenCalledWith( - '/some/test2/path', - expect.any(Function), - ); - }); - describe('auth services', () => { const pluginSubject = createBackendPlugin({ pluginId: 'test', diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.ts b/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.ts index 4a0dec49e6..fb2646580b 100644 --- a/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.ts @@ -26,16 +26,6 @@ import { createCredentialsBarrier } from './createCredentialsBarrier'; import { createAuthIntegrationRouter } from './createAuthIntegrationRouter'; import { createCookieAuthRefreshMiddleware } from './createCookieAuthRefreshMiddleware'; -/** - * @public - */ -export interface HttpRouterFactoryOptions { - /** - * A callback used to generate the path for each plugin, defaults to `/api/{pluginId}`. - */ - getPath?(pluginId: string): string; -} - /** * HTTP route registration for plugins. * @@ -45,57 +35,39 @@ export interface HttpRouterFactoryOptions { * * @public */ -export const httpRouterServiceFactory = createServiceFactory( - (options?: HttpRouterFactoryOptions) => ({ - service: coreServices.httpRouter, - initialization: 'always', - deps: { - plugin: coreServices.pluginMetadata, - config: coreServices.rootConfig, - logger: coreServices.logger, - lifecycle: coreServices.lifecycle, - rootHttpRouter: coreServices.rootHttpRouter, - auth: coreServices.auth, - httpAuth: coreServices.httpAuth, - }, - async factory({ - auth, +export const httpRouterServiceFactory = createServiceFactory({ + service: coreServices.httpRouter, + initialization: 'always', + deps: { + plugin: coreServices.pluginMetadata, + config: coreServices.rootConfig, + lifecycle: coreServices.lifecycle, + rootHttpRouter: coreServices.rootHttpRouter, + auth: coreServices.auth, + httpAuth: coreServices.httpAuth, + }, + async factory({ auth, httpAuth, config, plugin, rootHttpRouter, lifecycle }) { + const router = PromiseRouter(); + + rootHttpRouter.use(`/api/${plugin.getId()}`, router); + + const credentialsBarrier = createCredentialsBarrier({ httpAuth, config, - logger, - plugin, - rootHttpRouter, - lifecycle, - }) { - if (options?.getPath) { - logger.warn( - `DEPRECATION WARNING: The 'getPath' option for HttpRouterService is deprecated. The ability to reconfigure the '/api/' path prefix for plugins will be removed in the future.`, - ); - } - const getPath = options?.getPath ?? (id => `/api/${id}`); - const path = getPath(plugin.getId()); + }); - const router = PromiseRouter(); - rootHttpRouter.use(path, router); + router.use(createAuthIntegrationRouter({ auth })); + router.use(createLifecycleMiddleware({ lifecycle })); + router.use(credentialsBarrier.middleware); + router.use(createCookieAuthRefreshMiddleware({ auth, httpAuth })); - const credentialsBarrier = createCredentialsBarrier({ - httpAuth, - config, - }); - - router.use(createAuthIntegrationRouter({ auth })); - router.use(createLifecycleMiddleware({ lifecycle })); - router.use(credentialsBarrier.middleware); - router.use(createCookieAuthRefreshMiddleware({ auth, httpAuth })); - - return { - use(handler: Handler): void { - router.use(handler); - }, - addAuthPolicy(policy: HttpRouterServiceAuthPolicy): void { - credentialsBarrier.addAuthPolicy(policy); - }, - }; - }, - }), -); + return { + use(handler: Handler): void { + router.use(handler); + }, + addAuthPolicy(policy: HttpRouterServiceAuthPolicy): void { + credentialsBarrier.addAuthPolicy(policy); + }, + }; + }, +}); diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/index.ts b/packages/backend-defaults/src/entrypoints/httpRouter/index.ts index 928a232131..bc12480ae8 100644 --- a/packages/backend-defaults/src/entrypoints/httpRouter/index.ts +++ b/packages/backend-defaults/src/entrypoints/httpRouter/index.ts @@ -15,6 +15,5 @@ */ export { httpRouterServiceFactory } from './httpRouterServiceFactory'; -export type { HttpRouterFactoryOptions } from './httpRouterServiceFactory'; export { createLifecycleMiddleware } from './createLifecycleMiddleware'; export type { LifecycleMiddlewareOptions } from './createLifecycleMiddleware'; diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index a2fb4b7674..0a44fa5ed3 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -22,7 +22,6 @@ import { EventsService } from '@backstage/plugin-events-node'; import { ExtendedHttpServer } from '@backstage/backend-app-api'; import { ExtensionPoint } from '@backstage/backend-plugin-api'; import { HttpAuthService } from '@backstage/backend-plugin-api'; -import { HttpRouterFactoryOptions } from '@backstage/backend-defaults/httpRouter'; import { HttpRouterService } from '@backstage/backend-plugin-api'; import { IdentityService } from '@backstage/backend-plugin-api'; import { JsonObject } from '@backstage/types'; @@ -221,9 +220,7 @@ export namespace mockServices { // (undocumented) export namespace httpRouter { const // (undocumented) - factory: ( - options?: HttpRouterFactoryOptions | undefined, - ) => ServiceFactory; + factory: () => ServiceFactory; const // (undocumented) mock: ( partialImpl?: Partial | undefined, From 2f991786a3f9bfb227e7ea6ee97b2f9a8b6dfa28 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 10 Jul 2024 11:50:52 +0200 Subject: [PATCH 219/510] refactor(test-utils): rename `ServiceFactoryTester.get` to `ServiceFactoryTestest.getSubject` Signed-off-by: Camila Belo --- .changeset/chilly-coats-report.md | 7 +++ .../scheduler/schedulerServiceFactory.test.ts | 2 +- .../tokenManagerServiceFactory.test.ts | 2 +- .../auth/authServiceFactory.test.ts | 24 +++++----- .../httpRouterServiceFactory.test.ts | 4 +- .../scheduler/schedulerServiceFactory.test.ts | 2 +- packages/backend-test-utils/api-report.md | 4 ++ .../next/wiring/ServiceFactoryTester.test.ts | 46 +++++++++---------- .../src/next/wiring/ServiceFactoryTester.ts | 13 +++++- 9 files changed, 63 insertions(+), 41 deletions(-) create mode 100644 .changeset/chilly-coats-report.md diff --git a/.changeset/chilly-coats-report.md b/.changeset/chilly-coats-report.md new file mode 100644 index 0000000000..2fd044b57c --- /dev/null +++ b/.changeset/chilly-coats-report.md @@ -0,0 +1,7 @@ +--- +'@backstage/backend-test-utils': patch +'@backstage/backend-defaults': patch +'@backstage/backend-app-api': patch +--- + +The `ServiceFactoryTest.get` method was deprecated and the `ServiceFactoryTest.getSubject` should be used instead. The `getSubject` method has the same behavior, but has a better method name to indicate that the service instance returned is the subject currently being tested. diff --git a/packages/backend-app-api/src/services/implementations/scheduler/schedulerServiceFactory.test.ts b/packages/backend-app-api/src/services/implementations/scheduler/schedulerServiceFactory.test.ts index 7b889b3a0e..b16509cf96 100644 --- a/packages/backend-app-api/src/services/implementations/scheduler/schedulerServiceFactory.test.ts +++ b/packages/backend-app-api/src/services/implementations/scheduler/schedulerServiceFactory.test.ts @@ -22,7 +22,7 @@ describe('schedulerFactory', () => { it('creates sidecar database features', async () => { const tester = ServiceFactoryTester.from(schedulerServiceFactory()); - const scheduler = await tester.get(); + const scheduler = await tester.getSubject(); await scheduler.scheduleTask({ id: 'task1', timeout: { seconds: 1 }, diff --git a/packages/backend-app-api/src/services/implementations/tokenManager/tokenManagerServiceFactory.test.ts b/packages/backend-app-api/src/services/implementations/tokenManager/tokenManagerServiceFactory.test.ts index f603c6295e..dc52130ec6 100644 --- a/packages/backend-app-api/src/services/implementations/tokenManager/tokenManagerServiceFactory.test.ts +++ b/packages/backend-app-api/src/services/implementations/tokenManager/tokenManagerServiceFactory.test.ts @@ -21,7 +21,7 @@ describe('tokenManagerFactory', () => { it('should create a disabled manager without configuration', async () => { const tokenManager = await ServiceFactoryTester.from( tokenManagerServiceFactory, - ).get(); + ).getSubject(); await expect(tokenManager.authenticate('abc')).rejects.toThrow( 'no legacy keys are configured', diff --git a/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts b/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts index 22357d0f49..de89efa351 100644 --- a/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts +++ b/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts @@ -86,8 +86,8 @@ describe('authServiceFactory', () => { dependencies: mockDeps, }); - const searchAuth = await tester.get('search'); - const catalogAuth = await tester.get('catalog'); + const searchAuth = await tester.getSubject('search'); + const catalogAuth = await tester.getSubject('catalog'); const { token: searchToken } = await searchAuth.getPluginRequestToken({ onBehalfOf: await searchAuth.getOwnServiceCredentials(), @@ -117,8 +117,8 @@ describe('authServiceFactory', () => { dependencies: mockDeps, }); - const searchAuth = await tester.get('search'); - const catalogAuth = await tester.get('catalog'); + const searchAuth = await tester.getSubject('search'); + const catalogAuth = await tester.getSubject('catalog'); server.use( rest.get( @@ -163,7 +163,7 @@ describe('authServiceFactory', () => { dependencies: mockDeps, }); - const catalogAuth = await tester.get('catalog'); + const catalogAuth = await tester.getSubject('catalog'); await expect( catalogAuth.getPluginRequestToken({ @@ -194,7 +194,7 @@ describe('authServiceFactory', () => { dependencies: mockDeps, }); - const catalogAuth = await tester.get('catalog'); + const catalogAuth = await tester.getSubject('catalog'); const { token } = await catalogAuth.getPluginRequestToken({ onBehalfOf: { @@ -261,7 +261,7 @@ describe('authServiceFactory', () => { dependencies: mockDeps, }); - const catalogAuth = await tester.get('catalog'); + const catalogAuth = await tester.getSubject('catalog'); const fullToken = 'eyJ0eXAiOiJ2bmQuYmFja3N0YWdlLnVzZXIiLCJhbGciOiJFUzI1NiIsImtpZCI6IjhkMDFjM2RiLTU2ZjktNDVmMC04NmRkLTA1YjNjODM1YjNkMyJ9.eyJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjcwMDcvYXBpL2F1dGgiLCJzdWIiOiJ1c2VyOmRldmVsb3BtZW50L2d1ZXN0IiwiZW50IjpbInVzZXI6ZGV2ZWxvcG1lbnQvZ3Vlc3QiLCJncm91cDpkZWZhdWx0L3RlYW0tYSJdLCJhdWQiOiJiYWNrc3RhZ2UiLCJpYXQiOjE3MTIwNzE3MTQsImV4cCI6MTcxMjA3NTMxNCwidWlwIjoiSmwxVEpycG9VUjR1NENjUE9nalJMeHpEMi1FMGZPR3ptSm81UWI2eS1aN19meG5oVVBEdWVWRE1CS0l6WF9pc0lvSDhlZm9EUFA5bG9aQnpPblB5Z2cifQ.1gVMq1ofO8PzRctu72D6c4IMqXuIabT79WdGEhW6vIrBRs_qhuWAa94Wvz_KYKpBTb2nxgzXJ5OeddeoYApMyQ'; @@ -318,9 +318,9 @@ describe('authServiceFactory', () => { dependencies: mockDeps, }); - const searchAuth = await tester.get('search'); - const catalogAuth = await tester.get('catalog'); - const permissionAuth = await tester.get('permission'); + const searchAuth = await tester.getSubject('search'); + const catalogAuth = await tester.getSubject('catalog'); + const permissionAuth = await tester.getSubject('permission'); /* Corresponding private key in case this test needs to be updated in the future: { @@ -431,7 +431,7 @@ describe('authServiceFactory', () => { dependencies: mockDeps, }); - const catalogAuth = await tester.get('catalog'); + const catalogAuth = await tester.getSubject('catalog'); await expect( catalogAuth.authenticate('limited-static-token'), @@ -450,7 +450,7 @@ describe('authServiceFactory', () => { }, }); - const scaffolderAuth = await tester.get('scaffolder'); + const scaffolderAuth = await tester.getSubject('scaffolder'); await expect( scaffolderAuth.authenticate('limited-static-token'), diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.test.ts b/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.test.ts index 17665a176a..a8b749939b 100644 --- a/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.test.ts +++ b/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.test.ts @@ -35,7 +35,7 @@ describe('httpRouterFactory', () => { dependencies: [rootHttpRouter.factory], }); - const router1 = await tester.get('test1'); + const router1 = await tester.getSubject('test1'); router1.use(() => {}); expect(rootHttpRouter.use).toHaveBeenCalledTimes(1); expect(rootHttpRouter.use).toHaveBeenCalledWith( @@ -43,7 +43,7 @@ describe('httpRouterFactory', () => { expect.any(Function), ); - const router2 = await tester.get('test2'); + const router2 = await tester.getSubject('test2'); router2.use(() => {}); expect(rootHttpRouter.use).toHaveBeenCalledTimes(2); expect(rootHttpRouter.use).toHaveBeenCalledWith( diff --git a/packages/backend-defaults/src/entrypoints/scheduler/schedulerServiceFactory.test.ts b/packages/backend-defaults/src/entrypoints/scheduler/schedulerServiceFactory.test.ts index 7b889b3a0e..b16509cf96 100644 --- a/packages/backend-defaults/src/entrypoints/scheduler/schedulerServiceFactory.test.ts +++ b/packages/backend-defaults/src/entrypoints/scheduler/schedulerServiceFactory.test.ts @@ -22,7 +22,7 @@ describe('schedulerFactory', () => { it('creates sidecar database features', async () => { const tester = ServiceFactoryTester.from(schedulerServiceFactory()); - const scheduler = await tester.get(); + const scheduler = await tester.getSubject(); await scheduler.scheduleTask({ id: 'task1', timeout: { seconds: 1 }, diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index 0a44fa5ed3..a61d1ccb58 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -373,6 +373,7 @@ export class ServiceFactoryTester { | (() => ServiceFactory), options?: ServiceFactoryTesterOptions, ): ServiceFactoryTester; + // @deprecated get( ...args: 'root' extends TScope ? [] : [pluginId?: string] ): Promise; @@ -380,6 +381,9 @@ export class ServiceFactoryTester { service: ServiceRef, ...args: 'root' extends TGetScope ? [] : [pluginId?: string] ): Promise; + getSubject( + ...args: 'root' extends TScope ? [] : [pluginId?: string] + ): Promise; } // @public diff --git a/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.test.ts b/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.test.ts index 14dd427ecf..5970f6ea52 100644 --- a/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.test.ts +++ b/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.test.ts @@ -56,34 +56,34 @@ describe('ServiceFactoryTester', () => { it('should test a root service factory', async () => { const tester = ServiceFactoryTester.from(rootFactory); - await expect(tester.get()).resolves.toBe('root'); + await expect(tester.getSubject()).resolves.toBe('root'); }); it('should test a plugin service factory', async () => { const tester = ServiceFactoryTester.from(pluginFactory); - await expect(tester.get('x')).resolves.toBe('x-plugin'); - await expect(tester.get('y')).resolves.toBe('y-plugin'); - await expect(tester.get('z')).resolves.toBe('z-plugin'); + await expect(tester.getSubject('x')).resolves.toBe('x-plugin'); + await expect(tester.getSubject('y')).resolves.toBe('y-plugin'); + await expect(tester.getSubject('z')).resolves.toBe('z-plugin'); }); it('should test a plugin service factory with root context', async () => { const tester = ServiceFactoryTester.from(sharedPluginFactory); - await expect(tester.get('x')).resolves.toBe('x-1-plugin'); - await expect(tester.get('y')).resolves.toBe('y-2-plugin'); - await expect(tester.get('y')).resolves.toBe('y-2-plugin'); - await expect(tester.get('y')).resolves.toBe('y-2-plugin'); - await expect(tester.get('z')).resolves.toBe('z-3-plugin'); + await expect(tester.getSubject('x')).resolves.toBe('x-1-plugin'); + await expect(tester.getSubject('y')).resolves.toBe('y-2-plugin'); + await expect(tester.getSubject('y')).resolves.toBe('y-2-plugin'); + await expect(tester.getSubject('y')).resolves.toBe('y-2-plugin'); + await expect(tester.getSubject('z')).resolves.toBe('z-3-plugin'); const tester2 = ServiceFactoryTester.from(sharedPluginFactory); - await expect(tester2.get('z')).resolves.toBe('z-1-plugin'); - await expect(tester2.get('y')).resolves.toBe('y-2-plugin'); - await expect(tester2.get('x')).resolves.toBe('x-3-plugin'); - await expect(tester2.get('x')).resolves.toBe('x-3-plugin'); - await expect(tester2.get('y')).resolves.toBe('y-2-plugin'); - await expect(tester2.get('z')).resolves.toBe('z-1-plugin'); + await expect(tester2.getSubject('z')).resolves.toBe('z-1-plugin'); + await expect(tester2.getSubject('y')).resolves.toBe('y-2-plugin'); + await expect(tester2.getSubject('x')).resolves.toBe('x-3-plugin'); + await expect(tester2.getSubject('x')).resolves.toBe('x-3-plugin'); + await expect(tester2.getSubject('y')).resolves.toBe('y-2-plugin'); + await expect(tester2.getSubject('z')).resolves.toBe('z-1-plugin'); }); it('should use dependencies', async () => { @@ -96,7 +96,7 @@ describe('ServiceFactoryTester', () => { { dependencies: [rootFactory, pluginFactory()] }, ); - await expect(tester.get('x')).resolves.toBe('root, x-plugin'); + await expect(tester.getSubject('x')).resolves.toBe('root, x-plugin'); }); it('should use dependencies with root context', async () => { @@ -109,11 +109,11 @@ describe('ServiceFactoryTester', () => { { dependencies: [sharedPluginFactory(), pluginFactory] }, ); - await expect(tester.get('x')).resolves.toBe('x-1-plugin, x-plugin'); - await expect(tester.get('y')).resolves.toBe('y-2-plugin, y-plugin'); - await expect(tester.get('y')).resolves.toBe('y-2-plugin, y-plugin'); - await expect(tester.get('y')).resolves.toBe('y-2-plugin, y-plugin'); - await expect(tester.get('z')).resolves.toBe('z-3-plugin, z-plugin'); + await expect(tester.getSubject('x')).resolves.toBe('x-1-plugin, x-plugin'); + await expect(tester.getSubject('y')).resolves.toBe('y-2-plugin, y-plugin'); + await expect(tester.getSubject('y')).resolves.toBe('y-2-plugin, y-plugin'); + await expect(tester.getSubject('y')).resolves.toBe('y-2-plugin, y-plugin'); + await expect(tester.getSubject('z')).resolves.toBe('z-3-plugin, z-plugin'); }); it('should prioritize the subject implementation', async () => { @@ -126,7 +126,7 @@ describe('ServiceFactoryTester', () => { { dependencies: [rootFactory] }, ); - await expect(tester.get()).resolves.toBe('other-root'); + await expect(tester.getSubject()).resolves.toBe('other-root'); }); it('should throw on missing dependencies', async () => { @@ -138,7 +138,7 @@ describe('ServiceFactoryTester', () => { }), ); - await expect(tester.get('x')).rejects.toThrow( + await expect(tester.getSubject('x')).rejects.toThrow( "Failed to instantiate service 'b' for 'x' because the following dependent services are missing: 'a'", ); }); diff --git a/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts b/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts index 0555ab10a4..40b473663b 100644 --- a/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts +++ b/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts @@ -79,6 +79,17 @@ export class ServiceFactoryTester { this.#registry = registry; } + /** + * Returns the service instance for the subject. + * + * @deprecated Use `getSubject` instead. + */ + async get( + ...args: 'root' extends TScope ? [] : [pluginId?: string] + ): Promise { + return this.getSubject(...args); + } + /** * Returns the service instance for the subject. * @@ -89,7 +100,7 @@ export class ServiceFactoryTester { * * By default the plugin ID 'test' is used. */ - async get( + async getSubject( ...args: 'root' extends TScope ? [] : [pluginId?: string] ): Promise { const [pluginId] = args; From 062c01c7c411aa13eb3c28d3726bf757c80d74a6 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 10 Jul 2024 12:12:22 +0200 Subject: [PATCH 220/510] backend-plugin-api: deprecate service factories with callback form Signed-off-by: Patrik Oldsberg --- .changeset/spotty-apricots-tan.md | 55 ++++++++++ packages/backend-app-api/api-report-alpha.md | 7 +- packages/backend-app-api/api-report.md | 103 +++++++++++------- packages/backend-defaults/api-report-auth.md | 8 +- packages/backend-defaults/api-report-cache.md | 8 +- .../backend-defaults/api-report-database.md | 7 +- .../backend-defaults/api-report-discovery.md | 7 +- .../backend-defaults/api-report-httpAuth.md | 7 +- .../backend-defaults/api-report-httpRouter.md | 7 +- .../backend-defaults/api-report-lifecycle.md | 7 +- .../backend-defaults/api-report-logger.md | 7 +- .../api-report-permissions.md | 7 +- .../backend-defaults/api-report-rootConfig.md | 10 +- .../backend-defaults/api-report-rootHealth.md | 7 +- .../api-report-rootHttpRouter.md | 10 +- .../api-report-rootLifecycle.md | 7 +- .../backend-defaults/api-report-rootLogger.md | 7 +- .../backend-defaults/api-report-scheduler.md | 7 +- .../backend-defaults/api-report-urlReader.md | 7 +- .../backend-defaults/api-report-userInfo.md | 7 +- .../api-report.md | 28 +++-- packages/backend-plugin-api/api-report.md | 34 ++++-- .../src/services/system/index.ts | 1 + .../src/services/system/types.ts | 59 ++++++++-- packages/backend-test-utils/api-report.md | 51 +++++---- plugins/events-node/api-report.md | 7 +- 26 files changed, 321 insertions(+), 151 deletions(-) create mode 100644 .changeset/spotty-apricots-tan.md diff --git a/.changeset/spotty-apricots-tan.md b/.changeset/spotty-apricots-tan.md new file mode 100644 index 0000000000..bc1b26e2f4 --- /dev/null +++ b/.changeset/spotty-apricots-tan.md @@ -0,0 +1,55 @@ +--- +'@backstage/backend-plugin-api': patch +--- + +Deprecated the ability to define options for service factories through `createServiceFactory`. In the future all service factories will return a plain `ServiceFactory` object, rather than allowing users to pass options to the factory. To allow for customization of a service implementation one can instead export one or a few building blocks that allows for simple re-implementation of the service instead. + +For example, instead of: + +```ts +export const fooServiceFactory = createServiceFactory( + (options?: { bar: string }) => ({ + service: fooServiceRef, + deps: { logger: coreServices.logger }, + factory({ logger }) { + return { + // Implementation of the foo service using the `bar` option. + }; + }, + }), +); +``` + +We instead encourage service implementations to provide an easy to use API for re-implementing the service for advanced use-cases: + +```ts +/** @public */ +export class DefaultFooService implements FooService { + static create(options: { bar: string; logger: LoggerService }) { + return new DefaultFooService(options.logger, options.bar ?? 'default'); + } + + private constructor( + private readonly logger: string, + private readonly bar: string, + ) {} + + // The rest of the implementation +} +``` + +A user that wishes to customize the service can then easily do so by defining their own factory: + +```ts +export const fooServiceFactory = createServiceFactory({ + service: fooServiceRef, + deps: { logger: coreServices.logger }, + factory({ logger }) { + return DefaultFooService.create({ logger, bar: 'baz' }); + }, +}); +``` + +This is of course more verbose than the previous solution where the factory could be customized through `fooServiceFactory({ bar: 'baz' })`, but this is a simplified which in practice should be using static configuration instead. + +This change is being made because the ability to define an options callback encourages bad design of services factories. When possible, a service should be configurable through static configuration, and the existence of options may discourage that. More importantly though, the existing options do not work well with the dependency injection system of services, which is a problem for callbacks an other more advanced options. This lead to a bad pattern where only a few explicit dependencies where made available in callbacks, rather than providing an API that allowed simple re-implementation of the service with full access to dependency injection. diff --git a/packages/backend-app-api/api-report-alpha.md b/packages/backend-app-api/api-report-alpha.md index 488feedf2c..e4769f4e72 100644 --- a/packages/backend-app-api/api-report-alpha.md +++ b/packages/backend-app-api/api-report-alpha.md @@ -4,12 +4,13 @@ ```ts import { FeatureDiscoveryService } from '@backstage/backend-plugin-api/alpha'; -import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; // @alpha (undocumented) -export const featureDiscoveryServiceFactory: () => ServiceFactory< +export const featureDiscoveryServiceFactory: ServiceFactoryCompat< FeatureDiscoveryService, - 'root' + 'root', + undefined >; // (No @packageDocumentation comment for this package) diff --git a/packages/backend-app-api/api-report.md b/packages/backend-app-api/api-report.md index c577084a58..51839b88be 100644 --- a/packages/backend-app-api/api-report.md +++ b/packages/backend-app-api/api-report.md @@ -38,7 +38,7 @@ import { RootLifecycleService } from '@backstage/backend-plugin-api'; import { RootLoggerService } from '@backstage/backend-plugin-api'; import { SchedulerService } from '@backstage/backend-plugin-api'; import type { Server } from 'node:http'; -import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; import { ServiceFactoryOrFunction } from '@backstage/backend-plugin-api'; import { TokenManagerService } from '@backstage/backend-plugin-api'; import { transport } from 'winston'; @@ -46,7 +46,11 @@ import { UrlReaderService } from '@backstage/backend-plugin-api'; import { UserInfoService } from '@backstage/backend-plugin-api'; // @public @deprecated (undocumented) -export const authServiceFactory: () => ServiceFactory; +export const authServiceFactory: ServiceFactoryCompat< + AuthService, + 'plugin', + undefined +>; // @public (undocumented) export interface Backend { @@ -66,7 +70,11 @@ export interface Backend { } // @public @deprecated (undocumented) -export const cacheServiceFactory: () => ServiceFactory; +export const cacheServiceFactory: ServiceFactoryCompat< + CacheService, + 'plugin', + undefined +>; // Warning: (ae-forgotten-export) The symbol "createConfigSecretEnumerator_2" needs to be exported by the entry point index.d.ts // @@ -95,9 +103,10 @@ export interface CreateSpecializedBackendOptions { } // @public @deprecated (undocumented) -export const databaseServiceFactory: () => ServiceFactory< +export const databaseServiceFactory: ServiceFactoryCompat< DatabaseService, - 'plugin' + 'plugin', + undefined >; // @public @deprecated @@ -116,9 +125,10 @@ export class DefaultRootHttpRouter implements RootHttpRouterService { export type DefaultRootHttpRouterOptions = DefaultRootHttpRouterOptions_2; // @public @deprecated (undocumented) -export const discoveryServiceFactory: () => ServiceFactory< +export const discoveryServiceFactory: ServiceFactoryCompat< DiscoveryService, - 'plugin' + 'plugin', + undefined >; // Warning: (ae-forgotten-export) The symbol "ExtendedHttpServer_2" needs to be exported by the entry point index.d.ts @@ -141,15 +151,17 @@ export class HostDiscovery implements DiscoveryService { } // @public @deprecated (undocumented) -export const httpAuthServiceFactory: () => ServiceFactory< +export const httpAuthServiceFactory: ServiceFactoryCompat< HttpAuthService, - 'plugin' + 'plugin', + undefined >; // @public @deprecated -export const httpRouterServiceFactory: () => ServiceFactory< +export const httpRouterServiceFactory: ServiceFactoryCompat< HttpRouterService, - 'plugin' + 'plugin', + undefined >; // Warning: (ae-forgotten-export) The symbol "HttpServerCertificateOptions_2" needs to be exported by the entry point index.d.ts @@ -169,9 +181,11 @@ export type IdentityFactoryOptions = { }; // @public @deprecated (undocumented) -export const identityServiceFactory: ( - options?: IdentityFactoryOptions | undefined, -) => ServiceFactory; +export const identityServiceFactory: ServiceFactoryCompat< + IdentityService, + 'plugin', + IdentityFactoryOptions +>; // Warning: (ae-forgotten-export) The symbol "LifecycleMiddlewareOptions_2" needs to be exported by the entry point index.d.ts // @@ -179,9 +193,10 @@ export const identityServiceFactory: ( export type LifecycleMiddlewareOptions = LifecycleMiddlewareOptions_2; // @public @deprecated -export const lifecycleServiceFactory: () => ServiceFactory< +export const lifecycleServiceFactory: ServiceFactoryCompat< LifecycleService, - 'plugin' + 'plugin', + undefined >; // @public @deprecated @@ -195,9 +210,10 @@ export function loadBackendConfig(options: { }>; // @public @deprecated -export const loggerServiceFactory: () => ServiceFactory< +export const loggerServiceFactory: ServiceFactoryCompat< LoggerService, - 'plugin' + 'plugin', + undefined >; // @public @deprecated (undocumented) @@ -222,9 +238,10 @@ export type MiddlewareFactoryErrorOptions = MiddlewareFactoryErrorOptions_2; export type MiddlewareFactoryOptions = MiddlewareFactoryOptions_2; // @public @deprecated (undocumented) -export const permissionsServiceFactory: () => ServiceFactory< +export const permissionsServiceFactory: ServiceFactoryCompat< PermissionsService, - 'plugin' + 'plugin', + undefined >; // Warning: (ae-forgotten-export) The symbol "readCorsOptions_2" needs to be exported by the entry point index.d.ts @@ -251,9 +268,11 @@ export interface RootConfigFactoryOptions { } // @public @deprecated (undocumented) -export const rootConfigServiceFactory: ( - options?: RootConfigFactoryOptions | undefined, -) => ServiceFactory; +export const rootConfigServiceFactory: ServiceFactoryCompat< + RootConfigService, + 'root', + RootConfigFactoryOptions +>; // Warning: (ae-forgotten-export) The symbol "RootHttpRouterConfigureContext_2" needs to be exported by the entry point index.d.ts // @@ -266,44 +285,52 @@ export type RootHttpRouterConfigureContext = RootHttpRouterConfigureContext_2; export type RootHttpRouterFactoryOptions = RootHttpRouterFactoryOptions_2; // @public @deprecated (undocumented) -export const rootHttpRouterServiceFactory: ( - options?: RootHttpRouterFactoryOptions_2 | undefined, -) => ServiceFactory; +export const rootHttpRouterServiceFactory: ServiceFactoryCompat< + RootHttpRouterService, + 'root', + RootHttpRouterFactoryOptions_2 +>; // @public @deprecated -export const rootLifecycleServiceFactory: () => ServiceFactory< +export const rootLifecycleServiceFactory: ServiceFactoryCompat< RootLifecycleService, - 'root' + 'root', + undefined >; // @public @deprecated -export const rootLoggerServiceFactory: () => ServiceFactory< +export const rootLoggerServiceFactory: ServiceFactoryCompat< RootLoggerService, - 'root' + 'root', + undefined >; // @public @deprecated (undocumented) -export const schedulerServiceFactory: () => ServiceFactory< +export const schedulerServiceFactory: ServiceFactoryCompat< SchedulerService, - 'plugin' + 'plugin', + undefined >; // @public @deprecated (undocumented) -export const tokenManagerServiceFactory: () => ServiceFactory< +export const tokenManagerServiceFactory: ServiceFactoryCompat< TokenManagerService, - 'plugin' + 'plugin', + undefined >; // @public @deprecated (undocumented) -export const urlReaderServiceFactory: () => ServiceFactory< +export const urlReaderServiceFactory: ServiceFactoryCompat< UrlReaderService, - 'plugin' + 'plugin', + undefined >; // @public @deprecated (undocumented) -export const userInfoServiceFactory: () => ServiceFactory< +export const userInfoServiceFactory: ServiceFactoryCompat< UserInfoService, - 'plugin' + 'plugin', + undefined >; // @public @deprecated diff --git a/packages/backend-defaults/api-report-auth.md b/packages/backend-defaults/api-report-auth.md index d64ce5bc2a..7df0b394e3 100644 --- a/packages/backend-defaults/api-report-auth.md +++ b/packages/backend-defaults/api-report-auth.md @@ -4,10 +4,14 @@ ```ts import { AuthService } from '@backstage/backend-plugin-api'; -import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; // @public -export const authServiceFactory: () => ServiceFactory; +export const authServiceFactory: ServiceFactoryCompat< + AuthService, + 'plugin', + undefined +>; // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-defaults/api-report-cache.md b/packages/backend-defaults/api-report-cache.md index 0bfd7eb463..0b2d8706df 100644 --- a/packages/backend-defaults/api-report-cache.md +++ b/packages/backend-defaults/api-report-cache.md @@ -7,7 +7,7 @@ import { CacheService } from '@backstage/backend-plugin-api'; import { CacheServiceOptions } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import { LoggerService } from '@backstage/backend-plugin-api'; -import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; // @public export class CacheManager { @@ -25,7 +25,11 @@ export type CacheManagerOptions = { }; // @public -export const cacheServiceFactory: () => ServiceFactory; +export const cacheServiceFactory: ServiceFactoryCompat< + CacheService, + 'plugin', + undefined +>; // @public (undocumented) export interface PluginCacheManager { diff --git a/packages/backend-defaults/api-report-database.md b/packages/backend-defaults/api-report-database.md index 116830343a..0d54b43777 100644 --- a/packages/backend-defaults/api-report-database.md +++ b/packages/backend-defaults/api-report-database.md @@ -8,7 +8,7 @@ import { DatabaseService } from '@backstage/backend-plugin-api'; import { LifecycleService } from '@backstage/backend-plugin-api'; import { LoggerService } from '@backstage/backend-plugin-api'; import { PluginMetadataService } from '@backstage/backend-plugin-api'; -import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; // @public export class DatabaseManager implements LegacyRootDatabaseService { @@ -32,9 +32,10 @@ export type DatabaseManagerOptions = { }; // @public -export const databaseServiceFactory: () => ServiceFactory< +export const databaseServiceFactory: ServiceFactoryCompat< DatabaseService, - 'plugin' + 'plugin', + undefined >; // @public @deprecated diff --git a/packages/backend-defaults/api-report-discovery.md b/packages/backend-defaults/api-report-discovery.md index b434dab6fc..dbb469f758 100644 --- a/packages/backend-defaults/api-report-discovery.md +++ b/packages/backend-defaults/api-report-discovery.md @@ -5,12 +5,13 @@ ```ts import { Config } from '@backstage/config'; import { DiscoveryService } from '@backstage/backend-plugin-api'; -import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; // @public -export const discoveryServiceFactory: () => ServiceFactory< +export const discoveryServiceFactory: ServiceFactoryCompat< DiscoveryService, - 'plugin' + 'plugin', + undefined >; // @public diff --git a/packages/backend-defaults/api-report-httpAuth.md b/packages/backend-defaults/api-report-httpAuth.md index 6ffe3d6539..613e6a4452 100644 --- a/packages/backend-defaults/api-report-httpAuth.md +++ b/packages/backend-defaults/api-report-httpAuth.md @@ -4,12 +4,13 @@ ```ts import { HttpAuthService } from '@backstage/backend-plugin-api'; -import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; // @public -export const httpAuthServiceFactory: () => ServiceFactory< +export const httpAuthServiceFactory: ServiceFactoryCompat< HttpAuthService, - 'plugin' + 'plugin', + undefined >; // (No @packageDocumentation comment for this package) diff --git a/packages/backend-defaults/api-report-httpRouter.md b/packages/backend-defaults/api-report-httpRouter.md index f191a5a847..a2bf1cd39b 100644 --- a/packages/backend-defaults/api-report-httpRouter.md +++ b/packages/backend-defaults/api-report-httpRouter.md @@ -7,7 +7,7 @@ import { HttpRouterService } from '@backstage/backend-plugin-api'; import { HumanDuration } from '@backstage/types'; import { LifecycleService } from '@backstage/backend-plugin-api'; import { RequestHandler } from 'express'; -import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; // @public export function createLifecycleMiddleware( @@ -15,9 +15,10 @@ export function createLifecycleMiddleware( ): RequestHandler; // @public -export const httpRouterServiceFactory: () => ServiceFactory< +export const httpRouterServiceFactory: ServiceFactoryCompat< HttpRouterService, - 'plugin' + 'plugin', + undefined >; // @public diff --git a/packages/backend-defaults/api-report-lifecycle.md b/packages/backend-defaults/api-report-lifecycle.md index 4233584664..36adbbf6e7 100644 --- a/packages/backend-defaults/api-report-lifecycle.md +++ b/packages/backend-defaults/api-report-lifecycle.md @@ -4,12 +4,13 @@ ```ts import { LifecycleService } from '@backstage/backend-plugin-api'; -import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; // @public -export const lifecycleServiceFactory: () => ServiceFactory< +export const lifecycleServiceFactory: ServiceFactoryCompat< LifecycleService, - 'plugin' + 'plugin', + undefined >; // (No @packageDocumentation comment for this package) diff --git a/packages/backend-defaults/api-report-logger.md b/packages/backend-defaults/api-report-logger.md index fa9018a40c..c66f886bf4 100644 --- a/packages/backend-defaults/api-report-logger.md +++ b/packages/backend-defaults/api-report-logger.md @@ -4,12 +4,13 @@ ```ts import { LoggerService } from '@backstage/backend-plugin-api'; -import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; // @public -export const loggerServiceFactory: () => ServiceFactory< +export const loggerServiceFactory: ServiceFactoryCompat< LoggerService, - 'plugin' + 'plugin', + undefined >; // (No @packageDocumentation comment for this package) diff --git a/packages/backend-defaults/api-report-permissions.md b/packages/backend-defaults/api-report-permissions.md index c436443ff1..86b9605606 100644 --- a/packages/backend-defaults/api-report-permissions.md +++ b/packages/backend-defaults/api-report-permissions.md @@ -4,12 +4,13 @@ ```ts import { PermissionsService } from '@backstage/backend-plugin-api'; -import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; // @public -export const permissionsServiceFactory: () => ServiceFactory< +export const permissionsServiceFactory: ServiceFactoryCompat< PermissionsService, - 'plugin' + 'plugin', + undefined >; // (No @packageDocumentation comment for this package) diff --git a/packages/backend-defaults/api-report-rootConfig.md b/packages/backend-defaults/api-report-rootConfig.md index 317c451e1b..24e827f520 100644 --- a/packages/backend-defaults/api-report-rootConfig.md +++ b/packages/backend-defaults/api-report-rootConfig.md @@ -8,7 +8,7 @@ import { ConfigSchema } from '@backstage/config-loader'; import { LoggerService } from '@backstage/backend-plugin-api'; import { RemoteConfigSourceOptions } from '@backstage/config-loader'; import { RootConfigService } from '@backstage/backend-plugin-api'; -import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; // @public (undocumented) export function createConfigSecretEnumerator(options: { @@ -26,9 +26,11 @@ export interface RootConfigFactoryOptions { } // @public (undocumented) -export const rootConfigServiceFactory: ( - options?: RootConfigFactoryOptions | undefined, -) => ServiceFactory; +export const rootConfigServiceFactory: ServiceFactoryCompat< + RootConfigService, + 'root', + RootConfigFactoryOptions +>; // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-defaults/api-report-rootHealth.md b/packages/backend-defaults/api-report-rootHealth.md index ffa067605a..c69f66e747 100644 --- a/packages/backend-defaults/api-report-rootHealth.md +++ b/packages/backend-defaults/api-report-rootHealth.md @@ -4,12 +4,13 @@ ```ts import { RootHealthService } from '@backstage/backend-plugin-api'; -import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; // @public (undocumented) -export const rootHealthServiceFactory: () => ServiceFactory< +export const rootHealthServiceFactory: ServiceFactoryCompat< RootHealthService, - 'root' + 'root', + undefined >; // (No @packageDocumentation comment for this package) diff --git a/packages/backend-defaults/api-report-rootHttpRouter.md b/packages/backend-defaults/api-report-rootHttpRouter.md index d9727fd36d..9ea4cd7ebb 100644 --- a/packages/backend-defaults/api-report-rootHttpRouter.md +++ b/packages/backend-defaults/api-report-rootHttpRouter.md @@ -19,7 +19,7 @@ import { RequestListener } from 'http'; import { RootConfigService } from '@backstage/backend-plugin-api'; import { RootHttpRouterService } from '@backstage/backend-plugin-api'; import type { Server } from 'node:http'; -import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; // @public export function createHttpServer( @@ -141,9 +141,11 @@ export type RootHttpRouterFactoryOptions = { }; // @public (undocumented) -export const rootHttpRouterServiceFactory: ( - options?: RootHttpRouterFactoryOptions | undefined, -) => ServiceFactory; +export const rootHttpRouterServiceFactory: ServiceFactoryCompat< + RootHttpRouterService, + 'root', + RootHttpRouterFactoryOptions +>; // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-defaults/api-report-rootLifecycle.md b/packages/backend-defaults/api-report-rootLifecycle.md index 00eb9c1ebb..faa83706a7 100644 --- a/packages/backend-defaults/api-report-rootLifecycle.md +++ b/packages/backend-defaults/api-report-rootLifecycle.md @@ -4,12 +4,13 @@ ```ts import { RootLifecycleService } from '@backstage/backend-plugin-api'; -import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; // @public -export const rootLifecycleServiceFactory: () => ServiceFactory< +export const rootLifecycleServiceFactory: ServiceFactoryCompat< RootLifecycleService, - 'root' + 'root', + undefined >; // (No @packageDocumentation comment for this package) diff --git a/packages/backend-defaults/api-report-rootLogger.md b/packages/backend-defaults/api-report-rootLogger.md index 70dc0deee6..075a8b4aa9 100644 --- a/packages/backend-defaults/api-report-rootLogger.md +++ b/packages/backend-defaults/api-report-rootLogger.md @@ -7,13 +7,14 @@ import { Format } from 'logform'; import { JsonObject } from '@backstage/types'; import { LoggerService } from '@backstage/backend-plugin-api'; import { RootLoggerService } from '@backstage/backend-plugin-api'; -import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; import { transport } from 'winston'; // @public -export const rootLoggerServiceFactory: () => ServiceFactory< +export const rootLoggerServiceFactory: ServiceFactoryCompat< RootLoggerService, - 'root' + 'root', + undefined >; // @public diff --git a/packages/backend-defaults/api-report-scheduler.md b/packages/backend-defaults/api-report-scheduler.md index 58991ddca3..a3467b97de 100644 --- a/packages/backend-defaults/api-report-scheduler.md +++ b/packages/backend-defaults/api-report-scheduler.md @@ -6,7 +6,7 @@ import { DatabaseService } from '@backstage/backend-plugin-api'; import { LoggerService } from '@backstage/backend-plugin-api'; import { SchedulerService } from '@backstage/backend-plugin-api'; -import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; // @public export class DefaultSchedulerService { @@ -18,9 +18,10 @@ export class DefaultSchedulerService { } // @public -export const schedulerServiceFactory: () => ServiceFactory< +export const schedulerServiceFactory: ServiceFactoryCompat< SchedulerService, - 'plugin' + 'plugin', + undefined >; // (No @packageDocumentation comment for this package) diff --git a/packages/backend-defaults/api-report-urlReader.md b/packages/backend-defaults/api-report-urlReader.md index c56cdba69b..0980e3cd67 100644 --- a/packages/backend-defaults/api-report-urlReader.md +++ b/packages/backend-defaults/api-report-urlReader.md @@ -21,7 +21,7 @@ import { GitLabIntegration } from '@backstage/integration'; import { HarnessIntegration } from '@backstage/integration'; import { LoggerService } from '@backstage/backend-plugin-api'; import { Readable } from 'stream'; -import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; import { UrlReaderService } from '@backstage/backend-plugin-api'; import { UrlReaderServiceReadTreeOptions } from '@backstage/backend-plugin-api'; import { UrlReaderServiceReadTreeResponse } from '@backstage/backend-plugin-api'; @@ -426,9 +426,10 @@ export class UrlReaders { } // @public -export const urlReaderServiceFactory: () => ServiceFactory< +export const urlReaderServiceFactory: ServiceFactoryCompat< UrlReaderService, - 'plugin' + 'plugin', + undefined >; // @public diff --git a/packages/backend-defaults/api-report-userInfo.md b/packages/backend-defaults/api-report-userInfo.md index d11fb69718..b77878ff34 100644 --- a/packages/backend-defaults/api-report-userInfo.md +++ b/packages/backend-defaults/api-report-userInfo.md @@ -3,13 +3,14 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; import { UserInfoService } from '@backstage/backend-plugin-api'; // @public -export const userInfoServiceFactory: () => ServiceFactory< +export const userInfoServiceFactory: ServiceFactoryCompat< UserInfoService, - 'plugin' + 'plugin', + undefined >; // (No @packageDocumentation comment for this package) diff --git a/packages/backend-dynamic-feature-service/api-report.md b/packages/backend-dynamic-feature-service/api-report.md index 20db7db71b..39aa60b09b 100644 --- a/packages/backend-dynamic-feature-service/api-report.md +++ b/packages/backend-dynamic-feature-service/api-report.md @@ -28,7 +28,7 @@ import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { PluginTaskScheduler } from '@backstage/backend-tasks'; import { RootLoggerService } from '@backstage/backend-plugin-api'; import { Router } from 'express'; -import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; import { ServiceRef } from '@backstage/backend-plugin-api'; import { TaskRunner } from '@backstage/backend-tasks'; import { TemplateAction } from '@backstage/plugin-scaffolder-node'; @@ -114,18 +114,20 @@ export interface DynamicPluginsFactoryOptions { } // @public (undocumented) -export const dynamicPluginsFeatureDiscoveryServiceFactory: () => ServiceFactory< +export const dynamicPluginsFeatureDiscoveryServiceFactory: ServiceFactoryCompat< FeatureDiscoveryService, - 'root' + 'root', + undefined >; // @public (undocumented) export const dynamicPluginsFrontendSchemas: BackendFeatureCompat; // @public (undocumented) -export const dynamicPluginsRootLoggerServiceFactory: () => ServiceFactory< +export const dynamicPluginsRootLoggerServiceFactory: ServiceFactoryCompat< RootLoggerService, - 'root' + 'root', + undefined >; // @public (undocumented) @@ -142,14 +144,18 @@ export interface DynamicPluginsSchemasService { } // @public (undocumented) -export const dynamicPluginsSchemasServiceFactory: ( - options?: DynamicPluginsSchemasOptions | undefined, -) => ServiceFactory; +export const dynamicPluginsSchemasServiceFactory: ServiceFactoryCompat< + DynamicPluginsSchemasService, + 'root', + DynamicPluginsSchemasOptions +>; // @public (undocumented) -export const dynamicPluginsServiceFactory: ( - options?: DynamicPluginsFactoryOptions | undefined, -) => ServiceFactory; +export const dynamicPluginsServiceFactory: ServiceFactoryCompat< + DynamicPluginProvider, + 'root', + DynamicPluginsFactoryOptions +>; // @public (undocumented) export const dynamicPluginsServiceRef: ServiceRef< diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index 7b1e6ef2d3..0a01878148 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -257,9 +257,9 @@ export function createServiceFactory< TOpts extends object | undefined = undefined, >( options: RootServiceFactoryOptions, -): () => ServiceFactory; +): ServiceFactoryCompat; -// @public +// @public @deprecated export function createServiceFactory< TService, TImpl extends TService, @@ -271,7 +271,7 @@ export function createServiceFactory< options: ( options?: TOpts, ) => RootServiceFactoryOptions, -): (options?: TOpts) => ServiceFactory; +): ServiceFactoryCompat; // @public export function createServiceFactory< @@ -284,9 +284,9 @@ export function createServiceFactory< TOpts extends object | undefined = undefined, >( options: PluginServiceFactoryOptions, -): () => ServiceFactory; +): ServiceFactoryCompat; -// @public +// @public @deprecated export function createServiceFactory< TService, TImpl extends TService, @@ -299,7 +299,7 @@ export function createServiceFactory< options: ( options?: TOpts, ) => PluginServiceFactoryOptions, -): (options?: TOpts) => ServiceFactory; +): ServiceFactoryCompat; // @public export function createServiceRef( @@ -645,7 +645,19 @@ export interface ServiceFactory< service: ServiceRef; } -// @public +// @public @deprecated (undocumented) +export interface ServiceFactoryCompat< + TService = unknown, + TScope extends 'plugin' | 'root' = 'plugin' | 'root', + TOpts extends object | undefined = undefined, +> extends ServiceFactory { + // @deprecated (undocumented) + ( + ...options: undefined extends TOpts ? [] : [options?: TOpts] + ): ServiceFactory; +} + +// @public @deprecated export type ServiceFactoryOrFunction = ServiceFactory | (() => ServiceFactory); // @public @@ -668,9 +680,13 @@ export type ServiceRefConfig< // @public (undocumented) export interface ServiceRefOptions { // (undocumented) - defaultFactory?: ( + defaultFactory?( service: ServiceRef, - ) => Promise; + ): Promise; + // @deprecated (undocumented) + defaultFactory?( + service: ServiceRef, + ): Promise<() => ServiceFactory>; // (undocumented) id: string; // (undocumented) diff --git a/packages/backend-plugin-api/src/services/system/index.ts b/packages/backend-plugin-api/src/services/system/index.ts index 9f62968ecd..c2d3b9c6fc 100644 --- a/packages/backend-plugin-api/src/services/system/index.ts +++ b/packages/backend-plugin-api/src/services/system/index.ts @@ -21,5 +21,6 @@ export type { PluginServiceFactoryOptions, RootServiceFactoryOptions, ServiceFactoryOrFunction, + ServiceFactoryCompat, } from './types'; export { createServiceRef, createServiceFactory } from './types'; diff --git a/packages/backend-plugin-api/src/services/system/types.ts b/packages/backend-plugin-api/src/services/system/types.ts index 2d6951ffea..9545408ff2 100644 --- a/packages/backend-plugin-api/src/services/system/types.ts +++ b/packages/backend-plugin-api/src/services/system/types.ts @@ -55,6 +55,23 @@ export interface ServiceFactory< service: ServiceRef; } +/** + * @public + * @deprecated This type exists only as a helper for old code that relied on `createServiceFactory` to return `() => ServiceFactory` instead of `ServiceFactory`. You should remove the `()` parentheses at the end of your usages. This type will be removed in a future release. + */ +export interface ServiceFactoryCompat< + TService = unknown, + TScope extends 'plugin' | 'root' = 'plugin' | 'root', + TOpts extends object | undefined = undefined, +> extends ServiceFactory { + /** + * @deprecated You do not need to use this call signature; use the type directly instead by removing the `()` parentheses at the end. This call signature will be removed in a future release. + */ + ( + ...options: undefined extends TOpts ? [] : [options?: TOpts] + ): ServiceFactory; +} + /** @internal */ export interface InternalServiceFactory< TService = unknown, @@ -73,6 +90,7 @@ export interface InternalServiceFactory< /** * Represents either a {@link ServiceFactory} or a function that returns one. * + * @deprecated The support for service factory functions is deprecated and will be removed. * @public */ export type ServiceFactoryOrFunction = ServiceFactory | (() => ServiceFactory); @@ -81,9 +99,15 @@ export type ServiceFactoryOrFunction = ServiceFactory | (() => ServiceFactory); export interface ServiceRefOptions { id: string; scope?: TScope; - defaultFactory?: ( + defaultFactory?( service: ServiceRef, - ) => Promise; + ): Promise; + /** + * @deprecated The defaultFactory must return a plain `ServiceFactory` object, support for returning a function will be removed. + */ + defaultFactory?( + service: ServiceRef, + ): Promise<() => ServiceFactory>; } /** @@ -198,10 +222,14 @@ export function createServiceFactory< TOpts extends object | undefined = undefined, >( options: RootServiceFactoryOptions, -): () => ServiceFactory; +): ServiceFactoryCompat; /** * Creates a root scoped service factory with optional options. * + * @deprecated The ability to define options for service factories is deprecated + * and will be removed. Please use the non-callback form of createServiceFactory + * and provide an API that allows for a simple re-implementation of the service + * factory instead. * @public * @param options - The service factory configuration. */ @@ -214,7 +242,7 @@ export function createServiceFactory< options: ( options?: TOpts, ) => RootServiceFactoryOptions, -): (options?: TOpts) => ServiceFactory; +): ServiceFactoryCompat; /** * Creates a plugin scoped service factory without options. * @@ -229,10 +257,14 @@ export function createServiceFactory< TOpts extends object | undefined = undefined, >( options: PluginServiceFactoryOptions, -): () => ServiceFactory; +): ServiceFactoryCompat; /** * Creates a plugin scoped service factory with optional options. * + * @deprecated The ability to define options for service factories is deprecated + * and will be removed. Please use the non-callback form of createServiceFactory + * and provide an API that allows for a simple re-implementation of the service + * factory instead. * @public * @param options - The service factory configuration. */ @@ -246,7 +278,7 @@ export function createServiceFactory< options: ( options?: TOpts, ) => PluginServiceFactoryOptions, -): (options?: TOpts) => ServiceFactory; +): ServiceFactoryCompat; export function createServiceFactory< TService, TImpl extends TService, @@ -263,13 +295,13 @@ export function createServiceFactory< ) => PluginServiceFactoryOptions) | (() => RootServiceFactoryOptions) | (() => PluginServiceFactoryOptions), -): (options: TOpts) => ServiceFactory { +): ServiceFactoryCompat { const configCallback = typeof options === 'function' ? options : () => options; const factory = ( - o: TOpts, + o?: TOpts, ): InternalServiceFactory => { - const anyConf = configCallback(o); + const anyConf = configCallback(o!); if (anyConf.service.scope === 'root') { const c = anyConf as RootServiceFactoryOptions; return { @@ -303,7 +335,10 @@ export function createServiceFactory< }; }; - factory.$$type = '@backstage/BackendFeatureFactory'; - - return factory; + // This constructs the `ServiceFactoryCompat` type, which is both a plain + // factory object as well as a function that can be called to construct a + // factory, potentially with options. In the future only the plain factory + // form will be supported, but for now we need to allow callers to call the + // factory too. + return Object.assign(factory, factory(undefined as TOpts)); } diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index 0a44fa5ed3..566ac5b888 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -38,6 +38,7 @@ import { RootLifecycleService } from '@backstage/backend-plugin-api'; import { RootLoggerService } from '@backstage/backend-plugin-api'; import { SchedulerService } from '@backstage/backend-plugin-api'; import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; import { ServiceRef } from '@backstage/backend-plugin-api'; import { TokenManagerService } from '@backstage/backend-plugin-api'; import { UrlReaderService } from '@backstage/backend-plugin-api'; @@ -155,7 +156,7 @@ export namespace mockServices { // (undocumented) export namespace auth { const // (undocumented) - factory: () => ServiceFactory; + factory: ServiceFactoryCompat; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -164,7 +165,7 @@ export namespace mockServices { // (undocumented) export namespace cache { const // (undocumented) - factory: () => ServiceFactory; + factory: ServiceFactoryCompat; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -173,7 +174,7 @@ export namespace mockServices { // (undocumented) export namespace database { const // (undocumented) - factory: () => ServiceFactory; + factory: ServiceFactoryCompat; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -184,7 +185,7 @@ export namespace mockServices { // (undocumented) export namespace discovery { const // (undocumented) - factory: () => ServiceFactory; + factory: ServiceFactoryCompat; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -193,7 +194,7 @@ export namespace mockServices { // (undocumented) export namespace events { const // (undocumented) - factory: () => ServiceFactory; + factory: ServiceFactoryCompat; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -205,13 +206,13 @@ export namespace mockServices { }): HttpAuthService; // (undocumented) export namespace httpAuth { - const factory: ( - options?: - | { - defaultCredentials?: BackstageCredentials | undefined; - } - | undefined, - ) => ServiceFactory; + const factory: ServiceFactoryCompat< + HttpAuthService, + 'plugin', + { + defaultCredentials?: BackstageCredentials | undefined; + } + >; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -220,7 +221,7 @@ export namespace mockServices { // (undocumented) export namespace httpRouter { const // (undocumented) - factory: () => ServiceFactory; + factory: ServiceFactoryCompat; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -240,7 +241,7 @@ export namespace mockServices { // (undocumented) export namespace lifecycle { const // (undocumented) - factory: () => ServiceFactory; + factory: ServiceFactoryCompat; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -249,7 +250,7 @@ export namespace mockServices { // (undocumented) export namespace logger { const // (undocumented) - factory: () => ServiceFactory; + factory: ServiceFactoryCompat; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -258,7 +259,7 @@ export namespace mockServices { // (undocumented) export namespace permissions { const // (undocumented) - factory: () => ServiceFactory; + factory: ServiceFactoryCompat; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -280,7 +281,7 @@ export namespace mockServices { // (undocumented) export namespace rootHealth { const // (undocumented) - factory: () => ServiceFactory; + factory: ServiceFactoryCompat; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -289,9 +290,11 @@ export namespace mockServices { // (undocumented) export namespace rootHttpRouter { const // (undocumented) - factory: ( - options?: RootHttpRouterFactoryOptions | undefined, - ) => ServiceFactory; + factory: ServiceFactoryCompat< + RootHttpRouterService, + 'root', + RootHttpRouterFactoryOptions + >; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -300,7 +303,7 @@ export namespace mockServices { // (undocumented) export namespace rootLifecycle { const // (undocumented) - factory: () => ServiceFactory; + factory: ServiceFactoryCompat; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -326,7 +329,7 @@ export namespace mockServices { // (undocumented) export namespace scheduler { const // (undocumented) - factory: () => ServiceFactory; + factory: ServiceFactoryCompat; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -346,7 +349,7 @@ export namespace mockServices { // (undocumented) export namespace urlReader { const // (undocumented) - factory: () => ServiceFactory; + factory: ServiceFactoryCompat; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -357,7 +360,7 @@ export namespace mockServices { ): UserInfoService; // (undocumented) export namespace userInfo { - const factory: () => ServiceFactory; + const factory: ServiceFactoryCompat; const // (undocumented) mock: ( partialImpl?: Partial | undefined, diff --git a/plugins/events-node/api-report.md b/plugins/events-node/api-report.md index 46646d2ce8..5b45b4419e 100644 --- a/plugins/events-node/api-report.md +++ b/plugins/events-node/api-report.md @@ -4,7 +4,7 @@ ```ts import { LoggerService } from '@backstage/backend-plugin-api'; -import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; import { ServiceRef } from '@backstage/backend-plugin-api'; // @public @@ -63,9 +63,10 @@ export interface EventsService { export type EventsServiceEventHandler = (params: EventParams) => Promise; // @public (undocumented) -export const eventsServiceFactory: () => ServiceFactory< +export const eventsServiceFactory: ServiceFactoryCompat< EventsService, - 'plugin' + 'plugin', + undefined >; // @public From edf5cc349ef822619e19534690ec7a659b9ce0ad Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 10 Jul 2024 12:53:32 +0200 Subject: [PATCH 221/510] refactor(test-utils): deprecate the `isDockerDisabledForTests` function Signed-off-by: Camila Belo --- .changeset/forty-buttons-cover.md | 5 +++++ packages/backend-test-utils/api-report.md | 2 +- packages/backend-test-utils/src/deprecated.ts | 9 +++++++++ packages/backend-test-utils/src/index.ts | 1 - .../src/util/isDockerDisabledForTests.ts | 1 - 5 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 .changeset/forty-buttons-cover.md diff --git a/.changeset/forty-buttons-cover.md b/.changeset/forty-buttons-cover.md new file mode 100644 index 0000000000..16e66df061 --- /dev/null +++ b/.changeset/forty-buttons-cover.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-test-utils': patch +--- + +The function `isDockerDisabledForTests` is deprecated and will no longer be exported in the near future as it should only be used internally. diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index a61d1ccb58..d3a618d214 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -54,7 +54,7 @@ export interface CreateMockDirectoryOptions { mockOsTmpDir?: boolean; } -// @public (undocumented) +// @public @deprecated (undocumented) export function isDockerDisabledForTests(): boolean; // @public (undocumented) diff --git a/packages/backend-test-utils/src/deprecated.ts b/packages/backend-test-utils/src/deprecated.ts index fad7523367..5fe74e7ef3 100644 --- a/packages/backend-test-utils/src/deprecated.ts +++ b/packages/backend-test-utils/src/deprecated.ts @@ -15,9 +15,18 @@ */ import { CreateMockDirectoryOptions } from './filesystem'; +import { isDockerDisabledForTests as _isDockerDisabledForTests } from './util'; /** * @public * @deprecated Use `CreateMockDirectoryOptions` from `@backstage/backend-test-utils` instead. */ export type MockDirectoryOptions = CreateMockDirectoryOptions; + +/** + * @public + * @deprecated This is an internal function and will no longer be exported from this package. + */ +export function isDockerDisabledForTests(): boolean { + return _isDockerDisabledForTests(); +} diff --git a/packages/backend-test-utils/src/index.ts b/packages/backend-test-utils/src/index.ts index a9feacbacd..4124a861f4 100644 --- a/packages/backend-test-utils/src/index.ts +++ b/packages/backend-test-utils/src/index.ts @@ -26,4 +26,3 @@ export * from './database'; export * from './msw'; export * from './filesystem'; export * from './next'; -export * from './util'; diff --git a/packages/backend-test-utils/src/util/isDockerDisabledForTests.ts b/packages/backend-test-utils/src/util/isDockerDisabledForTests.ts index 05eeabd91a..ca7cc95425 100644 --- a/packages/backend-test-utils/src/util/isDockerDisabledForTests.ts +++ b/packages/backend-test-utils/src/util/isDockerDisabledForTests.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -/** @public */ export function isDockerDisabledForTests() { // If we are not running in continuous integration, the default is to skip // the (relatively heavy, long running) docker based tests. If you want to From 2414d8666862d00cbed6b6b4292d7e3a7e777d1e Mon Sep 17 00:00:00 2001 From: Seba <17096352+sebalaini@users.noreply.github.com> Date: Wed, 10 Jul 2024 14:28:50 +0200 Subject: [PATCH 222/510] Kubernetes react -> Warning: validateDOMNesting(...):
      cannot appear as a descendant of

      (#25559) * fix html markup in FixDialog Signed-off-by: sebalaini * Update .changeset/short-impalas-suffer.md Co-authored-by: Camila Belo Signed-off-by: Seba <17096352+sebalaini@users.noreply.github.com> --------- Signed-off-by: sebalaini Signed-off-by: Seba <17096352+sebalaini@users.noreply.github.com> Co-authored-by: Camila Belo --- .changeset/short-impalas-suffer.md | 5 +++++ .../components/Pods/FixDialog/FixDialog.tsx | 22 +++++++++---------- 2 files changed, 16 insertions(+), 11 deletions(-) create mode 100644 .changeset/short-impalas-suffer.md diff --git a/.changeset/short-impalas-suffer.md b/.changeset/short-impalas-suffer.md new file mode 100644 index 0000000000..34bc31e85d --- /dev/null +++ b/.changeset/short-impalas-suffer.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kubernetes-react': patch +--- + +Fix the `HTML` markup of the `FixDialog` component, `ul` and `li` are not allowed inside a `p` tag. diff --git a/plugins/kubernetes-react/src/components/Pods/FixDialog/FixDialog.tsx b/plugins/kubernetes-react/src/components/Pods/FixDialog/FixDialog.tsx index fd7440870f..99386b3d40 100644 --- a/plugins/kubernetes-react/src/components/Pods/FixDialog/FixDialog.tsx +++ b/plugins/kubernetes-react/src/components/Pods/FixDialog/FixDialog.tsx @@ -33,6 +33,8 @@ import { DetectedError } from '@backstage/plugin-kubernetes-common'; import { PodLogs } from '../PodLogs'; import { Events } from '../Events'; import { LinkButton } from '@backstage/core-components'; +import List from '@material-ui/core/List'; +import ListItem from '@material-ui/core/ListItem'; const useStyles = makeStyles((theme: Theme) => createStyles({ @@ -96,17 +98,15 @@ export const FixDialog: React.FC = ({ Fix: - -

        - {(error.proposedFix?.actions ?? []).map((fix, i) => { - return ( -
      • - {fix} -
      • - ); - })} -
      - + + {(error.proposedFix?.actions ?? []).map((fix, i) => { + return ( + + {fix} + + ); + })} + {pf && pf.type === 'logs' && ( From 6e4d937728c66d55e2ffde3986d1386cd12bf3f2 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 10 Jul 2024 15:19:03 +0200 Subject: [PATCH 223/510] docs/backend-system: update service factory options section Signed-off-by: Patrik Oldsberg --- .../architecture/03-services.md | 51 ++++++++----------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/docs/backend-system/architecture/03-services.md b/docs/backend-system/architecture/03-services.md index 777eddd3c4..7d6824c41e 100644 --- a/docs/backend-system/architecture/03-services.md +++ b/docs/backend-system/architecture/03-services.md @@ -190,43 +190,36 @@ If a service defines a default factory, that factory will be used if there is no When defining a default factory for a service, it is possible for it to end up with duplicate implementations at runtime. This applies both to any shared root context in your factory, as well as plugin specific instances of your service. This is because package dependency version ranges may not line up perfectly, causing duplicate installations of the same package. This can happen both for two different plugins using the same service, but also across a plugin and its modules. If your service would break in this scenario, you should not define a default factory for it, but instead require that users of your service explicitly install a factory in their backend instance. -## Service Factory Options +## Service Factory Customization -:::note Note - -This pattern is discouraged, only use it when necessary. If possible you should prefer to make services configurable via static configuration instead. - -::: - -When declaring a service factory it's possible to include an options callback. This allows you to customize the factory through code when installing it in the backend. For example, this is how you install an explicit factory instance in the backend without any options: +When declaring a service factory you may also want to make the export the building blocks of the implementation itself. This is to allow for further customization of the service implementation through code, beyond what is possible with static configuration, without the need to re-implement the entire service from scratch. For example, we might export our example `DefaultFooService` class, while moving construction to a static factory method to make it easier to evolve: ```ts -const backend = createBackend(); +export class DefaultFooService { + static create(options: { transform: (foo: string) => string }) { + return new DefaultFooService(options.transform ?? (foo) => foo); + } -backend.add(fooServiceFactory()); -``` + private constructor(private readonly transform: (foo: string) => string) {} -Note that we call `fooServiceFactory` to create the service factory instance. This is because `createServiceFactory` always returns a factory function that creates the actual service factory. To add options to your service factory, you wrap the object passed to `createServiceFactory` in a callback that accepts the desired options. Note that the options must always be optional. For example: - -```ts -export interface FooFactoryOptions { - transform: (foo: string) => string; + foo(foo: string): string { + return this.transform(foo); + } } - -export const fooServiceFactory = createServiceFactory( - (options?: FooFactoryOptions) => ({ - service: fooServiceRef, - factory() { - return new DefaultFooService(options?.transform); - }, - }), -); ``` -This lets us use the options to customize the factory implementation in any way we want. From the outside the service factory looks just like before, except that we're now also able to pass options when installing the factory: +By exporting `DefaultFooService` we now make it relatively simple for advanced users of our service to customize the implementation. To do so, they can define their own service factory that uses our provided implementation: ```ts -const backend = createBackend(); - -backend.add(fooServiceFactory({ transform: foo => foo.toUpperCase() })); +export const customFooServiceFactory = createServiceFactory({ + service: fooServiceRef, + deps: {}, + factory() { + return DefaultFooService.create({ + transform: foo => foo.toUpperCase(), + }); + }, +}); ``` + +This allows lets you provide more advanced options for the service implementation that couldn't be expressed through static configuration. It also gives users of the service implementation access to other services through dependency injection, which can be useful for their customizations. From b9451dd573a1dd3d095c49bfc2d96bf5009a03fc Mon Sep 17 00:00:00 2001 From: CasperJ Date: Wed, 10 Jul 2024 15:22:56 +0200 Subject: [PATCH 224/510] Fixed log message to output the correct file name being written to Signed-off-by: CasperJ --- .changeset/dirty-wasps-do.md | 5 +++++ .../src/scaffolder/actions/builtin/catalog/write.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/dirty-wasps-do.md diff --git a/.changeset/dirty-wasps-do.md b/.changeset/dirty-wasps-do.md new file mode 100644 index 0000000000..fbf6799baf --- /dev/null +++ b/.changeset/dirty-wasps-do.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Catalog:Write scaffolder action shows incorrect log message diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts index 9feaa14c07..a957adb71a 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts @@ -49,10 +49,10 @@ export function createCatalogWriteAction() { examples, supportsDryRun: true, async handler(ctx) { - ctx.logger.info(`Writing catalog-info.yaml`); const { filePath, entity } = ctx.input; const entityRef = ctx.templateInfo?.entityRef; const path = filePath ?? 'catalog-info.yaml'; + ctx.logger.info(`Writing ${path}`); await fs.writeFile( resolveSafeChildPath(ctx.workspacePath, path), From c6c6e2d33427eff8fd9d8f8044ccaee18d0fc63a Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 10 Jul 2024 15:38:28 +0200 Subject: [PATCH 225/510] changesets: add node about TS improvement when removing service factory options Signed-off-by: Patrik Oldsberg --- .changeset/spotty-apricots-tan.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.changeset/spotty-apricots-tan.md b/.changeset/spotty-apricots-tan.md index bc1b26e2f4..2b88e3a7f5 100644 --- a/.changeset/spotty-apricots-tan.md +++ b/.changeset/spotty-apricots-tan.md @@ -53,3 +53,5 @@ export const fooServiceFactory = createServiceFactory({ This is of course more verbose than the previous solution where the factory could be customized through `fooServiceFactory({ bar: 'baz' })`, but this is a simplified which in practice should be using static configuration instead. This change is being made because the ability to define an options callback encourages bad design of services factories. When possible, a service should be configurable through static configuration, and the existence of options may discourage that. More importantly though, the existing options do not work well with the dependency injection system of services, which is a problem for callbacks an other more advanced options. This lead to a bad pattern where only a few explicit dependencies where made available in callbacks, rather than providing an API that allowed simple re-implementation of the service with full access to dependency injection. + +A separate benefit of this change is that it simplifies the TypeScript types in a way that allows TypeScript to provide a much better error message when a service factory doesn't properly implement the service interface. From b05e1e115789f44a65bd13b4ddb60299acf9a5c0 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 10 Jul 2024 15:41:02 +0200 Subject: [PATCH 226/510] changesets: add changeset for packages with updated service factory exports Signed-off-by: Patrik Oldsberg --- .changeset/hot-items-kick.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .changeset/hot-items-kick.md diff --git a/.changeset/hot-items-kick.md b/.changeset/hot-items-kick.md new file mode 100644 index 0000000000..a3a9f129c1 --- /dev/null +++ b/.changeset/hot-items-kick.md @@ -0,0 +1,9 @@ +--- +'@backstage/backend-dynamic-feature-service': patch +'@backstage/backend-test-utils': patch +'@backstage/backend-defaults': patch +'@backstage/backend-app-api': patch +'@backstage/plugin-events-node': patch +--- + +Service factories exported by this package have been updated to use the new service factory format that doesn't use a callback. From 95a3a0b91c5403f35dc5d9520a8e0b3ce5e5c8ae Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 10 Jul 2024 13:28:48 +0200 Subject: [PATCH 227/510] refactor(test-utils): rename `setupRequestMockHandlers` to `setupMswHandler` Signed-off-by: Camila Belo --- .changeset/tiny-schools-draw.md | 53 +++++++++++++++++++ .../auth/authServiceFactory.test.ts | 4 +- .../external/ExternalTokenHandler.test.ts | 7 +-- .../entrypoints/auth/external/jwks.test.ts | 4 +- .../auth/user/UserTokenHandler.test.ts | 7 +-- .../urlReader/lib/AzureUrlReader.test.ts | 4 +- .../lib/BitbucketCloudUrlReader.test.ts | 4 +- .../lib/BitbucketServerUrlReader.test.ts | 4 +- .../urlReader/lib/BitbucketUrlReader.test.ts | 4 +- .../urlReader/lib/FetchUrlReader.test.ts | 7 +-- .../urlReader/lib/GerritUrlReader.test.ts | 4 +- .../urlReader/lib/GiteaUrlReader.test.ts | 7 +-- .../urlReader/lib/GithubUrlReader.test.ts | 4 +- .../urlReader/lib/GitlabUrlReader.test.ts | 4 +- .../urlReader/lib/HarnessUrlReader.test.ts | 7 +-- .../userInfo/DefaultUserInfoService.test.ts | 7 +-- packages/backend-test-utils/api-report.md | 7 +++ packages/backend-test-utils/src/deprecated.ts | 13 +++++ packages/backend-test-utils/src/msw/index.ts | 2 +- .../src/msw/setupRequestMockHandlers.ts | 2 +- .../cli/src/commands/versions/bump.test.ts | 7 +-- .../src/sources/RemoteConfigSource.test.ts | 4 +- .../auth/microsoft/MicrosoftAuth.test.ts | 4 +- .../DefaultAuthConnector.test.ts | 4 +- .../ProxiedSignInIdentity.test.ts | 4 +- .../ProxiedSignInPage.test.tsx | 4 +- packages/create-app/src/lib/tasks.test.ts | 4 +- packages/frontend-test-utils/api-report.md | 2 +- packages/frontend-test-utils/src/index.ts | 2 +- .../release-manifests/src/manifest.test.ts | 4 +- packages/test-utils/api-report.md | 7 +++ packages/test-utils/src/deprecated.ts | 29 ++++++++++ packages/test-utils/src/index.ts | 1 + .../apis/FetchApi/MockFetchApi.test.ts | 4 +- .../test-utils/src/testUtils/msw/index.ts | 2 +- ...estMockHandlers.ts => setupMswHandlers.ts} | 2 +- .../src/helpers.test.ts | 4 +- .../src/helpers.test.ts | 7 +-- .../src/authenticator.test.ts | 4 +- .../src/authenticator.test.ts | 4 +- .../src/module.test.ts | 4 +- .../src/authenticator.test.ts | 4 +- .../src/module.test.ts | 4 +- .../src/authenticator.test.ts | 4 +- .../bitbucketServer/provider.test.ts | 6 +-- .../src/providers/oidc/provider.test.ts | 7 +-- .../src/identity/IdentityClient.test.ts | 4 +- .../src/lib/azure.test.ts | 4 +- .../BitbucketCloudEntityProvider.test.ts | 7 +-- .../src/lib/BitbucketServerClient.test.ts | 4 +- .../BitbucketServerEntityProvider.test.ts | 7 +-- .../providers/GerritEntityProvider.test.ts | 7 +-- .../analyzers/GithubLocationAnalyzer.test.ts | 7 +-- .../src/lib/github.test.ts | 4 +- .../src/GitLabDiscoveryProcessor.test.ts | 7 +-- .../src/lib/client.test.ts | 7 +-- .../GitlabDiscoveryEntityProvider.test.ts | 7 +-- .../GitlabOrgDiscoveryEntityProvider.test.ts | 7 +-- .../src/microsoftGraph/client.test.ts | 4 +- .../src/puppet/read.test.ts | 4 +- .../modules/core/UrlReaderProcessor.test.ts | 7 +-- .../src/search/DefaultCatalogCollator.test.ts | 4 +- .../src/api/AzureRepoApiClient.test.ts | 4 +- .../src/api/CatalogImportClient.test.ts | 4 +- .../src/service/KubernetesBuilder.test.ts | 4 +- .../service/KubernetesFanOutHandler.test.ts | 7 +-- .../src/service/KubernetesFetcher.test.ts | 4 +- .../src/service/KubernetesProxy.test.ts | 4 +- .../src/auth/PinnipedHelper.test.ts | 4 +- .../src/api/KubernetesBackendClient.test.ts | 4 +- .../DefaultNotificationService.test.ts | 4 +- .../src/api/NotificationsClient.test.ts | 4 +- .../src/ServerPermissionClient.test.ts | 4 +- .../src/service/router.config.test.ts | 4 +- .../src/service/router.credentials.test.ts | 4 +- .../actions/bitbucketCloud.examples.test.ts | 4 +- .../src/actions/bitbucketCloud.test.ts | 4 +- ...itbucketCloudPipelinesRun.examples.test.ts | 4 +- .../bitbucketCloudPipelinesRun.test.ts | 4 +- .../actions/bitbucketServer.examples.test.ts | 4 +- .../src/actions/bitbucketServer.test.ts | 4 +- ...itbucketServerPullRequest.examples.test.ts | 4 +- .../src/actions/bitbucket.examples.test.ts | 4 +- .../src/actions/bitbucket.test.ts | 4 +- .../confluenceToMarkdown.examples.test.ts | 4 +- .../confluence/confluenceToMarkdown.test.ts | 4 +- .../src/actions/gerrit.test.ts | 4 +- .../src/actions/gitea.test.ts | 4 +- .../src/actions/createProject.test.ts | 4 +- plugins/scaffolder/src/api.test.ts | 4 +- .../DefaultCatalogCollatorFactory.test.ts | 4 +- .../ToolDocumentCollatorFactory.test.ts | 7 +-- ...ckOverflowQuestionsCollatorFactory.test.ts | 7 +-- .../DefaultTechDocsCollatorFactory.test.ts | 7 +-- .../search/DefaultTechDocsCollator.test.ts | 7 +-- .../StorageApi/UserSettingsStorage.test.ts | 4 +- 96 files changed, 285 insertions(+), 244 deletions(-) create mode 100644 .changeset/tiny-schools-draw.md create mode 100644 packages/test-utils/src/deprecated.ts rename packages/test-utils/src/testUtils/msw/{setupRequestMockHandlers.ts => setupMswHandlers.ts} (94%) diff --git a/.changeset/tiny-schools-draw.md b/.changeset/tiny-schools-draw.md new file mode 100644 index 0000000000..02f57308fb --- /dev/null +++ b/.changeset/tiny-schools-draw.md @@ -0,0 +1,53 @@ +--- +'@backstage/plugin-scaffolder-backend-module-confluence-to-markdown': patch +'@backstage/plugin-auth-backend-module-cloudflare-access-provider': patch +'@backstage/plugin-search-backend-module-stack-overflow-collator': patch +'@backstage/plugin-scaffolder-backend-module-bitbucket-server': patch +'@backstage/plugin-auth-backend-module-vmware-cloud-provider': patch +'@backstage/plugin-scaffolder-backend-module-bitbucket-cloud': patch +'@backstage/plugin-catalog-backend-module-bitbucket-server': patch +'@backstage/plugin-auth-backend-module-microsoft-provider': patch +'@backstage/plugin-catalog-backend-module-bitbucket-cloud': patch +'@backstage/plugin-auth-backend-module-pinniped-provider': patch +'@backstage/plugin-auth-backend-module-aws-alb-provider': patch +'@backstage/plugin-scaffolder-backend-module-bitbucket': patch +'@backstage/plugin-auth-backend-module-oidc-provider': patch +'@backstage/plugin-scaffolder-backend-module-gerrit': patch +'@backstage/plugin-scaffolder-backend-module-sentry': patch +'@backstage/plugin-catalog-backend-module-puppetdb': patch +'@backstage/plugin-scaffolder-backend-module-gitea': patch +'@backstage/plugin-catalog-backend-module-msgraph': patch +'@backstage/plugin-search-backend-module-techdocs': patch +'@backstage/plugin-catalog-backend-module-gerrit': patch +'@backstage/plugin-catalog-backend-module-github': patch +'@backstage/plugin-catalog-backend-module-gitlab': patch +'@backstage/plugin-search-backend-module-catalog': patch +'@backstage/plugin-search-backend-module-explore': patch +'@backstage/plugin-catalog-backend-module-azure': patch +'@backstage/frontend-test-utils': patch +'@backstage/backend-test-utils': patch +'@backstage/release-manifests': patch +'@backstage/plugin-kubernetes-backend': patch +'@backstage/plugin-notifications-node': patch +'@backstage/backend-defaults': patch +'@backstage/core-components': patch +'@backstage/plugin-kubernetes-react': patch +'@backstage/plugin-techdocs-backend': patch +'@backstage/plugin-catalog-backend': patch +'@backstage/plugin-kubernetes-node': patch +'@backstage/plugin-permission-node': patch +'@backstage/config-loader': patch +'@backstage/plugin-catalog-import': patch +'@backstage/core-app-api': patch +'@backstage/plugin-notifications': patch +'@backstage/plugin-proxy-backend': patch +'@backstage/plugin-user-settings': patch +'@backstage/plugin-auth-backend': patch +'@backstage/create-app': patch +'@backstage/test-utils': patch +'@backstage/plugin-scaffolder': patch +'@backstage/plugin-auth-node': patch +'@backstage/cli': patch +--- + +Rename frontend and backend `setupRequestMockHandlers` methods to `setupMswHandlers`. diff --git a/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts b/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts index de89efa351..385bc17a36 100644 --- a/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts +++ b/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts @@ -17,7 +17,7 @@ import { ServiceFactoryTester, mockServices, - setupRequestMockHandlers, + setupMswHandlers, } from '@backstage/backend-test-utils'; import { tokenManagerServiceFactory } from '@backstage/backend-app-api'; import { authServiceFactory } from './authServiceFactory'; @@ -68,7 +68,7 @@ const mockDeps = [ ]; describe('authServiceFactory', () => { - setupRequestMockHandlers(server); + setupMswHandlers(server); afterEach(() => { jest.useRealTimers(); diff --git a/packages/backend-defaults/src/entrypoints/auth/external/ExternalTokenHandler.test.ts b/packages/backend-defaults/src/entrypoints/auth/external/ExternalTokenHandler.test.ts index 559107c59c..2e413c73d6 100644 --- a/packages/backend-defaults/src/entrypoints/auth/external/ExternalTokenHandler.test.ts +++ b/packages/backend-defaults/src/entrypoints/auth/external/ExternalTokenHandler.test.ts @@ -17,10 +17,7 @@ import { BackstagePrincipalAccessRestrictions } from '@backstage/backend-plugin-api'; import { ExternalTokenHandler } from './ExternalTokenHandler'; import { TokenHandler } from './types'; -import { - mockServices, - setupRequestMockHandlers, -} from '@backstage/backend-test-utils'; +import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; import { randomBytes } from 'crypto'; import { SignJWT, exportJWK, generateKeyPair } from 'jose'; import { DateTime } from 'luxon'; @@ -81,7 +78,7 @@ class FakeTokenFactory { describe('ExternalTokenHandler', () => { const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); it('skips over inner handlers that do not match, and applies plugin restrictions', async () => { const handler1: TokenHandler = { diff --git a/packages/backend-defaults/src/entrypoints/auth/external/jwks.test.ts b/packages/backend-defaults/src/entrypoints/auth/external/jwks.test.ts index 56930e4480..02abd1e889 100644 --- a/packages/backend-defaults/src/entrypoints/auth/external/jwks.test.ts +++ b/packages/backend-defaults/src/entrypoints/auth/external/jwks.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { SignJWT, exportJWK, generateKeyPair } from 'jose'; import { rest } from 'msw'; @@ -81,7 +81,7 @@ describe('JWKSHandler', () => { let mockSubject: string; const keyDurationSeconds = 5; - setupRequestMockHandlers(server); + setupMswHandlers(server); beforeEach(() => { mockSubject = 'test_subject'; diff --git a/packages/backend-defaults/src/entrypoints/auth/user/UserTokenHandler.test.ts b/packages/backend-defaults/src/entrypoints/auth/user/UserTokenHandler.test.ts index 76bafb2a8f..9078be81e0 100644 --- a/packages/backend-defaults/src/entrypoints/auth/user/UserTokenHandler.test.ts +++ b/packages/backend-defaults/src/entrypoints/auth/user/UserTokenHandler.test.ts @@ -16,10 +16,7 @@ import { JsonObject } from '@backstage/types'; import { UserTokenHandler } from './UserTokenHandler'; -import { - mockServices, - setupRequestMockHandlers, -} from '@backstage/backend-test-utils'; +import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { AuthenticationError } from '@backstage/errors'; @@ -64,7 +61,7 @@ async function createToken(options: { describe('UserTokenHandler', () => { let userTokenHandler: UserTokenHandler; - setupRequestMockHandlers(server); + setupMswHandlers(server); beforeEach(() => { jest.useRealTimers(); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader.test.ts index ce2385507b..9e2aec1b56 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader.test.ts @@ -26,7 +26,7 @@ import { import { createMockDirectory, mockServices, - setupRequestMockHandlers, + setupMswHandlers, } from '@backstage/backend-test-utils'; import fs from 'fs-extra'; import { rest } from 'msw'; @@ -76,7 +76,7 @@ describe('AzureUrlReader', () => { beforeEach(mockDir.clear); const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); describe('read', () => { beforeEach(() => { diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.test.ts index dc182af619..43be9b1a92 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.test.ts @@ -21,7 +21,7 @@ import { } from '@backstage/integration'; import { createMockDirectory, - setupRequestMockHandlers, + setupMswHandlers, } from '@backstage/backend-test-utils'; import fs from 'fs-extra'; import { rest } from 'msw'; @@ -56,7 +56,7 @@ describe('BitbucketCloudUrlReader', () => { beforeEach(mockDir.clear); const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); describe('readUrl', () => { it('should be able to readUrl via buffer without ETag', async () => { diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader.test.ts index 2870138535..b63e557f3e 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader.test.ts @@ -21,7 +21,7 @@ import { } from '@backstage/integration'; import { createMockDirectory, - setupRequestMockHandlers, + setupMswHandlers, } from '@backstage/backend-test-utils'; import fs from 'fs-extra'; import { rest } from 'msw'; @@ -51,7 +51,7 @@ const reader = new BitbucketServerUrlReader( describe('BitbucketServerUrlReader', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); describe('readTree', () => { const repoBuffer = fs.readFileSync( diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader.test.ts index edd8d6d3fc..67953cd020 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader.test.ts @@ -22,7 +22,7 @@ import { import { createMockDirectory, mockServices, - setupRequestMockHandlers, + setupMswHandlers, } from '@backstage/backend-test-utils'; import fs from 'fs-extra'; import { rest } from 'msw'; @@ -104,7 +104,7 @@ describe('BitbucketUrlReader', () => { ); const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); describe('readUrl', () => { it('should be able to readUrl via buffer without ETag', async () => { diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/FetchUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/FetchUrlReader.test.ts index 38936806c6..31ad87178e 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/FetchUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/FetchUrlReader.test.ts @@ -16,10 +16,7 @@ import { ConfigReader } from '@backstage/config'; import { NotFoundError, NotModifiedError } from '@backstage/errors'; -import { - mockServices, - setupRequestMockHandlers, -} from '@backstage/backend-test-utils'; +import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { FetchUrlReader } from './FetchUrlReader'; @@ -30,7 +27,7 @@ const fetchUrlReader = new FetchUrlReader(); describe('FetchUrlReader', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); beforeEach(() => { jest.clearAllMocks(); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GerritUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GerritUrlReader.test.ts index 94627e074f..61ae9eba6a 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GerritUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GerritUrlReader.test.ts @@ -17,7 +17,7 @@ import { createMockDirectory, mockServices, - setupRequestMockHandlers, + setupMswHandlers, } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { NotModifiedError, NotFoundError } from '@backstage/errors'; @@ -92,7 +92,7 @@ const createReader = (config: JsonObject): UrlReaderPredicateTuple[] => { // eslint-disable-next-line jest/no-disabled-tests describe.skip('GerritUrlReader', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); beforeEach(() => { mockDir.clear(); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader.test.ts index 0b5983eefd..c3b744a792 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader.test.ts @@ -14,10 +14,7 @@ * limitations under the License. */ -import { - mockServices, - setupRequestMockHandlers, -} from '@backstage/backend-test-utils'; +import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { GiteaIntegration, readGiteaConfig } from '@backstage/integration'; import { JsonObject } from '@backstage/types'; @@ -64,7 +61,7 @@ const createReader = (config: JsonObject): UrlReaderPredicateTuple[] => { describe('GiteaUrlReader', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); afterAll(() => { jest.clearAllMocks(); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.test.ts index f07ada0cc3..b0734a0f0e 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.test.ts @@ -22,7 +22,7 @@ import { } from '@backstage/integration'; import { createMockDirectory, - setupRequestMockHandlers, + setupMswHandlers, } from '@backstage/backend-test-utils'; import fs from 'fs-extra'; import { rest } from 'msw'; @@ -74,7 +74,7 @@ const gheProcessor = new GithubUrlReader( describe('GithubUrlReader', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); beforeEach(mockDir.clear); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts index 46276fcdda..62f7d84c84 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts @@ -18,7 +18,7 @@ import { ConfigReader } from '@backstage/config'; import { createMockDirectory, mockServices, - setupRequestMockHandlers, + setupMswHandlers, } from '@backstage/backend-test-utils'; import fs from 'fs-extra'; import { rest } from 'msw'; @@ -72,7 +72,7 @@ describe('GitlabUrlReader', () => { beforeEach(mockDir.clear); const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); describe('read', () => { beforeEach(() => { diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/HarnessUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/HarnessUrlReader.test.ts index f1efbca108..a95cf7f479 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/HarnessUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/HarnessUrlReader.test.ts @@ -14,10 +14,7 @@ * limitations under the License. */ -import { - mockServices, - setupRequestMockHandlers, -} from '@backstage/backend-test-utils'; +import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { HarnessIntegration, readHarnessConfig } from '@backstage/integration'; import { JsonObject } from '@backstage/types'; @@ -120,7 +117,7 @@ const handlers = [ describe('HarnessUrlReader', () => { const worker = setupServer(...handlers); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); beforeAll(() => worker.listen({ onUnhandledRequest: 'bypass' })); afterAll(() => { jest.clearAllMocks(); diff --git a/packages/backend-defaults/src/entrypoints/userInfo/DefaultUserInfoService.test.ts b/packages/backend-defaults/src/entrypoints/userInfo/DefaultUserInfoService.test.ts index b63b24fb18..bba0c5145a 100644 --- a/packages/backend-defaults/src/entrypoints/userInfo/DefaultUserInfoService.test.ts +++ b/packages/backend-defaults/src/entrypoints/userInfo/DefaultUserInfoService.test.ts @@ -15,10 +15,7 @@ */ import { BackstageUserPrincipal } from '@backstage/backend-plugin-api'; -import { - mockServices, - setupRequestMockHandlers, -} from '@backstage/backend-test-utils'; +import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; import { JsonObject } from '@backstage/types'; import { SignJWT, base64url, importJWK } from 'jose'; import { rest } from 'msw'; @@ -28,7 +25,7 @@ import { DefaultUserInfoService } from './DefaultUserInfoService'; describe('DefaultUserInfoService', () => { const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); const mockPublicKey = { kty: 'EC', diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index d3a618d214..ac14bae321 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -403,6 +403,13 @@ export type ServiceMock = { }; // @public +export function setupMswHandlers(worker: { + listen: (t: any) => void; + close: () => void; + resetHandlers: () => void; +}): void; + +// @public @deprecated (undocumented) export function setupRequestMockHandlers(worker: { listen: (t: any) => void; close: () => void; diff --git a/packages/backend-test-utils/src/deprecated.ts b/packages/backend-test-utils/src/deprecated.ts index 5fe74e7ef3..a349030b12 100644 --- a/packages/backend-test-utils/src/deprecated.ts +++ b/packages/backend-test-utils/src/deprecated.ts @@ -16,6 +16,7 @@ import { CreateMockDirectoryOptions } from './filesystem'; import { isDockerDisabledForTests as _isDockerDisabledForTests } from './util'; +import { setupMswHandlers } from './msw'; /** * @public @@ -30,3 +31,15 @@ export type MockDirectoryOptions = CreateMockDirectoryOptions; export function isDockerDisabledForTests(): boolean { return _isDockerDisabledForTests(); } + +/** + * @public + * @deprecated Use `setupMswHandlers` from `@backstage/backend-test-utils` instead. + */ +export function setupRequestMockHandlers(worker: { + listen: (t: any) => void; + close: () => void; + resetHandlers: () => void; +}): void { + setupMswHandlers(worker); +} diff --git a/packages/backend-test-utils/src/msw/index.ts b/packages/backend-test-utils/src/msw/index.ts index 29cbdf854a..a339721ba5 100644 --- a/packages/backend-test-utils/src/msw/index.ts +++ b/packages/backend-test-utils/src/msw/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export { setupRequestMockHandlers } from './setupRequestMockHandlers'; +export { setupMswHandlers } from './setupRequestMockHandlers'; diff --git a/packages/backend-test-utils/src/msw/setupRequestMockHandlers.ts b/packages/backend-test-utils/src/msw/setupRequestMockHandlers.ts index 625ef0e0fc..e123bc91c0 100644 --- a/packages/backend-test-utils/src/msw/setupRequestMockHandlers.ts +++ b/packages/backend-test-utils/src/msw/setupRequestMockHandlers.ts @@ -19,7 +19,7 @@ * @public * @param worker - service worker */ -export function setupRequestMockHandlers(worker: { +export function setupMswHandlers(worker: { listen: (t: any) => void; close: () => void; resetHandlers: () => void; diff --git a/packages/cli/src/commands/versions/bump.test.ts b/packages/cli/src/commands/versions/bump.test.ts index 0dfe2f61c3..c7f8b7ed0c 100644 --- a/packages/cli/src/commands/versions/bump.test.ts +++ b/packages/cli/src/commands/versions/bump.test.ts @@ -18,10 +18,7 @@ import fs from 'fs-extra'; import { Command } from 'commander'; import * as runObj from '../../lib/run'; import bump, { bumpBackstageJsonVersion, createVersionFinder } from './bump'; -import { - setupRequestMockHandlers, - withLogCollector, -} from '@backstage/test-utils'; +import { setupMswHandlers, withLogCollector } from '@backstage/test-utils'; import { YarnInfoInspectData } from '../../lib/versioning/packages'; import { setupServer } from 'msw/node'; import { rest } from 'msw'; @@ -156,7 +153,7 @@ describe('bump', () => { }); const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); it('should bump backstage dependencies', async () => { mockDir.setContent({ diff --git a/packages/config-loader/src/sources/RemoteConfigSource.test.ts b/packages/config-loader/src/sources/RemoteConfigSource.test.ts index 6082c05e65..5fb16bf0c8 100644 --- a/packages/config-loader/src/sources/RemoteConfigSource.test.ts +++ b/packages/config-loader/src/sources/RemoteConfigSource.test.ts @@ -15,14 +15,14 @@ */ import { rest } from 'msw'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { setupServer } from 'msw/node'; import { RemoteConfigSource } from './RemoteConfigSource'; import { readN } from './__testUtils__/testUtils'; describe('RemoteConfigSource', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); it('should load config from a remote URL', async () => { worker.use( diff --git a/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.test.ts b/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.test.ts index b6d59bd3f2..698c9930b7 100644 --- a/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.test.ts +++ b/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.test.ts @@ -19,13 +19,13 @@ import MockOAuthApi from '../../OAuthRequestApi/MockOAuthApi'; import { UrlPatternDiscovery } from '../../DiscoveryApi'; import { ConfigReader } from '@backstage/config'; import { microsoftAuthApiRef } from '@backstage/core-plugin-api'; -import { setupRequestMockHandlers } from '@backstage/test-utils'; +import { setupMswHandlers } from '@backstage/test-utils'; import { setupServer } from 'msw/node'; import { rest } from 'msw'; describe('MicrosoftAuth', () => { const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); const microsoftAuth = MicrosoftAuth.create({ configApi: new ConfigReader(undefined), oauthRequestApi: new MockOAuthApi(), diff --git a/packages/core-app-api/src/lib/AuthConnector/DefaultAuthConnector.test.ts b/packages/core-app-api/src/lib/AuthConnector/DefaultAuthConnector.test.ts index 4273ea99ee..d4bd136201 100644 --- a/packages/core-app-api/src/lib/AuthConnector/DefaultAuthConnector.test.ts +++ b/packages/core-app-api/src/lib/AuthConnector/DefaultAuthConnector.test.ts @@ -18,7 +18,7 @@ import { DefaultAuthConnector } from './DefaultAuthConnector'; import MockOAuthApi from '../../apis/implementations/OAuthRequestApi/MockOAuthApi'; import * as loginPopup from '../loginPopup'; import { UrlPatternDiscovery } from '../../apis'; -import { setupRequestMockHandlers } from '@backstage/test-utils'; +import { setupMswHandlers } from '@backstage/test-utils'; import { setupServer } from 'msw/node'; import { rest } from 'msw'; import { ConfigReader } from '@backstage/config'; @@ -53,7 +53,7 @@ const defaultOptions = { describe('DefaultAuthConnector', () => { const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); afterEach(() => { jest.resetAllMocks(); diff --git a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts index b8c2b84085..4780b174e0 100644 --- a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts +++ b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { setupRequestMockHandlers } from '@backstage/test-utils'; +import { setupMswHandlers } from '@backstage/test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { @@ -60,7 +60,7 @@ describe('ProxiedSignInIdentity', () => { afterEach(() => jest.useRealTimers()); const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); it('runs the happy path', async () => { const getBaseUrl = jest.fn(); diff --git a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.test.tsx b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.test.tsx index 05960cd213..3cfde3d0f0 100644 --- a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.test.tsx +++ b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.test.tsx @@ -20,7 +20,7 @@ import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { TestApiProvider, - setupRequestMockHandlers, + setupMswHandlers, wrapInTestApp, } from '@backstage/test-utils'; import { ProxiedSignInPage } from './ProxiedSignInPage'; @@ -28,7 +28,7 @@ import { discoveryApiRef } from '@backstage/core-plugin-api'; describe('ProxiedSignInPage', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); const Subject = wrapInTestApp(
      authenticated
      , { components: { diff --git a/packages/create-app/src/lib/tasks.test.ts b/packages/create-app/src/lib/tasks.test.ts index 1f507b95ed..f26c3306f1 100644 --- a/packages/create-app/src/lib/tasks.test.ts +++ b/packages/create-app/src/lib/tasks.test.ts @@ -31,7 +31,7 @@ import { } from './tasks'; import { createMockDirectory, - setupRequestMockHandlers, + setupMswHandlers, } from '@backstage/backend-test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; @@ -423,7 +423,7 @@ describe('tasks', () => { describe('fetchYarnLockSeedTask', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); it('should fetch the yarn.lock seed file', async () => { worker.use( diff --git a/packages/frontend-test-utils/api-report.md b/packages/frontend-test-utils/api-report.md index 2605499a96..7c8f5a5837 100644 --- a/packages/frontend-test-utils/api-report.md +++ b/packages/frontend-test-utils/api-report.md @@ -20,7 +20,7 @@ import { MockStorageApi } from '@backstage/test-utils'; import { MockStorageBucket } from '@backstage/test-utils'; import { RenderResult } from '@testing-library/react'; import { RouteRef } from '@backstage/frontend-plugin-api'; -import { setupRequestMockHandlers } from '@backstage/test-utils'; +import { setupMswHandlers as setupRequestMockHandlers } from '@backstage/test-utils'; import { TestApiProvider } from '@backstage/test-utils'; import { TestApiProviderProps } from '@backstage/test-utils'; import { TestApiRegistry } from '@backstage/test-utils'; diff --git a/packages/frontend-test-utils/src/index.ts b/packages/frontend-test-utils/src/index.ts index 0dab8e75b7..9d41699073 100644 --- a/packages/frontend-test-utils/src/index.ts +++ b/packages/frontend-test-utils/src/index.ts @@ -28,4 +28,4 @@ export type { TestApiProviderProps } from '@backstage/test-utils'; export { withLogCollector } from '@backstage/test-utils'; -export { setupRequestMockHandlers } from '@backstage/test-utils'; +export { setupMswHandlers as setupRequestMockHandlers } from '@backstage/test-utils'; diff --git a/packages/release-manifests/src/manifest.test.ts b/packages/release-manifests/src/manifest.test.ts index 6a53f993c8..8192bf867e 100644 --- a/packages/release-manifests/src/manifest.test.ts +++ b/packages/release-manifests/src/manifest.test.ts @@ -16,7 +16,7 @@ import { setupServer } from 'msw/node'; import { rest } from 'msw'; -import { setupRequestMockHandlers } from '@backstage/test-utils'; +import { setupMswHandlers } from '@backstage/test-utils'; import { getManifestByReleaseLine, getManifestByVersion, @@ -25,7 +25,7 @@ import { describe('Release Manifests', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); describe('getManifestByVersion', () => { it('should return a list of packages in a release', async () => { diff --git a/packages/test-utils/api-report.md b/packages/test-utils/api-report.md index e31a820a1c..82816d931a 100644 --- a/packages/test-utils/api-report.md +++ b/packages/test-utils/api-report.md @@ -210,6 +210,13 @@ export function renderWithEffects( ): Promise; // @public +export function setupMswHandlers(worker: { + listen: (t: any) => void; + close: () => void; + resetHandlers: () => void; +}): void; + +// @public @deprecated (undocumented) export function setupRequestMockHandlers(worker: { listen: (t: any) => void; close: () => void; diff --git a/packages/test-utils/src/deprecated.ts b/packages/test-utils/src/deprecated.ts new file mode 100644 index 0000000000..6825f9d0da --- /dev/null +++ b/packages/test-utils/src/deprecated.ts @@ -0,0 +1,29 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { setupMswHandlers } from './testUtils/msw'; + +/** + * @public + * @deprecated Use `CreateMockDirectoryOptions` from `@backstage/backend-test-utils` instead. + */ +export function setupRequestMockHandlers(worker: { + listen: (t: any) => void; + close: () => void; + resetHandlers: () => void; +}): void { + setupMswHandlers(worker); +} diff --git a/packages/test-utils/src/index.ts b/packages/test-utils/src/index.ts index 83a955baa7..b971825f66 100644 --- a/packages/test-utils/src/index.ts +++ b/packages/test-utils/src/index.ts @@ -20,4 +20,5 @@ * @packageDocumentation */ +export * from './deprecated'; export * from './testUtils'; diff --git a/packages/test-utils/src/testUtils/apis/FetchApi/MockFetchApi.test.ts b/packages/test-utils/src/testUtils/apis/FetchApi/MockFetchApi.test.ts index 37b9d874f9..d51f4c7aee 100644 --- a/packages/test-utils/src/testUtils/apis/FetchApi/MockFetchApi.test.ts +++ b/packages/test-utils/src/testUtils/apis/FetchApi/MockFetchApi.test.ts @@ -16,12 +16,12 @@ import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '../../msw'; +import { setupMswHandlers } from '../../msw'; import { MockFetchApi } from './MockFetchApi'; describe('MockFetchApi', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); it('works with default constructor', async () => { worker.use( diff --git a/packages/test-utils/src/testUtils/msw/index.ts b/packages/test-utils/src/testUtils/msw/index.ts index 29cbdf854a..a924676d06 100644 --- a/packages/test-utils/src/testUtils/msw/index.ts +++ b/packages/test-utils/src/testUtils/msw/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export { setupRequestMockHandlers } from './setupRequestMockHandlers'; +export { setupMswHandlers } from './setupMswHandlers'; diff --git a/packages/test-utils/src/testUtils/msw/setupRequestMockHandlers.ts b/packages/test-utils/src/testUtils/msw/setupMswHandlers.ts similarity index 94% rename from packages/test-utils/src/testUtils/msw/setupRequestMockHandlers.ts rename to packages/test-utils/src/testUtils/msw/setupMswHandlers.ts index 625ef0e0fc..e123bc91c0 100644 --- a/packages/test-utils/src/testUtils/msw/setupRequestMockHandlers.ts +++ b/packages/test-utils/src/testUtils/msw/setupMswHandlers.ts @@ -19,7 +19,7 @@ * @public * @param worker - service worker */ -export function setupRequestMockHandlers(worker: { +export function setupMswHandlers(worker: { listen: (t: any) => void; close: () => void; resetHandlers: () => void; diff --git a/plugins/auth-backend-module-aws-alb-provider/src/helpers.test.ts b/plugins/auth-backend-module-aws-alb-provider/src/helpers.test.ts index 0bbcf9b5c1..1b902246fb 100644 --- a/plugins/auth-backend-module-aws-alb-provider/src/helpers.test.ts +++ b/plugins/auth-backend-module-aws-alb-provider/src/helpers.test.ts @@ -19,7 +19,7 @@ import { JWTHeaderParameters, UnsecuredJWT } from 'jose'; import NodeCache from 'node-cache'; import { http, HttpResponse } from 'msw'; import { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { PassportProfile } from '@backstage/plugin-auth-node'; import { makeProfileInfo, provisionKeyCache } from './helpers'; @@ -34,7 +34,7 @@ describe.each([ ], ])('helpers', (region, url) => { const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); const nodeCache = jest.fn() as unknown as NodeCache; nodeCache.set = jest.fn(); diff --git a/plugins/auth-backend-module-cloudflare-access-provider/src/helpers.test.ts b/plugins/auth-backend-module-cloudflare-access-provider/src/helpers.test.ts index 8043f4e214..a0b3335874 100644 --- a/plugins/auth-backend-module-cloudflare-access-provider/src/helpers.test.ts +++ b/plugins/auth-backend-module-cloudflare-access-provider/src/helpers.test.ts @@ -14,10 +14,7 @@ * limitations under the License. */ -import { - mockServices, - setupRequestMockHandlers, -} from '@backstage/backend-test-utils'; +import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { SignJWT, exportJWK, generateKeyPair } from 'jose'; import { HttpResponse, http } from 'msw'; @@ -89,7 +86,7 @@ describe('helpers', () => { const tokenFactory = new MockTokenFactory(); const cache = mockServices.cache.mock(); const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); beforeEach(() => { jest.clearAllMocks(); diff --git a/plugins/auth-backend-module-microsoft-provider/src/authenticator.test.ts b/plugins/auth-backend-module-microsoft-provider/src/authenticator.test.ts index 21a60a229b..fc392f68c2 100644 --- a/plugins/auth-backend-module-microsoft-provider/src/authenticator.test.ts +++ b/plugins/auth-backend-module-microsoft-provider/src/authenticator.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { encodeOAuthState, @@ -43,7 +43,7 @@ describe('microsoftAuthenticator', () => { const microsoftApi = new FakeMicrosoftAPI(); const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); let implementation: { domainHint: string | undefined; diff --git a/plugins/auth-backend-module-oidc-provider/src/authenticator.test.ts b/plugins/auth-backend-module-oidc-provider/src/authenticator.test.ts index 4203a70153..05ccebdf7d 100644 --- a/plugins/auth-backend-module-oidc-provider/src/authenticator.test.ts +++ b/plugins/auth-backend-module-oidc-provider/src/authenticator.test.ts @@ -23,7 +23,7 @@ import { } from '@backstage/plugin-auth-node'; import { oidcAuthenticator } from './authenticator'; import { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { JWK, SignJWT, exportJWK, generateKeyPair } from 'jose'; import { rest } from 'msw'; @@ -38,7 +38,7 @@ describe('oidcAuthenticator', () => { const revokedTokenMap: Record = {}; const mswServer = setupServer(); - setupRequestMockHandlers(mswServer); + setupMswHandlers(mswServer); const issuerMetadata = { issuer: 'https://oidc.test', diff --git a/plugins/auth-backend-module-oidc-provider/src/module.test.ts b/plugins/auth-backend-module-oidc-provider/src/module.test.ts index 1359634950..827ff9dd01 100644 --- a/plugins/auth-backend-module-oidc-provider/src/module.test.ts +++ b/plugins/auth-backend-module-oidc-provider/src/module.test.ts @@ -20,7 +20,7 @@ import { setupServer } from 'msw/node'; import { rest } from 'msw'; import { mockServices, - setupRequestMockHandlers, + setupMswHandlers, startTestBackend, } from '@backstage/backend-test-utils'; import { Server } from 'http'; @@ -35,7 +35,7 @@ describe('authModuleOidcProvider', () => { let publicKey: JWK; const mswServer = setupServer(); - setupRequestMockHandlers(mswServer); + setupMswHandlers(mswServer); const issuerMetadata = { issuer: 'https://oidc.test', diff --git a/plugins/auth-backend-module-pinniped-provider/src/authenticator.test.ts b/plugins/auth-backend-module-pinniped-provider/src/authenticator.test.ts index e2dedf2129..4cef747416 100644 --- a/plugins/auth-backend-module-pinniped-provider/src/authenticator.test.ts +++ b/plugins/auth-backend-module-pinniped-provider/src/authenticator.test.ts @@ -23,7 +23,7 @@ import { } from '@backstage/plugin-auth-node'; import { pinnipedAuthenticator } from './authenticator'; import { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { JWK, SignJWT, exportJWK, generateKeyPair } from 'jose'; import { rest } from 'msw'; @@ -37,7 +37,7 @@ describe('pinnipedAuthenticator', () => { let publicKey: JWK; const mswServer = setupServer(); - setupRequestMockHandlers(mswServer); + setupMswHandlers(mswServer); const issuerMetadata = { issuer: 'https://pinniped.test', diff --git a/plugins/auth-backend-module-pinniped-provider/src/module.test.ts b/plugins/auth-backend-module-pinniped-provider/src/module.test.ts index a5c8fb4599..a7cbcaa0da 100644 --- a/plugins/auth-backend-module-pinniped-provider/src/module.test.ts +++ b/plugins/auth-backend-module-pinniped-provider/src/module.test.ts @@ -15,7 +15,7 @@ */ import { mockServices, - setupRequestMockHandlers, + setupMswHandlers, startTestBackend, } from '@backstage/backend-test-utils'; import { Server } from 'http'; @@ -32,7 +32,7 @@ describe('authModulePinnipedProvider', () => { let publicKey: JWK; const mswServer = setupServer(); - setupRequestMockHandlers(mswServer); + setupMswHandlers(mswServer); const issuerMetadata = { issuer: 'https://pinniped.test', diff --git a/plugins/auth-backend-module-vmware-cloud-provider/src/authenticator.test.ts b/plugins/auth-backend-module-vmware-cloud-provider/src/authenticator.test.ts index c69d4e9ab1..b5b335a112 100644 --- a/plugins/auth-backend-module-vmware-cloud-provider/src/authenticator.test.ts +++ b/plugins/auth-backend-module-vmware-cloud-provider/src/authenticator.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { AuthResolverContext, @@ -37,7 +37,7 @@ jest.mock('uid2', () => jest.fn().mockReturnValue('sessionid')); describe('vmwareCloudAuthenticator', () => { const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); let oAuthState: OAuthState = { nonce: 'nonce', diff --git a/plugins/auth-backend/src/providers/bitbucketServer/provider.test.ts b/plugins/auth-backend/src/providers/bitbucketServer/provider.test.ts index 187c3b09a5..8e71b2e8bb 100644 --- a/plugins/auth-backend/src/providers/bitbucketServer/provider.test.ts +++ b/plugins/auth-backend/src/providers/bitbucketServer/provider.test.ts @@ -22,7 +22,7 @@ import { BitbucketServerOAuthResult, } from './provider'; import { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { rest } from 'msw'; import { AuthResolverContext } from '@backstage/plugin-auth-node'; @@ -131,7 +131,7 @@ describe('BitbucketServerAuthProvider', () => { describe('when transforming to type OAuthResponse', () => { const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); it('should map to a valid response', async () => { server.use(whoAmIHandler(), getUserHandler()); @@ -311,7 +311,7 @@ describe('BitbucketServerAuthProvider', () => { describe('when authenticating', () => { const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); it('should forward the refresh token', async () => { server.use(whoAmIHandler(), getUserHandler()); diff --git a/plugins/auth-backend/src/providers/oidc/provider.test.ts b/plugins/auth-backend/src/providers/oidc/provider.test.ts index c7e9c68580..01c3e04bc5 100644 --- a/plugins/auth-backend/src/providers/oidc/provider.test.ts +++ b/plugins/auth-backend/src/providers/oidc/provider.test.ts @@ -13,10 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { - mockServices, - setupRequestMockHandlers, -} from '@backstage/backend-test-utils'; +import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; import { LoggerService } from '@backstage/backend-plugin-api'; import { Config, ConfigReader } from '@backstage/config'; import { @@ -38,7 +35,7 @@ describe('oidc.create', () => { nonce: 'foo', }; const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); let publicKey: JWK; let tokenset: object; diff --git a/plugins/auth-node/src/identity/IdentityClient.test.ts b/plugins/auth-node/src/identity/IdentityClient.test.ts index bdc7dd5cd7..beefe43173 100644 --- a/plugins/auth-node/src/identity/IdentityClient.test.ts +++ b/plugins/auth-node/src/identity/IdentityClient.test.ts @@ -15,7 +15,7 @@ */ import { PluginEndpointDiscovery } from '@backstage/backend-common'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { decodeProtectedHeader, exportJWK, @@ -102,7 +102,7 @@ describe('IdentityClient', () => { let factory: FakeTokenFactory; const keyDurationSeconds = 5; - setupRequestMockHandlers(server); + setupMswHandlers(server); beforeEach(() => { client = IdentityClient.create({ discovery, issuer: mockBaseUrl }); diff --git a/plugins/catalog-backend-module-azure/src/lib/azure.test.ts b/plugins/catalog-backend-module-azure/src/lib/azure.test.ts index ef00610dc0..9d153e630c 100644 --- a/plugins/catalog-backend-module-azure/src/lib/azure.test.ts +++ b/plugins/catalog-backend-module-azure/src/lib/azure.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { codeSearch, CodeSearchResponse } from './azure'; @@ -26,7 +26,7 @@ import { ConfigReader } from '@backstage/config'; describe('azure', () => { const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); const createFixture = (host: string, token: string) => { const azureConfig = { diff --git a/plugins/catalog-backend-module-bitbucket-cloud/src/providers/BitbucketCloudEntityProvider.test.ts b/plugins/catalog-backend-module-bitbucket-cloud/src/providers/BitbucketCloudEntityProvider.test.ts index 55b701e016..1c6128ef9c 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/src/providers/BitbucketCloudEntityProvider.test.ts +++ b/plugins/catalog-backend-module-bitbucket-cloud/src/providers/BitbucketCloudEntityProvider.test.ts @@ -20,10 +20,7 @@ import { TaskInvocationDefinition, TaskRunner, } from '@backstage/backend-tasks'; -import { - mockServices, - setupRequestMockHandlers, -} from '@backstage/backend-test-utils'; +import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; import { CatalogApi } from '@backstage/catalog-client'; import { Entity, LocationEntity } from '@backstage/catalog-model'; import { ConfigReader } from '@backstage/config'; @@ -62,7 +59,7 @@ const logger = mockServices.logger.mock(); const server = setupServer(); describe('BitbucketCloudEntityProvider', () => { - setupRequestMockHandlers(server); + setupMswHandlers(server); const simpleConfig = new ConfigReader({ catalog: { diff --git a/plugins/catalog-backend-module-bitbucket-server/src/lib/BitbucketServerClient.test.ts b/plugins/catalog-backend-module-bitbucket-server/src/lib/BitbucketServerClient.test.ts index a3d4155121..31ee011c23 100644 --- a/plugins/catalog-backend-module-bitbucket-server/src/lib/BitbucketServerClient.test.ts +++ b/plugins/catalog-backend-module-bitbucket-server/src/lib/BitbucketServerClient.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { BitbucketServerIntegrationConfig } from '@backstage/integration'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; @@ -50,7 +50,7 @@ describe('BitbucketServerClient', () => { config: config, }); - setupRequestMockHandlers(server); + setupMswHandlers(server); it('listProjects', async () => { server.use( diff --git a/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerEntityProvider.test.ts b/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerEntityProvider.test.ts index 9624e396cd..fce1102aab 100644 --- a/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerEntityProvider.test.ts +++ b/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerEntityProvider.test.ts @@ -19,10 +19,7 @@ import { TaskInvocationDefinition, TaskRunner, } from '@backstage/backend-tasks'; -import { - mockServices, - setupRequestMockHandlers, -} from '@backstage/backend-test-utils'; +import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { EntityProviderConnection } from '@backstage/plugin-catalog-node'; import { rest } from 'msw'; @@ -103,7 +100,7 @@ function setupStubs(projects: Project[], baseUrl: string) { } describe('BitbucketServerEntityProvider', () => { - setupRequestMockHandlers(server); + setupMswHandlers(server); afterEach(() => { jest.clearAllMocks(); }); diff --git a/plugins/catalog-backend-module-gerrit/src/providers/GerritEntityProvider.test.ts b/plugins/catalog-backend-module-gerrit/src/providers/GerritEntityProvider.test.ts index 8b1acbdbaa..0a5baba297 100644 --- a/plugins/catalog-backend-module-gerrit/src/providers/GerritEntityProvider.test.ts +++ b/plugins/catalog-backend-module-gerrit/src/providers/GerritEntityProvider.test.ts @@ -19,10 +19,7 @@ import { TaskInvocationDefinition, TaskRunner, } from '@backstage/backend-tasks'; -import { - mockServices, - setupRequestMockHandlers, -} from '@backstage/backend-test-utils'; +import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { EntityProviderConnection } from '@backstage/plugin-catalog-node'; import fs from 'fs-extra'; @@ -57,7 +54,7 @@ class PersistingTaskRunner implements TaskRunner { const logger = mockServices.logger.mock(); describe('GerritEntityProvider', () => { - setupRequestMockHandlers(server); + setupMswHandlers(server); afterEach(() => { jest.clearAllMocks(); diff --git a/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.test.ts b/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.test.ts index e5c7eb5896..7b496a45c5 100644 --- a/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.test.ts +++ b/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.test.ts @@ -34,10 +34,7 @@ jest.mock('@octokit/rest', () => { import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { GithubLocationAnalyzer } from './GithubLocationAnalyzer'; -import { - setupRequestMockHandlers, - mockServices, -} from '@backstage/backend-test-utils'; +import { setupMswHandlers, mockServices } from '@backstage/backend-test-utils'; import { setupServer } from 'msw/node'; import { rest } from 'msw'; import { ConfigReader } from '@backstage/config'; @@ -63,7 +60,7 @@ describe('GithubLocationAnalyzer', () => { }, }); - setupRequestMockHandlers(server); + setupMswHandlers(server); beforeEach(() => { server.use( diff --git a/plugins/catalog-backend-module-github/src/lib/github.test.ts b/plugins/catalog-backend-module-github/src/lib/github.test.ts index d83e8031cc..ac88a79bee 100644 --- a/plugins/catalog-backend-module-github/src/lib/github.test.ts +++ b/plugins/catalog-backend-module-github/src/lib/github.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { GroupEntity, UserEntity } from '@backstage/catalog-model'; import { graphql as graphqlOctokit } from '@octokit/graphql'; import { graphql as graphqlMsw } from 'msw'; @@ -39,7 +39,7 @@ describe('github', () => { const graphql = graphqlOctokit.defaults({ request: { fetch } }); const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); describe('getOrganizationUsers using defaultUserMapper', () => { it('reads members', async () => { diff --git a/plugins/catalog-backend-module-gitlab/src/GitLabDiscoveryProcessor.test.ts b/plugins/catalog-backend-module-gitlab/src/GitLabDiscoveryProcessor.test.ts index c1608cd386..10751ad615 100644 --- a/plugins/catalog-backend-module-gitlab/src/GitLabDiscoveryProcessor.test.ts +++ b/plugins/catalog-backend-module-gitlab/src/GitLabDiscoveryProcessor.test.ts @@ -14,10 +14,7 @@ * limitations under the License. */ -import { - mockServices, - setupRequestMockHandlers, -} from '@backstage/backend-test-utils'; +import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { LocationSpec } from '@backstage/plugin-catalog-node'; import { rest, RestRequest } from 'msw'; @@ -157,7 +154,7 @@ function getProcessor({ } describe('GitlabDiscoveryProcessor', () => { - setupRequestMockHandlers(server); + setupMswHandlers(server); beforeAll(() => { jest.useFakeTimers(); diff --git a/plugins/catalog-backend-module-gitlab/src/lib/client.test.ts b/plugins/catalog-backend-module-gitlab/src/lib/client.test.ts index 7d40eb1204..212c5cd4a4 100644 --- a/plugins/catalog-backend-module-gitlab/src/lib/client.test.ts +++ b/plugins/catalog-backend-module-gitlab/src/lib/client.test.ts @@ -14,10 +14,7 @@ * limitations under the License. */ -import { - mockServices, - setupRequestMockHandlers, -} from '@backstage/backend-test-utils'; +import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { readGitLabIntegrationConfig } from '@backstage/integration'; import { setupServer } from 'msw/node'; @@ -27,7 +24,7 @@ import { GitLabClient, paginated } from './client'; import { GitLabGroup, GitLabUser } from './types'; const server = setupServer(...handlers); -setupRequestMockHandlers(server); +setupMswHandlers(server); describe('GitLabClient', () => { describe('isSelfManaged', () => { diff --git a/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.test.ts b/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.test.ts index e89b378cfe..c23a897df2 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.test.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.test.ts @@ -19,10 +19,7 @@ import { TaskInvocationDefinition, TaskRunner, } from '@backstage/backend-tasks'; -import { - mockServices, - setupRequestMockHandlers, -} from '@backstage/backend-test-utils'; +import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { EntityProviderConnection } from '@backstage/plugin-catalog-node'; import { DefaultEventsService } from '@backstage/plugin-events-node'; @@ -32,7 +29,7 @@ import * as mock from '../__testUtils__/mocks'; import { GitlabDiscoveryEntityProvider } from './GitlabDiscoveryEntityProvider'; const server = setupServer(...handlers); -setupRequestMockHandlers(server); +setupMswHandlers(server); afterEach(() => jest.clearAllMocks()); class PersistingTaskRunner implements TaskRunner { diff --git a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.test.ts b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.test.ts index ddc0d03570..2fb8a6c839 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.test.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.test.ts @@ -19,10 +19,7 @@ import { TaskInvocationDefinition, TaskRunner, } from '@backstage/backend-tasks'; -import { - mockServices, - setupRequestMockHandlers, -} from '@backstage/backend-test-utils'; +import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { EntityProviderConnection } from '@backstage/plugin-catalog-node'; import { DefaultEventsService } from '@backstage/plugin-events-node'; @@ -33,7 +30,7 @@ import { GroupNameTransformerOptions } from '../lib/types'; import { GitlabOrgDiscoveryEntityProvider } from './GitlabOrgDiscoveryEntityProvider'; const server = setupServer(...handlers); -setupRequestMockHandlers(server); +setupMswHandlers(server); afterEach(() => jest.clearAllMocks()); class PersistingTaskRunner implements TaskRunner { diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.test.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.test.ts index 6d63537b54..a58db08bfc 100644 --- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.test.ts +++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.test.ts @@ -15,7 +15,7 @@ */ import { TokenCredential } from '@azure/identity'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { MicrosoftGraphClient } from './client'; @@ -27,7 +27,7 @@ describe('MicrosoftGraphClient', () => { let client: MicrosoftGraphClient; const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); beforeEach(() => { tokenCredential.getToken.mockResolvedValue({ diff --git a/plugins/catalog-backend-module-puppetdb/src/puppet/read.test.ts b/plugins/catalog-backend-module-puppetdb/src/puppet/read.test.ts index ac28f04503..05ae65f85c 100644 --- a/plugins/catalog-backend-module-puppetdb/src/puppet/read.test.ts +++ b/plugins/catalog-backend-module-puppetdb/src/puppet/read.test.ts @@ -20,14 +20,14 @@ import { PuppetDbEntityProviderConfig, } from '../providers'; import { DEFAULT_NAMESPACE } from '@backstage/catalog-model'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { ANNOTATION_PUPPET_CERTNAME, ENDPOINT_FACTSETS } from './constants'; describe('readPuppetNodes', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); beforeEach(() => { jest.clearAllMocks(); diff --git a/plugins/catalog-backend/src/modules/core/UrlReaderProcessor.test.ts b/plugins/catalog-backend/src/modules/core/UrlReaderProcessor.test.ts index dd80f8f0c4..2d46ce2256 100644 --- a/plugins/catalog-backend/src/modules/core/UrlReaderProcessor.test.ts +++ b/plugins/catalog-backend/src/modules/core/UrlReaderProcessor.test.ts @@ -15,10 +15,7 @@ */ import { UrlReader, UrlReaders } from '@backstage/backend-common'; -import { - mockServices, - setupRequestMockHandlers, -} from '@backstage/backend-test-utils'; +import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; @@ -39,7 +36,7 @@ describe('UrlReaderProcessor', () => { set: jest.fn(), }; const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts b/plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts index 4c1673b785..8dc22f6ea0 100644 --- a/plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts +++ b/plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts @@ -18,7 +18,7 @@ import { PluginEndpointDiscovery, TokenManager, } from '@backstage/backend-common'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { Entity } from '@backstage/catalog-model'; import { DefaultCatalogCollator } from './DefaultCatalogCollator'; import { setupServer } from 'msw/node'; @@ -62,7 +62,7 @@ describe('DefaultCatalogCollator', () => { let mockTokenManager: jest.Mocked; let collator: DefaultCatalogCollator; - setupRequestMockHandlers(server); + setupMswHandlers(server); beforeAll(() => { mockDiscoveryApi = { getBaseUrl: jest.fn().mockResolvedValue('http://localhost:7007'), diff --git a/plugins/catalog-import/src/api/AzureRepoApiClient.test.ts b/plugins/catalog-import/src/api/AzureRepoApiClient.test.ts index a8fbe9db76..65ef2c035e 100644 --- a/plugins/catalog-import/src/api/AzureRepoApiClient.test.ts +++ b/plugins/catalog-import/src/api/AzureRepoApiClient.test.ts @@ -26,7 +26,7 @@ import { RepoApiClient, } from './AzureRepoApiClient'; import { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '@backstage/test-utils'; +import { setupMswHandlers } from '@backstage/test-utils'; function mockRepoEndpoint() { return rest.get( @@ -153,7 +153,7 @@ function mockPrEndpoint() { describe('RepoApiClient', () => { const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); const testToken = new Date().toString(); const sut = new RepoApiClient({ project: 'project', diff --git a/plugins/catalog-import/src/api/CatalogImportClient.test.ts b/plugins/catalog-import/src/api/CatalogImportClient.test.ts index 1f16840c33..67a019cc1b 100644 --- a/plugins/catalog-import/src/api/CatalogImportClient.test.ts +++ b/plugins/catalog-import/src/api/CatalogImportClient.test.ts @@ -57,7 +57,7 @@ import { ConfigReader, UrlPatternDiscovery } from '@backstage/core-app-api'; import { ScmIntegrations } from '@backstage/integration'; import { ScmAuthApi } from '@backstage/integration-react'; import { CatalogApi } from '@backstage/plugin-catalog-react'; -import { MockFetchApi, setupRequestMockHandlers } from '@backstage/test-utils'; +import { MockFetchApi, setupMswHandlers } from '@backstage/test-utils'; import { Octokit } from '@octokit/rest'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; @@ -70,7 +70,7 @@ import { describe('CatalogImportClient', () => { const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); const mockBaseUrl = 'http://backstage:9191/api/catalog'; const discoveryApi = UrlPatternDiscovery.compile(mockBaseUrl); diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts index 1ac653bb58..7b61a22009 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts @@ -38,7 +38,7 @@ import { ServiceMock, mockCredentials, mockServices, - setupRequestMockHandlers, + setupMswHandlers, startTestBackend, } from '@backstage/backend-test-utils'; import { rest } from 'msw'; @@ -508,7 +508,7 @@ describe('API integration tests', () => { describe('/proxy', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); beforeEach(() => { worker.use( diff --git a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts index a433374a2c..7a2aba2977 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts @@ -26,10 +26,7 @@ import { KubernetesFanOutHandler } from './KubernetesFanOutHandler'; import { KubernetesClientBasedFetcher } from './KubernetesFetcher'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { - mockServices, - setupRequestMockHandlers, -} from '@backstage/backend-test-utils'; +import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; import { FetchResponse, KubernetesRequestAuth, @@ -1128,7 +1125,7 @@ describe('KubernetesFanOutHandler', () => { describe('with a real fetcher', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); it('fetch error short-circuits requests to a single cluster, recovering across the fleet', async () => { const pods = [{ metadata: { name: 'pod-name' } }]; diff --git a/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts b/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts index dafb073bb1..e7196d9dc6 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts @@ -28,7 +28,7 @@ import { setupServer } from 'msw/node'; import { createMockDirectory, mockServices, - setupRequestMockHandlers, + setupMswHandlers, } from '@backstage/backend-test-utils'; import { Config } from '@kubernetes/client-node'; @@ -71,7 +71,7 @@ const POD_METRICS_FIXTURE = [ describe('KubernetesFetcher', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); const labels = (req: MockedRequest): object => { const selectorParam = req.url.searchParams.get('labelSelector'); diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts index 02eeb8c7ed..45a131439b 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts @@ -20,7 +20,7 @@ import { errorHandler } from '@backstage/backend-common'; import { createMockDirectory, mockServices, - setupRequestMockHandlers, + setupMswHandlers, } from '@backstage/backend-test-utils'; import { NotFoundError } from '@backstage/errors'; import { @@ -90,7 +90,7 @@ describe('KubernetesProxy', () => { getExternalBaseUrl: jest.fn(), }; - setupRequestMockHandlers(worker); + setupMswHandlers(worker); const buildMockRequest = (clusterName: any, path: string): Request => { const req = getMockReq({ diff --git a/plugins/kubernetes-node/src/auth/PinnipedHelper.test.ts b/plugins/kubernetes-node/src/auth/PinnipedHelper.test.ts index fdfea030a5..f882d2373c 100644 --- a/plugins/kubernetes-node/src/auth/PinnipedHelper.test.ts +++ b/plugins/kubernetes-node/src/auth/PinnipedHelper.test.ts @@ -18,7 +18,7 @@ import { ExtendedHttpServer } from '@backstage/backend-app-api'; import { ClusterDetails } from '../types'; import { mockServices, - setupRequestMockHandlers, + setupMswHandlers, startTestBackend, } from '@backstage/backend-test-utils'; import { createBackendModule } from '@backstage/backend-plugin-api'; @@ -43,7 +43,7 @@ describe('Pinniped - tokenCredentialRequest', () => { const logger = loggerToWinstonLogger(mockServices.logger.mock()); let httpsRequest: jest.SpyInstance; const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); beforeAll(() => { httpsRequest = jest.spyOn( diff --git a/plugins/kubernetes-react/src/api/KubernetesBackendClient.test.ts b/plugins/kubernetes-react/src/api/KubernetesBackendClient.test.ts index 82ac7c84e2..eecaed20b6 100644 --- a/plugins/kubernetes-react/src/api/KubernetesBackendClient.test.ts +++ b/plugins/kubernetes-react/src/api/KubernetesBackendClient.test.ts @@ -19,7 +19,7 @@ import { KubernetesBackendClient } from './KubernetesBackendClient'; import { rest } from 'msw'; import { UrlPatternDiscovery } from '@backstage/core-app-api'; import { setupServer } from 'msw/node'; -import { MockFetchApi, setupRequestMockHandlers } from '@backstage/test-utils'; +import { MockFetchApi, setupMswHandlers } from '@backstage/test-utils'; import { CustomObjectsByEntityRequest, KubernetesRequestBody, @@ -36,7 +36,7 @@ describe('KubernetesBackendClient', () => { }; let mockResponse: ObjectsByEntityResponse; const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); const identityApi = { getCredentials: jest.fn(), diff --git a/plugins/notifications-node/src/service/DefaultNotificationService.test.ts b/plugins/notifications-node/src/service/DefaultNotificationService.test.ts index d5c327e788..843852af21 100644 --- a/plugins/notifications-node/src/service/DefaultNotificationService.test.ts +++ b/plugins/notifications-node/src/service/DefaultNotificationService.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { setupRequestMockHandlers } from '@backstage/test-utils'; +import { setupMswHandlers } from '@backstage/test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { NotificationPayload } from '@backstage/plugin-notifications-common'; @@ -32,7 +32,7 @@ const testNotification: NotificationPayload = { describe('DefaultNotificationService', () => { const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); const discovery = mockServices.discovery.mock({ getBaseUrl: jest.fn().mockResolvedValue('http://example.com'), diff --git a/plugins/notifications/src/api/NotificationsClient.test.ts b/plugins/notifications/src/api/NotificationsClient.test.ts index e9acd04fc9..b4be073738 100644 --- a/plugins/notifications/src/api/NotificationsClient.test.ts +++ b/plugins/notifications/src/api/NotificationsClient.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { MockFetchApi, setupRequestMockHandlers } from '@backstage/test-utils'; +import { MockFetchApi, setupMswHandlers } from '@backstage/test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { NotificationsClient } from './NotificationsClient'; @@ -33,7 +33,7 @@ const testNotification: Partial = { }; describe('NotificationsClient', () => { - setupRequestMockHandlers(server); + setupMswHandlers(server); const mockBaseUrl = 'http://backstage/api/notifications'; const discoveryApi = { getBaseUrl: async () => mockBaseUrl }; const fetchApi = new MockFetchApi(); diff --git a/plugins/permission-node/src/ServerPermissionClient.test.ts b/plugins/permission-node/src/ServerPermissionClient.test.ts index 6e99ff71ab..b09c25eeb7 100644 --- a/plugins/permission-node/src/ServerPermissionClient.test.ts +++ b/plugins/permission-node/src/ServerPermissionClient.test.ts @@ -25,7 +25,7 @@ import { import { mockCredentials, mockServices, - setupRequestMockHandlers, + setupMswHandlers, } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { setupServer } from 'msw/node'; @@ -54,7 +54,7 @@ const config = new ConfigReader({ }); describe('ServerPermissionClient', () => { - setupRequestMockHandlers(server); + setupMswHandlers(server); const discovery = mockServices.discovery.mock(); diff --git a/plugins/proxy-backend/src/service/router.config.test.ts b/plugins/proxy-backend/src/service/router.config.test.ts index ba81553a4f..3f11faea46 100644 --- a/plugins/proxy-backend/src/service/router.config.test.ts +++ b/plugins/proxy-backend/src/service/router.config.test.ts @@ -19,7 +19,7 @@ import { createServiceFactory, } from '@backstage/backend-plugin-api'; import { - setupRequestMockHandlers, + setupMswHandlers, startTestBackend, } from '@backstage/backend-test-utils'; import { @@ -36,7 +36,7 @@ import fetch from 'node-fetch'; describe('createRouter reloadable configuration', () => { const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); it('should be able to observe the config', async () => { // Grab the subscriber function and use mutable config data to mock a config file change diff --git a/plugins/proxy-backend/src/service/router.credentials.test.ts b/plugins/proxy-backend/src/service/router.credentials.test.ts index 54c865ba11..aede6bb353 100644 --- a/plugins/proxy-backend/src/service/router.credentials.test.ts +++ b/plugins/proxy-backend/src/service/router.credentials.test.ts @@ -20,7 +20,7 @@ import { } from '@backstage/backend-app-api'; import { mockServices, - setupRequestMockHandlers, + setupMswHandlers, startTestBackend, } from '@backstage/backend-test-utils'; import { ResponseError } from '@backstage/errors'; @@ -34,7 +34,7 @@ import fetch from 'node-fetch'; describe('credentials', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); it('handles all valid credentials settings', async () => { const config = { diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.examples.test.ts b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.examples.test.ts index 5e95f41751..ef745fbd18 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.examples.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.examples.test.ts @@ -29,7 +29,7 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { import { createPublishBitbucketCloudAction } from './bitbucketCloud'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; @@ -66,7 +66,7 @@ describe('publish:bitbucketCloud', () => { }, }); const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.test.ts b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.test.ts index 6a079a3f9b..57215ac06d 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.test.ts @@ -29,7 +29,7 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { import { createPublishBitbucketCloudAction } from './bitbucketCloud'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; @@ -56,7 +56,7 @@ describe('publish:bitbucketCloud', () => { }, }); const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.examples.test.ts b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.examples.test.ts index 472c7a6a03..6a4f82066e 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.examples.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.examples.test.ts @@ -21,7 +21,7 @@ import yaml from 'yaml'; import { examples } from './bitbucketCloudPipelinesRun.examples'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; describe('bitbucket:pipelines:run', () => { @@ -48,7 +48,7 @@ describe('bitbucket:pipelines:run', () => { build_number: 1, }; const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.test.ts b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.test.ts index 9386246868..be8500895a 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.test.ts @@ -16,7 +16,7 @@ import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { createBitbucketPipelinesRunAction } from './bitbucketCloudPipelinesRun'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; @@ -48,7 +48,7 @@ describe('bitbucket:pipelines:run', () => { build_number: 1, }; const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); beforeEach(() => { jest.clearAllMocks(); diff --git a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.examples.test.ts b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.examples.test.ts index eae8385822..8e6356df18 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.examples.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.examples.test.ts @@ -29,7 +29,7 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { import { createPublishBitbucketServerAction } from './bitbucketServer'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import yaml from 'yaml'; @@ -68,7 +68,7 @@ describe('publish:bitbucketServer', () => { }, }); const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.test.ts b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.test.ts index 1d42e7368c..fb7d17c0ba 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.test.ts @@ -29,7 +29,7 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { import { createPublishBitbucketServerAction } from './bitbucketServer'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; @@ -66,7 +66,7 @@ describe('publish:bitbucketServer', () => { }, }); const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.examples.test.ts b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.examples.test.ts index 1d3556fc88..0bc6d1464b 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.examples.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.examples.test.ts @@ -29,7 +29,7 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { import { createPublishBitbucketServerPullRequestAction } from './bitbucketServerPullRequest'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import yaml from 'yaml'; @@ -191,7 +191,7 @@ describe('publish:bitbucketServer:pull-request', () => { }; const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.examples.test.ts b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.examples.test.ts index 6633246d70..964b2f207c 100644 --- a/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.examples.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.examples.test.ts @@ -29,7 +29,7 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { import { createPublishBitbucketAction } from './bitbucket'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; @@ -67,7 +67,7 @@ describe('publish:bitbucket', () => { }, }); const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.test.ts b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.test.ts index a63d657904..dddbcde828 100644 --- a/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.test.ts @@ -28,7 +28,7 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { import { createPublishBitbucketAction } from './bitbucket'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; @@ -63,7 +63,7 @@ describe('publish:bitbucket', () => { }, }); const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.examples.test.ts b/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.examples.test.ts index da82849c1e..3aff044b89 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.examples.test.ts +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.examples.test.ts @@ -20,7 +20,7 @@ import { ScmIntegrations } from '@backstage/integration'; import { createMockDirectory, mockServices, - setupRequestMockHandlers, + setupMswHandlers, } from '@backstage/backend-test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; @@ -32,7 +32,7 @@ import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test- describe('confluence:transform:markdown examples', () => { const baseUrl = `https://confluence.example.com`; const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); const config = new ConfigReader({ confluence: { diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.test.ts b/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.test.ts index b19259b3df..5958f1407b 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.test.ts +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.test.ts @@ -21,7 +21,7 @@ import { ScmIntegrations } from '@backstage/integration'; import { createMockDirectory, mockServices, - setupRequestMockHandlers, + setupMswHandlers, } from '@backstage/backend-test-utils'; import type { ActionContext } from '@backstage/plugin-scaffolder-node'; import { rest } from 'msw'; @@ -31,7 +31,7 @@ import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test- describe('confluence:transform:markdown', () => { const baseUrl = `https://nodomain.confluence.com`; const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); const config = new ConfigReader({ confluence: { 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 1f069d3835..b91cc2d84d 100644 --- a/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.test.ts +++ b/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.test.ts @@ -30,7 +30,7 @@ import path from 'path'; import { createPublishGerritAction } from './gerrit'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; @@ -61,7 +61,7 @@ describe('publish:gerrit', () => { }, }); const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts index 8a72265df0..ab4d4641d0 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts @@ -18,7 +18,7 @@ import { ConfigReader } from '@backstage/config'; import { createPublishGiteaAction } from './gitea'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; import { rest } from 'msw'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { setupServer } from 'msw/node'; @@ -62,7 +62,7 @@ describe('publish:gitea', () => { }); const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-sentry/src/actions/createProject.test.ts b/plugins/scaffolder-backend-module-sentry/src/actions/createProject.test.ts index 158b7db4ae..9eef522ddc 100644 --- a/plugins/scaffolder-backend-module-sentry/src/actions/createProject.test.ts +++ b/plugins/scaffolder-backend-module-sentry/src/actions/createProject.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { ConfigReader } from '@backstage/config'; import { InputError } from '@backstage/errors'; @@ -27,7 +27,7 @@ import { createSentryCreateProjectAction } from './createProject'; describe('sentry:project:create action', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); const createScaffolderConfig = (configData: JsonObject = {}) => ({ config: new ConfigReader({ diff --git a/plugins/scaffolder/src/api.test.ts b/plugins/scaffolder/src/api.test.ts index 488169719d..1da440ab7b 100644 --- a/plugins/scaffolder/src/api.test.ts +++ b/plugins/scaffolder/src/api.test.ts @@ -16,7 +16,7 @@ import { ConfigReader } from '@backstage/core-app-api'; import { ScmIntegrations } from '@backstage/integration'; -import { MockFetchApi, setupRequestMockHandlers } from '@backstage/test-utils'; +import { MockFetchApi, setupMswHandlers } from '@backstage/test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { ScaffolderClient } from './api'; @@ -30,7 +30,7 @@ const mockFetchEventSource = fetchEventSource as jest.MockedFunction< const server = setupServer(); describe('api', () => { - setupRequestMockHandlers(server); + setupMswHandlers(server); const mockBaseUrl = 'http://backstage/api'; const discoveryApi = { getBaseUrl: async () => mockBaseUrl }; diff --git a/plugins/search-backend-module-catalog/src/collators/DefaultCatalogCollatorFactory.test.ts b/plugins/search-backend-module-catalog/src/collators/DefaultCatalogCollatorFactory.test.ts index 7af3a8e9a2..0d9320f3dd 100644 --- a/plugins/search-backend-module-catalog/src/collators/DefaultCatalogCollatorFactory.test.ts +++ b/plugins/search-backend-module-catalog/src/collators/DefaultCatalogCollatorFactory.test.ts @@ -18,7 +18,7 @@ import { PluginEndpointDiscovery, TokenManager, } from '@backstage/backend-common'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { setupMswHandlers } from '@backstage/backend-test-utils'; import { Entity } from '@backstage/catalog-model'; import { ConfigReader } from '@backstage/config'; import { TestPipeline } from '@backstage/plugin-search-backend-node'; @@ -74,7 +74,7 @@ describe('DefaultCatalogCollatorFactory', () => { tokenManager: mockTokenManager, }; - setupRequestMockHandlers(server); + setupMswHandlers(server); beforeEach(() => { server.use( diff --git a/plugins/search-backend-module-explore/src/collators/ToolDocumentCollatorFactory.test.ts b/plugins/search-backend-module-explore/src/collators/ToolDocumentCollatorFactory.test.ts index 82305d0d86..e69b48b1c3 100644 --- a/plugins/search-backend-module-explore/src/collators/ToolDocumentCollatorFactory.test.ts +++ b/plugins/search-backend-module-explore/src/collators/ToolDocumentCollatorFactory.test.ts @@ -19,10 +19,7 @@ import { } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { TestPipeline } from '@backstage/plugin-search-backend-node'; -import { - mockServices, - setupRequestMockHandlers, -} from '@backstage/backend-test-utils'; +import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { Readable } from 'stream'; @@ -82,7 +79,7 @@ describe('ToolDocumentCollatorFactory', () => { let collator: Readable; const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); beforeEach(async () => { factory = ToolDocumentCollatorFactory.fromConfig(config, options); diff --git a/plugins/search-backend-module-stack-overflow-collator/src/collators/StackOverflowQuestionsCollatorFactory.test.ts b/plugins/search-backend-module-stack-overflow-collator/src/collators/StackOverflowQuestionsCollatorFactory.test.ts index f4d4a77c3c..3698f7c8f6 100644 --- a/plugins/search-backend-module-stack-overflow-collator/src/collators/StackOverflowQuestionsCollatorFactory.test.ts +++ b/plugins/search-backend-module-stack-overflow-collator/src/collators/StackOverflowQuestionsCollatorFactory.test.ts @@ -17,10 +17,7 @@ import { StackOverflowQuestionsCollatorFactory, StackOverflowQuestionsCollatorFactoryOptions, } from './StackOverflowQuestionsCollatorFactory'; -import { - mockServices, - setupRequestMockHandlers, -} from '@backstage/backend-test-utils'; +import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; import { TestPipeline } from '@backstage/plugin-search-backend-node'; import { ConfigReader } from '@backstage/config'; import { Readable } from 'stream'; @@ -95,7 +92,7 @@ describe('StackOverflowQuestionsCollatorFactory', () => { describe('getCollator', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); it('returns a readable stream', async () => { const factory = StackOverflowQuestionsCollatorFactory.fromConfig( diff --git a/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.test.ts b/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.test.ts index 26329e5ed6..a2e8cc9992 100644 --- a/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.test.ts +++ b/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.test.ts @@ -20,10 +20,7 @@ import { import { Entity } from '@backstage/catalog-model'; import { ConfigReader } from '@backstage/config'; import { TestPipeline } from '@backstage/plugin-search-backend-node'; -import { - mockServices, - setupRequestMockHandlers, -} from '@backstage/backend-test-utils'; +import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { Readable } from 'stream'; @@ -106,7 +103,7 @@ describe('DefaultTechDocsCollatorFactory', () => { let collator: Readable; const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); beforeEach(async () => { factory = DefaultTechDocsCollatorFactory.fromConfig(config, options); diff --git a/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.test.ts b/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.test.ts index a0fc908ee5..47245dc6fc 100644 --- a/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.test.ts +++ b/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.test.ts @@ -21,10 +21,7 @@ import { } from '@backstage/backend-common'; import { Entity } from '@backstage/catalog-model'; import { DefaultTechDocsCollator } from './DefaultTechDocsCollator'; -import { - mockServices, - setupRequestMockHandlers, -} from '@backstage/backend-test-utils'; +import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; import { setupServer } from 'msw/node'; import { rest } from 'msw'; import { ConfigReader } from '@backstage/config'; @@ -79,7 +76,7 @@ const expectedEntities: Entity[] = [ describe('TechDocs Collator', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + setupMswHandlers(worker); describe('DefaultTechDocsCollator with legacyPathCasing configuration', () => { let mockDiscoveryApi: jest.Mocked; diff --git a/plugins/user-settings/src/apis/StorageApi/UserSettingsStorage.test.ts b/plugins/user-settings/src/apis/StorageApi/UserSettingsStorage.test.ts index a421c413dc..6ee6a3df2f 100644 --- a/plugins/user-settings/src/apis/StorageApi/UserSettingsStorage.test.ts +++ b/plugins/user-settings/src/apis/StorageApi/UserSettingsStorage.test.ts @@ -21,14 +21,14 @@ import { IdentityApi, StorageApi, } from '@backstage/core-plugin-api'; -import { MockFetchApi, setupRequestMockHandlers } from '@backstage/test-utils'; +import { MockFetchApi, setupMswHandlers } from '@backstage/test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { UserSettingsStorage } from './UserSettingsStorage'; describe('Persistent Storage API', () => { const server = setupServer(); - setupRequestMockHandlers(server); + setupMswHandlers(server); const mockBaseUrl = 'http://backstage:9191/api'; const mockErrorApi = { post: jest.fn(), error$: jest.fn() }; From b82aff92aaa3b270e661dcd1a198e512b7a16099 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 10 Jul 2024 12:53:32 +0200 Subject: [PATCH 228/510] refactor(test-utils): deprecate the `isDockerDisabledForTests` function Signed-off-by: Camila Belo --- .changeset/tiny-schools-draw.md | 50 +------------------ .../02-testing.md | 6 +-- .../auth/authServiceFactory.test.ts | 4 +- .../external/ExternalTokenHandler.test.ts | 7 ++- .../entrypoints/auth/external/jwks.test.ts | 4 +- .../auth/user/UserTokenHandler.test.ts | 7 ++- .../urlReader/lib/AzureUrlReader.test.ts | 4 +- .../lib/BitbucketCloudUrlReader.test.ts | 4 +- .../lib/BitbucketServerUrlReader.test.ts | 4 +- .../urlReader/lib/BitbucketUrlReader.test.ts | 4 +- .../urlReader/lib/FetchUrlReader.test.ts | 7 ++- .../urlReader/lib/GerritUrlReader.test.ts | 4 +- .../urlReader/lib/GiteaUrlReader.test.ts | 7 ++- .../urlReader/lib/GithubUrlReader.test.ts | 4 +- .../urlReader/lib/GitlabUrlReader.test.ts | 4 +- .../urlReader/lib/HarnessUrlReader.test.ts | 7 ++- .../userInfo/DefaultUserInfoService.test.ts | 7 ++- packages/backend-test-utils/api-report.md | 14 +++--- packages/backend-test-utils/src/deprecated.ts | 22 ++++---- packages/backend-test-utils/src/msw/index.ts | 2 +- ...ockHandlers.ts => registerMswTestHooks.ts} | 2 +- .../cli/src/commands/versions/bump.test.ts | 4 +- .../ExampleComponent.test.tsx.hbs | 4 +- .../src/sources/RemoteConfigSource.test.ts | 4 +- .../auth/microsoft/MicrosoftAuth.test.ts | 4 +- .../DefaultAuthConnector.test.ts | 4 +- .../ProxiedSignInIdentity.test.ts | 4 +- .../ProxiedSignInPage.test.tsx | 4 +- packages/create-app/src/lib/tasks.test.ts | 4 +- packages/frontend-test-utils/api-report.md | 11 +++- .../frontend-test-utils/src/deprecated.ts | 29 +++++++++++ packages/frontend-test-utils/src/index.ts | 3 +- .../integration/src/bitbucket/core.test.ts | 4 +- .../src/bitbucketCloud/core.test.ts | 4 +- .../src/bitbucketServer/core.test.ts | 4 +- packages/integration/src/gerrit/core.test.ts | 4 +- packages/integration/src/gitea/core.test.ts | 4 +- packages/integration/src/harness/core.test.ts | 4 +- packages/integration/src/helpers.ts | 2 +- .../release-manifests/src/manifest.test.ts | 4 +- packages/test-utils/api-report.md | 14 +++--- packages/test-utils/src/deprecated.ts | 6 +-- .../apis/FetchApi/MockFetchApi.test.ts | 4 +- .../test-utils/src/testUtils/msw/index.ts | 2 +- ...MswHandlers.ts => registerMswTestHooks.ts} | 2 +- .../src/helpers.test.ts | 4 +- .../src/helpers.test.ts | 7 ++- .../src/authenticator.test.ts | 4 +- .../src/authenticator.test.ts | 4 +- .../src/module.test.ts | 4 +- .../src/authenticator.test.ts | 4 +- .../src/module.test.ts | 4 +- .../src/authenticator.test.ts | 4 +- .../bitbucketServer/provider.test.ts | 6 +-- .../src/providers/oidc/provider.test.ts | 7 ++- .../src/identity/IdentityClient.test.ts | 4 +- .../src/lib/azure.test.ts | 4 +- .../BitbucketCloudEntityProvider.test.ts | 7 ++- .../src/lib/BitbucketServerClient.test.ts | 4 +- .../BitbucketServerEntityProvider.test.ts | 7 ++- .../providers/GerritEntityProvider.test.ts | 7 ++- .../analyzers/GithubLocationAnalyzer.test.ts | 7 ++- .../src/lib/github.test.ts | 4 +- .../src/GitLabDiscoveryProcessor.test.ts | 7 ++- .../src/lib/client.test.ts | 7 ++- .../GitlabDiscoveryEntityProvider.test.ts | 7 ++- .../GitlabOrgDiscoveryEntityProvider.test.ts | 7 ++- .../src/microsoftGraph/client.test.ts | 4 +- .../src/puppet/read.test.ts | 4 +- .../modules/core/UrlReaderProcessor.test.ts | 7 ++- .../src/search/DefaultCatalogCollator.test.ts | 4 +- .../src/api/AzureRepoApiClient.test.ts | 4 +- .../src/api/CatalogImportClient.test.ts | 4 +- .../src/service/KubernetesBuilder.test.ts | 4 +- .../service/KubernetesFanOutHandler.test.ts | 7 ++- .../src/service/KubernetesFetcher.test.ts | 4 +- .../src/service/KubernetesProxy.test.ts | 4 +- .../src/auth/PinnipedHelper.test.ts | 4 +- .../src/api/KubernetesBackendClient.test.ts | 4 +- .../DefaultNotificationService.test.ts | 4 +- .../src/api/NotificationsClient.test.ts | 4 +- .../src/ServerPermissionClient.test.ts | 4 +- .../src/service/router.config.test.ts | 4 +- .../src/service/router.credentials.test.ts | 4 +- .../actions/bitbucketCloud.examples.test.ts | 4 +- .../src/actions/bitbucketCloud.test.ts | 4 +- ...itbucketCloudPipelinesRun.examples.test.ts | 4 +- .../bitbucketCloudPipelinesRun.test.ts | 4 +- .../actions/bitbucketServer.examples.test.ts | 4 +- .../src/actions/bitbucketServer.test.ts | 4 +- ...itbucketServerPullRequest.examples.test.ts | 4 +- .../bitbucketServerPullRequest.test.ts | 4 +- .../src/actions/bitbucket.examples.test.ts | 4 +- .../src/actions/bitbucket.test.ts | 4 +- .../confluenceToMarkdown.examples.test.ts | 4 +- .../confluence/confluenceToMarkdown.test.ts | 4 +- .../src/actions/gerrit.test.ts | 4 +- .../src/actions/gitea.test.ts | 4 +- .../src/actions/createProject.test.ts | 4 +- plugins/scaffolder/src/api.test.ts | 4 +- .../DefaultCatalogCollatorFactory.test.ts | 4 +- .../ToolDocumentCollatorFactory.test.ts | 7 ++- ...ckOverflowQuestionsCollatorFactory.test.ts | 7 ++- .../DefaultTechDocsCollatorFactory.test.ts | 7 ++- .../search/DefaultTechDocsCollator.test.ts | 7 ++- .../StorageApi/UserSettingsStorage.test.ts | 4 +- 106 files changed, 329 insertions(+), 272 deletions(-) rename packages/backend-test-utils/src/msw/{setupRequestMockHandlers.ts => registerMswTestHooks.ts} (95%) create mode 100644 packages/frontend-test-utils/src/deprecated.ts rename packages/test-utils/src/testUtils/msw/{setupMswHandlers.ts => registerMswTestHooks.ts} (95%) diff --git a/.changeset/tiny-schools-draw.md b/.changeset/tiny-schools-draw.md index 02f57308fb..2042f13fac 100644 --- a/.changeset/tiny-schools-draw.md +++ b/.changeset/tiny-schools-draw.md @@ -1,53 +1,7 @@ --- -'@backstage/plugin-scaffolder-backend-module-confluence-to-markdown': patch -'@backstage/plugin-auth-backend-module-cloudflare-access-provider': patch -'@backstage/plugin-search-backend-module-stack-overflow-collator': patch -'@backstage/plugin-scaffolder-backend-module-bitbucket-server': patch -'@backstage/plugin-auth-backend-module-vmware-cloud-provider': patch -'@backstage/plugin-scaffolder-backend-module-bitbucket-cloud': patch -'@backstage/plugin-catalog-backend-module-bitbucket-server': patch -'@backstage/plugin-auth-backend-module-microsoft-provider': patch -'@backstage/plugin-catalog-backend-module-bitbucket-cloud': patch -'@backstage/plugin-auth-backend-module-pinniped-provider': patch -'@backstage/plugin-auth-backend-module-aws-alb-provider': patch -'@backstage/plugin-scaffolder-backend-module-bitbucket': patch -'@backstage/plugin-auth-backend-module-oidc-provider': patch -'@backstage/plugin-scaffolder-backend-module-gerrit': patch -'@backstage/plugin-scaffolder-backend-module-sentry': patch -'@backstage/plugin-catalog-backend-module-puppetdb': patch -'@backstage/plugin-scaffolder-backend-module-gitea': patch -'@backstage/plugin-catalog-backend-module-msgraph': patch -'@backstage/plugin-search-backend-module-techdocs': patch -'@backstage/plugin-catalog-backend-module-gerrit': patch -'@backstage/plugin-catalog-backend-module-github': patch -'@backstage/plugin-catalog-backend-module-gitlab': patch -'@backstage/plugin-search-backend-module-catalog': patch -'@backstage/plugin-search-backend-module-explore': patch -'@backstage/plugin-catalog-backend-module-azure': patch -'@backstage/frontend-test-utils': patch '@backstage/backend-test-utils': patch -'@backstage/release-manifests': patch -'@backstage/plugin-kubernetes-backend': patch -'@backstage/plugin-notifications-node': patch -'@backstage/backend-defaults': patch -'@backstage/core-components': patch -'@backstage/plugin-kubernetes-react': patch -'@backstage/plugin-techdocs-backend': patch -'@backstage/plugin-catalog-backend': patch -'@backstage/plugin-kubernetes-node': patch -'@backstage/plugin-permission-node': patch -'@backstage/config-loader': patch -'@backstage/plugin-catalog-import': patch -'@backstage/core-app-api': patch -'@backstage/plugin-notifications': patch -'@backstage/plugin-proxy-backend': patch -'@backstage/plugin-user-settings': patch -'@backstage/plugin-auth-backend': patch -'@backstage/create-app': patch +'@backstage/frontend-test-utils': patch '@backstage/test-utils': patch -'@backstage/plugin-scaffolder': patch -'@backstage/plugin-auth-node': patch -'@backstage/cli': patch --- -Rename frontend and backend `setupRequestMockHandlers` methods to `setupMswHandlers`. +Rename frontend and backend `setupRequestMockHandlers` methods to `registerMswTestHooks`. 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 0739ad24aa..addcc72c84 100644 --- a/docs/backend-system/building-plugins-and-modules/02-testing.md +++ b/docs/backend-system/building-plugins-and-modules/02-testing.md @@ -61,7 +61,7 @@ requests and return mock responses. This lets you stub out remote services rather than the local clients, leading to more thorough and robust tests. You can read more about how it works [in their documentation](https://mswjs.io/). -The `@backstage/backend-test-utils` package exports a `setupRequestMockHandlers` +The `@backstage/backend-test-utils` package exports a `registerMswTestHooks` function which ensures that the correct `jest` lifecycle hooks are invoked to set up and tear down your `msw` instance, and enables the option that completely rejects requests that don't match one of your mock rules. This ensures that your @@ -70,13 +70,13 @@ tests cannot accidentally leak traffic into production from tests. Example: ```ts -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; describe('read from remote', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + registerMswTestHooks(worker); it('should auth and read successfully', async () => { expect.assertions(1); diff --git a/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts b/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts index 385bc17a36..f9ef4c9762 100644 --- a/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts +++ b/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts @@ -17,7 +17,7 @@ import { ServiceFactoryTester, mockServices, - setupMswHandlers, + registerMswTestHooks, } from '@backstage/backend-test-utils'; import { tokenManagerServiceFactory } from '@backstage/backend-app-api'; import { authServiceFactory } from './authServiceFactory'; @@ -68,7 +68,7 @@ const mockDeps = [ ]; describe('authServiceFactory', () => { - setupMswHandlers(server); + registerMswTestHooks(server); afterEach(() => { jest.useRealTimers(); diff --git a/packages/backend-defaults/src/entrypoints/auth/external/ExternalTokenHandler.test.ts b/packages/backend-defaults/src/entrypoints/auth/external/ExternalTokenHandler.test.ts index 2e413c73d6..39b01c46b6 100644 --- a/packages/backend-defaults/src/entrypoints/auth/external/ExternalTokenHandler.test.ts +++ b/packages/backend-defaults/src/entrypoints/auth/external/ExternalTokenHandler.test.ts @@ -17,7 +17,10 @@ import { BackstagePrincipalAccessRestrictions } from '@backstage/backend-plugin-api'; import { ExternalTokenHandler } from './ExternalTokenHandler'; import { TokenHandler } from './types'; -import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; import { randomBytes } from 'crypto'; import { SignJWT, exportJWK, generateKeyPair } from 'jose'; import { DateTime } from 'luxon'; @@ -78,7 +81,7 @@ class FakeTokenFactory { describe('ExternalTokenHandler', () => { const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); it('skips over inner handlers that do not match, and applies plugin restrictions', async () => { const handler1: TokenHandler = { diff --git a/packages/backend-defaults/src/entrypoints/auth/external/jwks.test.ts b/packages/backend-defaults/src/entrypoints/auth/external/jwks.test.ts index 02abd1e889..321e1823aa 100644 --- a/packages/backend-defaults/src/entrypoints/auth/external/jwks.test.ts +++ b/packages/backend-defaults/src/entrypoints/auth/external/jwks.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { SignJWT, exportJWK, generateKeyPair } from 'jose'; import { rest } from 'msw'; @@ -81,7 +81,7 @@ describe('JWKSHandler', () => { let mockSubject: string; const keyDurationSeconds = 5; - setupMswHandlers(server); + registerMswTestHooks(server); beforeEach(() => { mockSubject = 'test_subject'; diff --git a/packages/backend-defaults/src/entrypoints/auth/user/UserTokenHandler.test.ts b/packages/backend-defaults/src/entrypoints/auth/user/UserTokenHandler.test.ts index 9078be81e0..e85ec8db63 100644 --- a/packages/backend-defaults/src/entrypoints/auth/user/UserTokenHandler.test.ts +++ b/packages/backend-defaults/src/entrypoints/auth/user/UserTokenHandler.test.ts @@ -16,7 +16,10 @@ import { JsonObject } from '@backstage/types'; import { UserTokenHandler } from './UserTokenHandler'; -import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { AuthenticationError } from '@backstage/errors'; @@ -61,7 +64,7 @@ async function createToken(options: { describe('UserTokenHandler', () => { let userTokenHandler: UserTokenHandler; - setupMswHandlers(server); + registerMswTestHooks(server); beforeEach(() => { jest.useRealTimers(); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader.test.ts index 9e2aec1b56..f53a7b6c11 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader.test.ts @@ -26,7 +26,7 @@ import { import { createMockDirectory, mockServices, - setupMswHandlers, + registerMswTestHooks, } from '@backstage/backend-test-utils'; import fs from 'fs-extra'; import { rest } from 'msw'; @@ -76,7 +76,7 @@ describe('AzureUrlReader', () => { beforeEach(mockDir.clear); const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); describe('read', () => { beforeEach(() => { diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.test.ts index 43be9b1a92..f5caade3fa 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.test.ts @@ -21,7 +21,7 @@ import { } from '@backstage/integration'; import { createMockDirectory, - setupMswHandlers, + registerMswTestHooks, } from '@backstage/backend-test-utils'; import fs from 'fs-extra'; import { rest } from 'msw'; @@ -56,7 +56,7 @@ describe('BitbucketCloudUrlReader', () => { beforeEach(mockDir.clear); const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); describe('readUrl', () => { it('should be able to readUrl via buffer without ETag', async () => { diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader.test.ts index b63e557f3e..6af2858cde 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader.test.ts @@ -21,7 +21,7 @@ import { } from '@backstage/integration'; import { createMockDirectory, - setupMswHandlers, + registerMswTestHooks, } from '@backstage/backend-test-utils'; import fs from 'fs-extra'; import { rest } from 'msw'; @@ -51,7 +51,7 @@ const reader = new BitbucketServerUrlReader( describe('BitbucketServerUrlReader', () => { const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); describe('readTree', () => { const repoBuffer = fs.readFileSync( diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader.test.ts index 67953cd020..54880aaa75 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader.test.ts @@ -22,7 +22,7 @@ import { import { createMockDirectory, mockServices, - setupMswHandlers, + registerMswTestHooks, } from '@backstage/backend-test-utils'; import fs from 'fs-extra'; import { rest } from 'msw'; @@ -104,7 +104,7 @@ describe('BitbucketUrlReader', () => { ); const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); describe('readUrl', () => { it('should be able to readUrl via buffer without ETag', async () => { diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/FetchUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/FetchUrlReader.test.ts index 31ad87178e..f84422c564 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/FetchUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/FetchUrlReader.test.ts @@ -16,7 +16,10 @@ import { ConfigReader } from '@backstage/config'; import { NotFoundError, NotModifiedError } from '@backstage/errors'; -import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { FetchUrlReader } from './FetchUrlReader'; @@ -27,7 +30,7 @@ const fetchUrlReader = new FetchUrlReader(); describe('FetchUrlReader', () => { const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); beforeEach(() => { jest.clearAllMocks(); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GerritUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GerritUrlReader.test.ts index 61ae9eba6a..14ca4c018e 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GerritUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GerritUrlReader.test.ts @@ -17,7 +17,7 @@ import { createMockDirectory, mockServices, - setupMswHandlers, + registerMswTestHooks, } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { NotModifiedError, NotFoundError } from '@backstage/errors'; @@ -92,7 +92,7 @@ const createReader = (config: JsonObject): UrlReaderPredicateTuple[] => { // eslint-disable-next-line jest/no-disabled-tests describe.skip('GerritUrlReader', () => { const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); beforeEach(() => { mockDir.clear(); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader.test.ts index c3b744a792..77c995c552 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader.test.ts @@ -14,7 +14,10 @@ * limitations under the License. */ -import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { GiteaIntegration, readGiteaConfig } from '@backstage/integration'; import { JsonObject } from '@backstage/types'; @@ -61,7 +64,7 @@ const createReader = (config: JsonObject): UrlReaderPredicateTuple[] => { describe('GiteaUrlReader', () => { const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); afterAll(() => { jest.clearAllMocks(); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.test.ts index b0734a0f0e..f1dd7c0dc6 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.test.ts @@ -22,7 +22,7 @@ import { } from '@backstage/integration'; import { createMockDirectory, - setupMswHandlers, + registerMswTestHooks, } from '@backstage/backend-test-utils'; import fs from 'fs-extra'; import { rest } from 'msw'; @@ -74,7 +74,7 @@ const gheProcessor = new GithubUrlReader( describe('GithubUrlReader', () => { const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); beforeEach(mockDir.clear); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts index 62f7d84c84..dd6a0970d2 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts @@ -18,7 +18,7 @@ import { ConfigReader } from '@backstage/config'; import { createMockDirectory, mockServices, - setupMswHandlers, + registerMswTestHooks, } from '@backstage/backend-test-utils'; import fs from 'fs-extra'; import { rest } from 'msw'; @@ -72,7 +72,7 @@ describe('GitlabUrlReader', () => { beforeEach(mockDir.clear); const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); describe('read', () => { beforeEach(() => { diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/HarnessUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/HarnessUrlReader.test.ts index a95cf7f479..004e1931d0 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/HarnessUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/HarnessUrlReader.test.ts @@ -14,7 +14,10 @@ * limitations under the License. */ -import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { HarnessIntegration, readHarnessConfig } from '@backstage/integration'; import { JsonObject } from '@backstage/types'; @@ -117,7 +120,7 @@ const handlers = [ describe('HarnessUrlReader', () => { const worker = setupServer(...handlers); - setupMswHandlers(worker); + registerMswTestHooks(worker); beforeAll(() => worker.listen({ onUnhandledRequest: 'bypass' })); afterAll(() => { jest.clearAllMocks(); diff --git a/packages/backend-defaults/src/entrypoints/userInfo/DefaultUserInfoService.test.ts b/packages/backend-defaults/src/entrypoints/userInfo/DefaultUserInfoService.test.ts index bba0c5145a..692d179ee2 100644 --- a/packages/backend-defaults/src/entrypoints/userInfo/DefaultUserInfoService.test.ts +++ b/packages/backend-defaults/src/entrypoints/userInfo/DefaultUserInfoService.test.ts @@ -15,7 +15,10 @@ */ import { BackstageUserPrincipal } from '@backstage/backend-plugin-api'; -import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; import { JsonObject } from '@backstage/types'; import { SignJWT, base64url, importJWK } from 'jose'; import { rest } from 'msw'; @@ -25,7 +28,7 @@ import { DefaultUserInfoService } from './DefaultUserInfoService'; describe('DefaultUserInfoService', () => { const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); const mockPublicKey = { kty: 'EC', diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index ac14bae321..37dc5d097d 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -365,6 +365,13 @@ export namespace mockServices { } } +// @public +export function registerMswTestHooks(worker: { + listen: (t: any) => void; + close: () => void; + resetHandlers: () => void; +}): void; + // @public export class ServiceFactoryTester { static from( @@ -402,13 +409,6 @@ export type ServiceMock = { : TService[Key]; }; -// @public -export function setupMswHandlers(worker: { - listen: (t: any) => void; - close: () => void; - resetHandlers: () => void; -}): void; - // @public @deprecated (undocumented) export function setupRequestMockHandlers(worker: { listen: (t: any) => void; diff --git a/packages/backend-test-utils/src/deprecated.ts b/packages/backend-test-utils/src/deprecated.ts index a349030b12..9790580a9c 100644 --- a/packages/backend-test-utils/src/deprecated.ts +++ b/packages/backend-test-utils/src/deprecated.ts @@ -14,9 +14,9 @@ * limitations under the License. */ +import { registerMswTestHooks } from './msw'; import { CreateMockDirectoryOptions } from './filesystem'; import { isDockerDisabledForTests as _isDockerDisabledForTests } from './util'; -import { setupMswHandlers } from './msw'; /** * @public @@ -26,20 +26,20 @@ export type MockDirectoryOptions = CreateMockDirectoryOptions; /** * @public - * @deprecated This is an internal function and will no longer be exported from this package. - */ -export function isDockerDisabledForTests(): boolean { - return _isDockerDisabledForTests(); -} - -/** - * @public - * @deprecated Use `setupMswHandlers` from `@backstage/backend-test-utils` instead. + * @deprecated Use `registerMswTestHooks` from `@backstage/backend-test-utils` instead. */ export function setupRequestMockHandlers(worker: { listen: (t: any) => void; close: () => void; resetHandlers: () => void; }): void { - setupMswHandlers(worker); + registerMswTestHooks(worker); +} + +/** + * @public + * @deprecated This is an internal function and will no longer be exported from this package. + */ +export function isDockerDisabledForTests(): boolean { + return _isDockerDisabledForTests(); } diff --git a/packages/backend-test-utils/src/msw/index.ts b/packages/backend-test-utils/src/msw/index.ts index a339721ba5..fa6a37445f 100644 --- a/packages/backend-test-utils/src/msw/index.ts +++ b/packages/backend-test-utils/src/msw/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export { setupMswHandlers } from './setupRequestMockHandlers'; +export { registerMswTestHooks } from './registerMswTestHooks'; diff --git a/packages/backend-test-utils/src/msw/setupRequestMockHandlers.ts b/packages/backend-test-utils/src/msw/registerMswTestHooks.ts similarity index 95% rename from packages/backend-test-utils/src/msw/setupRequestMockHandlers.ts rename to packages/backend-test-utils/src/msw/registerMswTestHooks.ts index e123bc91c0..4e26c38321 100644 --- a/packages/backend-test-utils/src/msw/setupRequestMockHandlers.ts +++ b/packages/backend-test-utils/src/msw/registerMswTestHooks.ts @@ -19,7 +19,7 @@ * @public * @param worker - service worker */ -export function setupMswHandlers(worker: { +export function registerMswTestHooks(worker: { listen: (t: any) => void; close: () => void; resetHandlers: () => void; diff --git a/packages/cli/src/commands/versions/bump.test.ts b/packages/cli/src/commands/versions/bump.test.ts index c7f8b7ed0c..b8677a48c5 100644 --- a/packages/cli/src/commands/versions/bump.test.ts +++ b/packages/cli/src/commands/versions/bump.test.ts @@ -18,7 +18,7 @@ import fs from 'fs-extra'; import { Command } from 'commander'; import * as runObj from '../../lib/run'; import bump, { bumpBackstageJsonVersion, createVersionFinder } from './bump'; -import { setupMswHandlers, withLogCollector } from '@backstage/test-utils'; +import { registerMswTestHooks, withLogCollector } from '@backstage/test-utils'; import { YarnInfoInspectData } from '../../lib/versioning/packages'; import { setupServer } from 'msw/node'; import { rest } from 'msw'; @@ -153,7 +153,7 @@ describe('bump', () => { }); const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); it('should bump backstage dependencies', async () => { mockDir.setContent({ diff --git a/packages/cli/templates/default-plugin/src/components/ExampleComponent/ExampleComponent.test.tsx.hbs b/packages/cli/templates/default-plugin/src/components/ExampleComponent/ExampleComponent.test.tsx.hbs index 9db62feebc..c79977f301 100644 --- a/packages/cli/templates/default-plugin/src/components/ExampleComponent/ExampleComponent.test.tsx.hbs +++ b/packages/cli/templates/default-plugin/src/components/ExampleComponent/ExampleComponent.test.tsx.hbs @@ -4,14 +4,14 @@ import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { screen } from '@testing-library/react'; import { - setupRequestMockHandlers, + registerMswTestHooks, renderInTestApp, } from '@backstage/test-utils'; describe('ExampleComponent', () => { const server = setupServer(); // Enable sane handlers for network requests - setupRequestMockHandlers(server); + registerMswTestHooks(server); // setup mock response beforeEach(() => { diff --git a/packages/config-loader/src/sources/RemoteConfigSource.test.ts b/packages/config-loader/src/sources/RemoteConfigSource.test.ts index 5fb16bf0c8..e825bf3434 100644 --- a/packages/config-loader/src/sources/RemoteConfigSource.test.ts +++ b/packages/config-loader/src/sources/RemoteConfigSource.test.ts @@ -15,14 +15,14 @@ */ import { rest } from 'msw'; -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { setupServer } from 'msw/node'; import { RemoteConfigSource } from './RemoteConfigSource'; import { readN } from './__testUtils__/testUtils'; describe('RemoteConfigSource', () => { const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); it('should load config from a remote URL', async () => { worker.use( diff --git a/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.test.ts b/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.test.ts index 698c9930b7..0143aa2ded 100644 --- a/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.test.ts +++ b/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.test.ts @@ -19,13 +19,13 @@ import MockOAuthApi from '../../OAuthRequestApi/MockOAuthApi'; import { UrlPatternDiscovery } from '../../DiscoveryApi'; import { ConfigReader } from '@backstage/config'; import { microsoftAuthApiRef } from '@backstage/core-plugin-api'; -import { setupMswHandlers } from '@backstage/test-utils'; +import { registerMswTestHooks } from '@backstage/test-utils'; import { setupServer } from 'msw/node'; import { rest } from 'msw'; describe('MicrosoftAuth', () => { const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); const microsoftAuth = MicrosoftAuth.create({ configApi: new ConfigReader(undefined), oauthRequestApi: new MockOAuthApi(), diff --git a/packages/core-app-api/src/lib/AuthConnector/DefaultAuthConnector.test.ts b/packages/core-app-api/src/lib/AuthConnector/DefaultAuthConnector.test.ts index d4bd136201..60c4a3b8d9 100644 --- a/packages/core-app-api/src/lib/AuthConnector/DefaultAuthConnector.test.ts +++ b/packages/core-app-api/src/lib/AuthConnector/DefaultAuthConnector.test.ts @@ -18,7 +18,7 @@ import { DefaultAuthConnector } from './DefaultAuthConnector'; import MockOAuthApi from '../../apis/implementations/OAuthRequestApi/MockOAuthApi'; import * as loginPopup from '../loginPopup'; import { UrlPatternDiscovery } from '../../apis'; -import { setupMswHandlers } from '@backstage/test-utils'; +import { registerMswTestHooks } from '@backstage/test-utils'; import { setupServer } from 'msw/node'; import { rest } from 'msw'; import { ConfigReader } from '@backstage/config'; @@ -53,7 +53,7 @@ const defaultOptions = { describe('DefaultAuthConnector', () => { const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); afterEach(() => { jest.resetAllMocks(); diff --git a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts index 4780b174e0..7eebc13d56 100644 --- a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts +++ b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { setupMswHandlers } from '@backstage/test-utils'; +import { registerMswTestHooks } from '@backstage/test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { @@ -60,7 +60,7 @@ describe('ProxiedSignInIdentity', () => { afterEach(() => jest.useRealTimers()); const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); it('runs the happy path', async () => { const getBaseUrl = jest.fn(); diff --git a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.test.tsx b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.test.tsx index 3cfde3d0f0..e4e65b613f 100644 --- a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.test.tsx +++ b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.test.tsx @@ -20,7 +20,7 @@ import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { TestApiProvider, - setupMswHandlers, + registerMswTestHooks, wrapInTestApp, } from '@backstage/test-utils'; import { ProxiedSignInPage } from './ProxiedSignInPage'; @@ -28,7 +28,7 @@ import { discoveryApiRef } from '@backstage/core-plugin-api'; describe('ProxiedSignInPage', () => { const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); const Subject = wrapInTestApp(
      authenticated
      , { components: { diff --git a/packages/create-app/src/lib/tasks.test.ts b/packages/create-app/src/lib/tasks.test.ts index f26c3306f1..deba27273c 100644 --- a/packages/create-app/src/lib/tasks.test.ts +++ b/packages/create-app/src/lib/tasks.test.ts @@ -31,7 +31,7 @@ import { } from './tasks'; import { createMockDirectory, - setupMswHandlers, + registerMswTestHooks, } from '@backstage/backend-test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; @@ -423,7 +423,7 @@ describe('tasks', () => { describe('fetchYarnLockSeedTask', () => { const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); it('should fetch the yarn.lock seed file', async () => { worker.use( diff --git a/packages/frontend-test-utils/api-report.md b/packages/frontend-test-utils/api-report.md index 7c8f5a5837..9629e13bfa 100644 --- a/packages/frontend-test-utils/api-report.md +++ b/packages/frontend-test-utils/api-report.md @@ -18,9 +18,9 @@ import { MockFetchApiOptions } from '@backstage/test-utils'; import { MockPermissionApi } from '@backstage/test-utils'; import { MockStorageApi } from '@backstage/test-utils'; import { MockStorageBucket } from '@backstage/test-utils'; +import { registerMswTestHooks } from '@backstage/test-utils'; import { RenderResult } from '@testing-library/react'; import { RouteRef } from '@backstage/frontend-plugin-api'; -import { setupMswHandlers as setupRequestMockHandlers } from '@backstage/test-utils'; import { TestApiProvider } from '@backstage/test-utils'; import { TestApiProviderProps } from '@backstage/test-utils'; import { TestApiRegistry } from '@backstage/test-utils'; @@ -73,13 +73,20 @@ export { MockStorageApi }; export { MockStorageBucket }; +export { registerMswTestHooks }; + // @public export function renderInTestApp( element: JSX.Element, options?: TestAppOptions, ): RenderResult; -export { setupRequestMockHandlers }; +// @public @deprecated (undocumented) +export function setupRequestMockHandlers(worker: { + listen: (t: any) => void; + close: () => void; + resetHandlers: () => void; +}): void; export { TestApiProvider }; diff --git a/packages/frontend-test-utils/src/deprecated.ts b/packages/frontend-test-utils/src/deprecated.ts new file mode 100644 index 0000000000..1b67f73e6b --- /dev/null +++ b/packages/frontend-test-utils/src/deprecated.ts @@ -0,0 +1,29 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { registerMswTestHooks } from '@backstage/test-utils'; + +/** + * @public + * @deprecated Use `registerMswTestHooks` from `@backstage/frontend-test-utils` instead. + */ +export function setupRequestMockHandlers(worker: { + listen: (t: any) => void; + close: () => void; + resetHandlers: () => void; +}): void { + registerMswTestHooks(worker); +} diff --git a/packages/frontend-test-utils/src/index.ts b/packages/frontend-test-utils/src/index.ts index 9d41699073..20f393706e 100644 --- a/packages/frontend-test-utils/src/index.ts +++ b/packages/frontend-test-utils/src/index.ts @@ -20,6 +20,7 @@ * Contains utilities that can be used when testing frontend features such as extensions. */ +export * from './deprecated'; export * from './apis'; export * from './app'; @@ -28,4 +29,4 @@ export type { TestApiProviderProps } from '@backstage/test-utils'; export { withLogCollector } from '@backstage/test-utils'; -export { setupMswHandlers as setupRequestMockHandlers } from '@backstage/test-utils'; +export { registerMswTestHooks } from '@backstage/test-utils'; diff --git a/packages/integration/src/bitbucket/core.test.ts b/packages/integration/src/bitbucket/core.test.ts index 6af974723f..f1b4e04f15 100644 --- a/packages/integration/src/bitbucket/core.test.ts +++ b/packages/integration/src/bitbucket/core.test.ts @@ -16,7 +16,7 @@ import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '../helpers'; +import { registerMswTestHooks } from '../helpers'; import { BitbucketIntegrationConfig } from './config'; import { getBitbucketDefaultBranch, @@ -27,7 +27,7 @@ import { describe('bitbucket core', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + registerMswTestHooks(worker); describe('getBitbucketRequestOptions', () => { it('inserts a token when needed', () => { diff --git a/packages/integration/src/bitbucketCloud/core.test.ts b/packages/integration/src/bitbucketCloud/core.test.ts index 3a342bae8b..56a53b924d 100644 --- a/packages/integration/src/bitbucketCloud/core.test.ts +++ b/packages/integration/src/bitbucketCloud/core.test.ts @@ -16,7 +16,7 @@ import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '../helpers'; +import { registerMswTestHooks } from '../helpers'; import { BitbucketCloudIntegrationConfig } from './config'; import { getBitbucketCloudDefaultBranch, @@ -27,7 +27,7 @@ import { describe('bitbucketCloud core', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + registerMswTestHooks(worker); describe('getBitbucketCloudRequestOptions', () => { it('insert basic auth when needed', () => { diff --git a/packages/integration/src/bitbucketServer/core.test.ts b/packages/integration/src/bitbucketServer/core.test.ts index b03a8dda83..c1c72b38dd 100644 --- a/packages/integration/src/bitbucketServer/core.test.ts +++ b/packages/integration/src/bitbucketServer/core.test.ts @@ -16,7 +16,7 @@ import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '../helpers'; +import { registerMswTestHooks } from '../helpers'; import { BitbucketServerIntegrationConfig } from './config'; import { getBitbucketServerDefaultBranch, @@ -27,7 +27,7 @@ import { describe('bitbucketServer core', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + registerMswTestHooks(worker); describe('getBitbucketServerRequestOptions', () => { it('inserts a token when needed', () => { diff --git a/packages/integration/src/gerrit/core.test.ts b/packages/integration/src/gerrit/core.test.ts index c2bf5d3ed2..35632c654e 100644 --- a/packages/integration/src/gerrit/core.test.ts +++ b/packages/integration/src/gerrit/core.test.ts @@ -17,7 +17,7 @@ import { rest } from 'msw'; import { setupServer } from 'msw/node'; import fetch from 'cross-fetch'; -import { setupRequestMockHandlers } from '../helpers'; +import { registerMswTestHooks } from '../helpers'; import { GerritIntegrationConfig } from './config'; import { buildGerritGitilesArchiveUrl, @@ -32,7 +32,7 @@ import { describe('gerrit core', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + registerMswTestHooks(worker); describe('buildGerritGitilesArchiveUrl', () => { const config: GerritIntegrationConfig = { diff --git a/packages/integration/src/gitea/core.test.ts b/packages/integration/src/gitea/core.test.ts index ac29c469b6..e9d7c592f0 100644 --- a/packages/integration/src/gitea/core.test.ts +++ b/packages/integration/src/gitea/core.test.ts @@ -15,7 +15,7 @@ */ import { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '../helpers'; +import { registerMswTestHooks } from '../helpers'; import { GiteaIntegrationConfig } from './config'; import { getGiteaArchiveUrl, @@ -28,7 +28,7 @@ import { describe('gitea core', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + registerMswTestHooks(worker); describe('getGiteaFileCatalogInfoCntentsUrl', () => { it('can create an url from arguments', () => { diff --git a/packages/integration/src/harness/core.test.ts b/packages/integration/src/harness/core.test.ts index 78ca68a98a..90f37aaa08 100644 --- a/packages/integration/src/harness/core.test.ts +++ b/packages/integration/src/harness/core.test.ts @@ -15,7 +15,7 @@ */ import { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '../helpers'; +import { registerMswTestHooks } from '../helpers'; import { HarnessIntegrationConfig } from './config'; import { getHarnessArchiveUrl, @@ -28,7 +28,7 @@ import { describe('Harness code core', () => { const worker = setupServer(); - setupRequestMockHandlers(worker); + registerMswTestHooks(worker); describe('getHarnessFileContentsUrl', () => { it('can create an url from arguments', () => { diff --git a/packages/integration/src/helpers.ts b/packages/integration/src/helpers.ts index b403155cc5..f56d360325 100644 --- a/packages/integration/src/helpers.ts +++ b/packages/integration/src/helpers.ts @@ -114,7 +114,7 @@ export function defaultScmResolveUrl(options: { * * @param worker - service worker */ -export function setupRequestMockHandlers(worker: { +export function registerMswTestHooks(worker: { listen: (t: any) => void; close: () => void; resetHandlers: () => void; diff --git a/packages/release-manifests/src/manifest.test.ts b/packages/release-manifests/src/manifest.test.ts index 8192bf867e..3c7657a83f 100644 --- a/packages/release-manifests/src/manifest.test.ts +++ b/packages/release-manifests/src/manifest.test.ts @@ -16,7 +16,7 @@ import { setupServer } from 'msw/node'; import { rest } from 'msw'; -import { setupMswHandlers } from '@backstage/test-utils'; +import { registerMswTestHooks } from '@backstage/test-utils'; import { getManifestByReleaseLine, getManifestByVersion, @@ -25,7 +25,7 @@ import { describe('Release Manifests', () => { const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); describe('getManifestByVersion', () => { it('should return a list of packages in a release', async () => { diff --git a/packages/test-utils/api-report.md b/packages/test-utils/api-report.md index 82816d931a..cc1c645387 100644 --- a/packages/test-utils/api-report.md +++ b/packages/test-utils/api-report.md @@ -197,6 +197,13 @@ export type MockStorageBucket = { [key: string]: any; }; +// @public +export function registerMswTestHooks(worker: { + listen: (t: any) => void; + close: () => void; + resetHandlers: () => void; +}): void; + // @public export function renderInTestApp( Component: ComponentType> | ReactNode, @@ -209,13 +216,6 @@ export function renderWithEffects( options?: Pick & LegacyRootOption, ): Promise; -// @public -export function setupMswHandlers(worker: { - listen: (t: any) => void; - close: () => void; - resetHandlers: () => void; -}): void; - // @public @deprecated (undocumented) export function setupRequestMockHandlers(worker: { listen: (t: any) => void; diff --git a/packages/test-utils/src/deprecated.ts b/packages/test-utils/src/deprecated.ts index 6825f9d0da..2033bbea2e 100644 --- a/packages/test-utils/src/deprecated.ts +++ b/packages/test-utils/src/deprecated.ts @@ -14,16 +14,16 @@ * limitations under the License. */ -import { setupMswHandlers } from './testUtils/msw'; +import { registerMswTestHooks } from './testUtils/msw'; /** * @public - * @deprecated Use `CreateMockDirectoryOptions` from `@backstage/backend-test-utils` instead. + * @deprecated Use `registerMswTestHooks` from `@backstage/test-utils` instead. */ export function setupRequestMockHandlers(worker: { listen: (t: any) => void; close: () => void; resetHandlers: () => void; }): void { - setupMswHandlers(worker); + registerMswTestHooks(worker); } diff --git a/packages/test-utils/src/testUtils/apis/FetchApi/MockFetchApi.test.ts b/packages/test-utils/src/testUtils/apis/FetchApi/MockFetchApi.test.ts index d51f4c7aee..d33036ca8c 100644 --- a/packages/test-utils/src/testUtils/apis/FetchApi/MockFetchApi.test.ts +++ b/packages/test-utils/src/testUtils/apis/FetchApi/MockFetchApi.test.ts @@ -16,12 +16,12 @@ import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupMswHandlers } from '../../msw'; +import { registerMswTestHooks } from '../../msw'; import { MockFetchApi } from './MockFetchApi'; describe('MockFetchApi', () => { const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); it('works with default constructor', async () => { worker.use( diff --git a/packages/test-utils/src/testUtils/msw/index.ts b/packages/test-utils/src/testUtils/msw/index.ts index a924676d06..fa6a37445f 100644 --- a/packages/test-utils/src/testUtils/msw/index.ts +++ b/packages/test-utils/src/testUtils/msw/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export { setupMswHandlers } from './setupMswHandlers'; +export { registerMswTestHooks } from './registerMswTestHooks'; diff --git a/packages/test-utils/src/testUtils/msw/setupMswHandlers.ts b/packages/test-utils/src/testUtils/msw/registerMswTestHooks.ts similarity index 95% rename from packages/test-utils/src/testUtils/msw/setupMswHandlers.ts rename to packages/test-utils/src/testUtils/msw/registerMswTestHooks.ts index e123bc91c0..4e26c38321 100644 --- a/packages/test-utils/src/testUtils/msw/setupMswHandlers.ts +++ b/packages/test-utils/src/testUtils/msw/registerMswTestHooks.ts @@ -19,7 +19,7 @@ * @public * @param worker - service worker */ -export function setupMswHandlers(worker: { +export function registerMswTestHooks(worker: { listen: (t: any) => void; close: () => void; resetHandlers: () => void; diff --git a/plugins/auth-backend-module-aws-alb-provider/src/helpers.test.ts b/plugins/auth-backend-module-aws-alb-provider/src/helpers.test.ts index 1b902246fb..81251584e9 100644 --- a/plugins/auth-backend-module-aws-alb-provider/src/helpers.test.ts +++ b/plugins/auth-backend-module-aws-alb-provider/src/helpers.test.ts @@ -19,7 +19,7 @@ import { JWTHeaderParameters, UnsecuredJWT } from 'jose'; import NodeCache from 'node-cache'; import { http, HttpResponse } from 'msw'; import { setupServer } from 'msw/node'; -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { PassportProfile } from '@backstage/plugin-auth-node'; import { makeProfileInfo, provisionKeyCache } from './helpers'; @@ -34,7 +34,7 @@ describe.each([ ], ])('helpers', (region, url) => { const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); const nodeCache = jest.fn() as unknown as NodeCache; nodeCache.set = jest.fn(); diff --git a/plugins/auth-backend-module-cloudflare-access-provider/src/helpers.test.ts b/plugins/auth-backend-module-cloudflare-access-provider/src/helpers.test.ts index a0b3335874..9efab07ba5 100644 --- a/plugins/auth-backend-module-cloudflare-access-provider/src/helpers.test.ts +++ b/plugins/auth-backend-module-cloudflare-access-provider/src/helpers.test.ts @@ -14,7 +14,10 @@ * limitations under the License. */ -import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { SignJWT, exportJWK, generateKeyPair } from 'jose'; import { HttpResponse, http } from 'msw'; @@ -86,7 +89,7 @@ describe('helpers', () => { const tokenFactory = new MockTokenFactory(); const cache = mockServices.cache.mock(); const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); beforeEach(() => { jest.clearAllMocks(); diff --git a/plugins/auth-backend-module-microsoft-provider/src/authenticator.test.ts b/plugins/auth-backend-module-microsoft-provider/src/authenticator.test.ts index fc392f68c2..74a7ab9974 100644 --- a/plugins/auth-backend-module-microsoft-provider/src/authenticator.test.ts +++ b/plugins/auth-backend-module-microsoft-provider/src/authenticator.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { encodeOAuthState, @@ -43,7 +43,7 @@ describe('microsoftAuthenticator', () => { const microsoftApi = new FakeMicrosoftAPI(); const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); let implementation: { domainHint: string | undefined; diff --git a/plugins/auth-backend-module-oidc-provider/src/authenticator.test.ts b/plugins/auth-backend-module-oidc-provider/src/authenticator.test.ts index 05ccebdf7d..38e134bcd0 100644 --- a/plugins/auth-backend-module-oidc-provider/src/authenticator.test.ts +++ b/plugins/auth-backend-module-oidc-provider/src/authenticator.test.ts @@ -23,7 +23,7 @@ import { } from '@backstage/plugin-auth-node'; import { oidcAuthenticator } from './authenticator'; import { setupServer } from 'msw/node'; -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { JWK, SignJWT, exportJWK, generateKeyPair } from 'jose'; import { rest } from 'msw'; @@ -38,7 +38,7 @@ describe('oidcAuthenticator', () => { const revokedTokenMap: Record = {}; const mswServer = setupServer(); - setupMswHandlers(mswServer); + registerMswTestHooks(mswServer); const issuerMetadata = { issuer: 'https://oidc.test', diff --git a/plugins/auth-backend-module-oidc-provider/src/module.test.ts b/plugins/auth-backend-module-oidc-provider/src/module.test.ts index 827ff9dd01..1bbb5c1cff 100644 --- a/plugins/auth-backend-module-oidc-provider/src/module.test.ts +++ b/plugins/auth-backend-module-oidc-provider/src/module.test.ts @@ -20,7 +20,7 @@ import { setupServer } from 'msw/node'; import { rest } from 'msw'; import { mockServices, - setupMswHandlers, + registerMswTestHooks, startTestBackend, } from '@backstage/backend-test-utils'; import { Server } from 'http'; @@ -35,7 +35,7 @@ describe('authModuleOidcProvider', () => { let publicKey: JWK; const mswServer = setupServer(); - setupMswHandlers(mswServer); + registerMswTestHooks(mswServer); const issuerMetadata = { issuer: 'https://oidc.test', diff --git a/plugins/auth-backend-module-pinniped-provider/src/authenticator.test.ts b/plugins/auth-backend-module-pinniped-provider/src/authenticator.test.ts index 4cef747416..359e497e5f 100644 --- a/plugins/auth-backend-module-pinniped-provider/src/authenticator.test.ts +++ b/plugins/auth-backend-module-pinniped-provider/src/authenticator.test.ts @@ -23,7 +23,7 @@ import { } from '@backstage/plugin-auth-node'; import { pinnipedAuthenticator } from './authenticator'; import { setupServer } from 'msw/node'; -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { JWK, SignJWT, exportJWK, generateKeyPair } from 'jose'; import { rest } from 'msw'; @@ -37,7 +37,7 @@ describe('pinnipedAuthenticator', () => { let publicKey: JWK; const mswServer = setupServer(); - setupMswHandlers(mswServer); + registerMswTestHooks(mswServer); const issuerMetadata = { issuer: 'https://pinniped.test', diff --git a/plugins/auth-backend-module-pinniped-provider/src/module.test.ts b/plugins/auth-backend-module-pinniped-provider/src/module.test.ts index a7cbcaa0da..e170c8d4ed 100644 --- a/plugins/auth-backend-module-pinniped-provider/src/module.test.ts +++ b/plugins/auth-backend-module-pinniped-provider/src/module.test.ts @@ -15,7 +15,7 @@ */ import { mockServices, - setupMswHandlers, + registerMswTestHooks, startTestBackend, } from '@backstage/backend-test-utils'; import { Server } from 'http'; @@ -32,7 +32,7 @@ describe('authModulePinnipedProvider', () => { let publicKey: JWK; const mswServer = setupServer(); - setupMswHandlers(mswServer); + registerMswTestHooks(mswServer); const issuerMetadata = { issuer: 'https://pinniped.test', diff --git a/plugins/auth-backend-module-vmware-cloud-provider/src/authenticator.test.ts b/plugins/auth-backend-module-vmware-cloud-provider/src/authenticator.test.ts index b5b335a112..0e363d4700 100644 --- a/plugins/auth-backend-module-vmware-cloud-provider/src/authenticator.test.ts +++ b/plugins/auth-backend-module-vmware-cloud-provider/src/authenticator.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { AuthResolverContext, @@ -37,7 +37,7 @@ jest.mock('uid2', () => jest.fn().mockReturnValue('sessionid')); describe('vmwareCloudAuthenticator', () => { const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); let oAuthState: OAuthState = { nonce: 'nonce', diff --git a/plugins/auth-backend/src/providers/bitbucketServer/provider.test.ts b/plugins/auth-backend/src/providers/bitbucketServer/provider.test.ts index 8e71b2e8bb..3756e00b38 100644 --- a/plugins/auth-backend/src/providers/bitbucketServer/provider.test.ts +++ b/plugins/auth-backend/src/providers/bitbucketServer/provider.test.ts @@ -22,7 +22,7 @@ import { BitbucketServerOAuthResult, } from './provider'; import { setupServer } from 'msw/node'; -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { rest } from 'msw'; import { AuthResolverContext } from '@backstage/plugin-auth-node'; @@ -131,7 +131,7 @@ describe('BitbucketServerAuthProvider', () => { describe('when transforming to type OAuthResponse', () => { const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); it('should map to a valid response', async () => { server.use(whoAmIHandler(), getUserHandler()); @@ -311,7 +311,7 @@ describe('BitbucketServerAuthProvider', () => { describe('when authenticating', () => { const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); it('should forward the refresh token', async () => { server.use(whoAmIHandler(), getUserHandler()); diff --git a/plugins/auth-backend/src/providers/oidc/provider.test.ts b/plugins/auth-backend/src/providers/oidc/provider.test.ts index 01c3e04bc5..89cf9c3b2c 100644 --- a/plugins/auth-backend/src/providers/oidc/provider.test.ts +++ b/plugins/auth-backend/src/providers/oidc/provider.test.ts @@ -13,7 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; import { LoggerService } from '@backstage/backend-plugin-api'; import { Config, ConfigReader } from '@backstage/config'; import { @@ -35,7 +38,7 @@ describe('oidc.create', () => { nonce: 'foo', }; const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); let publicKey: JWK; let tokenset: object; diff --git a/plugins/auth-node/src/identity/IdentityClient.test.ts b/plugins/auth-node/src/identity/IdentityClient.test.ts index beefe43173..418eb544ad 100644 --- a/plugins/auth-node/src/identity/IdentityClient.test.ts +++ b/plugins/auth-node/src/identity/IdentityClient.test.ts @@ -15,7 +15,7 @@ */ import { PluginEndpointDiscovery } from '@backstage/backend-common'; -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { decodeProtectedHeader, exportJWK, @@ -102,7 +102,7 @@ describe('IdentityClient', () => { let factory: FakeTokenFactory; const keyDurationSeconds = 5; - setupMswHandlers(server); + registerMswTestHooks(server); beforeEach(() => { client = IdentityClient.create({ discovery, issuer: mockBaseUrl }); diff --git a/plugins/catalog-backend-module-azure/src/lib/azure.test.ts b/plugins/catalog-backend-module-azure/src/lib/azure.test.ts index 9d153e630c..4839b625d2 100644 --- a/plugins/catalog-backend-module-azure/src/lib/azure.test.ts +++ b/plugins/catalog-backend-module-azure/src/lib/azure.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { codeSearch, CodeSearchResponse } from './azure'; @@ -26,7 +26,7 @@ import { ConfigReader } from '@backstage/config'; describe('azure', () => { const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); const createFixture = (host: string, token: string) => { const azureConfig = { diff --git a/plugins/catalog-backend-module-bitbucket-cloud/src/providers/BitbucketCloudEntityProvider.test.ts b/plugins/catalog-backend-module-bitbucket-cloud/src/providers/BitbucketCloudEntityProvider.test.ts index 1c6128ef9c..80d09f3e2f 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/src/providers/BitbucketCloudEntityProvider.test.ts +++ b/plugins/catalog-backend-module-bitbucket-cloud/src/providers/BitbucketCloudEntityProvider.test.ts @@ -20,7 +20,10 @@ import { TaskInvocationDefinition, TaskRunner, } from '@backstage/backend-tasks'; -import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; import { CatalogApi } from '@backstage/catalog-client'; import { Entity, LocationEntity } from '@backstage/catalog-model'; import { ConfigReader } from '@backstage/config'; @@ -59,7 +62,7 @@ const logger = mockServices.logger.mock(); const server = setupServer(); describe('BitbucketCloudEntityProvider', () => { - setupMswHandlers(server); + registerMswTestHooks(server); const simpleConfig = new ConfigReader({ catalog: { diff --git a/plugins/catalog-backend-module-bitbucket-server/src/lib/BitbucketServerClient.test.ts b/plugins/catalog-backend-module-bitbucket-server/src/lib/BitbucketServerClient.test.ts index 31ee011c23..db2a05d0b1 100644 --- a/plugins/catalog-backend-module-bitbucket-server/src/lib/BitbucketServerClient.test.ts +++ b/plugins/catalog-backend-module-bitbucket-server/src/lib/BitbucketServerClient.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { BitbucketServerIntegrationConfig } from '@backstage/integration'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; @@ -50,7 +50,7 @@ describe('BitbucketServerClient', () => { config: config, }); - setupMswHandlers(server); + registerMswTestHooks(server); it('listProjects', async () => { server.use( diff --git a/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerEntityProvider.test.ts b/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerEntityProvider.test.ts index fce1102aab..49b69f0fa6 100644 --- a/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerEntityProvider.test.ts +++ b/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerEntityProvider.test.ts @@ -19,7 +19,10 @@ import { TaskInvocationDefinition, TaskRunner, } from '@backstage/backend-tasks'; -import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { EntityProviderConnection } from '@backstage/plugin-catalog-node'; import { rest } from 'msw'; @@ -100,7 +103,7 @@ function setupStubs(projects: Project[], baseUrl: string) { } describe('BitbucketServerEntityProvider', () => { - setupMswHandlers(server); + registerMswTestHooks(server); afterEach(() => { jest.clearAllMocks(); }); diff --git a/plugins/catalog-backend-module-gerrit/src/providers/GerritEntityProvider.test.ts b/plugins/catalog-backend-module-gerrit/src/providers/GerritEntityProvider.test.ts index 0a5baba297..ee3555c7f9 100644 --- a/plugins/catalog-backend-module-gerrit/src/providers/GerritEntityProvider.test.ts +++ b/plugins/catalog-backend-module-gerrit/src/providers/GerritEntityProvider.test.ts @@ -19,7 +19,10 @@ import { TaskInvocationDefinition, TaskRunner, } from '@backstage/backend-tasks'; -import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { EntityProviderConnection } from '@backstage/plugin-catalog-node'; import fs from 'fs-extra'; @@ -54,7 +57,7 @@ class PersistingTaskRunner implements TaskRunner { const logger = mockServices.logger.mock(); describe('GerritEntityProvider', () => { - setupMswHandlers(server); + registerMswTestHooks(server); afterEach(() => { jest.clearAllMocks(); diff --git a/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.test.ts b/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.test.ts index 7b496a45c5..29c8cbc66d 100644 --- a/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.test.ts +++ b/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.test.ts @@ -34,7 +34,10 @@ jest.mock('@octokit/rest', () => { import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { GithubLocationAnalyzer } from './GithubLocationAnalyzer'; -import { setupMswHandlers, mockServices } from '@backstage/backend-test-utils'; +import { + registerMswTestHooks, + mockServices, +} from '@backstage/backend-test-utils'; import { setupServer } from 'msw/node'; import { rest } from 'msw'; import { ConfigReader } from '@backstage/config'; @@ -60,7 +63,7 @@ describe('GithubLocationAnalyzer', () => { }, }); - setupMswHandlers(server); + registerMswTestHooks(server); beforeEach(() => { server.use( diff --git a/plugins/catalog-backend-module-github/src/lib/github.test.ts b/plugins/catalog-backend-module-github/src/lib/github.test.ts index ac88a79bee..9eae9e1161 100644 --- a/plugins/catalog-backend-module-github/src/lib/github.test.ts +++ b/plugins/catalog-backend-module-github/src/lib/github.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { GroupEntity, UserEntity } from '@backstage/catalog-model'; import { graphql as graphqlOctokit } from '@octokit/graphql'; import { graphql as graphqlMsw } from 'msw'; @@ -39,7 +39,7 @@ describe('github', () => { const graphql = graphqlOctokit.defaults({ request: { fetch } }); const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); describe('getOrganizationUsers using defaultUserMapper', () => { it('reads members', async () => { diff --git a/plugins/catalog-backend-module-gitlab/src/GitLabDiscoveryProcessor.test.ts b/plugins/catalog-backend-module-gitlab/src/GitLabDiscoveryProcessor.test.ts index 10751ad615..d7ce338d6d 100644 --- a/plugins/catalog-backend-module-gitlab/src/GitLabDiscoveryProcessor.test.ts +++ b/plugins/catalog-backend-module-gitlab/src/GitLabDiscoveryProcessor.test.ts @@ -14,7 +14,10 @@ * limitations under the License. */ -import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { LocationSpec } from '@backstage/plugin-catalog-node'; import { rest, RestRequest } from 'msw'; @@ -154,7 +157,7 @@ function getProcessor({ } describe('GitlabDiscoveryProcessor', () => { - setupMswHandlers(server); + registerMswTestHooks(server); beforeAll(() => { jest.useFakeTimers(); diff --git a/plugins/catalog-backend-module-gitlab/src/lib/client.test.ts b/plugins/catalog-backend-module-gitlab/src/lib/client.test.ts index 212c5cd4a4..1eebe7d6e0 100644 --- a/plugins/catalog-backend-module-gitlab/src/lib/client.test.ts +++ b/plugins/catalog-backend-module-gitlab/src/lib/client.test.ts @@ -14,7 +14,10 @@ * limitations under the License. */ -import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { readGitLabIntegrationConfig } from '@backstage/integration'; import { setupServer } from 'msw/node'; @@ -24,7 +27,7 @@ import { GitLabClient, paginated } from './client'; import { GitLabGroup, GitLabUser } from './types'; const server = setupServer(...handlers); -setupMswHandlers(server); +registerMswTestHooks(server); describe('GitLabClient', () => { describe('isSelfManaged', () => { diff --git a/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.test.ts b/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.test.ts index c23a897df2..473e547a57 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.test.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.test.ts @@ -19,7 +19,10 @@ import { TaskInvocationDefinition, TaskRunner, } from '@backstage/backend-tasks'; -import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { EntityProviderConnection } from '@backstage/plugin-catalog-node'; import { DefaultEventsService } from '@backstage/plugin-events-node'; @@ -29,7 +32,7 @@ import * as mock from '../__testUtils__/mocks'; import { GitlabDiscoveryEntityProvider } from './GitlabDiscoveryEntityProvider'; const server = setupServer(...handlers); -setupMswHandlers(server); +registerMswTestHooks(server); afterEach(() => jest.clearAllMocks()); class PersistingTaskRunner implements TaskRunner { diff --git a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.test.ts b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.test.ts index 2fb8a6c839..9706384ff0 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.test.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.test.ts @@ -19,7 +19,10 @@ import { TaskInvocationDefinition, TaskRunner, } from '@backstage/backend-tasks'; -import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { EntityProviderConnection } from '@backstage/plugin-catalog-node'; import { DefaultEventsService } from '@backstage/plugin-events-node'; @@ -30,7 +33,7 @@ import { GroupNameTransformerOptions } from '../lib/types'; import { GitlabOrgDiscoveryEntityProvider } from './GitlabOrgDiscoveryEntityProvider'; const server = setupServer(...handlers); -setupMswHandlers(server); +registerMswTestHooks(server); afterEach(() => jest.clearAllMocks()); class PersistingTaskRunner implements TaskRunner { diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.test.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.test.ts index a58db08bfc..624b6e42b0 100644 --- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.test.ts +++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.test.ts @@ -15,7 +15,7 @@ */ import { TokenCredential } from '@azure/identity'; -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { MicrosoftGraphClient } from './client'; @@ -27,7 +27,7 @@ describe('MicrosoftGraphClient', () => { let client: MicrosoftGraphClient; const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); beforeEach(() => { tokenCredential.getToken.mockResolvedValue({ diff --git a/plugins/catalog-backend-module-puppetdb/src/puppet/read.test.ts b/plugins/catalog-backend-module-puppetdb/src/puppet/read.test.ts index 05ae65f85c..8ad4c2b850 100644 --- a/plugins/catalog-backend-module-puppetdb/src/puppet/read.test.ts +++ b/plugins/catalog-backend-module-puppetdb/src/puppet/read.test.ts @@ -20,14 +20,14 @@ import { PuppetDbEntityProviderConfig, } from '../providers'; import { DEFAULT_NAMESPACE } from '@backstage/catalog-model'; -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { ANNOTATION_PUPPET_CERTNAME, ENDPOINT_FACTSETS } from './constants'; describe('readPuppetNodes', () => { const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); beforeEach(() => { jest.clearAllMocks(); diff --git a/plugins/catalog-backend/src/modules/core/UrlReaderProcessor.test.ts b/plugins/catalog-backend/src/modules/core/UrlReaderProcessor.test.ts index 2d46ce2256..7d1578db00 100644 --- a/plugins/catalog-backend/src/modules/core/UrlReaderProcessor.test.ts +++ b/plugins/catalog-backend/src/modules/core/UrlReaderProcessor.test.ts @@ -15,7 +15,10 @@ */ import { UrlReader, UrlReaders } from '@backstage/backend-common'; -import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; @@ -36,7 +39,7 @@ describe('UrlReaderProcessor', () => { set: jest.fn(), }; const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts b/plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts index 8dc22f6ea0..aee65bd2e1 100644 --- a/plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts +++ b/plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts @@ -18,7 +18,7 @@ import { PluginEndpointDiscovery, TokenManager, } from '@backstage/backend-common'; -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { Entity } from '@backstage/catalog-model'; import { DefaultCatalogCollator } from './DefaultCatalogCollator'; import { setupServer } from 'msw/node'; @@ -62,7 +62,7 @@ describe('DefaultCatalogCollator', () => { let mockTokenManager: jest.Mocked; let collator: DefaultCatalogCollator; - setupMswHandlers(server); + registerMswTestHooks(server); beforeAll(() => { mockDiscoveryApi = { getBaseUrl: jest.fn().mockResolvedValue('http://localhost:7007'), diff --git a/plugins/catalog-import/src/api/AzureRepoApiClient.test.ts b/plugins/catalog-import/src/api/AzureRepoApiClient.test.ts index 65ef2c035e..9f058dc744 100644 --- a/plugins/catalog-import/src/api/AzureRepoApiClient.test.ts +++ b/plugins/catalog-import/src/api/AzureRepoApiClient.test.ts @@ -26,7 +26,7 @@ import { RepoApiClient, } from './AzureRepoApiClient'; import { setupServer } from 'msw/node'; -import { setupMswHandlers } from '@backstage/test-utils'; +import { registerMswTestHooks } from '@backstage/test-utils'; function mockRepoEndpoint() { return rest.get( @@ -153,7 +153,7 @@ function mockPrEndpoint() { describe('RepoApiClient', () => { const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); const testToken = new Date().toString(); const sut = new RepoApiClient({ project: 'project', diff --git a/plugins/catalog-import/src/api/CatalogImportClient.test.ts b/plugins/catalog-import/src/api/CatalogImportClient.test.ts index 67a019cc1b..fa646e3ca4 100644 --- a/plugins/catalog-import/src/api/CatalogImportClient.test.ts +++ b/plugins/catalog-import/src/api/CatalogImportClient.test.ts @@ -57,7 +57,7 @@ import { ConfigReader, UrlPatternDiscovery } from '@backstage/core-app-api'; import { ScmIntegrations } from '@backstage/integration'; import { ScmAuthApi } from '@backstage/integration-react'; import { CatalogApi } from '@backstage/plugin-catalog-react'; -import { MockFetchApi, setupMswHandlers } from '@backstage/test-utils'; +import { MockFetchApi, registerMswTestHooks } from '@backstage/test-utils'; import { Octokit } from '@octokit/rest'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; @@ -70,7 +70,7 @@ import { describe('CatalogImportClient', () => { const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); const mockBaseUrl = 'http://backstage:9191/api/catalog'; const discoveryApi = UrlPatternDiscovery.compile(mockBaseUrl); diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts index 7b61a22009..5edb8845d4 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts @@ -38,7 +38,7 @@ import { ServiceMock, mockCredentials, mockServices, - setupMswHandlers, + registerMswTestHooks, startTestBackend, } from '@backstage/backend-test-utils'; import { rest } from 'msw'; @@ -508,7 +508,7 @@ describe('API integration tests', () => { describe('/proxy', () => { const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); beforeEach(() => { worker.use( diff --git a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts index 7a2aba2977..3491268d39 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts @@ -26,7 +26,10 @@ import { KubernetesFanOutHandler } from './KubernetesFanOutHandler'; import { KubernetesClientBasedFetcher } from './KubernetesFetcher'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; import { FetchResponse, KubernetesRequestAuth, @@ -1125,7 +1128,7 @@ describe('KubernetesFanOutHandler', () => { describe('with a real fetcher', () => { const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); it('fetch error short-circuits requests to a single cluster, recovering across the fleet', async () => { const pods = [{ metadata: { name: 'pod-name' } }]; diff --git a/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts b/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts index e7196d9dc6..8666e0ef16 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts @@ -28,7 +28,7 @@ import { setupServer } from 'msw/node'; import { createMockDirectory, mockServices, - setupMswHandlers, + registerMswTestHooks, } from '@backstage/backend-test-utils'; import { Config } from '@kubernetes/client-node'; @@ -71,7 +71,7 @@ const POD_METRICS_FIXTURE = [ describe('KubernetesFetcher', () => { const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); const labels = (req: MockedRequest): object => { const selectorParam = req.url.searchParams.get('labelSelector'); diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts index 45a131439b..fe4feaee11 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts @@ -20,7 +20,7 @@ import { errorHandler } from '@backstage/backend-common'; import { createMockDirectory, mockServices, - setupMswHandlers, + registerMswTestHooks, } from '@backstage/backend-test-utils'; import { NotFoundError } from '@backstage/errors'; import { @@ -90,7 +90,7 @@ describe('KubernetesProxy', () => { getExternalBaseUrl: jest.fn(), }; - setupMswHandlers(worker); + registerMswTestHooks(worker); const buildMockRequest = (clusterName: any, path: string): Request => { const req = getMockReq({ diff --git a/plugins/kubernetes-node/src/auth/PinnipedHelper.test.ts b/plugins/kubernetes-node/src/auth/PinnipedHelper.test.ts index f882d2373c..24cd459fde 100644 --- a/plugins/kubernetes-node/src/auth/PinnipedHelper.test.ts +++ b/plugins/kubernetes-node/src/auth/PinnipedHelper.test.ts @@ -18,7 +18,7 @@ import { ExtendedHttpServer } from '@backstage/backend-app-api'; import { ClusterDetails } from '../types'; import { mockServices, - setupMswHandlers, + registerMswTestHooks, startTestBackend, } from '@backstage/backend-test-utils'; import { createBackendModule } from '@backstage/backend-plugin-api'; @@ -43,7 +43,7 @@ describe('Pinniped - tokenCredentialRequest', () => { const logger = loggerToWinstonLogger(mockServices.logger.mock()); let httpsRequest: jest.SpyInstance; const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); beforeAll(() => { httpsRequest = jest.spyOn( diff --git a/plugins/kubernetes-react/src/api/KubernetesBackendClient.test.ts b/plugins/kubernetes-react/src/api/KubernetesBackendClient.test.ts index eecaed20b6..4698f01dfe 100644 --- a/plugins/kubernetes-react/src/api/KubernetesBackendClient.test.ts +++ b/plugins/kubernetes-react/src/api/KubernetesBackendClient.test.ts @@ -19,7 +19,7 @@ import { KubernetesBackendClient } from './KubernetesBackendClient'; import { rest } from 'msw'; import { UrlPatternDiscovery } from '@backstage/core-app-api'; import { setupServer } from 'msw/node'; -import { MockFetchApi, setupMswHandlers } from '@backstage/test-utils'; +import { MockFetchApi, registerMswTestHooks } from '@backstage/test-utils'; import { CustomObjectsByEntityRequest, KubernetesRequestBody, @@ -36,7 +36,7 @@ describe('KubernetesBackendClient', () => { }; let mockResponse: ObjectsByEntityResponse; const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); const identityApi = { getCredentials: jest.fn(), diff --git a/plugins/notifications-node/src/service/DefaultNotificationService.test.ts b/plugins/notifications-node/src/service/DefaultNotificationService.test.ts index 843852af21..3872f898ee 100644 --- a/plugins/notifications-node/src/service/DefaultNotificationService.test.ts +++ b/plugins/notifications-node/src/service/DefaultNotificationService.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { setupMswHandlers } from '@backstage/test-utils'; +import { registerMswTestHooks } from '@backstage/test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { NotificationPayload } from '@backstage/plugin-notifications-common'; @@ -32,7 +32,7 @@ const testNotification: NotificationPayload = { describe('DefaultNotificationService', () => { const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); const discovery = mockServices.discovery.mock({ getBaseUrl: jest.fn().mockResolvedValue('http://example.com'), diff --git a/plugins/notifications/src/api/NotificationsClient.test.ts b/plugins/notifications/src/api/NotificationsClient.test.ts index b4be073738..f378269e45 100644 --- a/plugins/notifications/src/api/NotificationsClient.test.ts +++ b/plugins/notifications/src/api/NotificationsClient.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { MockFetchApi, setupMswHandlers } from '@backstage/test-utils'; +import { MockFetchApi, registerMswTestHooks } from '@backstage/test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { NotificationsClient } from './NotificationsClient'; @@ -33,7 +33,7 @@ const testNotification: Partial = { }; describe('NotificationsClient', () => { - setupMswHandlers(server); + registerMswTestHooks(server); const mockBaseUrl = 'http://backstage/api/notifications'; const discoveryApi = { getBaseUrl: async () => mockBaseUrl }; const fetchApi = new MockFetchApi(); diff --git a/plugins/permission-node/src/ServerPermissionClient.test.ts b/plugins/permission-node/src/ServerPermissionClient.test.ts index b09c25eeb7..529b0db907 100644 --- a/plugins/permission-node/src/ServerPermissionClient.test.ts +++ b/plugins/permission-node/src/ServerPermissionClient.test.ts @@ -25,7 +25,7 @@ import { import { mockCredentials, mockServices, - setupMswHandlers, + registerMswTestHooks, } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { setupServer } from 'msw/node'; @@ -54,7 +54,7 @@ const config = new ConfigReader({ }); describe('ServerPermissionClient', () => { - setupMswHandlers(server); + registerMswTestHooks(server); const discovery = mockServices.discovery.mock(); diff --git a/plugins/proxy-backend/src/service/router.config.test.ts b/plugins/proxy-backend/src/service/router.config.test.ts index 3f11faea46..be26ddb9bc 100644 --- a/plugins/proxy-backend/src/service/router.config.test.ts +++ b/plugins/proxy-backend/src/service/router.config.test.ts @@ -19,7 +19,7 @@ import { createServiceFactory, } from '@backstage/backend-plugin-api'; import { - setupMswHandlers, + registerMswTestHooks, startTestBackend, } from '@backstage/backend-test-utils'; import { @@ -36,7 +36,7 @@ import fetch from 'node-fetch'; describe('createRouter reloadable configuration', () => { const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); it('should be able to observe the config', async () => { // Grab the subscriber function and use mutable config data to mock a config file change diff --git a/plugins/proxy-backend/src/service/router.credentials.test.ts b/plugins/proxy-backend/src/service/router.credentials.test.ts index aede6bb353..ac32179ef3 100644 --- a/plugins/proxy-backend/src/service/router.credentials.test.ts +++ b/plugins/proxy-backend/src/service/router.credentials.test.ts @@ -20,7 +20,7 @@ import { } from '@backstage/backend-app-api'; import { mockServices, - setupMswHandlers, + registerMswTestHooks, startTestBackend, } from '@backstage/backend-test-utils'; import { ResponseError } from '@backstage/errors'; @@ -34,7 +34,7 @@ import fetch from 'node-fetch'; describe('credentials', () => { const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); it('handles all valid credentials settings', async () => { const config = { diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.examples.test.ts b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.examples.test.ts index ef745fbd18..6b4b77879e 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.examples.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.examples.test.ts @@ -29,7 +29,7 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { import { createPublishBitbucketCloudAction } from './bitbucketCloud'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; @@ -66,7 +66,7 @@ describe('publish:bitbucketCloud', () => { }, }); const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.test.ts b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.test.ts index 57215ac06d..6cac8a0e1c 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.test.ts @@ -29,7 +29,7 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { import { createPublishBitbucketCloudAction } from './bitbucketCloud'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; @@ -56,7 +56,7 @@ describe('publish:bitbucketCloud', () => { }, }); const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.examples.test.ts b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.examples.test.ts index 6a4f82066e..3e306c4065 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.examples.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.examples.test.ts @@ -21,7 +21,7 @@ import yaml from 'yaml'; import { examples } from './bitbucketCloudPipelinesRun.examples'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; describe('bitbucket:pipelines:run', () => { @@ -48,7 +48,7 @@ describe('bitbucket:pipelines:run', () => { build_number: 1, }; const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.test.ts b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.test.ts index be8500895a..edabe2a7ba 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.test.ts @@ -16,7 +16,7 @@ import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { createBitbucketPipelinesRunAction } from './bitbucketCloudPipelinesRun'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; @@ -48,7 +48,7 @@ describe('bitbucket:pipelines:run', () => { build_number: 1, }; const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); beforeEach(() => { jest.clearAllMocks(); diff --git a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.examples.test.ts b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.examples.test.ts index 8e6356df18..101379d1e6 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.examples.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.examples.test.ts @@ -29,7 +29,7 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { import { createPublishBitbucketServerAction } from './bitbucketServer'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import yaml from 'yaml'; @@ -68,7 +68,7 @@ describe('publish:bitbucketServer', () => { }, }); const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.test.ts b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.test.ts index fb7d17c0ba..250b3f9b54 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.test.ts @@ -29,7 +29,7 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { import { createPublishBitbucketServerAction } from './bitbucketServer'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; @@ -66,7 +66,7 @@ describe('publish:bitbucketServer', () => { }, }); const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.examples.test.ts b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.examples.test.ts index 0bc6d1464b..b83ba2be55 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.examples.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.examples.test.ts @@ -29,7 +29,7 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { import { createPublishBitbucketServerPullRequestAction } from './bitbucketServerPullRequest'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import yaml from 'yaml'; @@ -191,7 +191,7 @@ describe('publish:bitbucketServer:pull-request', () => { }; const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.test.ts b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.test.ts index 61adf0e3c8..37df535fec 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.test.ts @@ -29,7 +29,7 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { import { createPublishBitbucketServerPullRequestAction } from './bitbucketServerPullRequest'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; @@ -221,7 +221,7 @@ describe('publish:bitbucketServer:pull-request', () => { ]; const server = setupServer(); - setupRequestMockHandlers(server); + registerMswTestHooks(server); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.examples.test.ts b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.examples.test.ts index 964b2f207c..d452f2e11f 100644 --- a/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.examples.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.examples.test.ts @@ -29,7 +29,7 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { import { createPublishBitbucketAction } from './bitbucket'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; @@ -67,7 +67,7 @@ describe('publish:bitbucket', () => { }, }); const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.test.ts b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.test.ts index dddbcde828..654b0fffcb 100644 --- a/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.test.ts @@ -28,7 +28,7 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { import { createPublishBitbucketAction } from './bitbucket'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; @@ -63,7 +63,7 @@ describe('publish:bitbucket', () => { }, }); const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.examples.test.ts b/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.examples.test.ts index 3aff044b89..36ae750723 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.examples.test.ts +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.examples.test.ts @@ -20,7 +20,7 @@ import { ScmIntegrations } from '@backstage/integration'; import { createMockDirectory, mockServices, - setupMswHandlers, + registerMswTestHooks, } from '@backstage/backend-test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; @@ -32,7 +32,7 @@ import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test- describe('confluence:transform:markdown examples', () => { const baseUrl = `https://confluence.example.com`; const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); const config = new ConfigReader({ confluence: { diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.test.ts b/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.test.ts index 5958f1407b..4c3c6b891f 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.test.ts +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.test.ts @@ -21,7 +21,7 @@ import { ScmIntegrations } from '@backstage/integration'; import { createMockDirectory, mockServices, - setupMswHandlers, + registerMswTestHooks, } from '@backstage/backend-test-utils'; import type { ActionContext } from '@backstage/plugin-scaffolder-node'; import { rest } from 'msw'; @@ -31,7 +31,7 @@ import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test- describe('confluence:transform:markdown', () => { const baseUrl = `https://nodomain.confluence.com`; const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); const config = new ConfigReader({ confluence: { 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 b91cc2d84d..c102353209 100644 --- a/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.test.ts +++ b/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.test.ts @@ -30,7 +30,7 @@ import path from 'path'; import { createPublishGerritAction } from './gerrit'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; @@ -61,7 +61,7 @@ describe('publish:gerrit', () => { }, }); const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts index ab4d4641d0..7812ded60a 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts @@ -18,7 +18,7 @@ import { ConfigReader } from '@backstage/config'; import { createPublishGiteaAction } from './gitea'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; import { rest } from 'msw'; -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { setupServer } from 'msw/node'; @@ -62,7 +62,7 @@ describe('publish:gitea', () => { }); const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-sentry/src/actions/createProject.test.ts b/plugins/scaffolder-backend-module-sentry/src/actions/createProject.test.ts index 9eef522ddc..48c437d2a4 100644 --- a/plugins/scaffolder-backend-module-sentry/src/actions/createProject.test.ts +++ b/plugins/scaffolder-backend-module-sentry/src/actions/createProject.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { ConfigReader } from '@backstage/config'; import { InputError } from '@backstage/errors'; @@ -27,7 +27,7 @@ import { createSentryCreateProjectAction } from './createProject'; describe('sentry:project:create action', () => { const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); const createScaffolderConfig = (configData: JsonObject = {}) => ({ config: new ConfigReader({ diff --git a/plugins/scaffolder/src/api.test.ts b/plugins/scaffolder/src/api.test.ts index 1da440ab7b..805828a9fe 100644 --- a/plugins/scaffolder/src/api.test.ts +++ b/plugins/scaffolder/src/api.test.ts @@ -16,7 +16,7 @@ import { ConfigReader } from '@backstage/core-app-api'; import { ScmIntegrations } from '@backstage/integration'; -import { MockFetchApi, setupMswHandlers } from '@backstage/test-utils'; +import { MockFetchApi, registerMswTestHooks } from '@backstage/test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { ScaffolderClient } from './api'; @@ -30,7 +30,7 @@ const mockFetchEventSource = fetchEventSource as jest.MockedFunction< const server = setupServer(); describe('api', () => { - setupMswHandlers(server); + registerMswTestHooks(server); const mockBaseUrl = 'http://backstage/api'; const discoveryApi = { getBaseUrl: async () => mockBaseUrl }; diff --git a/plugins/search-backend-module-catalog/src/collators/DefaultCatalogCollatorFactory.test.ts b/plugins/search-backend-module-catalog/src/collators/DefaultCatalogCollatorFactory.test.ts index 0d9320f3dd..4bdb8a5ae9 100644 --- a/plugins/search-backend-module-catalog/src/collators/DefaultCatalogCollatorFactory.test.ts +++ b/plugins/search-backend-module-catalog/src/collators/DefaultCatalogCollatorFactory.test.ts @@ -18,7 +18,7 @@ import { PluginEndpointDiscovery, TokenManager, } from '@backstage/backend-common'; -import { setupMswHandlers } from '@backstage/backend-test-utils'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { Entity } from '@backstage/catalog-model'; import { ConfigReader } from '@backstage/config'; import { TestPipeline } from '@backstage/plugin-search-backend-node'; @@ -74,7 +74,7 @@ describe('DefaultCatalogCollatorFactory', () => { tokenManager: mockTokenManager, }; - setupMswHandlers(server); + registerMswTestHooks(server); beforeEach(() => { server.use( diff --git a/plugins/search-backend-module-explore/src/collators/ToolDocumentCollatorFactory.test.ts b/plugins/search-backend-module-explore/src/collators/ToolDocumentCollatorFactory.test.ts index e69b48b1c3..82f5cffbc0 100644 --- a/plugins/search-backend-module-explore/src/collators/ToolDocumentCollatorFactory.test.ts +++ b/plugins/search-backend-module-explore/src/collators/ToolDocumentCollatorFactory.test.ts @@ -19,7 +19,10 @@ import { } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { TestPipeline } from '@backstage/plugin-search-backend-node'; -import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { Readable } from 'stream'; @@ -79,7 +82,7 @@ describe('ToolDocumentCollatorFactory', () => { let collator: Readable; const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); beforeEach(async () => { factory = ToolDocumentCollatorFactory.fromConfig(config, options); diff --git a/plugins/search-backend-module-stack-overflow-collator/src/collators/StackOverflowQuestionsCollatorFactory.test.ts b/plugins/search-backend-module-stack-overflow-collator/src/collators/StackOverflowQuestionsCollatorFactory.test.ts index 3698f7c8f6..90b324866f 100644 --- a/plugins/search-backend-module-stack-overflow-collator/src/collators/StackOverflowQuestionsCollatorFactory.test.ts +++ b/plugins/search-backend-module-stack-overflow-collator/src/collators/StackOverflowQuestionsCollatorFactory.test.ts @@ -17,7 +17,10 @@ import { StackOverflowQuestionsCollatorFactory, StackOverflowQuestionsCollatorFactoryOptions, } from './StackOverflowQuestionsCollatorFactory'; -import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; import { TestPipeline } from '@backstage/plugin-search-backend-node'; import { ConfigReader } from '@backstage/config'; import { Readable } from 'stream'; @@ -92,7 +95,7 @@ describe('StackOverflowQuestionsCollatorFactory', () => { describe('getCollator', () => { const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); it('returns a readable stream', async () => { const factory = StackOverflowQuestionsCollatorFactory.fromConfig( diff --git a/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.test.ts b/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.test.ts index a2e8cc9992..476c07ff48 100644 --- a/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.test.ts +++ b/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.test.ts @@ -20,7 +20,10 @@ import { import { Entity } from '@backstage/catalog-model'; import { ConfigReader } from '@backstage/config'; import { TestPipeline } from '@backstage/plugin-search-backend-node'; -import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { Readable } from 'stream'; @@ -103,7 +106,7 @@ describe('DefaultTechDocsCollatorFactory', () => { let collator: Readable; const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); beforeEach(async () => { factory = DefaultTechDocsCollatorFactory.fromConfig(config, options); diff --git a/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.test.ts b/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.test.ts index 47245dc6fc..64b0917202 100644 --- a/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.test.ts +++ b/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.test.ts @@ -21,7 +21,10 @@ import { } from '@backstage/backend-common'; import { Entity } from '@backstage/catalog-model'; import { DefaultTechDocsCollator } from './DefaultTechDocsCollator'; -import { mockServices, setupMswHandlers } from '@backstage/backend-test-utils'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; import { setupServer } from 'msw/node'; import { rest } from 'msw'; import { ConfigReader } from '@backstage/config'; @@ -76,7 +79,7 @@ const expectedEntities: Entity[] = [ describe('TechDocs Collator', () => { const worker = setupServer(); - setupMswHandlers(worker); + registerMswTestHooks(worker); describe('DefaultTechDocsCollator with legacyPathCasing configuration', () => { let mockDiscoveryApi: jest.Mocked; diff --git a/plugins/user-settings/src/apis/StorageApi/UserSettingsStorage.test.ts b/plugins/user-settings/src/apis/StorageApi/UserSettingsStorage.test.ts index 6ee6a3df2f..6bb0035b83 100644 --- a/plugins/user-settings/src/apis/StorageApi/UserSettingsStorage.test.ts +++ b/plugins/user-settings/src/apis/StorageApi/UserSettingsStorage.test.ts @@ -21,14 +21,14 @@ import { IdentityApi, StorageApi, } from '@backstage/core-plugin-api'; -import { MockFetchApi, setupMswHandlers } from '@backstage/test-utils'; +import { MockFetchApi, registerMswTestHooks } from '@backstage/test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { UserSettingsStorage } from './UserSettingsStorage'; describe('Persistent Storage API', () => { const server = setupServer(); - setupMswHandlers(server); + registerMswTestHooks(server); const mockBaseUrl = 'http://backstage:9191/api'; const mockErrorApi = { post: jest.fn(), error$: jest.fn() }; From ccfc9d12c11db4d5a64d551a56bda686cd036346 Mon Sep 17 00:00:00 2001 From: Mccaskey Skye Date: Wed, 10 Jul 2024 12:57:23 -0500 Subject: [PATCH 229/510] fix: Added owner and repo args to getEnvironmentPublicKey Signed-off-by: Mccaskey Skye --- .changeset/early-deers-beg.md | 16 ++++++++++++++++ .../src/actions/githubEnvironment.test.ts | 11 +++++++++++ .../src/actions/githubEnvironment.ts | 2 ++ 3 files changed, 29 insertions(+) create mode 100644 .changeset/early-deers-beg.md diff --git a/.changeset/early-deers-beg.md b/.changeset/early-deers-beg.md new file mode 100644 index 0000000000..2814273afa --- /dev/null +++ b/.changeset/early-deers-beg.md @@ -0,0 +1,16 @@ +--- +'@backstage/plugin-scaffolder-backend-module-github': patch +--- + +Fixed bug resulting from missing required owner and repo arguments in `octokit getEnvironmentPublicKey in action `github:environment:create`. + +Adding environment secrets now works as expected. + +```diff + const publicKeyResponse = await client.rest.actions.getEnvironmentPublicKey({ + repository_id: repository.data.id, ++ owner, ++ repo, + environment_name: name + }); +``` diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.test.ts index c4eae41029..139d8028eb 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.test.ts @@ -304,5 +304,16 @@ describe('github:environment:create', () => { key_id: 'keyid', encrypted_value: expect.any(String), }); + expect( + mockOctokit.rest.actions.getEnvironmentPublicKey, + ).toHaveBeenCalledTimes(1); + expect( + mockOctokit.rest.actions.getEnvironmentPublicKey, + ).toHaveBeenCalledWith({ + repository_id: 'repoid', + owner: 'owner', + repo: 'repository', + environment_name: 'envname', + }); }); }); diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.ts b/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.ts index 98e7cea1a9..d3e8d0e5d2 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.ts @@ -199,6 +199,8 @@ export function createGithubEnvironmentAction(options: { const publicKeyResponse = await client.rest.actions.getEnvironmentPublicKey({ repository_id: repository.data.id, + owner: owner, + repo: repo, environment_name: name, }); From a7d9216e505d7ee8c4b397bbd3810633ab174a14 Mon Sep 17 00:00:00 2001 From: Mccaskey Skye Date: Wed, 10 Jul 2024 13:38:35 -0500 Subject: [PATCH 230/510] Update early-deers-beg.md Signed-off-by: Mccaskey Skye --- .changeset/early-deers-beg.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/early-deers-beg.md b/.changeset/early-deers-beg.md index 2814273afa..4bac074d8c 100644 --- a/.changeset/early-deers-beg.md +++ b/.changeset/early-deers-beg.md @@ -2,7 +2,7 @@ '@backstage/plugin-scaffolder-backend-module-github': patch --- -Fixed bug resulting from missing required owner and repo arguments in `octokit getEnvironmentPublicKey in action `github:environment:create`. +Fixed bug resulting from missing required owner and repo arguments in `getEnvironmentPublicKey` in action `github:environment:create`. Adding environment secrets now works as expected. From e149572b1a5a2dbe49225a5b5589b52f4172d32d Mon Sep 17 00:00:00 2001 From: CasperJ Date: Wed, 10 Jul 2024 21:03:43 +0200 Subject: [PATCH 231/510] Update .changeset/dirty-wasps-do.md Co-authored-by: Andre Wanlin <67169551+awanlin@users.noreply.github.com> Signed-off-by: CasperJ --- .changeset/dirty-wasps-do.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/dirty-wasps-do.md b/.changeset/dirty-wasps-do.md index fbf6799baf..f8b4e614eb 100644 --- a/.changeset/dirty-wasps-do.md +++ b/.changeset/dirty-wasps-do.md @@ -2,4 +2,4 @@ '@backstage/plugin-scaffolder-backend': patch --- -Catalog:Write scaffolder action shows incorrect log message +Updated `catalog:write` scaffolder action to show correct file path location in log message From bebd569c565516fb411c276bf47b1aef80c5bc9e Mon Sep 17 00:00:00 2001 From: Stephen Glass Date: Wed, 10 Jul 2024 20:44:25 -0400 Subject: [PATCH 232/510] Fix extra divider displayed on user list picker component Signed-off-by: Stephen Glass --- .changeset/pink-gorillas-brake.md | 5 +++++ .../src/components/UserListPicker/UserListPicker.tsx | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 .changeset/pink-gorillas-brake.md diff --git a/.changeset/pink-gorillas-brake.md b/.changeset/pink-gorillas-brake.md new file mode 100644 index 0000000000..188884f13c --- /dev/null +++ b/.changeset/pink-gorillas-brake.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Fix extra divider displayed on user list picker component diff --git a/plugins/catalog-react/src/components/UserListPicker/UserListPicker.tsx b/plugins/catalog-react/src/components/UserListPicker/UserListPicker.tsx index 7f0ff8be74..c6b515aa67 100644 --- a/plugins/catalog-react/src/components/UserListPicker/UserListPicker.tsx +++ b/plugins/catalog-react/src/components/UserListPicker/UserListPicker.tsx @@ -247,11 +247,11 @@ export const UserListPicker = (props: UserListPickerProps) => { - {group.items.map(item => ( + {group.items.map((item, index) => ( setSelectedUserFilter(item.id)} selected={item.id === filters.user?.value} className={classes.menuItem} From 707eb3989dfd3ddf32dc14564ba06a4649935905 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 11 Jul 2024 10:16:25 +0200 Subject: [PATCH 233/510] Apply suggestions from code review Co-authored-by: Camila Belo Signed-off-by: Patrik Oldsberg --- .changeset/spotty-apricots-tan.md | 2 +- docs/backend-system/architecture/03-services.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.changeset/spotty-apricots-tan.md b/.changeset/spotty-apricots-tan.md index 2b88e3a7f5..8eea2b1dce 100644 --- a/.changeset/spotty-apricots-tan.md +++ b/.changeset/spotty-apricots-tan.md @@ -41,7 +41,7 @@ export class DefaultFooService implements FooService { A user that wishes to customize the service can then easily do so by defining their own factory: ```ts -export const fooServiceFactory = createServiceFactory({ +export const customFooServiceFactory = createServiceFactory({ service: fooServiceRef, deps: { logger: coreServices.logger }, factory({ logger }) { diff --git a/docs/backend-system/architecture/03-services.md b/docs/backend-system/architecture/03-services.md index 7d6824c41e..e1d86164c3 100644 --- a/docs/backend-system/architecture/03-services.md +++ b/docs/backend-system/architecture/03-services.md @@ -192,7 +192,7 @@ When defining a default factory for a service, it is possible for it to end up w ## Service Factory Customization -When declaring a service factory you may also want to make the export the building blocks of the implementation itself. This is to allow for further customization of the service implementation through code, beyond what is possible with static configuration, without the need to re-implement the entire service from scratch. For example, we might export our example `DefaultFooService` class, while moving construction to a static factory method to make it easier to evolve: +When declaring a service factory you may also want to make the export the building blocks of the implementation itself. This is to allow for further customization of the service implementation through code, beyond what is possible with static configuration, without the need to re-implement the entire service from scratch. For example, we might export our example `DefaultFooService` class, while moving construction to a static `create` factory method to make it easier to evolve: ```ts export class DefaultFooService { @@ -222,4 +222,4 @@ export const customFooServiceFactory = createServiceFactory({ }); ``` -This allows lets you provide more advanced options for the service implementation that couldn't be expressed through static configuration. It also gives users of the service implementation access to other services through dependency injection, which can be useful for their customizations. +This allows you to provide more advanced options for the service implementation that couldn't be expressed through static configuration. It also gives users of the service implementation access to other services through dependency injection, which can be useful for their customizations. From 87d3f665f820c3520716a3a0415e6d86552d28a7 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 11 Jul 2024 10:45:18 +0200 Subject: [PATCH 234/510] backend-plugin-api: update deprecation message for ServiceFactoryCompat Signed-off-by: Patrik Oldsberg --- packages/backend-plugin-api/src/services/system/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend-plugin-api/src/services/system/types.ts b/packages/backend-plugin-api/src/services/system/types.ts index 9545408ff2..d31350806d 100644 --- a/packages/backend-plugin-api/src/services/system/types.ts +++ b/packages/backend-plugin-api/src/services/system/types.ts @@ -65,7 +65,7 @@ export interface ServiceFactoryCompat< TOpts extends object | undefined = undefined, > extends ServiceFactory { /** - * @deprecated You do not need to use this call signature; use the type directly instead by removing the `()` parentheses at the end. This call signature will be removed in a future release. + * @deprecated Callable service factories will be removed in a future release, please re-implement the service factory using the available APIs instead. If no options are being passed, you can simply remove the trailing `()`. */ ( ...options: undefined extends TOpts ? [] : [options?: TOpts] From 617a7d29c242679b9659ab15944856b85a27a2ca Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 11 Jul 2024 11:18:18 +0200 Subject: [PATCH 235/510] backend-app-api: avoid using service factory options for plugin meta service Signed-off-by: Patrik Oldsberg --- .changeset/nice-cats-nail.md | 5 +++++ .../backend-app-api/src/wiring/ServiceRegistry.ts | 12 ++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 .changeset/nice-cats-nail.md diff --git a/.changeset/nice-cats-nail.md b/.changeset/nice-cats-nail.md new file mode 100644 index 0000000000..0e9b1603b8 --- /dev/null +++ b/.changeset/nice-cats-nail.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-app-api': patch +--- + +Internal refactor that avoids the use of service factory options. diff --git a/packages/backend-app-api/src/wiring/ServiceRegistry.ts b/packages/backend-app-api/src/wiring/ServiceRegistry.ts index 6e20dd98e8..56d8d611bb 100644 --- a/packages/backend-app-api/src/wiring/ServiceRegistry.ts +++ b/packages/backend-app-api/src/wiring/ServiceRegistry.ts @@ -48,13 +48,13 @@ function toInternalServiceFactory( return f; } -const pluginMetadataServiceFactory = createServiceFactory( - (options?: { pluginId: string }) => ({ +function createPluginMetadataServiceFactory(pluginId: string) { + return createServiceFactory({ service: coreServices.pluginMetadata, deps: {}, - factory: async () => ({ getId: () => options?.pluginId! }), - }), -); + factory: async () => ({ getId: () => pluginId }), + }); +} export class ServiceRegistry { static create(factories: Array): ServiceRegistry { @@ -97,7 +97,7 @@ export class ServiceRegistry { // Special case handling of the plugin metadata service, generating a custom factory for it each time if (ref.id === coreServices.pluginMetadata.id) { return Promise.resolve( - toInternalServiceFactory(pluginMetadataServiceFactory({ pluginId })), + toInternalServiceFactory(createPluginMetadataServiceFactory(pluginId)), ); } From a8bd40162c55b9311438e7fd95b55688c213459a Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Tue, 23 Apr 2024 10:01:22 +0100 Subject: [PATCH 236/510] yarn-plugin: validate version of yarn in yarn plugin Signed-off-by: MT Lewis --- packages/yarn-plugin/package.json | 1 + packages/yarn-plugin/src/index.ts | 13 ++++++++++++- yarn.lock | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/yarn-plugin/package.json b/packages/yarn-plugin/package.json index ad42bdba23..fd70dc8600 100644 --- a/packages/yarn-plugin/package.json +++ b/packages/yarn-plugin/package.json @@ -34,6 +34,7 @@ "@backstage/release-manifests": "workspace:^", "@yarnpkg/core": "^4.0.3", "@yarnpkg/fslib": "^3.0.2", + "chalk": "^4.0.0", "semver": "^7.6.0" }, "devDependencies": { diff --git a/packages/yarn-plugin/src/index.ts b/packages/yarn-plugin/src/index.ts index 6c1c805fd8..f548463829 100644 --- a/packages/yarn-plugin/src/index.ts +++ b/packages/yarn-plugin/src/index.ts @@ -21,10 +21,21 @@ * @packageDocumentation */ -import { Plugin } from '@yarnpkg/core'; +import { Plugin, semverUtils, YarnVersion } from '@yarnpkg/core'; +import chalk from 'chalk'; import { beforeWorkspacePacking } from './handlers/beforeWorkspacePacking'; import { BackstageResolver } from './resolver/BackstageResolver'; +if (!semverUtils.satisfiesWithPrereleases(YarnVersion, '^4.1.1')) { + console.error(); + console.error( + `${chalk.bold.red( + 'Unsupported yarn version.', + )}: The Backstage yarn plugin only works with yarn ^4.1.1. Please upgrade yarn, or remove this plugin with "yarn plugin remove @yarnpkg/plugin-backstage".`, + ); + console.error(); +} + /** * @public */ diff --git a/yarn.lock b/yarn.lock index f50727e805..afe89e4263 100644 --- a/yarn.lock +++ b/yarn.lock @@ -44721,6 +44721,7 @@ __metadata: "@yarnpkg/builder": ^4.0.0 "@yarnpkg/core": ^4.0.3 "@yarnpkg/fslib": ^3.0.2 + chalk: ^4.0.0 nodemon: ^3.0.1 semver: ^7.6.0 languageName: unknown From f9e4e22e5f80dbaadca4cc9ab65e334bd9df836c Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Sun, 14 Apr 2024 21:08:08 +0100 Subject: [PATCH 237/510] sync_release-manifest: full yarn install Since we now need to build the yarn-plugin before pushing it to the versions repo for each release, we need a full yarn install in this repo. Signed-off-by: MT Lewis --- .github/workflows/sync_release-manifest.yml | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/workflows/sync_release-manifest.yml b/.github/workflows/sync_release-manifest.yml index db35945550..34bbabcd0b 100644 --- a/.github/workflows/sync_release-manifest.yml +++ b/.github/workflows/sync_release-manifest.yml @@ -12,14 +12,6 @@ jobs: with: egress-policy: audit - # Setup node & install deps before checkout, keeping install quick - - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 - with: - node-version: 18.x - - name: Install dependencies - # Just the deps for the assemble manifest script - run: npm install semver@7.3.5 fs-extra@10.0.0 @manypkg/get-packages@1.1.1 - - name: Checkout uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 with: @@ -27,6 +19,18 @@ jobs: # 'v' prefix is added here for the tag, we keep it out of the manifest logic ref: v${{ github.event.client_payload.version }} + - name: use node.js 18.x + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: 18.x + registry-url: https://registry.npmjs.org/ # Needed for auth + + - name: yarn install + uses: backstage/actions/yarn-install@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 + with: + path: backstage + cache-prefix: ${{ runner.os }}-v18.x + # Checkout backstage/versions into /backstage/versions, which is where store the output - name: Checkout versions uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 From 0bdf7ab1ebfdc211a72a394788cfc892a8eb3388 Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Sun, 14 Apr 2024 21:16:04 +0100 Subject: [PATCH 238/510] sync_release-manifest: add yarn-plugin to release directory Since yarn plugins aren't installable via npm, we need a place to make the version available for each release. Since versions.backstage.io already provides an API backed by a git repo organized by release (and even includes release line links), it seems like the perfect spot. This commit adds the yarn plugin to the appropriate directory when the sync_release-management workflow runs, reorganizing the existing functionality for pushing the changes to the versions repo with a little bit of refactoring. Signed-off-by: MT Lewis --- .github/workflows/sync_release-manifest.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.github/workflows/sync_release-manifest.yml b/.github/workflows/sync_release-manifest.yml index 34bbabcd0b..e7c06747f7 100644 --- a/.github/workflows/sync_release-manifest.yml +++ b/.github/workflows/sync_release-manifest.yml @@ -31,6 +31,10 @@ jobs: path: backstage cache-prefix: ${{ runner.os }}-v18.x + - name: Build yarn plugin + working-directory: backstage/packages/yarn-plugin + run: yarn build + # Checkout backstage/versions into /backstage/versions, which is where store the output - name: Checkout versions uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 @@ -51,6 +55,20 @@ jobs: mkdir -p scripts wget -O scripts/assemble-manifest.js https://raw.githubusercontent.com/backstage/backstage/master/scripts/assemble-manifest.js node scripts/assemble-manifest.js ${{ github.event.client_payload.version }} + + # Copies the build output of the yarn-plugin package to the appropriate + # directory, allowing the plugin to be installed with a command like + # `yarn plugin import https://versions.backstage.io/v1/tags/main/yarn-plugin` + - name: Add yarn plugin to release + working-directory: backstage/packages/yarn-plugin + run: >- + cp + bundles/@yarnpkg/plugin-backstage.js + ../../versions/v1/releases/${{ github.event.client_payload.version }}/yarn-plugin + + - name: Commit to versions repo + working-directory: backstage/versions + run: | cd versions git add . git commit -am "${{ github.event.client_payload.version }}" From 513175ae970a34a29b900d4660a2ff45ebc9bedb Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Sun, 14 Apr 2024 21:31:38 +0100 Subject: [PATCH 239/510] sync_release-manifest: remove top-level backstage directory The top-level backstage/ directory included in this repo means we can't use the yarn-install backstage action (or we'd have to add a `path` input option to it). Looking at this workflow, I can't actually spot why the top-level `backstage` dir is needed - nothing is ever written outside it as far as I can spot. With that in mind, proposing we remove it to simplify the workflow and enable the use of the `yarn-install` action without needing to extend it. Signed-off-by: MT Lewis --- .github/workflows/sync_release-manifest.yml | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/.github/workflows/sync_release-manifest.yml b/.github/workflows/sync_release-manifest.yml index e7c06747f7..6d02309f8a 100644 --- a/.github/workflows/sync_release-manifest.yml +++ b/.github/workflows/sync_release-manifest.yml @@ -15,7 +15,6 @@ jobs: - name: Checkout uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 with: - path: backstage # 'v' prefix is added here for the tag, we keep it out of the manifest logic ref: v${{ github.event.client_payload.version }} @@ -28,11 +27,10 @@ jobs: - name: yarn install uses: backstage/actions/yarn-install@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 with: - path: backstage cache-prefix: ${{ runner.os }}-v18.x - name: Build yarn plugin - working-directory: backstage/packages/yarn-plugin + working-directory: packages/yarn-plugin run: yarn build # Checkout backstage/versions into /backstage/versions, which is where store the output @@ -40,7 +38,7 @@ jobs: uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 with: repository: backstage/versions - path: backstage/versions + path: versions token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }} - name: Configure Git @@ -51,7 +49,6 @@ jobs: - name: Create release # This grabs the scripts from master in order to support backfills run: | - cd backstage mkdir -p scripts wget -O scripts/assemble-manifest.js https://raw.githubusercontent.com/backstage/backstage/master/scripts/assemble-manifest.js node scripts/assemble-manifest.js ${{ github.event.client_payload.version }} @@ -60,16 +57,15 @@ jobs: # directory, allowing the plugin to be installed with a command like # `yarn plugin import https://versions.backstage.io/v1/tags/main/yarn-plugin` - name: Add yarn plugin to release - working-directory: backstage/packages/yarn-plugin + working-directory: packages/yarn-plugin run: >- cp bundles/@yarnpkg/plugin-backstage.js ../../versions/v1/releases/${{ github.event.client_payload.version }}/yarn-plugin - name: Commit to versions repo - working-directory: backstage/versions + working-directory: versions run: | - cd versions git add . git commit -am "${{ github.event.client_payload.version }}" git push @@ -87,7 +83,7 @@ jobs: workflow_id: 'release.yml', ref: 'master', inputs: { - version: require('./backstage/packages/create-app/package.json').version, - releaseVersion: require('./backstage/package.json').version + version: require('./packages/create-app/package.json').version, + releaseVersion: require('./package.json').version }, }); From 0600286c95a0f9409954facf1ec01826e8248f4f Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 11 Jul 2024 13:22:51 +0200 Subject: [PATCH 240/510] Update .changeset/early-deers-beg.md Signed-off-by: Patrik Oldsberg --- .changeset/early-deers-beg.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.changeset/early-deers-beg.md b/.changeset/early-deers-beg.md index 4bac074d8c..735c68aace 100644 --- a/.changeset/early-deers-beg.md +++ b/.changeset/early-deers-beg.md @@ -5,12 +5,3 @@ Fixed bug resulting from missing required owner and repo arguments in `getEnvironmentPublicKey` in action `github:environment:create`. Adding environment secrets now works as expected. - -```diff - const publicKeyResponse = await client.rest.actions.getEnvironmentPublicKey({ - repository_id: repository.data.id, -+ owner, -+ repo, - environment_name: name - }); -``` From 4a77a91da87f67ef91e1f35b2b7269b957e754fd Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Thu, 11 Jul 2024 06:58:33 -0500 Subject: [PATCH 241/510] Added comment to resolvers Signed-off-by: Andre Wanlin --- docs/auth/microsoft/azure-easyauth.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/auth/microsoft/azure-easyauth.md b/docs/auth/microsoft/azure-easyauth.md index e8d6f2f105..c2a6eab218 100644 --- a/docs/auth/microsoft/azure-easyauth.md +++ b/docs/auth/microsoft/azure-easyauth.md @@ -66,6 +66,7 @@ auth: azureEasyAuth: signIn: resolvers: + # typically you would pick one of these - resolver: emailMatchingUserEntityProfileEmail - resolver: emailLocalPartMatchingUserEntityName - resolver: idMatchingUserEntityAnnotation From b652b6de1fb647cc8fe65af2f6e6baa71574c9ac Mon Sep 17 00:00:00 2001 From: Chap Ambrose Date: Thu, 11 Jul 2024 08:16:21 -0500 Subject: [PATCH 242/510] add deploy buttuon to heroku.md Signed-off-by: Chap Ambrose --- docs/deployment/heroku.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/deployment/heroku.md b/docs/deployment/heroku.md index 74732bb431..faf1c2106e 100644 --- a/docs/deployment/heroku.md +++ b/docs/deployment/heroku.md @@ -7,6 +7,8 @@ description: How to deploy Backstage to Heroku Heroku is a Platform as a Service (PaaS) designed to simplify application deployment. +[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/chap/backstage-button) + ## Create App Starting with an existing Backstage app or follow the [getting started guide](https://backstage.io/docs/getting-started/) to create a new one. From 8fc26223c26e2fe642414f28c8486fd1ef44349d Mon Sep 17 00:00:00 2001 From: Bond Yan Date: Thu, 11 Jul 2024 11:20:17 -0400 Subject: [PATCH 243/510] setting useNavigate in a ref Signed-off-by: Bond Yan --- .changeset/chatty-adults-boil.md | 5 +++++ .../TechDocsReaderPageContent/useNavigateUrl.tsx | 9 +++++---- 2 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 .changeset/chatty-adults-boil.md diff --git a/.changeset/chatty-adults-boil.md b/.changeset/chatty-adults-boil.md new file mode 100644 index 0000000000..76f3bddf41 --- /dev/null +++ b/.changeset/chatty-adults-boil.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Fixed an issue that was causing techdocs pages unnecessarily re-render on navigate. diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/useNavigateUrl.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/useNavigateUrl.tsx index 02d181dccf..f036edef65 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/useNavigateUrl.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/useNavigateUrl.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ import { configApiRef, useApi } from '@backstage/core-plugin-api'; -import { useCallback } from 'react'; +import { useCallback, useRef } from 'react'; import { useNavigate } from 'react-router-dom'; /** @@ -53,7 +53,8 @@ export function resolveUrlToRelative(url: string, baseUrl: string) { * @public */ export function useNavigateUrl() { - const navigate = useNavigate(); + // useRef prevents useNavigate from causing unnecessary re-renders + const navigate = useRef(useNavigate()); const configApi = useApi(configApiRef); const appBaseUrl = configApi.getOptionalString('app.baseUrl'); const navigateFn = useCallback( @@ -70,9 +71,9 @@ export function useNavigateUrl() { // URL passed in was relative. } } - navigate(url); + navigate.current(url); }, - [navigate, appBaseUrl], + [appBaseUrl], ); return navigateFn; } From a3449e0767d0ce17bee320341ec1309e6830dc88 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 12 Jul 2024 07:40:53 +0000 Subject: [PATCH 244/510] chore(deps): update snyk/actions digest to 640e317 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/sync_snyk-github-issues.yml | 2 +- .github/workflows/sync_snyk-monitor.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/sync_snyk-github-issues.yml b/.github/workflows/sync_snyk-github-issues.yml index fb3456bfb6..1cdc0cb22a 100644 --- a/.github/workflows/sync_snyk-github-issues.yml +++ b/.github/workflows/sync_snyk-github-issues.yml @@ -29,7 +29,7 @@ jobs: cache-prefix: ${{ runner.os }}-v18.x - name: Create Snyk report - uses: snyk/actions/node@d406fd286b663eb8c6f8adcced4f7bcd199c0a3f # master + uses: snyk/actions/node@640e31719aac3e44867d239dc86c20c3e34c8e4f # master continue-on-error: true # Snyk CLI exits with error when vulnerabilities are found with: args: > diff --git a/.github/workflows/sync_snyk-monitor.yml b/.github/workflows/sync_snyk-monitor.yml index a3c72c1d7b..b1e50397ce 100644 --- a/.github/workflows/sync_snyk-monitor.yml +++ b/.github/workflows/sync_snyk-monitor.yml @@ -31,7 +31,7 @@ jobs: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Monitor and Synchronize Snyk Policies - uses: snyk/actions/node@d406fd286b663eb8c6f8adcced4f7bcd199c0a3f # master + uses: snyk/actions/node@640e31719aac3e44867d239dc86c20c3e34c8e4f # master with: command: monitor args: > @@ -46,7 +46,7 @@ jobs: # Above we run the `monitor` command, this runs the `test` command which is # the one that generates the SARIF report that we can upload to GitHub. - name: Create Snyk report - uses: snyk/actions/node@d406fd286b663eb8c6f8adcced4f7bcd199c0a3f # master + uses: snyk/actions/node@640e31719aac3e44867d239dc86c20c3e34c8e4f # master continue-on-error: true # To make sure that SARIF upload gets called with: args: > From f691c9bf75dc4562f45e51c02ec5e132bfdd8433 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 10 Jul 2024 13:24:37 +0200 Subject: [PATCH 245/510] backend-app-api: simplify defaultServiceFactories option Signed-off-by: Patrik Oldsberg --- .changeset/dry-wombats-type.md | 5 +++ packages/backend-app-api/api-report.md | 4 +- .../src/wiring/createSpecializedBackend.ts | 8 +--- packages/backend-app-api/src/wiring/types.ts | 4 +- .../backend-defaults/src/CreateBackend.ts | 40 +++++++++---------- 5 files changed, 31 insertions(+), 30 deletions(-) create mode 100644 .changeset/dry-wombats-type.md diff --git a/.changeset/dry-wombats-type.md b/.changeset/dry-wombats-type.md new file mode 100644 index 0000000000..31fed70293 --- /dev/null +++ b/.changeset/dry-wombats-type.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-app-api': minor +--- + +**BREAKING**: Removed the ability to pass callback-form service factories through the `defaultServiceFactories` option of `createSpecializedBackend`. This is an immediate breaking change as usage of this function is expected to be very rare. diff --git a/packages/backend-app-api/api-report.md b/packages/backend-app-api/api-report.md index 51839b88be..2a447d52ef 100644 --- a/packages/backend-app-api/api-report.md +++ b/packages/backend-app-api/api-report.md @@ -38,8 +38,8 @@ import { RootLifecycleService } from '@backstage/backend-plugin-api'; import { RootLoggerService } from '@backstage/backend-plugin-api'; import { SchedulerService } from '@backstage/backend-plugin-api'; import type { Server } from 'node:http'; +import { ServiceFactory } from '@backstage/backend-plugin-api'; import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; -import { ServiceFactoryOrFunction } from '@backstage/backend-plugin-api'; import { TokenManagerService } from '@backstage/backend-plugin-api'; import { transport } from 'winston'; import { UrlReaderService } from '@backstage/backend-plugin-api'; @@ -99,7 +99,7 @@ export function createSpecializedBackend( // @public (undocumented) export interface CreateSpecializedBackendOptions { // (undocumented) - defaultServiceFactories: ServiceFactoryOrFunction[]; + defaultServiceFactories: ServiceFactory[]; } // @public @deprecated (undocumented) diff --git a/packages/backend-app-api/src/wiring/createSpecializedBackend.ts b/packages/backend-app-api/src/wiring/createSpecializedBackend.ts index f5c4d8b152..fd449be541 100644 --- a/packages/backend-app-api/src/wiring/createSpecializedBackend.ts +++ b/packages/backend-app-api/src/wiring/createSpecializedBackend.ts @@ -24,13 +24,9 @@ import { Backend, CreateSpecializedBackendOptions } from './types'; export function createSpecializedBackend( options: CreateSpecializedBackendOptions, ): Backend { - const services = options.defaultServiceFactories.map(sf => - typeof sf === 'function' ? sf() : sf, - ); - const exists = new Set(); const duplicates = new Set(); - for (const { service } of services) { + for (const { service } of options.defaultServiceFactories) { if (exists.has(service.id)) { duplicates.add(service.id); } else { @@ -47,5 +43,5 @@ export function createSpecializedBackend( ); } - return new BackstageBackend(services); + return new BackstageBackend(options.defaultServiceFactories); } diff --git a/packages/backend-app-api/src/wiring/types.ts b/packages/backend-app-api/src/wiring/types.ts index 027b2bf254..776dcdcb35 100644 --- a/packages/backend-app-api/src/wiring/types.ts +++ b/packages/backend-app-api/src/wiring/types.ts @@ -18,7 +18,7 @@ import { BackendFeature, ExtensionPoint, ServiceRef, - ServiceFactoryOrFunction, + ServiceFactory, } from '@backstage/backend-plugin-api'; /** @@ -39,7 +39,7 @@ export interface Backend { * @public */ export interface CreateSpecializedBackendOptions { - defaultServiceFactories: ServiceFactoryOrFunction[]; + defaultServiceFactories: ServiceFactory[]; } /** diff --git a/packages/backend-defaults/src/CreateBackend.ts b/packages/backend-defaults/src/CreateBackend.ts index e3195748a6..47fa09da49 100644 --- a/packages/backend-defaults/src/CreateBackend.ts +++ b/packages/backend-defaults/src/CreateBackend.ts @@ -40,26 +40,26 @@ import { userInfoServiceFactory } from '@backstage/backend-defaults/userInfo'; import { eventsServiceFactory } from '@backstage/plugin-events-node'; export const defaultServiceFactories = [ - authServiceFactory(), - cacheServiceFactory(), - rootConfigServiceFactory(), - databaseServiceFactory(), - discoveryServiceFactory(), - httpAuthServiceFactory(), - httpRouterServiceFactory(), - identityServiceFactory(), - lifecycleServiceFactory(), - loggerServiceFactory(), - permissionsServiceFactory(), - rootHealthServiceFactory(), - rootHttpRouterServiceFactory(), - rootLifecycleServiceFactory(), - rootLoggerServiceFactory(), - schedulerServiceFactory(), - tokenManagerServiceFactory(), - userInfoServiceFactory(), - urlReaderServiceFactory(), - eventsServiceFactory(), + authServiceFactory, + cacheServiceFactory, + rootConfigServiceFactory, + databaseServiceFactory, + discoveryServiceFactory, + httpAuthServiceFactory, + httpRouterServiceFactory, + identityServiceFactory, + lifecycleServiceFactory, + loggerServiceFactory, + permissionsServiceFactory, + rootHealthServiceFactory, + rootHttpRouterServiceFactory, + rootLifecycleServiceFactory, + rootLoggerServiceFactory, + schedulerServiceFactory, + tokenManagerServiceFactory, + userInfoServiceFactory, + urlReaderServiceFactory, + eventsServiceFactory, ]; /** From 18b96b15edeb2526bf36c60530e1739cb8d8f274 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 10 Jul 2024 13:30:14 +0200 Subject: [PATCH 246/510] backend-app-api: deprecate callback form of backend.add(...) Signed-off-by: Patrik Oldsberg --- .changeset/three-lizards-crash.md | 5 +++++ packages/backend-app-api/api-report.md | 9 ++++++++- packages/backend-app-api/src/wiring/types.ts | 11 +++++++++-- 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 .changeset/three-lizards-crash.md diff --git a/.changeset/three-lizards-crash.md b/.changeset/three-lizards-crash.md new file mode 100644 index 0000000000..5dffed0f3b --- /dev/null +++ b/.changeset/three-lizards-crash.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-app-api': patch +--- + +The ability to install backend features in callback form (`() => BackendFeature`) has been deprecated. This typically means that you need to update the installed features to use the latest version of `@backstage/backend-plugin-api`. If the feature is from a third-party package, please reach out to the package maintainer to update it. diff --git a/packages/backend-app-api/api-report.md b/packages/backend-app-api/api-report.md index 2a447d52ef..54e2900cc2 100644 --- a/packages/backend-app-api/api-report.md +++ b/packages/backend-app-api/api-report.md @@ -58,9 +58,16 @@ export interface Backend { add( feature: | BackendFeature + | Promise<{ + default: BackendFeature; + }>, + ): void; + // @deprecated (undocumented) + add( + feature: | (() => BackendFeature) | Promise<{ - default: BackendFeature | (() => BackendFeature); + default: () => BackendFeature; }>, ): void; // (undocumented) diff --git a/packages/backend-app-api/src/wiring/types.ts b/packages/backend-app-api/src/wiring/types.ts index 776dcdcb35..075eb58b3f 100644 --- a/packages/backend-app-api/src/wiring/types.ts +++ b/packages/backend-app-api/src/wiring/types.ts @@ -25,11 +25,18 @@ import { * @public */ export interface Backend { + add(feature: BackendFeature | Promise<{ default: BackendFeature }>): void; + /** + * @deprecated The ability to add features defined as a callback is being + * removed. Please update the installed feature to no longer be defined as a + * callback, typically this means updating it to use the latest version of + * `@backstage/backend-plugin-api`. If the feature is from a third-party + * package, please reach out to the package maintainer to update it. + */ add( feature: - | BackendFeature | (() => BackendFeature) - | Promise<{ default: BackendFeature | (() => BackendFeature) }>, + | Promise<{ default: () => BackendFeature }>, ): void; start(): Promise; stop(): Promise; From 906c817fd342f1efcd4bbd8dda5c4d9e59345c99 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 12 Jul 2024 10:43:19 +0200 Subject: [PATCH 247/510] backend-test-utils: update ServiceFactoryTester to not accept callback form Signed-off-by: Patrik Oldsberg --- .changeset/smooth-pianos-argue.md | 5 +++++ packages/backend-test-utils/api-report.md | 6 ++---- .../src/next/wiring/ServiceFactoryTester.ts | 15 +++++---------- 3 files changed, 12 insertions(+), 14 deletions(-) create mode 100644 .changeset/smooth-pianos-argue.md diff --git a/.changeset/smooth-pianos-argue.md b/.changeset/smooth-pianos-argue.md new file mode 100644 index 0000000000..5ab8be8136 --- /dev/null +++ b/.changeset/smooth-pianos-argue.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-test-utils': patch +--- + +Updated `ServiceFactoryTester` to only accept plain service factory objects, no longer supporting the callback form. This lines up with the changes to `@backstage/backend-plugin-api` and should not require any code changes. diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index 566ac5b888..d122e038a6 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -371,9 +371,7 @@ export namespace mockServices { // @public export class ServiceFactoryTester { static from( - subject: - | ServiceFactory - | (() => ServiceFactory), + subject: ServiceFactory, options?: ServiceFactoryTesterOptions, ): ServiceFactoryTester; get( @@ -387,7 +385,7 @@ export class ServiceFactoryTester { // @public export interface ServiceFactoryTesterOptions { - dependencies?: Array ServiceFactory)>; + dependencies?: Array; } // @public (undocumented) diff --git a/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts b/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts index 0555ab10a4..9247a9132e 100644 --- a/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts +++ b/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts @@ -35,7 +35,7 @@ export interface ServiceFactoryTesterOptions { * If a service factory is provided for a service that already has a default * implementation, the provided factory will override the default. */ - dependencies?: Array ServiceFactory)>; + dependencies?: Array; } /** @@ -55,20 +55,15 @@ export class ServiceFactoryTester { * @returns A new tester instance for the provided subject. */ static from( - subject: - | ServiceFactory - | (() => ServiceFactory), + subject: ServiceFactory, options?: ServiceFactoryTesterOptions, ) { - const subjectFactory = typeof subject === 'function' ? subject() : subject; const registry = ServiceRegistry.create([ ...defaultServiceFactories, - ...(options?.dependencies?.map(f => - typeof f === 'function' ? f() : f, - ) ?? []), - subjectFactory, + ...(options?.dependencies ?? []), + subject, ]); - return new ServiceFactoryTester(subjectFactory.service, registry); + return new ServiceFactoryTester(subject.service, registry); } private constructor( From 972bcbb57af95ed825056b0608b8f1057892bf48 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 12 Jul 2024 10:49:44 +0200 Subject: [PATCH 248/510] backend-test-utils: remove callback form features from startTestBackend Signed-off-by: Patrik Oldsberg --- .changeset/smooth-pianos-argue.md | 2 +- packages/backend-test-utils/api-report.md | 3 +-- packages/backend-test-utils/src/next/wiring/TestBackend.ts | 6 +----- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/.changeset/smooth-pianos-argue.md b/.changeset/smooth-pianos-argue.md index 5ab8be8136..e7fc66dee4 100644 --- a/.changeset/smooth-pianos-argue.md +++ b/.changeset/smooth-pianos-argue.md @@ -2,4 +2,4 @@ '@backstage/backend-test-utils': patch --- -Updated `ServiceFactoryTester` to only accept plain service factory objects, no longer supporting the callback form. This lines up with the changes to `@backstage/backend-plugin-api` and should not require any code changes. +Updated `startTestBackend` and `ServiceFactoryTester` to only accept plain service factory or backend feature objects, no longer supporting the callback form. This lines up with the changes to `@backstage/backend-plugin-api` and should not require any code changes. diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index d122e038a6..be6c22192d 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -430,9 +430,8 @@ export interface TestBackendOptions { // (undocumented) features?: Array< | BackendFeature - | (() => BackendFeature) | Promise<{ - default: BackendFeature | (() => BackendFeature); + default: BackendFeature; }> >; } diff --git a/packages/backend-test-utils/src/next/wiring/TestBackend.ts b/packages/backend-test-utils/src/next/wiring/TestBackend.ts index f23883ba3e..16ee6b78d2 100644 --- a/packages/backend-test-utils/src/next/wiring/TestBackend.ts +++ b/packages/backend-test-utils/src/next/wiring/TestBackend.ts @@ -48,11 +48,7 @@ export interface TestBackendOptions { ]; }, ]; - features?: Array< - | BackendFeature - | (() => BackendFeature) - | Promise<{ default: BackendFeature | (() => BackendFeature) }> - >; + features?: Array>; } /** @public */ From f4085b87f5bd2fc707a0970395a4b1f129ad7ca4 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 12 Jul 2024 12:14:17 +0200 Subject: [PATCH 249/510] permission-common: removed the token option from the base evaluator options Signed-off-by: Patrik Oldsberg --- .changeset/eight-dancers-burn.md | 5 +++++ plugins/permission-common/api-report.md | 21 ++++++++++++------ .../permission-common/src/PermissionClient.ts | 14 +++++++++--- plugins/permission-common/src/types/api.ts | 22 +++++++++---------- 4 files changed, 40 insertions(+), 22 deletions(-) create mode 100644 .changeset/eight-dancers-burn.md diff --git a/.changeset/eight-dancers-burn.md b/.changeset/eight-dancers-burn.md new file mode 100644 index 0000000000..228ff036ab --- /dev/null +++ b/.changeset/eight-dancers-burn.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-permission-common': minor +--- + +**BREAKING**: Removed the deprecated and unused `token` option from `EvaluatorRequestOptions`. The `PermissionsClient` now has its own `PermissionClientRequestOptions` type that declares the `token` option instead. diff --git a/plugins/permission-common/api-report.md b/plugins/permission-common/api-report.md index 1c2476d20d..e9935c612d 100644 --- a/plugins/permission-common/api-report.md +++ b/plugins/permission-common/api-report.md @@ -94,9 +94,7 @@ export type EvaluatePermissionResponseBatch = PermissionMessageBatch; // @public -export type EvaluatorRequestOptions = { - token?: string; -}; +export interface EvaluatorRequestOptions {} // @public export type IdentifiedPermissionMessage = T & { @@ -162,14 +160,19 @@ export class PermissionClient implements PermissionEvaluator { constructor(options: { discovery: DiscoveryApi; config: Config }); authorize( requests: AuthorizePermissionRequest[], - options?: EvaluatorRequestOptions, + options?: PermissionClientRequestOptions, ): Promise; authorizeConditional( queries: QueryPermissionRequest[], - options?: EvaluatorRequestOptions, + options?: PermissionClientRequestOptions, ): Promise; } +// @public +export type PermissionClientRequestOptions = { + token?: string; +}; + // @public export type PermissionCondition< TResourceType extends string = string, @@ -191,11 +194,15 @@ export type PermissionCriteria = export interface PermissionEvaluator { authorize( requests: AuthorizePermissionRequest[], - options?: EvaluatorRequestOptions, + options?: EvaluatorRequestOptions & { + _ignored?: never; + }, ): Promise; authorizeConditional( requests: QueryPermissionRequest[], - options?: EvaluatorRequestOptions, + options?: EvaluatorRequestOptions & { + _ignored?: never; + }, ): Promise; } diff --git a/plugins/permission-common/src/PermissionClient.ts b/plugins/permission-common/src/PermissionClient.ts index a5d08205d8..2414774775 100644 --- a/plugins/permission-common/src/PermissionClient.ts +++ b/plugins/permission-common/src/PermissionClient.ts @@ -27,7 +27,6 @@ import { PermissionEvaluator, QueryPermissionRequest, AuthorizePermissionRequest, - EvaluatorRequestOptions, AuthorizePermissionResponse, QueryPermissionResponse, } from './types/api'; @@ -93,6 +92,15 @@ const responseSchema = ( ), }); +/** + * Options for {@link PermissionClient} requests. + * + * @public + */ +export type PermissionClientRequestOptions = { + token?: string; +}; + /** * An isomorphic client for requesting authorization for Backstage permissions. * @public @@ -112,7 +120,7 @@ export class PermissionClient implements PermissionEvaluator { */ async authorize( requests: AuthorizePermissionRequest[], - options?: EvaluatorRequestOptions, + options?: PermissionClientRequestOptions, ): Promise { return this.makeRequest( requests, @@ -126,7 +134,7 @@ export class PermissionClient implements PermissionEvaluator { */ async authorizeConditional( queries: QueryPermissionRequest[], - options?: EvaluatorRequestOptions, + options?: PermissionClientRequestOptions, ): Promise { return this.makeRequest(queries, queryPermissionResponseSchema, options); } diff --git a/plugins/permission-common/src/types/api.ts b/plugins/permission-common/src/types/api.ts index e597384a56..072615989b 100644 --- a/plugins/permission-common/src/types/api.ts +++ b/plugins/permission-common/src/types/api.ts @@ -244,7 +244,7 @@ export interface PermissionEvaluator { */ authorize( requests: AuthorizePermissionRequest[], - options?: EvaluatorRequestOptions, + options?: EvaluatorRequestOptions & { _ignored?: never }, // Since the options are empty we add this placeholder to reject all options ): Promise; /** @@ -257,22 +257,20 @@ export interface PermissionEvaluator { */ authorizeConditional( requests: QueryPermissionRequest[], - options?: EvaluatorRequestOptions, + options?: EvaluatorRequestOptions & { _ignored?: never }, // Since the options are empty we add this placeholder to reject all options ): Promise; } +// Note(Rugvip): I kept the below type around in case we want to add new options +// in the future, for example a signal. It also helps out enabling API +// constraints, as without this we can't have the permissions service implement +// the evaluator interface due to the mismatch in parameter count. + /** * Options for {@link PermissionEvaluator} requests. * + * This is currently empty, as there are no longer any common options for the permission evaluator. + * * @public */ -export type EvaluatorRequestOptions = { - /** - * @deprecated Backend plugins should no longer depend on the - * `PermissionEvaluator`, but instead use the `PermissionService` from - * `@backstage/backend-plugin-api`. Frontend plugins should not need to inject - * this token at all, but instead implicitly rely on underlying fetchApi to do - * it for them. - */ - token?: string; -}; +export interface EvaluatorRequestOptions {} From 36f91e8956a6e6308c066c26f49f34e3542e7b8c Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 12 Jul 2024 12:17:39 +0200 Subject: [PATCH 250/510] backend-plugin-api,permission-node: remove deprecated token option from permissions service Signed-off-by: Patrik Oldsberg --- .changeset/gold-worms-complain.md | 5 + .changeset/swift-seals-drive.md | 5 + packages/backend-plugin-api/api-report.md | 17 +- .../definitions/PermissionsService.ts | 19 +- .../src/ServerPermissionClient.test.ts | 232 ++++-------------- .../src/ServerPermissionClient.ts | 8 - 6 files changed, 77 insertions(+), 209 deletions(-) create mode 100644 .changeset/gold-worms-complain.md create mode 100644 .changeset/swift-seals-drive.md diff --git a/.changeset/gold-worms-complain.md b/.changeset/gold-worms-complain.md new file mode 100644 index 0000000000..229293cc2f --- /dev/null +++ b/.changeset/gold-worms-complain.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-permission-node': minor +--- + +**BREAKING**: Updated the `ServerPermissionClient` to match the new `PermissionsService` interface, where the deprecated `token` option has been removed and the options are now required. diff --git a/.changeset/swift-seals-drive.md b/.changeset/swift-seals-drive.md new file mode 100644 index 0000000000..a03f490d3f --- /dev/null +++ b/.changeset/swift-seals-drive.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-plugin-api': minor +--- + +**BREAKING**: The `PermissionsService` no longer supports passing the deprecated `token` option, and the request options are now required. diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index 7b1e6ef2d3..1937ba6ca9 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -9,6 +9,7 @@ import { AuthorizePermissionRequest } from '@backstage/plugin-permission-common' import { AuthorizePermissionResponse } from '@backstage/plugin-permission-common'; import { Config } from '@backstage/config'; import { Duration } from 'luxon'; +import { EvaluatorRequestOptions } from '@backstage/plugin-permission-common'; import { Handler } from 'express'; import { HumanDuration } from '@backstage/types'; import { IdentityApi } from '@backstage/plugin-auth-node'; @@ -423,22 +424,20 @@ export interface LoggerService { export interface PermissionsService extends PermissionEvaluator { authorize( requests: AuthorizePermissionRequest[], - options?: PermissionsServiceRequestOptions, + options: PermissionsServiceRequestOptions, ): Promise; authorizeConditional( requests: QueryPermissionRequest[], - options?: PermissionsServiceRequestOptions, + options: PermissionsServiceRequestOptions, ): Promise; } // @public -export type PermissionsServiceRequestOptions = - | { - token?: string; - } - | { - credentials: BackstageCredentials; - }; +export interface PermissionsServiceRequestOptions + extends EvaluatorRequestOptions { + // (undocumented) + credentials: BackstageCredentials; +} // @public export interface PluginMetadataService { diff --git a/packages/backend-plugin-api/src/services/definitions/PermissionsService.ts b/packages/backend-plugin-api/src/services/definitions/PermissionsService.ts index c5046a988b..a25081d17a 100644 --- a/packages/backend-plugin-api/src/services/definitions/PermissionsService.ts +++ b/packages/backend-plugin-api/src/services/definitions/PermissionsService.ts @@ -17,6 +17,7 @@ import { AuthorizePermissionRequest, AuthorizePermissionResponse, + EvaluatorRequestOptions, PermissionEvaluator, QueryPermissionRequest, QueryPermissionResponse, @@ -24,18 +25,14 @@ import { import { BackstageCredentials } from './AuthService'; /** - * Options for {@link @backstage/plugin-permission-common#PermissionEvaluator} requests. + * Options for {@link PermissionsService} requests. * * @public */ -export type PermissionsServiceRequestOptions = - | { - /** @deprecated use the `credentials` option instead. */ - token?: string; - } - | { - credentials: BackstageCredentials; - }; +export interface PermissionsServiceRequestOptions + extends EvaluatorRequestOptions { + credentials: BackstageCredentials; +} /** * Permission system integration for authorization of user/service actions. @@ -59,7 +56,7 @@ export interface PermissionsService extends PermissionEvaluator { */ authorize( requests: AuthorizePermissionRequest[], - options?: PermissionsServiceRequestOptions, + options: PermissionsServiceRequestOptions, ): Promise; /** @@ -79,6 +76,6 @@ export interface PermissionsService extends PermissionEvaluator { */ authorizeConditional( requests: QueryPermissionRequest[], - options?: PermissionsServiceRequestOptions, + options: PermissionsServiceRequestOptions, ): Promise; } diff --git a/plugins/permission-node/src/ServerPermissionClient.test.ts b/plugins/permission-node/src/ServerPermissionClient.test.ts index 6e99ff71ab..028517c5e0 100644 --- a/plugins/permission-node/src/ServerPermissionClient.test.ts +++ b/plugins/permission-node/src/ServerPermissionClient.test.ts @@ -83,18 +83,22 @@ describe('ServerPermissionClient', () => { const client = ServerPermissionClient.fromConfig(new ConfigReader({}), { discovery, tokenManager: mockServices.tokenManager.mock(), + auth: mockServices.auth(), }); - await client.authorize([ - { - permission: testBasicPermission, - }, - ]); + await client.authorize( + [ + { + permission: testBasicPermission, + }, + ], + { credentials: mockCredentials.none() }, + ); expect(mockAuthorizeHandler).not.toHaveBeenCalled(); }); - it('should bypass the permission backend if permissions are enabled and request has valid server token', async () => { + it('should bypass the permission backend if permissions are enabled and request has valid server credentials', async () => { const client = ServerPermissionClient.fromConfig(config, { discovery, tokenManager: mockServices.tokenManager.mock(), @@ -102,13 +106,13 @@ describe('ServerPermissionClient', () => { }); await client.authorize([{ permission: testBasicPermission }], { - token: mockCredentials.service.token(), + credentials: mockCredentials.service(), }); expect(mockAuthorizeHandler).not.toHaveBeenCalled(); }); - it('should call the permission backend if permissions are enabled and request does not have valid server token', async () => { + it('should call the permission backend if permissions are enabled and request does not have valid server credentials', async () => { const client = ServerPermissionClient.fromConfig(config, { discovery, tokenManager: mockServices.tokenManager.mock(), @@ -116,10 +120,18 @@ describe('ServerPermissionClient', () => { }); await client.authorize([{ permission: testBasicPermission }], { - token: mockCredentials.user.token(), + credentials: mockCredentials.user(), }); expect(mockAuthorizeHandler).toHaveBeenCalled(); + expect( + mockAuthorizeHandler.mock.calls[0][0].headers.get('authorization'), + ).toBe( + mockCredentials.service.header({ + onBehalfOf: mockCredentials.user(), + targetPluginId: 'permission', + }), + ); }); }); @@ -145,201 +157,59 @@ describe('ServerPermissionClient', () => { const client = ServerPermissionClient.fromConfig(new ConfigReader({}), { discovery, tokenManager: mockServices.tokenManager.mock(), - }); - - await client.authorizeConditional([ - { permission: testResourcePermission }, - ]); - - expect(mockAuthorizeHandler).not.toHaveBeenCalled(); - }); - - it('should bypass the permission backend if permissions are enabled and request has valid server token', async () => { - const client = ServerPermissionClient.fromConfig(config, { - discovery, - tokenManager: mockServices.tokenManager.mock(), + auth: mockServices.auth(), }); await client.authorizeConditional( [{ permission: testResourcePermission }], { - token: mockCredentials.service.token(), + credentials: mockCredentials.none(), }, ); expect(mockAuthorizeHandler).not.toHaveBeenCalled(); }); - it('should call the permission backend if permissions are enabled and request does not have valid server token', async () => { - const auth = mockServices.auth(); + it('should bypass the permission backend if permissions are enabled and request has valid server credentials', async () => { const client = ServerPermissionClient.fromConfig(config, { discovery, tokenManager: mockServices.tokenManager.mock(), - auth, + auth: mockServices.auth(), }); await client.authorizeConditional( [{ permission: testResourcePermission }], { - token: mockCredentials.user.token(), + credentials: mockCredentials.service(), + }, + ); + + expect(mockAuthorizeHandler).not.toHaveBeenCalled(); + }); + + it('should call the permission backend if permissions are enabled and request does not have valid server credentials', async () => { + const client = ServerPermissionClient.fromConfig(config, { + discovery, + tokenManager: mockServices.tokenManager.mock(), + auth: mockServices.auth(), + }); + + await client.authorizeConditional( + [{ permission: testResourcePermission }], + { + credentials: mockCredentials.user(), }, ); expect(mockAuthorizeHandler).toHaveBeenCalled(); - }); - }); - - describe('with credentials', () => { - describe('authorize', () => { - let mockAuthorizeHandler: jest.Mock; - - beforeEach(() => { - mockAuthorizeHandler = jest.fn((req, res, { json }: RestContext) => { - const responses = req.body.items.map( - (r: IdentifiedPermissionMessage) => ({ - id: r.id, - result: AuthorizeResult.ALLOW, - }), - ); - - return res(json({ items: responses })); - }); - - server.use(rest.post(`${mockBaseUrl}/authorize`, mockAuthorizeHandler)); - }); - - it('should bypass the permission backend if permissions are disabled', async () => { - const client = ServerPermissionClient.fromConfig(new ConfigReader({}), { - discovery, - tokenManager: mockServices.tokenManager.mock(), - auth: mockServices.auth(), - }); - - await client.authorize( - [ - { - permission: testBasicPermission, - }, - ], - { credentials: mockCredentials.none() }, - ); - - expect(mockAuthorizeHandler).not.toHaveBeenCalled(); - }); - - it('should bypass the permission backend if permissions are enabled and request has valid server token', async () => { - const client = ServerPermissionClient.fromConfig(config, { - discovery, - tokenManager: mockServices.tokenManager.mock(), - auth: mockServices.auth(), - }); - - await client.authorize([{ permission: testBasicPermission }], { - credentials: mockCredentials.service(), - }); - - expect(mockAuthorizeHandler).not.toHaveBeenCalled(); - }); - - it('should call the permission backend if permissions are enabled and request does not have valid server token', async () => { - const client = ServerPermissionClient.fromConfig(config, { - discovery, - tokenManager: mockServices.tokenManager.mock(), - auth: mockServices.auth(), - }); - - await client.authorize([{ permission: testBasicPermission }], { - credentials: mockCredentials.user(), - }); - - expect(mockAuthorizeHandler).toHaveBeenCalled(); - expect( - mockAuthorizeHandler.mock.calls[0][0].headers.get('authorization'), - ).toBe( - mockCredentials.service.header({ - onBehalfOf: mockCredentials.user(), - targetPluginId: 'permission', - }), - ); - }); - }); - - describe('authorizeConditional', () => { - let mockAuthorizeHandler: jest.Mock; - - beforeEach(() => { - mockAuthorizeHandler = jest.fn((req, res, { json }: RestContext) => { - const responses = req.body.items.map( - (r: IdentifiedPermissionMessage) => ({ - id: r.id, - result: AuthorizeResult.ALLOW, - }), - ); - - return res(json({ items: responses })); - }); - - server.use(rest.post(`${mockBaseUrl}/authorize`, mockAuthorizeHandler)); - }); - - it('should bypass the permission backend if permissions are disabled', async () => { - const client = ServerPermissionClient.fromConfig(new ConfigReader({}), { - discovery, - tokenManager: mockServices.tokenManager.mock(), - auth: mockServices.auth(), - }); - - await client.authorizeConditional( - [{ permission: testResourcePermission }], - { - credentials: mockCredentials.none(), - }, - ); - - expect(mockAuthorizeHandler).not.toHaveBeenCalled(); - }); - - it('should bypass the permission backend if permissions are enabled and request has valid server token', async () => { - const client = ServerPermissionClient.fromConfig(config, { - discovery, - tokenManager: mockServices.tokenManager.mock(), - auth: mockServices.auth(), - }); - - await client.authorizeConditional( - [{ permission: testResourcePermission }], - { - credentials: mockCredentials.service(), - }, - ); - - expect(mockAuthorizeHandler).not.toHaveBeenCalled(); - }); - - it('should call the permission backend if permissions are enabled and request does not have valid server token', async () => { - const client = ServerPermissionClient.fromConfig(config, { - discovery, - tokenManager: mockServices.tokenManager.mock(), - auth: mockServices.auth(), - }); - - await client.authorizeConditional( - [{ permission: testResourcePermission }], - { - credentials: mockCredentials.user(), - }, - ); - - expect(mockAuthorizeHandler).toHaveBeenCalled(); - expect( - mockAuthorizeHandler.mock.calls[0][0].headers.get('authorization'), - ).toBe( - mockCredentials.service.header({ - onBehalfOf: mockCredentials.user(), - targetPluginId: 'permission', - }), - ); - }); + expect( + mockAuthorizeHandler.mock.calls[0][0].headers.get('authorization'), + ).toBe( + mockCredentials.service.header({ + onBehalfOf: mockCredentials.user(), + targetPluginId: 'permission', + }), + ); }); }); diff --git a/plugins/permission-node/src/ServerPermissionClient.ts b/plugins/permission-node/src/ServerPermissionClient.ts index cf54f3b894..e21067bfa1 100644 --- a/plugins/permission-node/src/ServerPermissionClient.ts +++ b/plugins/permission-node/src/ServerPermissionClient.ts @@ -146,14 +146,6 @@ export class ServerPermissionClient implements PermissionsService { return options.credentials; } - if (options?.token) { - try { - return await this.#auth.authenticate(options.token); - } catch { - // ignore - } - } - return undefined; } From 343f656eb15315164a2722e8b32553494b4b5d69 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 12 Jul 2024 12:21:41 +0200 Subject: [PATCH 251/510] search-backend: update to treat requests without credentials as unauthenticated Signed-off-by: Patrik Oldsberg --- .changeset/tiny-pianos-work.md | 5 ++ .../service/AuthorizedSearchEngine.test.ts | 49 ++++++++++++------- .../src/service/AuthorizedSearchEngine.ts | 16 ++++-- plugins/search-backend/src/service/router.ts | 1 + 4 files changed, 48 insertions(+), 23 deletions(-) create mode 100644 .changeset/tiny-pianos-work.md diff --git a/.changeset/tiny-pianos-work.md b/.changeset/tiny-pianos-work.md new file mode 100644 index 0000000000..033e8272e5 --- /dev/null +++ b/.changeset/tiny-pianos-work.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search-backend': patch +--- + +The `AuthorizedSearchEngine` will now ignore the deprecated `token` option, and treat it as an unauthorized request. This will not have any effect in practice, since credentials are always provided by the router. diff --git a/plugins/search-backend/src/service/AuthorizedSearchEngine.test.ts b/plugins/search-backend/src/service/AuthorizedSearchEngine.test.ts index 420af5744b..e41f3f888b 100644 --- a/plugins/search-backend/src/service/AuthorizedSearchEngine.test.ts +++ b/plugins/search-backend/src/service/AuthorizedSearchEngine.test.ts @@ -32,6 +32,7 @@ import { decodePageCursor, AuthorizedSearchEngine, } from './AuthorizedSearchEngine'; +import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; describe('AuthorizedSearchEngine', () => { const typeUsers = 'users'; @@ -117,10 +118,11 @@ describe('AuthorizedSearchEngine', () => { searchEngine, defaultTypes, permissionEvaluator, + mockServices.auth(), new ConfigReader({}), ); - const options = { token: 'token' }; + const options = { credentials: mockCredentials.user() }; const allowAll: PermissionEvaluator['authorize'] & PermissionEvaluator['authorizeConditional'] = async queries => { @@ -149,7 +151,7 @@ describe('AuthorizedSearchEngine', () => { types: ['one', 'two'], filters, }, - { token: 'token' }, + options, ); }); @@ -160,7 +162,18 @@ describe('AuthorizedSearchEngine', () => { await authorizedSearchEngine.query({ term: '' }, options); expect(mockedQuery).toHaveBeenCalledWith( { term: '', types: ['users', 'templates', 'services', 'groups'] }, - { token: 'token' }, + options, + ); + }); + + it('should fall back to none credentials if a token is provided', async () => { + mockedQuery.mockImplementation(async () => ({ results })); + mockedPermissionQuery.mockImplementation(allowAll); + + await authorizedSearchEngine.query({ term: '' }, { token: 'token' }); + expect(mockedQuery).toHaveBeenCalledWith( + { term: '', types: ['users', 'templates', 'services', 'groups'] }, + { credentials: mockCredentials.none() }, ); }); @@ -184,7 +197,7 @@ describe('AuthorizedSearchEngine', () => { ); expect(mockedQuery).toHaveBeenCalledWith( { term: '', types: ['users', 'templates'] }, - { token: 'token' }, + options, ); expect(mockedPermissionQuery).toHaveBeenCalledTimes(1); expect(mockedPermissionQuery).toHaveBeenLastCalledWith( @@ -192,7 +205,7 @@ describe('AuthorizedSearchEngine', () => { { permission: defaultTypes[typeUsers].visibilityPermission }, { permission: defaultTypes[typeTemplates].visibilityPermission }, ], - { token: 'token' }, + options, ); }); @@ -218,7 +231,7 @@ describe('AuthorizedSearchEngine', () => { expect(mockedQuery).toHaveBeenCalledWith( { term: '', types: ['templates', 'services', 'groups'] }, - { token: 'token' }, + options, ); expect(mockedPermissionQuery).toHaveBeenCalledTimes(1); @@ -270,7 +283,7 @@ describe('AuthorizedSearchEngine', () => { expect(mockedQuery).toHaveBeenCalledWith( { term: '', types: ['users'] }, - { token: 'token' }, + options, ); }); @@ -326,7 +339,7 @@ describe('AuthorizedSearchEngine', () => { }), }, ], - { token: 'token' }, + options, ); expect(mockedAuthorize).toHaveBeenCalledTimes(1); expect(mockedAuthorize).toHaveBeenCalledWith( @@ -338,7 +351,7 @@ describe('AuthorizedSearchEngine', () => { resourceRef: 'template_doc_0', }, ], - { token: 'token' }, + options, ); }); @@ -403,7 +416,7 @@ describe('AuthorizedSearchEngine', () => { expect(mockedQuery).toHaveBeenNthCalledWith( 1, { term: '', types: ['users', 'templates', 'services'] }, - { token: 'token' }, + options, ); expect(mockedQuery).toHaveBeenNthCalledWith( 2, @@ -412,7 +425,7 @@ describe('AuthorizedSearchEngine', () => { types: ['users', 'templates', 'services'], pageCursor: 'MQ==', }, - { token: 'token' }, + options, ); expect(mockedQuery).toHaveBeenNthCalledWith( 3, @@ -421,7 +434,7 @@ describe('AuthorizedSearchEngine', () => { types: ['users', 'templates', 'services'], pageCursor: 'Mg==', }, - { token: 'token' }, + options, ); const expectedResult = allDocuments @@ -494,7 +507,7 @@ describe('AuthorizedSearchEngine', () => { expect(mockedQuery).toHaveBeenNthCalledWith( 1, { term: '', types: ['users', 'templates', 'services', 'groups'] }, - { token: 'token' }, + options, ); expect(mockedQuery).toHaveBeenNthCalledWith( 2, @@ -503,7 +516,7 @@ describe('AuthorizedSearchEngine', () => { types: ['users', 'templates', 'services', 'groups'], pageCursor: 'MQ==', }, - { token: 'token' }, + options, ); expect(mockedQuery).toHaveBeenNthCalledWith( 3, @@ -512,7 +525,7 @@ describe('AuthorizedSearchEngine', () => { types: ['users', 'templates', 'services', 'groups'], pageCursor: 'Mg==', }, - { token: 'token' }, + options, ); const expectedResult = allDocuments @@ -574,7 +587,7 @@ describe('AuthorizedSearchEngine', () => { expect(mockedQuery).toHaveBeenNthCalledWith( 1, { term: '', types: ['users', 'templates', 'services'] }, - { token: 'token' }, + options, ); expect(mockedQuery).toHaveBeenNthCalledWith( 2, @@ -583,7 +596,7 @@ describe('AuthorizedSearchEngine', () => { types: ['users', 'templates', 'services'], pageCursor: 'MQ==', }, - { token: 'token' }, + options, ); expect(mockedQuery).toHaveBeenNthCalledWith( 3, @@ -592,7 +605,7 @@ describe('AuthorizedSearchEngine', () => { types: ['users', 'templates', 'services'], pageCursor: 'Mg==', }, - { token: 'token' }, + options, ); const expectedResults = servicesWithAuth diff --git a/plugins/search-backend/src/service/AuthorizedSearchEngine.ts b/plugins/search-backend/src/service/AuthorizedSearchEngine.ts index defb535f42..d9d3feeacf 100644 --- a/plugins/search-backend/src/service/AuthorizedSearchEngine.ts +++ b/plugins/search-backend/src/service/AuthorizedSearchEngine.ts @@ -39,7 +39,7 @@ import { import { Config } from '@backstage/config'; import { InputError } from '@backstage/errors'; import { Writable } from 'stream'; -import { PermissionsService } from '@backstage/backend-plugin-api'; +import { AuthService, PermissionsService } from '@backstage/backend-plugin-api'; export function decodePageCursor(pageCursor?: string): { page: number } { if (!pageCursor) { @@ -71,6 +71,7 @@ export class AuthorizedSearchEngine implements SearchEngine { private readonly searchEngine: SearchEngine, private readonly types: Record, private readonly permissions: PermissionsService, + private readonly auth: AuthService, config: Config, ) { this.queryLatencyBudgetMs = @@ -92,9 +93,14 @@ export class AuthorizedSearchEngine implements SearchEngine { ): Promise { const queryStartTime = Date.now(); + const compatOptions = + 'credentials' in options + ? options + : { credentials: await this.auth.getNoneCredentials() }; + const conditionFetcher = new DataLoader( (requests: readonly QueryPermissionRequest[]) => - this.permissions.authorizeConditional(requests.slice(), options), + this.permissions.authorizeConditional(requests.slice(), compatOptions), { cacheKeyFn: ({ permission: { name } }) => name, }, @@ -102,7 +108,7 @@ export class AuthorizedSearchEngine implements SearchEngine { const authorizer = new DataLoader( (requests: readonly AuthorizePermissionRequest[]) => - this.permissions.authorize(requests.slice(), options), + this.permissions.authorize(requests.slice(), compatOptions), { // Serialize the permission name and resourceRef as // a query string to avoid collisions from overlapping @@ -159,7 +165,7 @@ export class AuthorizedSearchEngine implements SearchEngine { if (!resultByResultFilteringRequired) { return this.searchEngine.query( { ...query, types: authorizedTypes }, - options, + compatOptions, ); } @@ -174,7 +180,7 @@ export class AuthorizedSearchEngine implements SearchEngine { do { const nextPage = await this.searchEngine.query( { ...query, types: authorizedTypes, pageCursor: nextPageCursor }, - options, + compatOptions, ); filteredResults = filteredResults.concat( diff --git a/plugins/search-backend/src/service/router.ts b/plugins/search-backend/src/service/router.ts index 250be2853c..d226805baf 100644 --- a/plugins/search-backend/src/service/router.ts +++ b/plugins/search-backend/src/service/router.ts @@ -145,6 +145,7 @@ export async function createRouter( inputEngine, types, permissionEvaluator, + auth, config, ) : inputEngine; From ed10fd202c81f4114480fd3f831ad01507f5b021 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 12 Jul 2024 13:39:40 +0200 Subject: [PATCH 252/510] permission-node: update policy handler to work with new auth system Signed-off-by: Patrik Oldsberg --- .changeset/brown-rats-judge.md | 5 ++ .changeset/eleven-foxes-sip.md | 11 +++++ .../building-backends/08-migrating.md | 4 +- docs/features/kubernetes/proxy.md | 4 +- ...authorizing-scaffolder-template-details.md | 24 ++++----- docs/permissions/custom-rules.md | 9 ++-- .../02-adding-a-basic-permission-check.md | 11 ++--- .../03-adding-a-resource-permission-check.md | 8 +-- docs/permissions/writing-a-policy.md | 23 ++++----- .../src/policy.ts | 4 +- .../src/service/router.test.ts | 7 +++ .../permission-backend/src/service/router.ts | 14 +++--- plugins/permission-node/api-report.md | 18 +++++-- plugins/permission-node/src/policy/index.ts | 2 +- plugins/permission-node/src/policy/types.ts | 49 +++++++++++++++++-- 15 files changed, 127 insertions(+), 66 deletions(-) create mode 100644 .changeset/brown-rats-judge.md create mode 100644 .changeset/eleven-foxes-sip.md diff --git a/.changeset/brown-rats-judge.md b/.changeset/brown-rats-judge.md new file mode 100644 index 0000000000..0076c65d77 --- /dev/null +++ b/.changeset/brown-rats-judge.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-permission-backend-module-allow-all-policy': patch +--- + +Internal refactor to use new `PolicyQueryUser` type. diff --git a/.changeset/eleven-foxes-sip.md b/.changeset/eleven-foxes-sip.md new file mode 100644 index 0000000000..8b21ddb20f --- /dev/null +++ b/.changeset/eleven-foxes-sip.md @@ -0,0 +1,11 @@ +--- +'@backstage/plugin-permission-backend': patch +'@backstage/plugin-permission-node': patch +--- + +The `PermissionPolicy` interface has been updated to align with the recent changes to the Backstage auth system. The second argument to the `handle` method is now of the new `PolicyQueryUser` type. This type maintains the old fields from the `BackstageIdentityResponse`, which are now all deprecated. Instead, two new fields have been added, which allows access to the same information: + +- `credentials` - A `BackstageCredentials` object, which is useful for making requests to other services on behalf of the user as part of evaluating the policy. This replaces the deprecated `token` field. See the [Auth Service documentation](https://backstage.io/docs/backend-system/core-services/auth#creating-request-tokens) for information about how to create a token using these credentials. +- `info` - A `BackstageUserInfo` object, which contains the same information as the deprecated `identity`, except for the `type` field that was redundant. + +Most existing policies can be updated by replacing the `BackstageIdentityResponse` type with `PolicyQueryUser`, which is exported from `@backstage/plugin-permission-node`, as well as replacing any occurrences of `user?.identity` with `user?.info`. diff --git a/docs/backend-system/building-backends/08-migrating.md b/docs/backend-system/building-backends/08-migrating.md index d38acb695e..c6db44078e 100644 --- a/docs/backend-system/building-backends/08-migrating.md +++ b/docs/backend-system/building-backends/08-migrating.md @@ -1254,7 +1254,6 @@ In order to add your own permission policy you'll need to do the following: ```ts import { createBackendModule } from '@backstage/backend-plugin-api'; -import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; import { PolicyDecision, AuthorizeResult, @@ -1262,13 +1261,14 @@ import { import { PermissionPolicy, PolicyQuery, + PolicyQueryUser, } from '@backstage/plugin-permission-node'; import { policyExtensionPoint } from '@backstage/plugin-permission-node/alpha'; class CustomPermissionPolicy implements PermissionPolicy { async handle( request: PolicyQuery, - user?: BackstageIdentityResponse, + user?: PolicyQueryUser, ): Promise { // TODO: Add code here that inspects the incoming request and user, and returns AuthorizeResult.ALLOW, AuthorizeResult.DENY, or AuthorizeResult.CONDITIONAL as needed. See the docs at https://backstage.io/docs/permissions/writing-a-policy for more information diff --git a/docs/features/kubernetes/proxy.md b/docs/features/kubernetes/proxy.md index 2da797d8ef..85ad86f83b 100644 --- a/docs/features/kubernetes/proxy.md +++ b/docs/features/kubernetes/proxy.md @@ -60,7 +60,6 @@ This feature assumes your backstage instance has enabled the [permissions framew A sample policy like: ```typescript -import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; import { AuthorizeResult, PolicyDecision, @@ -68,12 +67,13 @@ import { import { PermissionPolicy, PolicyQuery, + PolicyQueryUser, } from '@backstage/plugin-permission-node'; class KubernetesDenyAllProxyEndpointPolicy implements PermissionPolicy { async handle( request: PolicyQuery, - user?: BackstageIdentityResponse, + user?: PolicyQueryUser, ): Promise { if (request.permission.name === 'kubernetes.proxy') { return { diff --git a/docs/features/software-templates/authorizing-scaffolder-template-details.md b/docs/features/software-templates/authorizing-scaffolder-template-details.md index 127677757c..942431c993 100644 --- a/docs/features/software-templates/authorizing-scaffolder-template-details.md +++ b/docs/features/software-templates/authorizing-scaffolder-template-details.md @@ -66,14 +66,14 @@ import { class ExamplePermissionPolicy implements PermissionPolicy { async handle( request: PolicyQuery, - user?: BackstageIdentityResponse, + user?: PolicyQueryUser, ): Promise { /* highlight-add-start */ if ( isPermission(request.permission, templateParameterReadPermission) || isPermission(request.permission, templateStepReadPermission) ) { - if (user?.identity.userEntityRef === 'user:default/spiderman') + if (user?.info.userEntityRef === 'user:default/spiderman') return createScaffolderTemplateConditionalDecision(request.permission, { not: scaffolderTemplateConditions.hasTag({ tag: 'secret' }), }); @@ -109,11 +109,11 @@ import { class ExamplePermissionPolicy implements PermissionPolicy { async handle( request: PolicyQuery, - user?: BackstageIdentityResponse, + user?: PolicyQueryUser, ): Promise { /* highlight-add-start */ if (isPermission(request.permission, actionExecutePermission)) { - if (user?.identity.userEntityRef === 'user:default/spiderman') { + if (user?.info.userEntityRef === 'user:default/spiderman') { return createScaffolderActionConditionalDecision(request.permission, { not: scaffolderActionConditions.hasActionId({ actionId: 'debug:log', @@ -147,11 +147,11 @@ import { class ExamplePermissionPolicy implements PermissionPolicy { async handle( request: PolicyQuery, - user?: BackstageIdentityResponse, + user?: PolicyQueryUser, ): Promise { /* highlight-add-start */ if (isPermission(request.permission, actionExecutePermission)) { - if (user?.identity.userEntityRef === 'user:default/spiderman') { + if (user?.info.userEntityRef === 'user:default/spiderman') { return createScaffolderActionConditionalDecision(request.permission, { not: { allOf: [ @@ -190,25 +190,25 @@ import { class ExamplePermissionPolicy implements PermissionPolicy { async handle( request: PolicyQuery, - user?: BackstageIdentityResponse, + user?: PolicyQueryUser, ): Promise { /* highlight-add-start */ if (isPermission(request.permission, taskCreatePermission)) { - if (user?.identity.userEntityRef === 'user:default/spiderman') { + if (user?.info.userEntityRef === 'user:default/spiderman') { return { result: AuthorizeResult.ALLOW, }; } } if (isPermission(request.permission, taskCancelPermission)) { - if (user?.identity.userEntityRef === 'user:default/spiderman') { + if (user?.info.userEntityRef === 'user:default/spiderman') { return { result: AuthorizeResult.ALLOW, }; } } if (isPermission(request.permission, taskReadPermission)) { - if (user?.identity.userEntityRef === 'user:default/spiderman') { + if (user?.info.userEntityRef === 'user:default/spiderman') { return { result: AuthorizeResult.ALLOW, }; @@ -239,7 +239,6 @@ Instead of the changes in `permission.ts` noted in the above example you will ma ```ts title="packages/backend/src/index.ts" import { createBackendModule } from '@backstage/backend-plugin-api'; -import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; import { PolicyDecision, AuthorizeResult, @@ -247,13 +246,14 @@ import { import { PermissionPolicy, PolicyQuery, + PolicyQueryUser, } from '@backstage/plugin-permission-node'; import { policyExtensionPoint } from '@backstage/plugin-permission-node/alpha'; class ExamplePermissionPolicy implements PermissionPolicy { async handle( request: PolicyQuery, - user?: BackstageIdentityResponse, + user?: PolicyQueryUser, ): Promise { // Various scaffolder permission checks ... diff --git a/docs/permissions/custom-rules.md b/docs/permissions/custom-rules.md index 9063ed7257..57565755fb 100644 --- a/docs/permissions/custom-rules.md +++ b/docs/permissions/custom-rules.md @@ -66,9 +66,8 @@ import { catalogConditions, createCatalogConditionalDecision, createCatalogPermi /* highlight-remove-next-line */ import { createConditionFactory } from '@backstage/plugin-permission-node'; /* highlight-add-next-line */ -import { PermissionPolicy, PolicyQuery, createConditionFactory } from '@backstage/plugin-permission-node'; +import { PermissionPolicy, PolicyQuery, PolicyQueryUser, createConditionFactory } from '@backstage/plugin-permission-node'; /* highlight-add-start */ -import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; import { AuthorizeResult, PolicyDecision, isResourcePermission } from '@backstage/plugin-permission-common'; /* highlight-add-end */ ... @@ -102,21 +101,21 @@ const isInSystem = createConditionFactory(isInSystemRule); class TestPermissionPolicy implements PermissionPolicy { async handle( request: PolicyQuery, - user?: BackstageIdentityResponse, + user?: PolicyQueryUser, ): Promise { if (isResourcePermission(request.permission, 'catalog-entity')) { return createCatalogConditionalDecision( request.permission, /* highlight-remove-start */ catalogConditions.isEntityOwner({ - claims: user?.identity.ownershipEntityRefs ?? [], + claims: user?.info.ownershipEntityRefs ?? [], }), /* highlight-remove-end */ /* highlight-add-start */ { anyOf: [ catalogConditions.isEntityOwner({ - claims: user?.identity.ownershipEntityRefs ?? [], + claims: user?.info.ownershipEntityRefs ?? [], }), isInSystem({ systemRef: 'interviewing' }), ], diff --git a/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md b/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md index aacd60af8c..724edb7ccb 100644 --- a/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md +++ b/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md @@ -169,15 +169,12 @@ Before running this step, please make sure you followed the steps described in [ In order to test the logic above, the integrators of your backstage instance need to change their permission policy to return `DENY` for our newly-created permission: ```ts title="packages/backend/src/plugins/permission.ts" -/* highlight-add-start */ -import { - BackstageIdentityResponse, -} from '@backstage/plugin-auth-node'; -/* highlight-add-end */ import { PermissionPolicy, - /* highlight-add-next-line */ + /* highlight-add-start */ PolicyQuery, + PolicyQueryUser, + /* highlight-add-end */ } from '@backstage/plugin-permission-node'; /* highlight-add-start */ import { isPermission } from '@backstage/plugin-permission-common'; @@ -190,7 +187,7 @@ class TestPermissionPolicy implements PermissionPolicy { /* highlight-add-start */ async handle( request: PolicyQuery, - _user?: BackstageIdentityResponse, + _user?: PolicyQueryUser, ): Promise { if (isPermission(request.permission, todoListCreatePermission)) { return { diff --git a/docs/permissions/plugin-authors/03-adding-a-resource-permission-check.md b/docs/permissions/plugin-authors/03-adding-a-resource-permission-check.md index b3aeb13a68..7ad551e926 100644 --- a/docs/permissions/plugin-authors/03-adding-a-resource-permission-check.md +++ b/docs/permissions/plugin-authors/03-adding-a-resource-permission-check.md @@ -237,12 +237,12 @@ Let's go back to the permission policy's handle function and try to authorize ou ```ts title="packages/backend/src/plugins/permission.ts" import { - BackstageIdentityResponse, IdentityClient } from '@backstage/plugin-auth-node'; import { PermissionPolicy, PolicyQuery, + PolicyQueryUser, } from '@backstage/plugin-permission-node'; import { isPermission } from '@backstage/plugin-permission-common'; /* highlight-remove-next-line */ @@ -262,9 +262,9 @@ import { async handle( request: PolicyQuery, /* highlight-remove-next-line */ - _user?: BackstageIdentityResponse, + _user?: PolicyQueryUser, /* highlight-add-next-line */ - user?: BackstageIdentityResponse, + user?: PolicyQueryUser, ): Promise { if (isPermission(request.permission, todoListCreatePermission)) { return { @@ -276,7 +276,7 @@ async handle( return createTodoListConditionalDecision( request.permission, todoListConditions.isOwner({ - userId: user?.identity.userEntityRef ?? '', + userId: user?.info.userEntityRef ?? '', }), ); } diff --git a/docs/permissions/writing-a-policy.md b/docs/permissions/writing-a-policy.md index 3d4371f038..0f2d4fe091 100644 --- a/docs/permissions/writing-a-policy.md +++ b/docs/permissions/writing-a-policy.md @@ -10,7 +10,10 @@ That policy looked like this: ```typescript title="packages/backend/src/plugins/permission.ts" class TestPermissionPolicy implements PermissionPolicy { - async handle(request: PolicyQuery): Promise { + async handle( + request: PolicyQuery, + _user?: PolicyQueryUser, + ): Promise { if (request.permission.name === 'catalog.entity.delete') { return { result: AuthorizeResult.DENY, @@ -35,14 +38,6 @@ As we confirmed in the previous section, we know that this now prevents us from Let's change the policy to the following: ```ts -/* highlight-remove-next-line */ -import { IdentityClient } from '@backstage/plugin-auth-node'; -/* highlight-add-start */ -import { - BackstageIdentityResponse, - IdentityClient -} from '@backstage/plugin-auth-node'; - /* highlight-add-end */ import { AuthorizeResult, PolicyDecision, @@ -65,7 +60,7 @@ class TestPermissionPolicy implements PermissionPolicy { /* highlight-add-start */ async handle( request: PolicyQuery, - user?: BackstageIdentityResponse, + user?: PolicyQueryUser, ): Promise { /* highlight-add-end */ /* highlight-remove-next-line */ @@ -81,7 +76,7 @@ class TestPermissionPolicy implements PermissionPolicy { return createCatalogConditionalDecision( request.permission, catalogConditions.isEntityOwner({ - claims: user?.identity.ownershipEntityRefs ?? [], + claims: user?.info.ownershipEntityRefs ?? [], }), ); /* highlight-add-end */ @@ -95,7 +90,7 @@ Let's walk through the new code that we just added. Instead of returning an Definitive Policy Decision, we use factory methods to construct a [Conditional Policy Decision](https://backstage.io/docs/reference/plugin-permission-common.conditionalpolicydecision) (See the [Concepts page](./concepts.md) for more details). Since the policy doesn't have enough information to determine if `user` is the entity owner, this criteria is encapsulated within the conditional decision. However, `createCatalogConditionalDecision` will not compile unless `request.permission` is a catalog entity [`ResourcePermission`](https://backstage.io/docs/reference/plugin-permission-common.resourcepermission). This type constraint ensures that policies return conditional decisions that are compatible with the requested permission. To address this, we use [`isPermission`](https://backstage.io/docs/reference/plugin-permission-common.ispermission) to ["narrow"](https://www.typescriptlang.org/docs/handbook/2/narrowing.html) the type of `request.permission` to `ResourcePermission<'catalog-entity'>`. This matches the runtime behavior that was in place before, but you'll notice that the type of `request.permission` has changed within the scope of that `if` statement. -The `catalogConditions` object contains all of the rules defined by the catalog plugin. These rules can be combined to form a [`PermissionCriteria`](https://backstage.io/docs/reference/plugin-permission-common.permissioncriteria) object, but for this case we only need to use the `isEntityOwner` rule. This rule accepts a list of entity refs that represent User identity and Group membership used to determine ownership. The second argument to `PermissionPolicy#handle` provides us with a `BackstageIdentityResponse` object, from which we can grab the user's `ownershipEntityRefs`. We provide an empty array as a fallback since the user may be anonymous. +The `catalogConditions` object contains all of the rules defined by the catalog plugin. These rules can be combined to form a [`PermissionCriteria`](https://backstage.io/docs/reference/plugin-permission-common.permissioncriteria) object, but for this case we only need to use the `isEntityOwner` rule. This rule accepts a list of entity refs that represent User identity and Group membership used to determine ownership. The second argument to `PermissionPolicy#handle` provides us with a `PolicyQueryUser` object, from which we can grab the user's `ownershipEntityRefs`. We provide an empty array as a fallback since the user may be anonymous. You should now be able to see in your Backstage app that the unregister entity button is enabled for entities that you own, but disabled for all other entities! @@ -125,7 +120,7 @@ import { class TestPermissionPolicy implements PermissionPolicy { async handle( request: PolicyQuery, - user?: BackstageIdentityResponse, + user?: PolicyQueryUser, ): Promise { /* highlight-remove-next-line */ if (isPermission(request.permission, catalogEntityDeletePermission)) { @@ -134,7 +129,7 @@ class TestPermissionPolicy implements PermissionPolicy { return createCatalogConditionalDecision( request.permission, catalogConditions.isEntityOwner({ - claims: user?.identity.ownershipEntityRefs ?? [], + claims: user?.info.ownershipEntityRefs ?? [], }), ); } diff --git a/plugins/permission-backend-module-policy-allow-all/src/policy.ts b/plugins/permission-backend-module-policy-allow-all/src/policy.ts index da853e47db..90ae21f341 100644 --- a/plugins/permission-backend-module-policy-allow-all/src/policy.ts +++ b/plugins/permission-backend-module-policy-allow-all/src/policy.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; import { AuthorizeResult, PolicyDecision, @@ -22,12 +21,13 @@ import { import { PermissionPolicy, PolicyQuery, + PolicyQueryUser, } from '@backstage/plugin-permission-node'; export class AllowAllPermissionPolicy implements PermissionPolicy { async handle( _request: PolicyQuery, - _user?: BackstageIdentityResponse, + _user?: PolicyQueryUser, ): Promise { return { result: AuthorizeResult.ALLOW, diff --git a/plugins/permission-backend/src/service/router.test.ts b/plugins/permission-backend/src/service/router.test.ts index be90c5f628..f12bacc61d 100644 --- a/plugins/permission-backend/src/service/router.test.ts +++ b/plugins/permission-backend/src/service/router.test.ts @@ -186,6 +186,13 @@ describe('createRouter', () => { mockCredentials.user().principal.userEntityRef, ], }, + info: { + userEntityRef: mockCredentials.user().principal.userEntityRef, + ownershipEntityRefs: [ + mockCredentials.user().principal.userEntityRef, + ], + }, + credentials: mockCredentials.user(), }, ); expect(response.body).toEqual({ diff --git a/plugins/permission-backend/src/service/router.ts b/plugins/permission-backend/src/service/router.ts index cc45d0b41a..fd33f0b629 100644 --- a/plugins/permission-backend/src/service/router.ts +++ b/plugins/permission-backend/src/service/router.ts @@ -22,10 +22,7 @@ import { errorHandler, } from '@backstage/backend-common'; import { InputError } from '@backstage/errors'; -import { - BackstageIdentityResponse, - IdentityApi, -} from '@backstage/plugin-auth-node'; +import { IdentityApi } from '@backstage/plugin-auth-node'; import { AuthorizeResult, EvaluatePermissionRequest, @@ -40,6 +37,7 @@ import { ApplyConditionsRequestEntry, ApplyConditionsResponseEntry, PermissionPolicy, + PolicyQueryUser, } from '@backstage/plugin-permission-node'; import { PermissionIntegrationClient } from './PermissionIntegrationClient'; import { memoize } from 'lodash'; @@ -130,9 +128,9 @@ const handleRequest = async ( ); }); - let user: BackstageIdentityResponse | undefined; + let user: PolicyQueryUser | undefined; if (auth.isPrincipal(credentials, 'user')) { - const { ownershipEntityRefs } = await userInfo.getUserInfo(credentials); + const info = await userInfo.getUserInfo(credentials); const { token } = await auth.getPluginRequestToken({ onBehalfOf: credentials, targetPluginId: 'catalog', // TODO: unknown at this point @@ -141,9 +139,11 @@ const handleRequest = async ( identity: { type: 'user', userEntityRef: credentials.principal.userEntityRef, - ownershipEntityRefs, + ownershipEntityRefs: info.ownershipEntityRefs, }, token, + credentials, + info, }; } diff --git a/plugins/permission-node/api-report.md b/plugins/permission-node/api-report.md index 290c586f2c..81460ef630 100644 --- a/plugins/permission-node/api-report.md +++ b/plugins/permission-node/api-report.md @@ -8,7 +8,9 @@ import { AnyOfCriteria } from '@backstage/plugin-permission-common'; import { AuthorizePermissionRequest } from '@backstage/plugin-permission-common'; import { AuthorizePermissionResponse } from '@backstage/plugin-permission-common'; import { AuthService } from '@backstage/backend-plugin-api'; -import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; +import { BackstageCredentials } from '@backstage/backend-plugin-api'; +import { BackstageUserIdentity } from '@backstage/plugin-auth-node'; +import { BackstageUserInfo } from '@backstage/backend-plugin-api'; import { ConditionalPolicyDecision } from '@backstage/plugin-permission-common'; import { Config } from '@backstage/config'; import { DefinitivePolicyDecision } from '@backstage/plugin-permission-common'; @@ -246,10 +248,7 @@ export type PermissionIntegrationRouterOptions< // @public export interface PermissionPolicy { // (undocumented) - handle( - request: PolicyQuery, - user?: BackstageIdentityResponse, - ): Promise; + handle(request: PolicyQuery, user?: PolicyQueryUser): Promise; } // @public @@ -272,6 +271,15 @@ export type PolicyQuery = { permission: Permission; }; +// @public +export type PolicyQueryUser = { + token: string; + expiresInSeconds?: number; + identity: BackstageUserIdentity; + credentials: BackstageCredentials; + info: BackstageUserInfo; +}; + // @public export class ServerPermissionClient implements PermissionsService { // (undocumented) diff --git a/plugins/permission-node/src/policy/index.ts b/plugins/permission-node/src/policy/index.ts index f151cfb4fb..fd47ed7e62 100644 --- a/plugins/permission-node/src/policy/index.ts +++ b/plugins/permission-node/src/policy/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export type { PermissionPolicy, PolicyQuery } from './types'; +export type { PermissionPolicy, PolicyQuery, PolicyQueryUser } from './types'; diff --git a/plugins/permission-node/src/policy/types.ts b/plugins/permission-node/src/policy/types.ts index 0f469cfbfe..a7b8b75218 100644 --- a/plugins/permission-node/src/policy/types.ts +++ b/plugins/permission-node/src/policy/types.ts @@ -18,7 +18,11 @@ import { Permission, PolicyDecision, } from '@backstage/plugin-permission-common'; -import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; +import { BackstageUserIdentity } from '@backstage/plugin-auth-node'; +import { + BackstageCredentials, + BackstageUserInfo, +} from '@backstage/backend-plugin-api'; /** * A query to be evaluated by the {@link PermissionPolicy}. @@ -34,6 +38,44 @@ export type PolicyQuery = { permission: Permission; }; +/** + * The context within which a policy query is evaluated. + * + * @public + */ +export type PolicyQueryUser = { + /** + * The token used to authenticate the user within Backstage. + * + * @deprecated User the `credentials` field in combination with `coreServices.auth` to generate a request token instead. + */ + token: string; + + /** + * The number of seconds until the token expires. If not set, it can be assumed that the token does not expire. + * + * @deprecated This field is deprecated and will be removed in a future release. + */ + expiresInSeconds?: number; + + /** + * A plaintext description of the identity that is encapsulated within the token. + * + * @deprecated Use the `info` field instead. + */ + identity: BackstageUserIdentity; + + /** + * The credentials of the user making the request. + */ + credentials: BackstageCredentials; + + /** + * The information for the user making the request. + */ + info: BackstageUserInfo; +}; + /** * A policy to evaluate authorization requests for any permissioned action performed in Backstage. * @@ -51,8 +93,5 @@ export type PolicyQuery = { * @public */ export interface PermissionPolicy { - handle( - request: PolicyQuery, - user?: BackstageIdentityResponse, - ): Promise; + handle(request: PolicyQuery, user?: PolicyQueryUser): Promise; } From 4d7e11f0149b5940fc43b79e2d4d0fa08af4ad8f Mon Sep 17 00:00:00 2001 From: Frank Kong <50030060+Zaperex@users.noreply.github.com> Date: Fri, 12 Jul 2024 10:06:01 -0400 Subject: [PATCH 253/510] chore(scaffolder): allow task viewer to be resizable and disable rendering of empty output (#25495) chore(scaffolder): allow task viewer to be resizable and disable rendering of empty output (#25495) --- .changeset/four-donuts-switch.md | 5 +++ .changeset/witty-keys-share.md | 5 +++ .../DefaultTemplateOutputs.test.tsx | 21 +++++++++-- .../DefaultTemplateOutputs.tsx | 35 ++++++++++++------- plugins/scaffolder/package.json | 2 ++ .../components/OngoingTask/OngoingTask.tsx | 5 +-- yarn.lock | 13 ++++++- 7 files changed, 68 insertions(+), 18 deletions(-) create mode 100644 .changeset/four-donuts-switch.md create mode 100644 .changeset/witty-keys-share.md diff --git a/.changeset/four-donuts-switch.md b/.changeset/four-donuts-switch.md new file mode 100644 index 0000000000..bb876a4341 --- /dev/null +++ b/.changeset/four-donuts-switch.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +enable resizing of the task log stream viewer diff --git a/.changeset/witty-keys-share.md b/.changeset/witty-keys-share.md new file mode 100644 index 0000000000..0ef89e56e2 --- /dev/null +++ b/.changeset/witty-keys-share.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-react': patch +--- + +disables rendering of output box if no output is returned diff --git a/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.test.tsx b/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.test.tsx index 4c631b86b0..7ec3b0867c 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.test.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.test.tsx @@ -31,7 +31,7 @@ describe('', () => { ], }; - const { getByRole } = await renderInTestApp( + const { getByRole, queryByTestId } = await renderInTestApp( , { mountedRoutes: { @@ -39,7 +39,8 @@ describe('', () => { }, }, ); - + expect(queryByTestId('output-box')).not.toBeNull(); + expect(queryByTestId('text-output-box')).not.toBeNull(); // first text output default visible expect(getByRole('heading', { level: 2 }).innerHTML).toBe( output.text[0].title, @@ -61,4 +62,20 @@ describe('', () => { expect(getByRole('heading', { level: 2 }).innerHTML).toBe(text.title); } }); + it('should not render anything when output is empty', async () => { + // This is the default case when no output field is present in the template + const output = {}; + const { queryByTestId } = await renderInTestApp( + , + { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, + }, + ); + + // Ensure that nothing renders from this component + expect(queryByTestId('output-box')).toBeNull(); + expect(queryByTestId('text-output-box')).toBeNull(); + }); }); diff --git a/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.tsx b/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.tsx index 7d90623077..cbc299bf1c 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.tsx @@ -56,22 +56,31 @@ export const DefaultTemplateOutputs = (props: { return null; } + const emptyOutput = Object.keys(output).length === 0; + return ( <> - - - - - - - - + {!emptyOutput ? ( + + + + + + + + + ) : null} {textOutput ? ( - + + - + ) : null} diff --git a/yarn.lock b/yarn.lock index afe89e4263..b0bff82017 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7314,6 +7314,7 @@ __metadata: "@types/humanize-duration": ^3.18.1 "@types/json-schema": ^7.0.9 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react-resizable": ^3.0.8 "@types/react-window": ^1.8.8 "@uiw/react-codemirror": ^4.9.3 classnames: ^2.2.6 @@ -7326,6 +7327,7 @@ __metadata: luxon: ^3.0.0 msw: ^1.0.0 qs: ^6.9.4 + react-resizable: ^3.0.5 react-use: ^17.2.4 react-window: ^1.8.10 swr: ^2.0.0 @@ -18461,6 +18463,15 @@ __metadata: languageName: node linkType: hard +"@types/react-resizable@npm:^3.0.8": + version: 3.0.8 + resolution: "@types/react-resizable@npm:3.0.8" + dependencies: + "@types/react": "*" + checksum: aabdef8056bbab3065559bce7ce93232e645fb4f915fd55f0903a2f4df5d2395762dfd75bb0242d5a73d39461e8c062d81eaab87b91213dddfd973ff908f79e4 + languageName: node + linkType: hard + "@types/react-sparklines@npm:^1.7.0": version: 1.7.5 resolution: "@types/react-sparklines@npm:1.7.5" @@ -38371,7 +38382,7 @@ __metadata: languageName: node linkType: hard -"react-resizable@npm:^3.0.4": +"react-resizable@npm:^3.0.4, react-resizable@npm:^3.0.5": version: 3.0.5 resolution: "react-resizable@npm:3.0.5" dependencies: From 842457d9ad2d2be4f43c6f859f6e4198e1f2f24e Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Fri, 12 Jul 2024 16:14:59 +0200 Subject: [PATCH 254/510] docs: update root logger service docs Signed-off-by: Camila Belo --- docs/backend-system/core-services/logger.md | 44 ------------------- .../core-services/root-logger.md | 44 ++++++++++++++++++- 2 files changed, 43 insertions(+), 45 deletions(-) diff --git a/docs/backend-system/core-services/logger.md b/docs/backend-system/core-services/logger.md index 015d2055d5..e18bd6a4c0 100644 --- a/docs/backend-system/core-services/logger.md +++ b/docs/backend-system/core-services/logger.md @@ -31,47 +31,3 @@ createBackendPlugin({ }, }); ``` - -## Root Logger - -The root logger is the logger that is used by other root services. It's where the implementation lies for creating child loggers around the backstage ecosystem including child loggers for plugins with the correct metadata and annotations. - -If you want to override the implementation for logging across all of the backend, this is the service that you should override. - -## Configuring the service - -The following example is how you can override the root logger service to add additional metadata to all log lines. - -```ts -import { coreServices } from '@backstage/backend-plugin-api'; -import { WinstonLogger } from '@backstage/backend-app-api'; - -const backend = createBackend(); - -backend.add( - createServiceFactory({ - service: coreServices.rootLogger, - deps: { - config: coreServices.rootConfig, - }, - async factory({ config }) { - const logger = WinstonLogger.create({ - meta: { - service: 'backstage', - // here's some additional information that is not part of the - // original implementation - podName: 'myk8spod', - }, - level: process.env.LOG_LEVEL || 'info', - format: - process.env.NODE_ENV === 'production' - ? format.json() - : WinstonLogger.colorFormat(), - transports: [new transports.Console()], - }); - - return logger; - }, - }), -); -``` diff --git a/docs/backend-system/core-services/root-logger.md b/docs/backend-system/core-services/root-logger.md index 09b7929efe..733b7b8277 100644 --- a/docs/backend-system/core-services/root-logger.md +++ b/docs/backend-system/core-services/root-logger.md @@ -5,4 +5,46 @@ sidebar_label: Root Logger description: Documentation for the Root Logger service --- -TODO +## Root Logger + +The root logger is the logger that is used by other root services. It's where the implementation lies for creating child loggers around the backstage ecosystem including child loggers for plugins with the correct metadata and annotations. + +If you want to override the implementation for logging across all of the backend, this is the service that you should override. + +## Configuring the service + +The following example is how you can override the root logger service to add additional metadata to all log lines. + +```ts +import { coreServices } from '@backstage/backend-plugin-api'; +import { WinstonLogger } from '@backstage/backend-app-api'; + +const backend = createBackend(); + +backend.add( + createServiceFactory({ + service: coreServices.rootLogger, + deps: { + config: coreServices.rootConfig, + }, + async factory({ config }) { + const logger = WinstonLogger.create({ + meta: { + service: 'backstage', + // here's some additional information that is not part of the + // original implementation + podName: 'myk8spod', + }, + level: process.env.LOG_LEVEL || 'info', + format: + process.env.NODE_ENV === 'production' + ? format.json() + : WinstonLogger.colorFormat(), + transports: [new transports.Console()], + }); + + return logger; + }, + }), +); +``` From dae85dfd213b1711fd850e48777361065725b1e4 Mon Sep 17 00:00:00 2001 From: parmar-abhinav Date: Sat, 13 Jul 2024 14:07:56 +0530 Subject: [PATCH 255/510] Add examples for fetch:cookiecutter scaffolder action & improve related tests Signed-off-by: parmar-abhinav --- .changeset/stupid-dots-relate.md | 5 + .../package.json | 1 + .../fetch/cookiecutter.examples.test.ts | 274 ++++++++++++++++++ .../actions/fetch/cookiecutter.examples.ts | 119 ++++++++ .../src/actions/fetch/cookiecutter.ts | 2 + 5 files changed, 401 insertions(+) create mode 100644 .changeset/stupid-dots-relate.md create mode 100644 plugins/scaffolder-backend-module-cookiecutter/src/actions/fetch/cookiecutter.examples.test.ts create mode 100644 plugins/scaffolder-backend-module-cookiecutter/src/actions/fetch/cookiecutter.examples.ts diff --git a/.changeset/stupid-dots-relate.md b/.changeset/stupid-dots-relate.md new file mode 100644 index 0000000000..a83777bff9 --- /dev/null +++ b/.changeset/stupid-dots-relate.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch +--- + +Add examples for `fetch:cookiecutter` scaffolder action & improve related tests diff --git a/plugins/scaffolder-backend-module-cookiecutter/package.json b/plugins/scaffolder-backend-module-cookiecutter/package.json index 43a7e348a4..261010f681 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/package.json +++ b/plugins/scaffolder-backend-module-cookiecutter/package.json @@ -53,6 +53,7 @@ "command-exists": "^1.2.9", "fs-extra": "^11.2.0", "winston": "^3.2.1", + "yaml": "^2.0.0", "yn": "^4.0.0" }, "devDependencies": { diff --git a/plugins/scaffolder-backend-module-cookiecutter/src/actions/fetch/cookiecutter.examples.test.ts b/plugins/scaffolder-backend-module-cookiecutter/src/actions/fetch/cookiecutter.examples.test.ts new file mode 100644 index 0000000000..ae46ef1bd6 --- /dev/null +++ b/plugins/scaffolder-backend-module-cookiecutter/src/actions/fetch/cookiecutter.examples.test.ts @@ -0,0 +1,274 @@ +/* + * 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 { UrlReader, ContainerRunner } from '@backstage/backend-common'; +import { ConfigReader } from '@backstage/config'; +import { JsonObject } from '@backstage/types'; +import { ScmIntegrations } from '@backstage/integration'; +import { createMockDirectory } from '@backstage/backend-test-utils'; +import { createFetchCookiecutterAction } from './cookiecutter'; +import { join } from 'path'; +import type { ActionContext } from '@backstage/plugin-scaffolder-node'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { examples } from './cookiecutter.examples'; +import yaml from 'yaml'; + +const executeShellCommand = jest.fn(); +const commandExists = jest.fn(); +const fetchContents = jest.fn(); + +jest.mock('@backstage/plugin-scaffolder-node', () => ({ + ...jest.requireActual('@backstage/plugin-scaffolder-node'), + fetchContents: (...args: any[]) => fetchContents(...args), + executeShellCommand: (...args: any[]) => executeShellCommand(...args), +})); + +jest.mock( + 'command-exists', + () => + (...args: any[]) => + commandExists(...args), +); + +describe('fetch:cookiecutter', () => { + const mockDir = createMockDirectory({ mockOsTmpDir: true }); + const integrations = ScmIntegrations.fromConfig( + new ConfigReader({ + integrations: { + azure: [ + { host: 'dev.azure.com', token: 'tokenlols' }, + { host: 'myazurehostnotoken.com' }, + ], + }, + }), + ); + + const mockTmpDir = mockDir.path; + + let mockContext: ActionContext<{ + url: string; + targetPath?: string; + values: JsonObject; + copyWithoutRender?: string[]; + extensions?: string[]; + imageName?: string; + }>; + + const containerRunner: jest.Mocked = { + runContainer: jest.fn(), + }; + + const mockReader: UrlReader = { + readUrl: jest.fn(), + readTree: jest.fn(), + search: jest.fn(), + }; + + const action = createFetchCookiecutterAction({ + integrations, + containerRunner, + reader: mockReader, + }); + + beforeEach(() => { + jest.resetAllMocks(); + + mockContext = createMockActionContext({ + input: { + url: 'https://google.com/cookie/cutter', + targetPath: 'something', + values: { + help: 'me', + }, + }, + templateInfo: { + entityRef: 'template:default/cookiecutter', + baseUrl: 'somebase', + }, + workspacePath: mockTmpDir, + }); + mockDir.setContent({ template: {} }); + + commandExists.mockResolvedValue(null); + + // Mock when run container is called it creates some new files in the mock filesystem + containerRunner.runContainer.mockImplementation(async () => { + mockDir.setContent({ + 'intermediate/testfile.json': '{}', + }); + }); + + // Mock when executeShellCommand is called it creates some new files in the mock filesystem + executeShellCommand.mockImplementation(async () => { + mockDir.setContent({ + 'intermediate/testfile.json': '{}', + }); + }); + }); + + it(`should ${examples[0].description}`, async () => { + const input = yaml.parse(examples[0].example).steps[0].input; + + commandExists.mockResolvedValue(false); + + fetchContents.mockImplementation(() => Promise.resolve()); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(fetchContents).toHaveBeenCalledWith( + expect.objectContaining({ + reader: mockReader, + integrations, + baseUrl: mockContext.templateInfo?.baseUrl, + fetchUrl: mockContext.input.url, + outputPath: join( + mockTmpDir, + 'template', + "{{cookiecutter and 'contents'}}", + ), + }), + ); + expect(containerRunner.runContainer).toHaveBeenCalled(); + }); + + it(`should ${examples[1].description}`, async () => { + const input = yaml.parse(examples[1].example).steps[0].input; + + commandExists.mockResolvedValue(false); + + fetchContents.mockImplementation(() => Promise.resolve()); + + await action.handler({ + ...mockContext, + input: input, + }); + + expect(fetchContents).toHaveBeenCalledWith( + expect.objectContaining({ + reader: mockReader, + integrations, + baseUrl: mockContext.templateInfo?.baseUrl, + fetchUrl: mockContext.input.url, + outputPath: join( + mockTmpDir, + 'template', + "{{cookiecutter and 'contents'}}", + ), + }), + ); + expect(containerRunner.runContainer).toHaveBeenCalled(); + }); + + it(`should ${examples[2].description}`, async () => { + const input = yaml.parse(examples[2].example).steps[0].input; + + commandExists.mockResolvedValue(false); + + fetchContents.mockImplementation(() => Promise.resolve()); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(fetchContents).toHaveBeenCalledWith( + expect.objectContaining({ + reader: mockReader, + integrations, + baseUrl: mockContext.templateInfo?.baseUrl, + fetchUrl: mockContext.input.url, + outputPath: join( + mockTmpDir, + 'template', + "{{cookiecutter and 'contents'}}", + ), + }), + ); + + expect(containerRunner.runContainer).toHaveBeenCalled(); + }); + + it(`should ${examples[3].description}`, async () => { + const input = yaml.parse(examples[3].example).steps[0].input; + + commandExists.mockResolvedValue(false); + + fetchContents.mockImplementation(() => Promise.resolve()); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(fetchContents).toHaveBeenCalledWith( + expect.objectContaining({ + reader: mockReader, + integrations, + baseUrl: mockContext.templateInfo?.baseUrl, + fetchUrl: mockContext.input.url, + outputPath: join( + mockTmpDir, + 'template', + "{{cookiecutter and 'contents'}}", + ), + }), + ); + expect(containerRunner.runContainer).toHaveBeenCalled(); + }); + + it(`should ${examples[4].description}`, async () => { + const input = yaml.parse(examples[4].example).steps[0].input; + + commandExists.mockResolvedValue(false); + + fetchContents.mockImplementation(() => Promise.resolve()); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(fetchContents).toHaveBeenCalledWith( + expect.objectContaining({ + reader: mockReader, + integrations, + baseUrl: mockContext.templateInfo?.baseUrl, + fetchUrl: mockContext.input.url, + outputPath: join( + mockTmpDir, + 'template', + "{{cookiecutter and 'contents'}}", + ), + }), + ); + expect(containerRunner.runContainer).toHaveBeenCalled(); + }); +}); diff --git a/plugins/scaffolder-backend-module-cookiecutter/src/actions/fetch/cookiecutter.examples.ts b/plugins/scaffolder-backend-module-cookiecutter/src/actions/fetch/cookiecutter.examples.ts new file mode 100644 index 0000000000..6ebada50f0 --- /dev/null +++ b/plugins/scaffolder-backend-module-cookiecutter/src/actions/fetch/cookiecutter.examples.ts @@ -0,0 +1,119 @@ +/* + * 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 { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: 'Fetch and template using cookiecutter with minimal options.', + example: yaml.stringify({ + steps: [ + { + id: 'fetchTemplate', + action: 'fetch:cookiecutter', + name: 'Fetch and Template Using Cookiecutter', + input: { + url: 'https://google.com/cookie/cutter', + values: { + help: 'me', + }, + }, + }, + ], + }), + }, + { + description: + 'Fetch and template using cookiecutter with custom target path.', + example: yaml.stringify({ + steps: [ + { + id: 'fetchTemplate', + action: 'fetch:cookiecutter', + name: 'Fetch and Template Using Cookiecutter', + input: { + url: 'https://google.com/cookie/cutter', + targetPath: 'custom-path', + values: { + help: 'me', + }, + }, + }, + ], + }), + }, + { + description: + 'Fetch and template using cookiecutter with copyWithoutRender.', + example: yaml.stringify({ + steps: [ + { + id: 'fetchTemplate', + action: 'fetch:cookiecutter', + name: 'Fetch and Template Using Cookiecutter', + input: { + url: 'https://google.com/cookie/cutter', + values: { + help: 'me', + }, + copyWithoutRender: ['.github/*', '*.md'], + }, + }, + ], + }), + }, + { + description: + 'Fetch and template using cookiecutter with custom extensions.', + example: yaml.stringify({ + steps: [ + { + id: 'fetchTemplate', + action: 'fetch:cookiecutter', + name: 'Fetch and Template Using Cookiecutter', + input: { + url: 'https://google.com/cookie/cutter', + values: { + help: 'me', + }, + extensions: ['jinja2_time.TimeExtension'], + }, + }, + ], + }), + }, + { + description: + 'Fetch and template using cookiecutter with a custom Docker image.', + example: yaml.stringify({ + steps: [ + { + id: 'fetchTemplate', + action: 'fetch:cookiecutter', + name: 'Fetch and Template Using Cookiecutter', + input: { + url: 'https://google.com/cookie/cutter', + values: { + help: 'me', + }, + imageName: 'custom/cookiecutter-image', + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-cookiecutter/src/actions/fetch/cookiecutter.ts b/plugins/scaffolder-backend-module-cookiecutter/src/actions/fetch/cookiecutter.ts index d170acb5d0..efbe0a07cf 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/src/actions/fetch/cookiecutter.ts +++ b/plugins/scaffolder-backend-module-cookiecutter/src/actions/fetch/cookiecutter.ts @@ -28,6 +28,7 @@ import { fetchContents, executeShellCommand, } from '@backstage/plugin-scaffolder-node'; +import { examples } from './cookiecutter.examples'; export class CookiecutterRunner { private readonly containerRunner?: ContainerRunner; @@ -156,6 +157,7 @@ export function createFetchCookiecutterAction(options: { id: 'fetch:cookiecutter', description: 'Downloads a template from the given URL into the workspace, and runs cookiecutter on it.', + examples, schema: { input: { type: 'object', From 6fc03c7d3ab0b1ff75ea037c113314bf47fecb99 Mon Sep 17 00:00:00 2001 From: parmar-abhinav Date: Sat, 13 Jul 2024 16:06:42 +0530 Subject: [PATCH 256/510] Add examples for notification:send scaffolder action & improve related tests Signed-off-by: parmar-abhinav --- .changeset/cool-insects-remember.md | 5 + .../package.json | 3 +- .../actions/sendNotification.examples.test.ts | 272 ++++++++++++++++++ .../src/actions/sendNotification.examples.ts | 255 ++++++++++++++++ .../src/actions/sendNotification.ts | 2 + 5 files changed, 536 insertions(+), 1 deletion(-) create mode 100644 .changeset/cool-insects-remember.md create mode 100644 plugins/scaffolder-backend-module-notifications/src/actions/sendNotification.examples.test.ts create mode 100644 plugins/scaffolder-backend-module-notifications/src/actions/sendNotification.examples.ts diff --git a/.changeset/cool-insects-remember.md b/.changeset/cool-insects-remember.md new file mode 100644 index 0000000000..ab33015377 --- /dev/null +++ b/.changeset/cool-insects-remember.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-notifications': patch +--- + +Add examples for notification:send scaffolder action & improve related tests diff --git a/plugins/scaffolder-backend-module-notifications/package.json b/plugins/scaffolder-backend-module-notifications/package.json index 7c983c36ce..5e45676f99 100644 --- a/plugins/scaffolder-backend-module-notifications/package.json +++ b/plugins/scaffolder-backend-module-notifications/package.json @@ -38,7 +38,8 @@ "@backstage/plugin-notifications-common": "workspace:^", "@backstage/plugin-notifications-node": "workspace:^", "@backstage/plugin-scaffolder-node": "workspace:^", - "octokit": "^3.0.0" + "octokit": "^3.0.0", + "yaml": "^2.0.0" }, "devDependencies": { "@backstage/cli": "workspace:^", diff --git a/plugins/scaffolder-backend-module-notifications/src/actions/sendNotification.examples.test.ts b/plugins/scaffolder-backend-module-notifications/src/actions/sendNotification.examples.test.ts new file mode 100644 index 0000000000..84473335e0 --- /dev/null +++ b/plugins/scaffolder-backend-module-notifications/src/actions/sendNotification.examples.test.ts @@ -0,0 +1,272 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { createSendNotificationAction } from './sendNotification'; +import { NotificationService } from '@backstage/plugin-notifications-node'; +import { TemplateAction } from '@backstage/plugin-scaffolder-node'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { examples } from './sendNotification.examples'; +import yaml from 'yaml'; + +describe('notification:send', () => { + const notificationService: jest.Mocked = { + send: jest.fn(), + }; + + let action: TemplateAction; + + beforeEach(() => { + jest.resetAllMocks(); + action = createSendNotificationAction({ + notifications: notificationService, + }); + }); + + const mockContext = createMockActionContext({ + input: { + recipients: 'broadcast', + title: 'Test notification', + }, + }); + + it(`should ${examples[0].description}`, async () => { + const input = yaml.parse(examples[0].example).steps[0].input; + const ctx = Object.assign({}, mockContext, { + input: input, + }); + await action.handler(ctx); + expect(notificationService.send).toHaveBeenCalledWith({ + recipients: { type: 'broadcast' }, + payload: { + title: 'Test notification', + }, + }); + }); + + it(`should ${examples[1].description}`, async () => { + const input = yaml.parse(examples[1].example).steps[0].input; + const ctx = Object.assign({}, mockContext, { + input: input, + }); + await action.handler(ctx); + expect(notificationService.send).toHaveBeenCalledWith({ + recipients: { + entityRef: ['entity:component:1'], + type: 'entity', + }, + payload: { + description: 'A security update has been applied. Please review.', + title: 'Security Update', + link: 'https://example.com/security/update', + severity: 'high', + scope: 'internal', + }, + }); + }); + + it(`should ${examples[2].description}`, async () => { + const input = yaml.parse(examples[2].example).steps[0].input; + const ctx = Object.assign({}, mockContext, { + input: input, + }); + await action.handler(ctx); + expect(notificationService.send).toHaveBeenCalledWith({ + recipients: { + type: 'entity', + entityRef: ['entity:component:1'], + }, + payload: { + description: 'Here is your weekly update.', + link: undefined, + severity: 'low', + scope: undefined, + title: 'Weekly Update', + }, + }); + }); + + it(`should ${examples[3].description}`, async () => { + const input = yaml.parse(examples[3].example).steps[0].input; + const ctx = Object.assign({}, mockContext, { + input: input, + }); + await action.handler(ctx); + expect(notificationService.send).toHaveBeenCalledWith({ + recipients: { type: 'broadcast' }, + payload: { + description: 'Version 2.0.0 is now available. Upgrade now!', + link: undefined, + severity: 'normal', + scope: 'public', + title: 'New Release Available', + }, + }); + }); + + it(`should ${examples[4].description}`, async () => { + const input = yaml.parse(examples[4].example).steps[0].input; + const ctx = Object.assign({}, mockContext, { + input: input, + }); + await action.handler(ctx); + expect(notificationService.send).toHaveBeenCalledWith({ + recipients: { + type: 'entity', + entityRef: ['entity:component:1'], + }, + payload: { + description: + 'A critical bug has been identified. Immediate action required.', + link: undefined, + scope: 'internal', + severity: 'critical', + title: 'Critical Bug Found', + }, + }); + }); + + it(`should ${examples[5].description}`, async () => { + const input = yaml.parse(examples[5].example).steps[0].input; + const ctx = Object.assign({}, mockContext, { + input: input, + }); + await action.handler(ctx); + expect(notificationService.send).toHaveBeenCalledWith({ + recipients: { + type: 'broadcast', + }, + payload: { + description: 'Server maintenance will occur tonight at 11 PM.', + link: undefined, + scope: 'internal', + severity: 'normal', + title: 'Server Maintenance Scheduled', + }, + }); + }); + + it(`should ${examples[6].description}`, async () => { + const input = yaml.parse(examples[6].example).steps[0].input; + const ctx = Object.assign({}, mockContext, { + input: input, + }); + await action.handler(ctx); + expect(notificationService.send).toHaveBeenCalledWith({ + recipients: { type: 'broadcast' }, + payload: { + description: 'New features have been deployed. Explore them now!', + link: undefined, + scope: undefined, + severity: 'normal', + title: 'New Feature Deployment', + }, + }); + }); + + it(`should ${examples[7].description}`, async () => { + const input = yaml.parse(examples[7].example).steps[0].input; + const ctx = Object.assign({}, mockContext, { + input: input, + }); + await action.handler(ctx); + expect(notificationService.send).toHaveBeenCalledWith({ + recipients: { type: 'broadcast' }, + payload: { + description: undefined, + link: undefined, + scope: 'internal', + severity: 'low', + title: 'Holiday Office Closure', + }, + }); + }); + + it(`should ${examples[8].description}`, async () => { + const input = yaml.parse(examples[8].example).steps[0].input; + const ctx = Object.assign({}, mockContext, { + input: input, + }); + await action.handler(ctx); + expect(notificationService.send).toHaveBeenCalledWith({ + recipients: { type: 'broadcast' }, + payload: { + description: + "Don't forget, the weekly meeting is scheduled for tomorrow.", + link: undefined, + scope: 'internal', + severity: undefined, + title: 'Reminder: Weekly Meeting Tomorrow', + }, + }); + }); + + it(`should ${examples[9].description}`, async () => { + const input = yaml.parse(examples[9].example).steps[0].input; + const ctx = Object.assign({}, mockContext, { + input: input, + }); + await action.handler(ctx); + expect(notificationService.send).toHaveBeenCalledWith({ + recipients: { type: 'broadcast' }, + payload: { + title: 'Important Announcement', + description: + 'Please read the latest announcement regarding the upcoming changes.', + link: undefined, + scope: undefined, + severity: 'high', + }, + }); + }); + + it(`should ${examples[10].description}`, async () => { + const input = yaml.parse(examples[10].example).steps[0].input; + const ctx = Object.assign({}, mockContext, { + input: input, + }); + await action.handler(ctx); + expect(notificationService.send).toHaveBeenCalledWith({ + recipients: { type: 'broadcast' }, + payload: { + title: 'Broadcast Notification', + description: 'This is a broadcast notification', + link: undefined, + scope: undefined, + severity: 'low', + }, + }); + }); + + it(`should ${examples[11].description}`, async () => { + const input = yaml.parse(examples[11].example).steps[0].input; + const ctx = Object.assign({}, mockContext, { + input: input, + }); + await action.handler(ctx); + expect(notificationService.send).toHaveBeenCalledWith({ + recipients: { + type: 'entity', + entityRef: ['entity:service1'], + }, + payload: { + title: 'Entity Notification', + description: 'This is a notification for entity service1', + link: undefined, + scope: undefined, + severity: 'normal', + }, + }); + }); +}); diff --git a/plugins/scaffolder-backend-module-notifications/src/actions/sendNotification.examples.ts b/plugins/scaffolder-backend-module-notifications/src/actions/sendNotification.examples.ts new file mode 100644 index 0000000000..05bbd368f8 --- /dev/null +++ b/plugins/scaffolder-backend-module-notifications/src/actions/sendNotification.examples.ts @@ -0,0 +1,255 @@ +/* + * 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: 'Sends a notification with minimal options', + example: yaml.stringify({ + steps: [ + { + id: 'sendNotification', + action: 'notification:send', + name: 'Send Notification', + input: { + recipients: 'broadcast', + title: 'Test notification', + }, + }, + ], + }), + }, + { + description: 'Sends a notification with entity recipients and link', + example: yaml.stringify({ + steps: [ + { + id: 'sendNotification', + action: 'notification:send', + name: 'Send Notification', + input: { + recipients: 'entity', + entityRefs: ['entity:component:1'], + title: 'Security Update', + info: 'A security update has been applied. Please review.', + link: 'https://example.com/security/update', + severity: 'high', + scope: 'internal', + }, + }, + ], + }), + }, + { + description: + 'Sends a notification with entity recipients and optional flag', + example: yaml.stringify({ + steps: [ + { + id: 'sendNotification', + action: 'notification:send', + name: 'Send Notification', + input: { + recipients: 'entity', + entityRefs: ['entity:component:1'], + title: 'Weekly Update', + info: 'Here is your weekly update.', + severity: 'low', + optional: true, + }, + }, + ], + }), + }, + { + description: + 'Sends a notification with broadcast recipients and custom scope', + example: yaml.stringify({ + steps: [ + { + id: 'sendNotification', + action: 'notification:send', + name: 'Send Notification', + input: { + recipients: 'broadcast', + title: 'New Release Available', + info: 'Version 2.0.0 is now available. Upgrade now!', + severity: 'normal', + scope: 'public', + }, + }, + ], + }), + }, + { + description: + 'Sends a notification with entity recipients and custom severity', + example: yaml.stringify({ + steps: [ + { + id: 'sendNotification', + action: 'notification:send', + name: 'Send Notification', + input: { + recipients: 'entity', + entityRefs: ['entity:component:1'], + title: 'Critical Bug Found', + info: 'A critical bug has been identified. Immediate action required.', + severity: 'critical', + scope: 'internal', + }, + }, + ], + }), + }, + { + description: 'Sends a notification with broadcast recipients and no link', + example: yaml.stringify({ + steps: [ + { + id: 'sendNotification', + action: 'notification:send', + name: 'Send Notification', + input: { + recipients: 'broadcast', + title: 'Server Maintenance Scheduled', + info: 'Server maintenance will occur tonight at 11 PM.', + severity: 'normal', + scope: 'internal', + }, + }, + ], + }), + }, + { + description: + 'Sends a notification with broadcast recipients and optional flag', + example: yaml.stringify({ + steps: [ + { + id: 'sendNotification', + action: 'notification:send', + name: 'Send Notification', + input: { + recipients: 'broadcast', + title: 'New Feature Deployment', + info: 'New features have been deployed. Explore them now!', + severity: 'normal', + optional: true, + }, + }, + ], + }), + }, + { + description: + 'Sends a notification with broadcast recipients and no description', + example: yaml.stringify({ + steps: [ + { + id: 'sendNotification', + action: 'notification:send', + name: 'Send Notification', + input: { + recipients: 'broadcast', + title: 'Holiday Office Closure', + severity: 'low', + scope: 'internal', + }, + }, + ], + }), + }, + { + description: + 'Sends a notification with broadcast recipients and no severity', + example: yaml.stringify({ + steps: [ + { + id: 'sendNotification', + action: 'notification:send', + name: 'Send Notification', + input: { + recipients: 'broadcast', + title: 'Reminder: Weekly Meeting Tomorrow', + info: "Don't forget, the weekly meeting is scheduled for tomorrow.", + scope: 'internal', + }, + }, + ], + }), + }, + { + description: 'Sends a notification with broadcast recipients and no scope', + example: yaml.stringify({ + steps: [ + { + id: 'sendNotification', + action: 'notification:send', + name: 'Send Notification', + input: { + recipients: 'broadcast', + title: 'Important Announcement', + info: 'Please read the latest announcement regarding the upcoming changes.', + severity: 'high', + }, + }, + ], + }), + }, + { + description: 'Sends a notification with optional parameters', + example: yaml.stringify({ + steps: [ + { + id: 'sendNotification', + action: 'notification:send', + name: 'Send Notification', + input: { + recipients: 'broadcast', + title: 'Broadcast Notification', + info: 'This is a broadcast notification', + severity: 'low', + optional: true, + }, + }, + ], + }), + }, + { + description: + 'Sends a notification with entity recipients and optional set to false', + example: yaml.stringify({ + steps: [ + { + id: 'sendNotification', + action: 'notification:send', + name: 'Send Notification to Entity', + input: { + recipients: 'entity', + entityRefs: ['entity:service1'], + title: 'Entity Notification', + info: 'This is a notification for entity service1', + severity: 'normal', + optional: false, + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-notifications/src/actions/sendNotification.ts b/plugins/scaffolder-backend-module-notifications/src/actions/sendNotification.ts index f50e178174..9646de0001 100644 --- a/plugins/scaffolder-backend-module-notifications/src/actions/sendNotification.ts +++ b/plugins/scaffolder-backend-module-notifications/src/actions/sendNotification.ts @@ -22,6 +22,7 @@ import { NotificationSeverity, } from '@backstage/plugin-notifications-common'; import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; +import { examples } from './sendNotification.examples'; /** * @public @@ -42,6 +43,7 @@ export function createSendNotificationAction(options: { }>({ id: 'notification:send', description: 'Sends a notification using NotificationService', + examples, schema: { input: { type: 'object', From 449def7c2c3445f234106becf9e8b74291758ddf Mon Sep 17 00:00:00 2001 From: parmar-abhinav Date: Sat, 13 Jul 2024 17:30:14 +0530 Subject: [PATCH 257/510] Add examples for fetch:rails scaffolder action & improve related tests Signed-off-by: parmar-abhinav --- .changeset/friendly-feet-refuse.md | 5 + .../package.json | 3 +- .../fetch/rails/index.examples.test.ts | 292 ++++++++++++++ .../src/actions/fetch/rails/index.examples.ts | 370 ++++++++++++++++++ .../src/actions/fetch/rails/index.ts | 2 + 5 files changed, 671 insertions(+), 1 deletion(-) create mode 100644 .changeset/friendly-feet-refuse.md create mode 100644 plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.examples.test.ts create mode 100644 plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.examples.ts diff --git a/.changeset/friendly-feet-refuse.md b/.changeset/friendly-feet-refuse.md new file mode 100644 index 0000000000..677d21d48a --- /dev/null +++ b/.changeset/friendly-feet-refuse.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-rails': patch +--- + +Add examples for fetch:rails scaffolder action & improve related tests diff --git a/plugins/scaffolder-backend-module-rails/package.json b/plugins/scaffolder-backend-module-rails/package.json index c15815d2fa..fb917f4e25 100644 --- a/plugins/scaffolder-backend-module-rails/package.json +++ b/plugins/scaffolder-backend-module-rails/package.json @@ -51,7 +51,8 @@ "@backstage/plugin-scaffolder-node": "workspace:^", "@backstage/types": "workspace:^", "command-exists": "^1.2.9", - "fs-extra": "^11.0.0" + "fs-extra": "^11.0.0", + "yaml": "^2.0.0" }, "devDependencies": { "@backstage/backend-test-utils": "workspace:^", diff --git a/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.examples.test.ts b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.examples.test.ts new file mode 100644 index 0000000000..d35cb3f319 --- /dev/null +++ b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.examples.test.ts @@ -0,0 +1,292 @@ +/* + * 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. + */ + +const mockRailsTemplater = { run: jest.fn() }; +jest.mock('@backstage/plugin-scaffolder-node', () => ({ + ...jest.requireActual('@backstage/plugin-scaffolder-node'), + fetchContents: jest.fn(), +})); +jest.mock('./railsNewRunner', () => { + return { + RailsNewRunner: jest.fn().mockImplementation(() => { + return mockRailsTemplater; + }), + }; +}); + +import { ContainerRunner, UrlReader } from '@backstage/backend-common'; +import { ConfigReader } from '@backstage/config'; +import { ScmIntegrations } from '@backstage/integration'; +import { resolve as resolvePath } from 'path'; +import { createFetchRailsAction } from './index'; +import { fetchContents } from '@backstage/plugin-scaffolder-node'; +import { createMockDirectory } from '@backstage/backend-test-utils'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { Writable } from 'stream'; +import { examples } from './index.examples'; +import yaml from 'yaml'; + +describe('fetch:rails', () => { + const mockDir = createMockDirectory(); + const integrations = ScmIntegrations.fromConfig( + new ConfigReader({ + integrations: { + azure: [ + { host: 'dev.azure.com', token: 'tokenlols' }, + { host: 'myazurehostnotoken.com' }, + ], + }, + }), + ); + + const mockContext = createMockActionContext({ + input: { + url: 'https://rubyonrails.org/generator', + targetPath: 'something', + values: { + help: 'me', + }, + }, + templateInfo: { + baseUrl: 'somebase', + entityRef: 'template:default/myTemplate', + }, + workspacePath: mockDir.path, + }); + + const mockReader: UrlReader = { + readUrl: jest.fn(), + readTree: jest.fn(), + search: jest.fn(), + }; + const containerRunner: ContainerRunner = { + runContainer: jest.fn(), + }; + + const action = createFetchRailsAction({ + integrations, + reader: mockReader, + containerRunner, + allowedImageNames: ['foo/rails-custom-image'], + }); + + beforeEach(() => { + mockDir.setContent({ + result: '{}', + }); + jest.clearAllMocks(); + }); + + it(`should ${examples[0].description}`, async () => { + const input = yaml.parse(examples[0].example).steps[0].input; + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(fetchContents).toHaveBeenCalledWith({ + reader: mockReader, + integrations, + baseUrl: mockContext.templateInfo?.baseUrl, + fetchUrl: input.url, + outputPath: resolvePath(mockContext.workspacePath), + }); + }); + + it(`should ${examples[1].description}`, async () => { + const input = yaml.parse(examples[1].example).steps[0].input; + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(fetchContents).toHaveBeenCalledWith({ + reader: mockReader, + integrations, + baseUrl: mockContext.templateInfo?.baseUrl, + fetchUrl: input.url, + outputPath: resolvePath(mockContext.workspacePath), + }); + }); + + it(`should ${examples[2].description}`, async () => { + const input = yaml.parse(examples[2].example).steps[0].input; + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(fetchContents).toHaveBeenCalledWith({ + reader: mockReader, + integrations, + baseUrl: mockContext.templateInfo?.baseUrl, + fetchUrl: input.url, + outputPath: resolvePath(mockContext.workspacePath), + }); + }); + + it(`should ${examples[3].description}`, async () => { + const input = yaml.parse(examples[3].example).steps[0].input; + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(fetchContents).toHaveBeenCalledWith({ + reader: mockReader, + integrations, + baseUrl: mockContext.templateInfo?.baseUrl, + fetchUrl: input.url, + outputPath: resolvePath(mockContext.workspacePath), + }); + }); + + it(`should ${examples[4].description}`, async () => { + const input = yaml.parse(examples[4].example).steps[0].input; + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(fetchContents).toHaveBeenCalledWith({ + reader: mockReader, + integrations, + baseUrl: mockContext.templateInfo?.baseUrl, + fetchUrl: input.url, + outputPath: resolvePath(mockContext.workspacePath), + }); + }); + + it(`should ${examples[5].description}`, async () => { + const input = yaml.parse(examples[5].example).steps[0].input; + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(fetchContents).toHaveBeenCalledWith({ + reader: mockReader, + integrations, + baseUrl: mockContext.templateInfo?.baseUrl, + fetchUrl: input.url, + outputPath: resolvePath(mockContext.workspacePath), + }); + }); + + it(`should ${examples[6].description}`, async () => { + const input = yaml.parse(examples[6].example).steps[0].input; + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(fetchContents).toHaveBeenCalledWith({ + reader: mockReader, + integrations, + baseUrl: mockContext.templateInfo?.baseUrl, + fetchUrl: input.url, + outputPath: resolvePath(mockContext.workspacePath), + }); + }); + + it(`should ${examples[7].description}`, async () => { + const input = yaml.parse(examples[7].example).steps[0].input; + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(fetchContents).toHaveBeenCalledWith({ + reader: mockReader, + integrations, + baseUrl: mockContext.templateInfo?.baseUrl, + fetchUrl: input.url, + outputPath: resolvePath(mockContext.workspacePath), + }); + }); + + it(`should ${examples[8].description}`, async () => { + const input = yaml.parse(examples[8].example).steps[0].input; + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(fetchContents).toHaveBeenCalledWith({ + reader: mockReader, + integrations, + baseUrl: mockContext.templateInfo?.baseUrl, + fetchUrl: input.url, + outputPath: resolvePath(mockContext.workspacePath), + }); + }); + + it(`should ${examples[9].description}`, async () => { + const input = yaml.parse(examples[9].example).steps[0].input; + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(fetchContents).toHaveBeenCalledWith({ + reader: mockReader, + integrations, + baseUrl: mockContext.templateInfo?.baseUrl, + fetchUrl: input.url, + outputPath: resolvePath(mockContext.workspacePath), + }); + }); +}); diff --git a/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.examples.ts b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.examples.ts new file mode 100644 index 0000000000..4c77eb3c1b --- /dev/null +++ b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.examples.ts @@ -0,0 +1,370 @@ +/* + * 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 { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: 'Fetch and template a minimal Rails app', + example: yaml.stringify({ + steps: [ + { + id: 'fetchTemplate', + action: 'fetch:rails', + name: 'Fetch and Template Rails App', + input: { + url: 'https://github.com/backstage/backstage', + values: { + railsArguments: { + minimal: true, + skipBundle: true, + skipWebpackInstall: true, + skipTest: true, + skipActionCable: true, + skipActionMailer: true, + skipActionMailbox: true, + skipActiveStorage: true, + skipActionText: true, + skipActiveRecord: true, + force: true, + api: true, + webpacker: 'react', + database: 'postgresql', + railsVersion: 'dev', + }, + }, + }, + }, + ], + }), + }, + { + description: 'Fetch and template a Rails app with custom options', + example: yaml.stringify({ + steps: [ + { + id: 'fetchTemplate', + action: 'fetch:rails', + name: 'Fetch and Template Rails App', + input: { + url: 'https://github.com/backstage/backstage', + targetPath: 'custom-path', + values: { + railsArguments: { + minimal: false, + skipBundle: false, + skipWebpackInstall: false, + skipTest: false, + skipActionCable: false, + skipActionMailer: false, + skipActionMailbox: false, + skipActiveStorage: false, + skipActionText: false, + skipActiveRecord: false, + force: false, + api: false, + webpacker: 'vue', + database: 'mysql', + railsVersion: 'edge', + }, + }, + }, + }, + ], + }), + }, + { + description: 'Fetch and template a Rails app with Docker image', + example: yaml.stringify({ + steps: [ + { + id: 'fetchTemplate', + action: 'fetch:rails', + name: 'Fetch and Template Rails App', + input: { + url: 'https://github.com/backstage/backstage', + values: { + railsArguments: { + minimal: true, + skipBundle: true, + skipWebpackInstall: true, + skipTest: true, + skipActionCable: true, + skipActionMailer: true, + skipActionMailbox: true, + skipActiveStorage: true, + skipActionText: true, + skipActiveRecord: true, + force: true, + api: true, + webpacker: 'react', + database: 'postgresql', + railsVersion: 'dev', + }, + imageName: 'custom/rails-image', + }, + }, + }, + ], + }), + }, + { + description: + 'Fetch and template a Rails app with different database and action mailer settings', + example: yaml.stringify({ + steps: [ + { + id: 'fetchTemplate', + action: 'fetch:rails', + name: 'Fetch and Template Rails App', + input: { + url: 'https://github.com/backstage/backstage', + values: { + railsArguments: { + minimal: false, + skipBundle: false, + skipWebpackInstall: false, + skipTest: false, + skipActionCable: false, + skipActionMailer: false, + skipActionMailbox: true, + skipActiveStorage: false, + skipActionText: false, + skipActiveRecord: false, + force: true, + api: true, + webpacker: 'angular', + database: 'sqlite3', + railsVersion: 'master', + }, + }, + }, + }, + ], + }), + }, + { + description: + 'Fetch and template a Rails app with full options including action mailer and active storage', + example: yaml.stringify({ + steps: [ + { + id: 'fetchTemplate', + action: 'fetch:rails', + name: 'Fetch and Template Rails App', + input: { + url: 'https://github.com/backstage/backstage', + values: { + railsArguments: { + minimal: false, + skipBundle: false, + skipWebpackInstall: false, + skipTest: false, + skipActionCable: false, + skipActionMailer: false, + skipActionMailbox: false, + skipActiveStorage: false, + skipActionText: false, + skipActiveRecord: false, + force: false, + api: false, + webpacker: 'stimulus', + database: 'postgresql', + railsVersion: 'fromImage', + }, + }, + }, + }, + ], + }), + }, + { + description: + 'Fetch and template a Rails app with API-only stack and custom template path', + example: yaml.stringify({ + steps: [ + { + id: 'fetchTemplate', + action: 'fetch:rails', + name: 'Fetch and Template Rails App', + input: { + url: 'https://github.com/backstage/backstage', + values: { + railsArguments: { + minimal: false, + skipBundle: true, + skipWebpackInstall: true, + skipTest: true, + skipActionCable: true, + skipActionMailer: true, + skipActionMailbox: true, + skipActiveStorage: true, + skipActionText: true, + skipActiveRecord: true, + force: true, + api: true, + webpacker: 'elm', + database: 'mysql', + railsVersion: 'dev', + template: 'path/to/custom/template', + }, + }, + }, + }, + ], + }), + }, + { + description: 'Fetch and template a Rails app with custom Webpack setup', + example: yaml.stringify({ + steps: [ + { + id: 'fetchTemplate', + action: 'fetch:rails', + name: 'Fetch and Template Rails App', + input: { + url: 'https://github.com/backstage/backstage', + values: { + railsArguments: { + minimal: false, + skipBundle: false, + skipWebpackInstall: false, + skipTest: false, + skipActionCable: false, + skipActionMailer: false, + skipActionMailbox: false, + skipActiveStorage: false, + skipActionText: false, + skipActiveRecord: false, + force: false, + api: false, + webpacker: 'angular', + database: 'postgresql', + railsVersion: 'dev', + }, + }, + }, + }, + ], + }), + }, + { + description: + 'Fetch and template a Rails app with specific Rails version and Action Mailer enabled', + example: yaml.stringify({ + steps: [ + { + id: 'fetchTemplate', + action: 'fetch:rails', + name: 'Fetch and Template Rails App', + input: { + url: 'https://github.com/backstage/backstage', + values: { + railsArguments: { + minimal: false, + skipBundle: false, + skipWebpackInstall: false, + skipTest: false, + skipActionCable: false, + skipActionMailer: false, + skipActionMailbox: false, + skipActiveStorage: false, + skipActionText: false, + skipActiveRecord: false, + force: true, + api: true, + webpacker: 'react', + database: 'sqlite3', + railsVersion: 'master', + }, + }, + }, + }, + ], + }), + }, + { + description: + 'Fetch and template a Rails app with specific database and Active Storage enabled', + example: yaml.stringify({ + steps: [ + { + id: 'fetchTemplate', + action: 'fetch:rails', + name: 'Fetch and Template Rails App', + input: { + url: 'https://github.com/backstage/backstage', + values: { + railsArguments: { + minimal: false, + skipBundle: false, + skipWebpackInstall: false, + skipTest: false, + skipActionCable: false, + skipActionMailer: false, + skipActionMailbox: false, + skipActiveStorage: false, + skipActionText: false, + skipActiveRecord: false, + force: true, + api: true, + webpacker: 'vue', + database: 'postgresql', + railsVersion: 'fromImage', + }, + }, + }, + }, + ], + }), + }, + { + description: + 'Fetch and template a Rails app with full options including database and skip options', + example: yaml.stringify({ + steps: [ + { + id: 'fetchTemplate', + action: 'fetch:rails', + name: 'Fetch and Template Rails App', + input: { + url: 'https://github.com/backstage/backstage', + values: { + railsArguments: { + minimal: false, + skipBundle: true, + skipWebpackInstall: true, + skipTest: true, + skipActionCable: true, + skipActionMailer: true, + skipActionMailbox: true, + skipActiveStorage: true, + skipActionText: true, + skipActiveRecord: true, + force: false, + api: false, + webpacker: 'stimulus', + database: 'sqlite3', + railsVersion: 'dev', + }, + }, + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.ts b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.ts index 394d0fb02c..94a2a3539b 100644 --- a/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.ts +++ b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.ts @@ -27,6 +27,7 @@ import { import { resolve as resolvePath } from 'path'; import { RailsNewRunner } from './railsNewRunner'; import { PassThrough } from 'stream'; +import { examples } from './index.examples'; /** * Creates the `fetch:rails` Scaffolder action. @@ -56,6 +57,7 @@ export function createFetchRailsAction(options: { id: 'fetch:rails', description: 'Downloads a template from the given `url` into the workspace, and runs a rails new generator on it.', + examples, schema: { input: { type: 'object', From 1145181834f58328fc846c6776fdb8ff26c1d79f Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Sat, 13 Jul 2024 10:45:17 -0500 Subject: [PATCH 258/510] Moved from root note to title Signed-off-by: Andre Wanlin --- docs/auth/guest/provider.md | 3 +-- docs/features/kubernetes/authenticationstrategy.md | 3 +-- docs/features/kubernetes/installation.md | 9 +++------ docs/features/search/getting-started.md | 6 ++---- docs/features/software-catalog/configuration.md | 6 ++---- docs/features/software-templates/builtin-actions.md | 3 +-- docs/features/techdocs/getting-started.md | 9 +++------ docs/getting-started/config/database.md | 3 +-- docs/getting-started/configure-app-with-plugins.md | 3 +-- docs/getting-started/homepage.md | 3 +-- docs/integrations/aws-s3/discovery--old.md | 3 +-- docs/integrations/aws-s3/discovery.md | 3 +-- docs/integrations/azure/discovery--old.md | 3 +-- docs/integrations/azure/discovery.md | 3 +-- docs/integrations/azure/org--old.md | 3 +-- docs/integrations/azure/org.md | 3 +-- docs/integrations/bitbucketCloud/discovery.md | 3 +-- docs/integrations/bitbucketServer/discovery.md | 3 +-- docs/integrations/gerrit/discovery.md | 3 +-- docs/integrations/github/discovery--old.md | 6 ++---- docs/integrations/github/discovery.md | 3 +-- docs/integrations/github/org--old.md | 6 ++---- docs/integrations/github/org.md | 3 +-- docs/integrations/gitlab/discovery.md | 3 +-- docs/integrations/gitlab/org.md | 3 +-- docs/integrations/ldap/org--old.md | 3 +-- docs/integrations/ldap/org.md | 3 +-- docs/permissions/getting-started.md | 3 +-- docs/permissions/plugin-authors/01-setup.md | 3 +-- docs/plugins/backend-plugin.md | 3 +-- docs/releases/v1.6.0-changelog.md | 6 ++---- docs/releases/v1.6.0-next.0-changelog.md | 6 ++---- docs/tutorials/configuring-plugin-databases.md | 13 ++++++++----- docs/tutorials/switching-sqlite-postgres.md | 3 +-- 34 files changed, 51 insertions(+), 91 deletions(-) diff --git a/docs/auth/guest/provider.md b/docs/auth/guest/provider.md index b28274d2ba..b541178571 100644 --- a/docs/auth/guest/provider.md +++ b/docs/auth/guest/provider.md @@ -25,8 +25,7 @@ This will only work with the new backend system. There is no support for this in Add the `@backstage/plugin-auth-backend-module-guest-provider` to your backend installation. -```sh -# From your Backstage root directory +```sh title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-guest-provider ``` diff --git a/docs/features/kubernetes/authenticationstrategy.md b/docs/features/kubernetes/authenticationstrategy.md index a7d093248a..ffea69d610 100644 --- a/docs/features/kubernetes/authenticationstrategy.md +++ b/docs/features/kubernetes/authenticationstrategy.md @@ -173,8 +173,7 @@ To create the Backend module, run `yarn new`, select `backend-module`. Then fill This will create a new package at `plugins/kubernetes-backend-module-pinniped`. We are going to need also the `@backstage/plugin-kubernetes-node` and `@backstage/plugin-kubernetes-common` dependencies, the `@backstage/plugin-kubernetes-node` houses the [kubernetesAuthStrategyExtensionPoint](https://github.com/backstage/backstage/blob/ebe7afad9d19f279469168ca0d4feceb92c1ad36/plugins/kubernetes-node/src/extensions.ts#L77) and a [Pinniped Helper](https://github.com/backstage/backstage/blob/ebe7afad9d19f279469168ca0d4feceb92c1ad36/plugins/kubernetes-node/src/auth/PinnipedHelper.ts#L53) class. -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd plugins/kubernetes-backend-module-pinniped add @backstage/plugin-kubernetes-node yarn --cwd plugins/kubernetes-backend-module-pinniped add @backstage/plugin-kubernetes-common ``` diff --git a/docs/features/kubernetes/installation.md b/docs/features/kubernetes/installation.md index b3d03cc0b4..279c9cbf3f 100644 --- a/docs/features/kubernetes/installation.md +++ b/docs/features/kubernetes/installation.md @@ -15,8 +15,7 @@ If you haven't setup Backstage already, read the The first step is to add the Kubernetes frontend plugin to your Backstage application. -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/app add @backstage/plugin-kubernetes ``` @@ -53,8 +52,7 @@ work. Navigate to `packages/backend` of your Backstage app, and install the `@backstage/plugin-kubernetes-backend` package. -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-kubernetes-backend ``` @@ -109,8 +107,7 @@ To get the Kubernetes plugin install using the New Backend System you will need Run this command to add the package: -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-kubernetes-backend ``` diff --git a/docs/features/search/getting-started.md b/docs/features/search/getting-started.md index 7989b60ae2..b2a074974f 100644 --- a/docs/features/search/getting-started.md +++ b/docs/features/search/getting-started.md @@ -16,8 +16,7 @@ If you haven't setup Backstage already, start ## Adding Search to the Frontend -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/app add @backstage/plugin-search @backstage/plugin-search-react ``` @@ -133,8 +132,7 @@ For more information about using `Root.tsx`, please see Add the following plugins into your backend app: -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-search-backend @backstage/plugin-search-backend-node ``` diff --git a/docs/features/software-catalog/configuration.md b/docs/features/software-catalog/configuration.md index f5df9eafca..17d5f49205 100644 --- a/docs/features/software-catalog/configuration.md +++ b/docs/features/software-catalog/configuration.md @@ -184,8 +184,7 @@ Catalog errors are published to the [events plugin](https://github.com/backstage The first step is to add the events backend plugin to your Backstage application. Navigate to your Backstage application directory and add the plugin package. -```ts -# From your Backstage root directory +```ts title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-events-backend ``` @@ -201,8 +200,7 @@ If you want to log catalog errors you can install the `@backstage/plugin-catalog Install the catalog logs module. -```ts -# From your Backstage root directory +```ts title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-logs ``` diff --git a/docs/features/software-templates/builtin-actions.md b/docs/features/software-templates/builtin-actions.md index 5b1e4347da..301fb4c457 100644 --- a/docs/features/software-templates/builtin-actions.md +++ b/docs/features/software-templates/builtin-actions.md @@ -24,8 +24,7 @@ There are also several modules available for various SCM tools: Here's how to add an action module, first you need to run this command: -```sh -# From your Backstage root directory +```sh title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-scaffolder-backend-module-github ``` diff --git a/docs/features/techdocs/getting-started.md b/docs/features/techdocs/getting-started.md index 7909f8166f..a157d29c0d 100644 --- a/docs/features/techdocs/getting-started.md +++ b/docs/features/techdocs/getting-started.md @@ -21,8 +21,7 @@ The first step is to add the TechDocs plugin to your Backstage application. Navigate to your new Backstage application directory. And then to your `packages/app` directory, and install the `@backstage/plugin-techdocs` package. -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/app add @backstage/plugin-techdocs ``` @@ -106,8 +105,7 @@ That's it! Now, we need the TechDocs Backend plugin for the frontend to work. Navigate to `packages/backend` of your Backstage app, and install the `@backstage/plugin-techdocs-backend` package. -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-techdocs-backend ``` @@ -199,8 +197,7 @@ To install TechDocs when using the New Backend system you will need to do the fo Navigate to `packages/backend` of your Backstage app, and install the `@backstage/plugin-techdocs-backend` package. -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-techdocs-backend ``` diff --git a/docs/getting-started/config/database.md b/docs/getting-started/config/database.md index a560fe507b..0fbd66d5a3 100644 --- a/docs/getting-started/config/database.md +++ b/docs/getting-started/config/database.md @@ -73,8 +73,7 @@ to install and configure the client. Go to the root directory of your freshly installed Backstage App. Run the following to install the PostgreSQL client into your backend: -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add pg ``` diff --git a/docs/getting-started/configure-app-with-plugins.md b/docs/getting-started/configure-app-with-plugins.md index 2fdb016e7b..95fd456dc0 100644 --- a/docs/getting-started/configure-app-with-plugins.md +++ b/docs/getting-started/configure-app-with-plugins.md @@ -21,8 +21,7 @@ to an entity in the software catalog. 1. Add the plugin's npm package to the repo: - ```bash - # From your Backstage root directory + ```bash title="From your Backstage root directory" yarn --cwd packages/app add @circleci/backstage-plugin ``` diff --git a/docs/getting-started/homepage.md b/docs/getting-started/homepage.md index 7e1a2ed909..d7c9b46faa 100644 --- a/docs/getting-started/homepage.md +++ b/docs/getting-started/homepage.md @@ -28,8 +28,7 @@ Now, let's get started by installing the home plugin and creating a simple homep #### 1. Install the plugin -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/app add @backstage/plugin-home ``` diff --git a/docs/integrations/aws-s3/discovery--old.md b/docs/integrations/aws-s3/discovery--old.md index bff63af9e5..09b6eb6cc0 100644 --- a/docs/integrations/aws-s3/discovery--old.md +++ b/docs/integrations/aws-s3/discovery--old.md @@ -66,8 +66,7 @@ catalog: As this provider is not one of the default providers, you will first need to install the AWS catalog plugin: -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-aws ``` diff --git a/docs/integrations/aws-s3/discovery.md b/docs/integrations/aws-s3/discovery.md index cce410ea8b..db9119680e 100644 --- a/docs/integrations/aws-s3/discovery.md +++ b/docs/integrations/aws-s3/discovery.md @@ -66,8 +66,7 @@ catalog: As this provider is not one of the default providers, you will first need to install the AWS catalog plugin: -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-aws ``` diff --git a/docs/integrations/azure/discovery--old.md b/docs/integrations/azure/discovery--old.md index be490d70fe..56a2fe559f 100644 --- a/docs/integrations/azure/discovery--old.md +++ b/docs/integrations/azure/discovery--old.md @@ -102,8 +102,7 @@ It may take some time before the branch is indexed and searchable. As this provider is not one of the default providers, you will first need to install the Azure catalog plugin: -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-azure ``` diff --git a/docs/integrations/azure/discovery.md b/docs/integrations/azure/discovery.md index 7e7b465118..c8a8a3af7c 100644 --- a/docs/integrations/azure/discovery.md +++ b/docs/integrations/azure/discovery.md @@ -102,8 +102,7 @@ It may take some time before the branch is indexed and searchable. As this provider is not one of the default providers, you will first need to install the Azure catalog plugin: -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-azure ``` diff --git a/docs/integrations/azure/org--old.md b/docs/integrations/azure/org--old.md index 13d53b24b3..899120e88a 100644 --- a/docs/integrations/azure/org--old.md +++ b/docs/integrations/azure/org--old.md @@ -18,8 +18,7 @@ Microsoft Graph API. The package is not installed by default, therefore you have to add `@backstage/plugin-catalog-backend-module-msgraph` to your backend package. -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-msgraph ``` diff --git a/docs/integrations/azure/org.md b/docs/integrations/azure/org.md index 2dfdee7bce..0a4eda2db5 100644 --- a/docs/integrations/azure/org.md +++ b/docs/integrations/azure/org.md @@ -18,8 +18,7 @@ Microsoft Graph API. The package is not installed by default, therefore you have to add `@backstage/plugin-catalog-backend-module-msgraph` to your backend package. -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-msgraph ``` diff --git a/docs/integrations/bitbucketCloud/discovery.md b/docs/integrations/bitbucketCloud/discovery.md index 160827cb0a..04dc111d30 100644 --- a/docs/integrations/bitbucketCloud/discovery.md +++ b/docs/integrations/bitbucketCloud/discovery.md @@ -19,8 +19,7 @@ backend. The provider is not installed by default, therefore you have to add a dependency to `@backstage/plugin-catalog-backend-module-bitbucket-cloud` to your backend package. -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-bitbucket-cloud ``` diff --git a/docs/integrations/bitbucketServer/discovery.md b/docs/integrations/bitbucketServer/discovery.md index d9fc946460..99e04affa8 100644 --- a/docs/integrations/bitbucketServer/discovery.md +++ b/docs/integrations/bitbucketServer/discovery.md @@ -19,8 +19,7 @@ backend. The provider is not installed by default, therefore you have to add a dependency to `@backstage/plugin-catalog-backend-module-bitbucket-server` to your backend package. -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-bitbucket-server ``` diff --git a/docs/integrations/gerrit/discovery.md b/docs/integrations/gerrit/discovery.md index e2922c1f76..96dfbd47fb 100644 --- a/docs/integrations/gerrit/discovery.md +++ b/docs/integrations/gerrit/discovery.md @@ -16,8 +16,7 @@ stored in the root of the matching projects. As this provider is not one of the default providers, you will first need to install the Gerrit provider plugin: -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-gerrit ``` diff --git a/docs/integrations/github/discovery--old.md b/docs/integrations/github/discovery--old.md index 138e54a538..752aa51bde 100644 --- a/docs/integrations/github/discovery--old.md +++ b/docs/integrations/github/discovery--old.md @@ -25,8 +25,7 @@ backend. They are not installed by default, therefore you have to add a dependency on `@backstage/plugin-catalog-backend-module-github` to your backend package. -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-github ``` @@ -273,8 +272,7 @@ backend. They are not installed by default, therefore you have to add a dependency on `@backstage/plugin-catalog-backend-module-github` to your backend package, plus `@backstage/integration` for the basic credentials management: -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/integration @backstage/plugin-catalog-backend-module-github ``` diff --git a/docs/integrations/github/discovery.md b/docs/integrations/github/discovery.md index d8374932b8..43e63a618c 100644 --- a/docs/integrations/github/discovery.md +++ b/docs/integrations/github/discovery.md @@ -24,8 +24,7 @@ You will have to add the GitHub Entity provider to your backend as it is not ins dependency on `@backstage/plugin-catalog-backend-module-github` to your backend package. -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-github ``` diff --git a/docs/integrations/github/org--old.md b/docs/integrations/github/org--old.md index 3d1639a924..bf12cad036 100644 --- a/docs/integrations/github/org--old.md +++ b/docs/integrations/github/org--old.md @@ -29,8 +29,7 @@ the Processor method (not recommended), it is described separately below. The provider is not installed by default, therefore you have to add a dependency to `@backstage/plugin-catalog-backend-module-github` to your backend package. -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-github ``` @@ -334,8 +333,7 @@ frequency with which they are refreshed, separately from other processors. The `GithubOrgReaderProcessor` is not registered by default, so you have to install and register it in the catalog plugin: -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-github ``` diff --git a/docs/integrations/github/org.md b/docs/integrations/github/org.md index f94ffe6c7a..18865cd630 100644 --- a/docs/integrations/github/org.md +++ b/docs/integrations/github/org.md @@ -38,8 +38,7 @@ You will have to add the GitHub Org provider to your backend as it is not instal dependency on `@backstage/plugin-catalog-backend-module-github-org` to your backend package. -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-github-org ``` diff --git a/docs/integrations/gitlab/discovery.md b/docs/integrations/gitlab/discovery.md index 98fbb0fbce..13ffd79801 100644 --- a/docs/integrations/gitlab/discovery.md +++ b/docs/integrations/gitlab/discovery.md @@ -20,8 +20,7 @@ This provider can also be configured to ingest GitLab data based on [GitLab Webh As this provider is not one of the default providers, you will first need to install the gitlab catalog plugin: -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-gitlab ``` diff --git a/docs/integrations/gitlab/org.md b/docs/integrations/gitlab/org.md index 46d720c164..65f66aa763 100644 --- a/docs/integrations/gitlab/org.md +++ b/docs/integrations/gitlab/org.md @@ -25,8 +25,7 @@ This provider can also be configured to ingest GitLab data based on [GitLab Syst As this provider is not one of the default providers, you will first need to install the Gitlab provider plugin: -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-gitlab @backstage/plugin-catalog-backend-module-gitlab-org ``` diff --git a/docs/integrations/ldap/org--old.md b/docs/integrations/ldap/org--old.md index 63f052371f..448e9bbed1 100644 --- a/docs/integrations/ldap/org--old.md +++ b/docs/integrations/ldap/org--old.md @@ -24,8 +24,7 @@ the Processor method (not recommended), it is described separately below. The provider is not installed by default, therefore you have to add a dependency to `@backstage/plugin-catalog-backend-module-ldap` to your backend package. -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-ldap ``` diff --git a/docs/integrations/ldap/org.md b/docs/integrations/ldap/org.md index 36cffb9b1f..b1aa460bd6 100644 --- a/docs/integrations/ldap/org.md +++ b/docs/integrations/ldap/org.md @@ -21,8 +21,7 @@ Backstage in general supports OpenLDAP compatible vendors, as well as Active Dir The provider is not installed by default, therefore you have to add a dependency to `@backstage/plugin-catalog-backend-module-ldap` to your backend package. -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-ldap ``` diff --git a/docs/permissions/getting-started.md b/docs/permissions/getting-started.md index 4dabf3fcbd..e8132e571b 100644 --- a/docs/permissions/getting-started.md +++ b/docs/permissions/getting-started.md @@ -50,8 +50,7 @@ The permissions framework uses a new `permission-backend` plugin to accept autho 1. Add `@backstage/plugin-permission-backend` as a dependency of your Backstage backend: - ```bash - # From your Backstage root directory + ```bash title="From your Backstage root directory" yarn --cwd packages/backend add @backstage/plugin-permission-backend ``` diff --git a/docs/permissions/plugin-authors/01-setup.md b/docs/permissions/plugin-authors/01-setup.md index a674d82e25..f11bdff930 100644 --- a/docs/permissions/plugin-authors/01-setup.md +++ b/docs/permissions/plugin-authors/01-setup.md @@ -39,8 +39,7 @@ The source code is available here: 2. Add these packages as dependencies for your Backstage app: - ```sh - # From your Backstage root directory + ```sh title="From your Backstage root directory" yarn --cwd packages/backend add @internal/plugin-todo-list-backend @internal/plugin-todo-list-common yarn --cwd packages/app add @internal/plugin-todo-list ``` diff --git a/docs/plugins/backend-plugin.md b/docs/plugins/backend-plugin.md index 7f155f3b05..1366a59099 100644 --- a/docs/plugins/backend-plugin.md +++ b/docs/plugins/backend-plugin.md @@ -71,8 +71,7 @@ Backstage application / backend exposes it. To actually attach and run the plugin router, you will make some modifications to your backend. -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add @internal/plugin-carmen-backend@^0.1.0 # Change this to match the plugin's package.json ``` diff --git a/docs/releases/v1.6.0-changelog.md b/docs/releases/v1.6.0-changelog.md index 0532243cbf..e9692f4f1b 100644 --- a/docs/releases/v1.6.0-changelog.md +++ b/docs/releases/v1.6.0-changelog.md @@ -248,8 +248,7 @@ 1. First we need to add the @backstage/plugin-azure-devops package to your frontend app: - ```bash - # From your Backstage root directory + ```bash title="From your Backstage root directory" yarn add --cwd packages/app @backstage/plugin-azure-devops ``` @@ -313,8 +312,7 @@ 1. First we need to add the @backstage/plugin-azure-devops package to your frontend app: - ```bash - # From your Backstage root directory + ```bash title="From your Backstage root directory" yarn add --cwd packages/app @backstage/plugin-azure-devops ``` diff --git a/docs/releases/v1.6.0-next.0-changelog.md b/docs/releases/v1.6.0-next.0-changelog.md index 5ff2311b79..fbe9caefde 100644 --- a/docs/releases/v1.6.0-next.0-changelog.md +++ b/docs/releases/v1.6.0-next.0-changelog.md @@ -10,8 +10,7 @@ 1. First we need to add the @backstage/plugin-azure-devops package to your frontend app: - ```bash - # From your Backstage root directory + ```bash title="From your Backstage root directory" yarn add --cwd packages/app @backstage/plugin-azure-devops ``` @@ -69,8 +68,7 @@ 1. First we need to add the @backstage/plugin-azure-devops package to your frontend app: - ```bash - # From your Backstage root directory + ```bash title="From your Backstage root directory" yarn add --cwd packages/app @backstage/plugin-azure-devops ``` diff --git a/docs/tutorials/configuring-plugin-databases.md b/docs/tutorials/configuring-plugin-databases.md index 528d2c6325..db3f126de7 100644 --- a/docs/tutorials/configuring-plugin-databases.md +++ b/docs/tutorials/configuring-plugin-databases.md @@ -36,12 +36,15 @@ Please ensure the appropriate database drivers are installed in your `backend` package. If you intend to use both PostgreSQL and SQLite, you can install both of them. -```bash -# From your Backstage root directory -# install pg if you need PostgreSQL -yarn --cwd packages/backend add pg +Install pg if you need PostgreSQL: -# install SQLite 3 if you intend to set it as the client +```bash title="From your Backstage root directory" +yarn --cwd packages/backend add pg +``` + +Install SQLite 3 if you intend to set it as the client: + +```bash title="From your Backstage root directory" yarn --cwd packages/backend add better-sqlite3 ``` diff --git a/docs/tutorials/switching-sqlite-postgres.md b/docs/tutorials/switching-sqlite-postgres.md index 2ef481dbf3..aec9ca2ee9 100644 --- a/docs/tutorials/switching-sqlite-postgres.md +++ b/docs/tutorials/switching-sqlite-postgres.md @@ -19,8 +19,7 @@ switch between database backends. First, add PostgreSQL to your `backend` package: -```bash -# From your Backstage root directory +```bash title="From your Backstage root directory" yarn --cwd packages/backend add pg ``` From b9e73a0e5a7545bb659f626b02fba9a6d82e7c3e Mon Sep 17 00:00:00 2001 From: parmar-abhinav Date: Sun, 14 Jul 2024 10:45:49 +0530 Subject: [PATCH 259/510] chore: run yarn install to update dependencies Signed-off-by: parmar-abhinav --- yarn.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/yarn.lock b/yarn.lock index b0bff82017..574792b052 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7055,6 +7055,7 @@ __metadata: command-exists: ^1.2.9 fs-extra: ^11.0.0 jest-when: ^3.1.0 + yaml: ^2.0.0 languageName: unknown linkType: soft From b687beb2dcc16eddc89b85675b425fec7cc02c51 Mon Sep 17 00:00:00 2001 From: parmar-abhinav Date: Sun, 14 Jul 2024 10:52:16 +0530 Subject: [PATCH 260/510] chore: run yarn install to update dependencies Signed-off-by: parmar-abhinav --- yarn.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/yarn.lock b/yarn.lock index b0bff82017..18f51570ec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7032,6 +7032,7 @@ __metadata: "@backstage/plugin-scaffolder-node": "workspace:^" "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" octokit: ^3.0.0 + yaml: ^2.0.0 languageName: unknown linkType: soft From b084597b3299049b92c9cbc3e76c704ec8f41a7e Mon Sep 17 00:00:00 2001 From: parmar-abhinav Date: Sun, 14 Jul 2024 10:55:19 +0530 Subject: [PATCH 261/510] chore: run yarn install to update dependencies Signed-off-by: parmar-abhinav --- yarn.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/yarn.lock b/yarn.lock index b0bff82017..4dcfba4743 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6917,6 +6917,7 @@ __metadata: command-exists: ^1.2.9 fs-extra: ^11.2.0 winston: ^3.2.1 + yaml: ^2.0.0 yn: ^4.0.0 languageName: unknown linkType: soft From 065353f144c00589e5f4cbb427738ccc6f74deb4 Mon Sep 17 00:00:00 2001 From: parmar-abhinav Date: Sun, 14 Jul 2024 10:58:53 +0530 Subject: [PATCH 262/510] chore: removed unused imports Signed-off-by: parmar-abhinav --- .../src/actions/fetch/rails/index.examples.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.examples.test.ts b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.examples.test.ts index d35cb3f319..a80985321e 100644 --- a/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.examples.test.ts +++ b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.examples.test.ts @@ -35,7 +35,6 @@ import { createFetchRailsAction } from './index'; import { fetchContents } from '@backstage/plugin-scaffolder-node'; import { createMockDirectory } from '@backstage/backend-test-utils'; import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; -import { Writable } from 'stream'; import { examples } from './index.examples'; import yaml from 'yaml'; From 0ab868dfd1510b6ef85d1967db2ac3688de496bd Mon Sep 17 00:00:00 2001 From: Stephen Glass Date: Sun, 14 Jul 2024 04:00:51 -0400 Subject: [PATCH 263/510] Wip Signed-off-by: Stephen Glass --- .../components/ReviewState/ReviewState.tsx | 42 +--------- .../src/next/components/ReviewState/util.ts | 84 +++++++++++++------ 2 files changed, 59 insertions(+), 67 deletions(-) diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx index 95f5d76212..d320ad80a6 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx +++ b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx @@ -18,7 +18,7 @@ import { StructuredMetadataTable } from '@backstage/core-components'; import { JsonObject } from '@backstage/types'; import { Draft07 as JSONSchema } from 'json-schema-library'; import { ParsedTemplateSchema } from '../../hooks/useTemplateSchema'; -import { flattenObject, isJsonObject } from './util'; +import { processEntry } from './util'; /** * The props for the {@link ReviewState} component. @@ -38,49 +38,11 @@ export const ReviewState = (props: ReviewStateProps) => { Object.entries(props.formState) .flatMap(([key, value]) => { for (const step of props.schemas) { - const parsedSchema = new JSONSchema(step.mergedSchema); - const definitionInSchema = parsedSchema.getSchema({ - pointer: `#/${key}`, - data: props.formState, - }); - - if (definitionInSchema) { - const backstageReviewOptions = - definitionInSchema['ui:backstage']?.review; - - if (backstageReviewOptions) { - if (backstageReviewOptions.mask) { - return [[key, backstageReviewOptions.mask]]; - } - if (backstageReviewOptions.show === false) { - return []; - } - if (backstageReviewOptions.explode && isJsonObject(value)) { - return flattenObject(value, key, parsedSchema, props.formState); - } - } - - if (definitionInSchema['ui:widget'] === 'password') { - return [[key, '******']]; - } - - if (definitionInSchema.enum && definitionInSchema.enumNames) { - return [ - [ - key, - definitionInSchema.enumNames[ - definitionInSchema.enum.indexOf(value) - ] || value, - ], - ]; - } - } + return processEntry(key, value, step, props.formState); } - return [[key, value]]; }) .filter(prop => prop.length > 0), ); - return ; }; diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/util.ts b/plugins/scaffolder-react/src/next/components/ReviewState/util.ts index 0bb6fc08d2..e040b851d3 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/util.ts +++ b/plugins/scaffolder-react/src/next/components/ReviewState/util.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ /* * Copyright 2022 The Backstage Authors * @@ -16,34 +17,63 @@ import { JsonObject, JsonValue } from '@backstage/types'; import { Draft07 as JSONSchema } from 'json-schema-library'; - -export function flattenObject( - obj: JsonObject, - prefix: string, - schema: JSONSchema, - formState: JsonObject, -): [string, JsonValue | undefined][] { - return Object.entries(obj).flatMap(([key, value]) => { - const prefixedKey = prefix ? `${prefix}/${key}` : key; - - const definitionInSchema = schema.getSchema({ - pointer: `#/${prefixedKey}`, - data: formState, - }); - - if (definitionInSchema) { - const backstageReviewOptions = definitionInSchema['ui:backstage']?.review; - - // Recurse into nested objects - if (backstageReviewOptions?.explode && isJsonObject(value)) { - return flattenObject(value, prefixedKey, schema, formState); - } - } - - return [[key, value]]; - }); -} +import { ParsedTemplateSchema } from '../../hooks'; export function isJsonObject(value?: JsonValue): value is JsonObject { return typeof value === 'object' && value !== null && !Array.isArray(value); } + +export function processEntry( + key: string, + value: JsonValue | undefined, + schema: ParsedTemplateSchema, + formState: JsonObject, +): [string, JsonValue | undefined][] { + const parsedSchema = new JSONSchema(schema.mergedSchema); + const definitionInSchema = parsedSchema.getSchema({ + pointer: `#/${key}`, + data: formState, + }); + + if (definitionInSchema) { + const backstageReviewOptions = definitionInSchema['ui:backstage']?.review; + if (backstageReviewOptions) { + if (backstageReviewOptions.mask) { + return [[getLastKey(key), backstageReviewOptions.mask]]; + } + if (backstageReviewOptions.show === false) { + return []; + } + } + + if (isJsonObject(value)) { + // Process nested objects + return Object.entries(value).flatMap(([nestedKey, nestedValue]) => + processEntry(`${key}/${nestedKey}`, nestedValue, schema, formState), + ); + } + + if (definitionInSchema['ui:widget'] === 'password') { + return [[getLastKey(key), '******']]; + } + + if (definitionInSchema.enum && definitionInSchema.enumNames) { + return [ + [ + getLastKey(key), + definitionInSchema.enumNames[ + definitionInSchema.enum.indexOf(value) + ] || value, + ], + ]; + } + } + + return [[getLastKey(key), value]]; +} + +// Helper function to get the last part of the key +function getLastKey(key: string): string { + const parts = key.split('/'); + return parts[parts.length - 1]; +} From 3ac2a6a6b85f5ac054a421c661d24fb67d45a770 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Sun, 14 Jul 2024 13:05:51 -0500 Subject: [PATCH 264/510] Added the Postgres Search Engine to the `create-app` template Signed-off-by: Andre Wanlin --- .changeset/twenty-buses-carry.md | 5 +++++ .../templates/default-app/packages/backend/package.json.hbs | 1 + .../templates/default-app/packages/backend/src/index.ts | 6 ++++++ 3 files changed, 12 insertions(+) create mode 100644 .changeset/twenty-buses-carry.md diff --git a/.changeset/twenty-buses-carry.md b/.changeset/twenty-buses-carry.md new file mode 100644 index 0000000000..00347e60d8 --- /dev/null +++ b/.changeset/twenty-buses-carry.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Added the Postgres Search Engine to the `create-app` template diff --git a/packages/create-app/templates/default-app/packages/backend/package.json.hbs b/packages/create-app/templates/default-app/packages/backend/package.json.hbs index e26c788496..1ec475b0ed 100644 --- a/packages/create-app/templates/default-app/packages/backend/package.json.hbs +++ b/packages/create-app/templates/default-app/packages/backend/package.json.hbs @@ -36,6 +36,7 @@ "@backstage/plugin-scaffolder-backend": "^{{version '@backstage/plugin-scaffolder-backend'}}", "@backstage/plugin-search-backend": "^{{version '@backstage/plugin-search-backend'}}", "@backstage/plugin-search-backend-module-catalog": "^{{version '@backstage/plugin-search-backend-module-catalog'}}", + "@backstage/plugin-search-backend-module-pg": "^{{version '@backstage/plugin-search-backend-module-pg'}}", "@backstage/plugin-search-backend-module-techdocs": "^{{version '@backstage/plugin-search-backend-module-techdocs'}}", "@backstage/plugin-search-backend-node": "^{{version '@backstage/plugin-search-backend-node'}}", "@backstage/plugin-techdocs-backend": "^{{version '@backstage/plugin-techdocs-backend'}}", diff --git a/packages/create-app/templates/default-app/packages/backend/src/index.ts b/packages/create-app/templates/default-app/packages/backend/src/index.ts index 239269288e..6bb9b1322d 100644 --- a/packages/create-app/templates/default-app/packages/backend/src/index.ts +++ b/packages/create-app/templates/default-app/packages/backend/src/index.ts @@ -38,6 +38,12 @@ backend.add( // search plugin backend.add(import('@backstage/plugin-search-backend/alpha')); + +// search engine +// See https://backstage.io/docs/features/search/search-engines +backend.add(import('@backstage/plugin-search-backend-module-pg/alpha')); + +// search collators backend.add(import('@backstage/plugin-search-backend-module-catalog/alpha')); backend.add(import('@backstage/plugin-search-backend-module-techdocs/alpha')); From c0a705d44298c5274f1d94b230d642a86cada2c9 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 14 Jun 2024 10:49:04 -0500 Subject: [PATCH 265/510] Added the Kubernetes plugin to `create-app` Signed-off-by: Andre Wanlin --- .changeset/blue-pumas-cheer.md | 5 +++++ packages/create-app/src/lib/versions.ts | 4 ++++ .../templates/default-app/app-config.yaml.hbs | 3 +++ .../default-app/packages/app/package.json.hbs | 1 + .../app/src/components/catalog/EntityPage.tsx | 21 +++++++++++++++++++ .../packages/backend/package.json.hbs | 1 + .../default-app/packages/backend/src/index.ts | 3 +++ 7 files changed, 38 insertions(+) create mode 100644 .changeset/blue-pumas-cheer.md diff --git a/.changeset/blue-pumas-cheer.md b/.changeset/blue-pumas-cheer.md new file mode 100644 index 0000000000..f6cbf180ff --- /dev/null +++ b/.changeset/blue-pumas-cheer.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Added the Kubernetes plugin to `create-app` diff --git a/packages/create-app/src/lib/versions.ts b/packages/create-app/src/lib/versions.ts index 25fd7b7c3c..194ffa21d9 100644 --- a/packages/create-app/src/lib/versions.ts +++ b/packages/create-app/src/lib/versions.ts @@ -62,6 +62,8 @@ import { version as pluginCatalogBackendModuleLogs } from '../../../../plugins/c import { version as pluginCatalogBackendModuleScaffolderEntityModel } from '../../../../plugins/catalog-backend-module-scaffolder-entity-model/package.json'; import { version as pluginCatalogGraph } from '../../../../plugins/catalog-graph/package.json'; import { version as pluginCatalogImport } from '../../../../plugins/catalog-import/package.json'; +import { version as pluginKubernetes } from '../../../../plugins/kubernetes/package.json'; +import { version as pluginKubernetesBackend } from '../../../../plugins/kubernetes-backend/package.json'; import { version as pluginOrg } from '../../../../plugins/org/package.json'; import { version as pluginPermissionBackend } from '../../../../plugins/permission-backend/package.json'; import { version as pluginPermissionBackendModulePolicyAllowAll } from '../../../../plugins/permission-backend-module-policy-allow-all/package.json'; @@ -118,6 +120,8 @@ export const packageVersions = { pluginCatalogBackendModuleScaffolderEntityModel, '@backstage/plugin-catalog-graph': pluginCatalogGraph, '@backstage/plugin-catalog-import': pluginCatalogImport, + '@backstage/plugin-kubernetes': pluginKubernetes, + '@backstage/plugin-kubernetes-backend': pluginKubernetesBackend, '@backstage/plugin-org': pluginOrg, '@backstage/plugin-permission-backend': pluginPermissionBackend, '@backstage/plugin-permission-backend-module-allow-all-policy': diff --git a/packages/create-app/templates/default-app/app-config.yaml.hbs b/packages/create-app/templates/default-app/app-config.yaml.hbs index 248cff137a..a4797d4c41 100644 --- a/packages/create-app/templates/default-app/app-config.yaml.hbs +++ b/packages/create-app/templates/default-app/app-config.yaml.hbs @@ -103,3 +103,6 @@ catalog: # target: https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/acme-corp.yaml # rules: # - allow: [User, Group] + +kubernetes: + # see https://backstage.io/docs/features/kubernetes/configuration for kubernetes configuration options \ No newline at end of file diff --git a/packages/create-app/templates/default-app/packages/app/package.json.hbs b/packages/create-app/templates/default-app/packages/app/package.json.hbs index d4db9e5885..08a1d58362 100644 --- a/packages/create-app/templates/default-app/packages/app/package.json.hbs +++ b/packages/create-app/templates/default-app/packages/app/package.json.hbs @@ -27,6 +27,7 @@ "@backstage/plugin-catalog-graph": "^{{version '@backstage/plugin-catalog-graph'}}", "@backstage/plugin-catalog-import": "^{{version '@backstage/plugin-catalog-import'}}", "@backstage/plugin-catalog-react": "^{{version '@backstage/plugin-catalog-react'}}", + "@backstage/plugin-kubernetes": "^{{version '@backstage/plugin-kubernetes'}}", "@backstage/plugin-org": "^{{version '@backstage/plugin-org'}}", "@backstage/plugin-permission-react": "^{{version '@backstage/plugin-permission-react'}}", "@backstage/plugin-scaffolder": "^{{version '@backstage/plugin-scaffolder'}}", 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 53b6685c3f..6164c76004 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 @@ -54,6 +54,11 @@ import { import { TechDocsAddons } from '@backstage/plugin-techdocs-react'; import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib'; +import { + EntityKubernetesContent, + isKubernetesAvailable, +} from '@backstage/plugin-kubernetes'; + const techdocsContent = ( @@ -150,6 +155,14 @@ const serviceEntityPage = ( {cicdContent} + + + + @@ -188,6 +201,14 @@ const websiteEntityPage = ( {cicdContent} + + + + diff --git a/packages/create-app/templates/default-app/packages/backend/package.json.hbs b/packages/create-app/templates/default-app/packages/backend/package.json.hbs index e26c788496..8aad8a4b5d 100644 --- a/packages/create-app/templates/default-app/packages/backend/package.json.hbs +++ b/packages/create-app/templates/default-app/packages/backend/package.json.hbs @@ -28,6 +28,7 @@ "@backstage/plugin-catalog-backend": "^{{version '@backstage/plugin-catalog-backend'}}", "@backstage/plugin-catalog-backend-module-logs": "^{{version '@backstage/plugin-catalog-backend-module-logs'}}", "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "^{{version '@backstage/plugin-catalog-backend-module-scaffolder-entity-model'}}", + "@backstage/plugin-kubernetes-backend": "^{{version '@backstage/plugin-kubernetes-backend'}}", "@backstage/plugin-permission-backend": "^{{version '@backstage/plugin-permission-backend'}}", "@backstage/plugin-permission-backend-module-allow-all-policy": "^{{version '@backstage/plugin-permission-backend-module-allow-all-policy'}}", "@backstage/plugin-permission-common": "^{{version '@backstage/plugin-permission-common'}}", diff --git a/packages/create-app/templates/default-app/packages/backend/src/index.ts b/packages/create-app/templates/default-app/packages/backend/src/index.ts index 239269288e..983202caa6 100644 --- a/packages/create-app/templates/default-app/packages/backend/src/index.ts +++ b/packages/create-app/templates/default-app/packages/backend/src/index.ts @@ -41,4 +41,7 @@ backend.add(import('@backstage/plugin-search-backend/alpha')); backend.add(import('@backstage/plugin-search-backend-module-catalog/alpha')); backend.add(import('@backstage/plugin-search-backend-module-techdocs/alpha')); +// kubernetes +backend.add(import('@backstage/plugin-kubernetes-backend/alpha')); + backend.start(); From dba4a14ee9b4ec8e2b99f94e9271cc9c26c951b8 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 14 Jun 2024 11:17:30 -0500 Subject: [PATCH 266/510] Added new line Signed-off-by: Andre Wanlin --- packages/create-app/templates/default-app/app-config.yaml.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/create-app/templates/default-app/app-config.yaml.hbs b/packages/create-app/templates/default-app/app-config.yaml.hbs index a4797d4c41..f784d5ba88 100644 --- a/packages/create-app/templates/default-app/app-config.yaml.hbs +++ b/packages/create-app/templates/default-app/app-config.yaml.hbs @@ -105,4 +105,4 @@ catalog: # - allow: [User, Group] kubernetes: - # see https://backstage.io/docs/features/kubernetes/configuration for kubernetes configuration options \ No newline at end of file + # see https://backstage.io/docs/features/kubernetes/configuration for kubernetes configuration options From f26905d7a88559eb5ca5472a3842afe745e15059 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 14 Jun 2024 11:48:09 -0500 Subject: [PATCH 267/510] Fixed test Signed-off-by: Andre Wanlin --- packages/create-app/src/lib/tasks.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/create-app/src/lib/tasks.test.ts b/packages/create-app/src/lib/tasks.test.ts index 1f507b95ed..7b17307721 100644 --- a/packages/create-app/src/lib/tasks.test.ts +++ b/packages/create-app/src/lib/tasks.test.ts @@ -88,6 +88,8 @@ jest.mock('./versions', () => ({ '@backstage/plugin-catalog-graph': '1.0.0', '@backstage/plugin-catalog-import': '1.0.0', '@backstage/plugin-catalog-react': '1.0.0', + '@backstage/plugin-kubernetes': '1.0.0', + '@backstage/plugin-kubernetes-backend': '1.0.0', '@backstage/plugin-org': '1.0.0', '@backstage/plugin-scaffolder': '1.0.0', '@backstage/plugin-permission-react': '1.0.0', From fe6ab86d9207cd1c2586aa016efdfbc007915ade Mon Sep 17 00:00:00 2001 From: Stephen Glass Date: Sun, 14 Jul 2024 15:24:38 -0400 Subject: [PATCH 268/510] Refactor review state schema processing code to support nested objects Signed-off-by: Stephen Glass --- .../ReviewState/ReviewState.test.tsx | 179 +++++++++++------- .../components/ReviewState/ReviewState.tsx | 55 +++++- .../next/components/ReviewState/util.test.ts | 170 +++-------------- .../src/next/components/ReviewState/util.ts | 55 +----- 4 files changed, 189 insertions(+), 270 deletions(-) diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.test.tsx b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.test.tsx index dfa1c9c097..194c5f3e77 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.test.tsx +++ b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.test.tsx @@ -69,6 +69,9 @@ describe('ReviewState', () => { const formState = { name: 'John Doe', test: 'bob', + nest: { + foo: 'bar', + }, }; const schemas: ParsedTemplateSchema[] = [ @@ -85,6 +88,20 @@ describe('ReviewState', () => { }, }, }, + nest: { + type: 'object', + properties: { + foo: { + type: 'string', + 'ui:widget': 'password', + 'ui:backstage': { + review: { + show: false, + }, + }, + }, + }, + }, }, }, schema: {}, @@ -99,12 +116,16 @@ describe('ReviewState', () => { ); expect(getAllByRole('row').length).toEqual(1); expect(queryByRole('row', { name: 'Name ******' })).not.toBeInTheDocument(); + expect(queryByRole('row', { name: 'Foo ******' })).not.toBeInTheDocument(); }); it('should allow for masking an option with a set text', () => { const formState = { name: 'John Doe', test: 'bob', + nest: { + foo: 'bar', + }, }; const schemas: ParsedTemplateSchema[] = [ @@ -121,6 +142,20 @@ describe('ReviewState', () => { }, }, }, + nest: { + type: 'object', + properties: { + foo: { + type: 'string', + 'ui:widget': 'password', + 'ui:backstage': { + review: { + mask: 'lols', + }, + }, + }, + }, + }, }, }, schema: {}, @@ -135,11 +170,15 @@ describe('ReviewState', () => { ); expect(getByRole('row', { name: 'Name lols' })).toBeInTheDocument(); + expect(getByRole('row', { name: 'Foo lols' })).toBeInTheDocument(); }); it('should display enum label from enumNames', async () => { const formState = { name: 'type2', + nest: { + foo: 'type2', + }, }; const schemas: ParsedTemplateSchema[] = [ @@ -153,6 +192,17 @@ describe('ReviewState', () => { enum: ['type1', 'type2', 'type3'], enumNames: ['Label-type1', 'Label-type2', 'Label-type3'], }, + nest: { + type: 'object', + properties: { + foo: { + type: 'string', + default: 'type1', + enum: ['type1', 'type2', 'type3'], + enumNames: ['Label-type1', 'Label-type2', 'Label-type3'], + }, + }, + }, }, }, schema: {}, @@ -169,6 +219,7 @@ describe('ReviewState', () => { expect( queryByRole('row', { name: 'Name Label-type2' }), ).toBeInTheDocument(); + expect(queryByRole('row', { name: 'Foo Label-type2' })).toBeInTheDocument(); }); it('should display enum value if no corresponding enumNames', async () => { @@ -203,7 +254,7 @@ describe('ReviewState', () => { expect(queryByRole('row', { name: 'Name type4' })).toBeInTheDocument(); }); - it('should display exploded object in separate rows', async () => { + it('should display object in separate rows', async () => { const formState = { name: { foo: 'type3', @@ -218,11 +269,6 @@ describe('ReviewState', () => { properties: { name: { type: 'object', - 'ui:backstage': { - review: { - explode: true, - }, - }, properties: { foo: { type: 'string', @@ -239,7 +285,6 @@ describe('ReviewState', () => { schema: {}, title: 'test', uiSchema: {}, - description: 'asd', }, ]; @@ -251,7 +296,7 @@ describe('ReviewState', () => { expect(queryByRole('row', { name: 'Bar type4' })).toBeInTheDocument(); }); - it('should display exploded nested objects', async () => { + it('should display nested objects in separate rows', async () => { const formState = { name: { foo: 'type3', @@ -269,11 +314,60 @@ describe('ReviewState', () => { properties: { name: { type: 'object', - 'ui:backstage': { - review: { - explode: true, + properties: { + foo: { + type: 'string', + default: 'type1', + }, + bar: { + type: 'string', + default: 'type2', + }, + example: { + type: 'object', + properties: { + test: { + type: 'string', + }, + }, }, }, + }, + }, + }, + schema: {}, + title: 'test', + uiSchema: {}, + }, + ]; + + const { queryByRole } = render( + , + ); + + expect(queryByRole('row', { name: 'Foo type3' })).toBeInTheDocument(); + expect(queryByRole('row', { name: 'Bar type4' })).toBeInTheDocument(); + expect(queryByRole('row', { name: 'Test type6' })).toBeInTheDocument(); + }); + + it('should display partially nested objects', async () => { + const formState = { + name: { + foo: 'type3', + bar: 'type4', + example: { + test: 'type6', + }, + }, + }; + + const schemas: ParsedTemplateSchema[] = [ + { + mergedSchema: { + type: 'object', + properties: { + name: { + type: 'object', properties: { foo: { type: 'string', @@ -287,7 +381,7 @@ describe('ReviewState', () => { type: 'object', 'ui:backstage': { review: { - explode: true, + explode: false, }, }, properties: { @@ -303,67 +397,6 @@ describe('ReviewState', () => { schema: {}, title: 'test', uiSchema: {}, - description: 'asd', - }, - ]; - - const { queryByRole } = render( - , - ); - - expect(queryByRole('row', { name: 'Foo type3' })).toBeInTheDocument(); - expect(queryByRole('row', { name: 'Bar type4' })).toBeInTheDocument(); - expect(queryByRole('row', { name: 'Test type6' })).toBeInTheDocument(); - }); - - it('should display partially exploded nested objects', async () => { - const formState = { - name: { - foo: 'type3', - bar: 'type4', - example: { - test: 'type6', - }, - }, - }; - - const schemas: ParsedTemplateSchema[] = [ - { - mergedSchema: { - type: 'object', - properties: { - name: { - type: 'object', - 'ui:backstage': { - review: { - explode: true, - }, - }, - properties: { - foo: { - type: 'string', - default: 'type1', - }, - bar: { - type: 'string', - default: 'type2', - }, - example: { - type: 'object', - properties: { - test: { - type: 'string', - }, - }, - }, - }, - }, - }, - }, - schema: {}, - title: 'test', - uiSchema: {}, - description: 'asd', }, ]; diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx index d320ad80a6..d87584afff 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx +++ b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx @@ -15,10 +15,10 @@ */ import React from 'react'; import { StructuredMetadataTable } from '@backstage/core-components'; -import { JsonObject } from '@backstage/types'; +import { JsonObject, JsonValue } from '@backstage/types'; import { Draft07 as JSONSchema } from 'json-schema-library'; import { ParsedTemplateSchema } from '../../hooks/useTemplateSchema'; -import { processEntry } from './util'; +import { isJsonObject, getLastKey } from './util'; /** * The props for the {@link ReviewState} component. @@ -29,6 +29,55 @@ export type ReviewStateProps = { formState: JsonObject; }; +function processSchema( + key: string, + value: JsonValue | undefined, + schema: ParsedTemplateSchema, + formState: JsonObject, +): [string, JsonValue | undefined][] { + const parsedSchema = new JSONSchema(schema.mergedSchema); + const definitionInSchema = parsedSchema.getSchema({ + pointer: `#/${key}`, + data: formState, + }); + + if (definitionInSchema) { + const backstageReviewOptions = definitionInSchema['ui:backstage']?.review; + if (backstageReviewOptions) { + if (backstageReviewOptions.mask) { + return [[getLastKey(key), backstageReviewOptions.mask]]; + } + if (backstageReviewOptions.show === false) { + return []; + } + } + + if (definitionInSchema['ui:widget'] === 'password') { + return [[getLastKey(key), '******']]; + } + + if (definitionInSchema.enum && definitionInSchema.enumNames) { + return [ + [ + getLastKey(key), + definitionInSchema.enumNames[ + definitionInSchema.enum.indexOf(value) + ] || value, + ], + ]; + } + + if (backstageReviewOptions?.explode !== false && isJsonObject(value)) { + // Recurse nested objects + return Object.entries(value).flatMap(([nestedKey, nestedValue]) => + processSchema(`${key}/${nestedKey}`, nestedValue, schema, formState), + ); + } + } + + return [[getLastKey(key), value]]; +} + /** * The component used by the {@link Stepper} to render the review step. * @alpha @@ -38,7 +87,7 @@ export const ReviewState = (props: ReviewStateProps) => { Object.entries(props.formState) .flatMap(([key, value]) => { for (const step of props.schemas) { - return processEntry(key, value, step, props.formState); + return processSchema(key, value, step, props.formState); } return [[key, value]]; }) diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/util.test.ts b/plugins/scaffolder-react/src/next/components/ReviewState/util.test.ts index e2a10587dc..9b88ff157e 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/util.test.ts +++ b/plugins/scaffolder-react/src/next/components/ReviewState/util.test.ts @@ -14,9 +14,7 @@ * limitations under the License. */ -import { flattenObject, isJsonObject } from './util'; -import { Draft07 as JSONSchema } from 'json-schema-library'; -import { ParsedTemplateSchema } from '../../hooks/useTemplateSchema'; +import { isJsonObject, getLastKey } from './util'; describe('isJsonObject', () => { it('should return true for non-null objects', () => { @@ -24,10 +22,6 @@ describe('isJsonObject', () => { expect(isJsonObject({ key: 'value' })).toBe(true); }); - it('should return false for null', () => { - expect(isJsonObject(null)).toBe(false); - }); - it('should return false for arrays', () => { expect(isJsonObject([])).toBe(false); expect(isJsonObject([1, 2, 3])).toBe(false); @@ -41,146 +35,40 @@ describe('isJsonObject', () => { }); }); -describe('flattenObject', () => { - it('should handle an empty object', () => { - const schemas: ParsedTemplateSchema[] = [ - { - mergedSchema: { - type: 'object', - properties: { - name: { - type: 'object', - 'ui:backstage': { - review: { - explode: true, - }, - }, - properties: {}, - }, - }, - }, - schema: {}, - title: 'test', - uiSchema: {}, - }, - ]; - - const parsedSchema = new JSONSchema(schemas[0].mergedSchema); - - const result = flattenObject({}, '', parsedSchema, {}); - - expect(result).toEqual([]); +describe('getLastKey', () => { + it('should return the last part of a simple key', () => { + expect(getLastKey('simple')).toBe('simple'); }); - it('should flatten a simple object', () => { - const formState = { - name: { - foo: 'value1', - bar: 'value2', - }, - }; - - const schemas: ParsedTemplateSchema[] = [ - { - mergedSchema: { - type: 'object', - properties: { - name: { - type: 'object', - 'ui:backstage': { - review: { - explode: true, - }, - }, - properties: { - foo: { - type: 'string', - }, - bar: { - type: 'string', - }, - }, - }, - }, - }, - schema: {}, - title: 'test', - uiSchema: {}, - }, - ]; - - const [key, value] = Object.entries(formState)[0]; - const parsedSchema = new JSONSchema(schemas[0].mergedSchema); - - const result = flattenObject(value, key, parsedSchema, formState); - - expect(result).toEqual([ - ['foo', 'value1'], - ['bar', 'value2'], - ]); + it('should return the last part of a nested key', () => { + expect(getLastKey('parent/child')).toBe('child'); }); - it('should recurse into a nested object', () => { - const formState = { - name: { - foo: 'value1', - bar: 'value2', - example: { - test: 'value3', - }, - }, - }; - const schemas: ParsedTemplateSchema[] = [ - { - mergedSchema: { - type: 'object', - properties: { - name: { - type: 'object', - 'ui:backstage': { - review: { - explode: true, - }, - }, - properties: { - foo: { - type: 'string', - }, - bar: { - type: 'string', - }, - example: { - type: 'object', - 'ui:backstage': { - review: { - explode: true, - }, - }, - properties: { - test: { - type: 'string', - }, - }, - }, - }, - }, - }, - }, - schema: {}, - title: 'test', - uiSchema: {}, - }, - ]; + it('should return the last part of a deeply nested key', () => { + expect(getLastKey('grandparent/parent/child')).toBe('child'); + }); - const [key, value] = Object.entries(formState)[0]; - const parsedSchema = new JSONSchema(schemas[0].mergedSchema); + it('should handle keys with trailing slash', () => { + expect(getLastKey('parent/child/')).toBe(''); + }); - const result = flattenObject(value, key, parsedSchema, formState); + it('should handle empty string', () => { + expect(getLastKey('')).toBe(''); + }); - expect(result).toEqual([ - ['foo', 'value1'], - ['bar', 'value2'], - ['test', 'value3'], - ]); + it('should handle keys with multiple consecutive slashes', () => { + expect(getLastKey('parent//child')).toBe('child'); + }); + + it('should handle keys with only slashes', () => { + expect(getLastKey('////')).toBe(''); + }); + + it('should handle keys with spaces', () => { + expect(getLastKey('parent/child with spaces')).toBe('child with spaces'); + }); + + it('should handle keys with special characters', () => { + expect(getLastKey('parent/child@!#$%^&*()')).toBe('child@!#$%^&*()'); }); }); diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/util.ts b/plugins/scaffolder-react/src/next/components/ReviewState/util.ts index e040b851d3..52503bedfd 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/util.ts +++ b/plugins/scaffolder-react/src/next/components/ReviewState/util.ts @@ -16,64 +16,13 @@ */ import { JsonObject, JsonValue } from '@backstage/types'; -import { Draft07 as JSONSchema } from 'json-schema-library'; -import { ParsedTemplateSchema } from '../../hooks'; export function isJsonObject(value?: JsonValue): value is JsonObject { - return typeof value === 'object' && value !== null && !Array.isArray(value); -} - -export function processEntry( - key: string, - value: JsonValue | undefined, - schema: ParsedTemplateSchema, - formState: JsonObject, -): [string, JsonValue | undefined][] { - const parsedSchema = new JSONSchema(schema.mergedSchema); - const definitionInSchema = parsedSchema.getSchema({ - pointer: `#/${key}`, - data: formState, - }); - - if (definitionInSchema) { - const backstageReviewOptions = definitionInSchema['ui:backstage']?.review; - if (backstageReviewOptions) { - if (backstageReviewOptions.mask) { - return [[getLastKey(key), backstageReviewOptions.mask]]; - } - if (backstageReviewOptions.show === false) { - return []; - } - } - - if (isJsonObject(value)) { - // Process nested objects - return Object.entries(value).flatMap(([nestedKey, nestedValue]) => - processEntry(`${key}/${nestedKey}`, nestedValue, schema, formState), - ); - } - - if (definitionInSchema['ui:widget'] === 'password') { - return [[getLastKey(key), '******']]; - } - - if (definitionInSchema.enum && definitionInSchema.enumNames) { - return [ - [ - getLastKey(key), - definitionInSchema.enumNames[ - definitionInSchema.enum.indexOf(value) - ] || value, - ], - ]; - } - } - - return [[getLastKey(key), value]]; + return typeof value === 'object' && !Array.isArray(value); } // Helper function to get the last part of the key -function getLastKey(key: string): string { +export function getLastKey(key: string): string { const parts = key.split('/'); return parts[parts.length - 1]; } From ba67e2884712d3036c10e3d9b19c126305a5d16d Mon Sep 17 00:00:00 2001 From: Stephen Glass Date: Sun, 14 Jul 2024 15:37:16 -0400 Subject: [PATCH 269/510] Remove comment Signed-off-by: Stephen Glass --- plugins/scaffolder-react/src/next/components/ReviewState/util.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/util.ts b/plugins/scaffolder-react/src/next/components/ReviewState/util.ts index 52503bedfd..49c3b30e7a 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/util.ts +++ b/plugins/scaffolder-react/src/next/components/ReviewState/util.ts @@ -1,4 +1,3 @@ -/* eslint-disable no-console */ /* * Copyright 2022 The Backstage Authors * From 486c7d7b2638263c252ead495ad04113bb32dcdd Mon Sep 17 00:00:00 2001 From: Evan Shortiss Date: Sun, 14 Jul 2024 21:36:53 -0700 Subject: [PATCH 270/510] docs: fix typo and link in contributing.md Signed-off-by: Evan Shortiss --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ce0e97c781..f10116844b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -99,7 +99,7 @@ You'll see how you get both logs for the frontend `webpack-dev-server` which ser Visit and you should see the bleeding edge of Backstage ready for contributions! -If you want to get a better understanding of the layout of the repo not that you have a local copy running feel free to review the [Backstage Project Structure](https://backstage.io/docs/getting-started/project-structure) documentation. +If you want to get a better understanding of the layout of the repo now that you have a local copy running feel free to review the [Backstage Project Structure](https://backstage.io/docs/getting-started/#general-folder-structure) documentation. ## Coding Guidelines From 8c4d6bca9af7ae412d700d5d049dfa9e4e6665af Mon Sep 17 00:00:00 2001 From: David Weber Date: Mon, 15 Jul 2024 08:11:36 +0200 Subject: [PATCH 271/510] ci: add timeout to cron job Signed-off-by: David Weber Signed-off-by: David Weber --- .github/workflows/cron.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml index 923293667a..bdbe22aae8 100644 --- a/.github/workflows/cron.yml +++ b/.github/workflows/cron.yml @@ -7,6 +7,7 @@ on: jobs: cron: runs-on: ubuntu-latest + timeout-minutes: 10 steps: - name: Harden Runner uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 From e6e293ca30256d8d7641f5c9ff27e29b76f149de Mon Sep 17 00:00:00 2001 From: Benjamin Janssens Date: Mon, 15 Jul 2024 10:22:21 +0200 Subject: [PATCH 272/510] chore: extract BaseRepoUrlPickerProps Signed-off-by: Benjamin Janssens --- .../fields/RepoUrlPicker/AzureRepoPicker.tsx | 15 +++++++-------- .../RepoUrlPicker/BitbucketRepoPicker.tsx | 17 ++++++++--------- .../fields/RepoUrlPicker/GerritRepoPicker.tsx | 8 ++------ .../fields/RepoUrlPicker/GiteaRepoPicker.tsx | 15 +++++++-------- .../fields/RepoUrlPicker/GithubRepoPicker.tsx | 13 ++++++------- .../fields/RepoUrlPicker/GitlabRepoPicker.tsx | 15 +++++++-------- .../components/fields/RepoUrlPicker/types.ts | 6 ++++++ 7 files changed, 43 insertions(+), 46 deletions(-) diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/AzureRepoPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/AzureRepoPicker.tsx index 833a0849fb..48fcb4f6af 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/AzureRepoPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/AzureRepoPicker.tsx @@ -19,16 +19,15 @@ 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 { RepoUrlPickerState } from './types'; +import { BaseRepoUrlPickerProps } from './types'; import { Select, SelectItem } from '@backstage/core-components'; -export const AzureRepoPicker = (props: { - allowedOrganizations?: string[]; - allowedProject?: string[]; - rawErrors: string[]; - state: RepoUrlPickerState; - onChange: (state: RepoUrlPickerState) => void; -}) => { +export const AzureRepoPicker = ( + props: BaseRepoUrlPickerProps<{ + allowedOrganizations?: string[]; + allowedProject?: string[]; + }>, +) => { const { allowedOrganizations = [], allowedProject = [], diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx index 10d4a6e6c3..5d627e9512 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx @@ -17,7 +17,7 @@ import React, { useEffect, useState } from 'react'; import FormControl from '@material-ui/core/FormControl'; import FormHelperText from '@material-ui/core/FormHelperText'; import { Select, SelectItem } from '@backstage/core-components'; -import { RepoUrlPickerState } from './types'; +import { BaseRepoUrlPickerProps } from './types'; import Autocomplete from '@material-ui/lab/Autocomplete'; import TextField from '@material-ui/core/TextField'; import useDebounce from 'react-use/esm/useDebounce'; @@ -33,14 +33,13 @@ import { scaffolderApiRef } from '@backstage/plugin-scaffolder-react'; * @param allowedProjects - Allowed projects for the Bitbucket cloud repository * */ -export const BitbucketRepoPicker = (props: { - allowedOwners?: string[]; - allowedProjects?: string[]; - onChange: (state: RepoUrlPickerState) => void; - state: RepoUrlPickerState; - rawErrors: string[]; - accessToken?: string; -}) => { +export const BitbucketRepoPicker = ( + props: BaseRepoUrlPickerProps<{ + allowedOwners?: string[]; + allowedProjects?: string[]; + accessToken?: string; + }>, +) => { const { allowedOwners = [], allowedProjects = [], diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/GerritRepoPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/GerritRepoPicker.tsx index 13af966c25..1b13c5eb29 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/GerritRepoPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/GerritRepoPicker.tsx @@ -18,13 +18,9 @@ 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 { RepoUrlPickerState } from './types'; +import { BaseRepoUrlPickerProps } from './types'; -export const GerritRepoPicker = (props: { - onChange: (state: RepoUrlPickerState) => void; - state: RepoUrlPickerState; - rawErrors: string[]; -}) => { +export const GerritRepoPicker = (props: BaseRepoUrlPickerProps) => { const { onChange, rawErrors, state } = props; const { workspace, owner } = state; return ( diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/GiteaRepoPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/GiteaRepoPicker.tsx index 566a2732e3..9fb3af211f 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/GiteaRepoPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/GiteaRepoPicker.tsx @@ -19,15 +19,14 @@ 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'; +import { BaseRepoUrlPickerProps } from './types'; -export const GiteaRepoPicker = (props: { - allowedOwners?: string[]; - allowedRepos?: string[]; - state: RepoUrlPickerState; - onChange: (state: RepoUrlPickerState) => void; - rawErrors: string[]; -}) => { +export const GiteaRepoPicker = ( + props: BaseRepoUrlPickerProps<{ + allowedOwners?: string[]; + allowedRepos?: string[]; + }>, +) => { const { allowedOwners = [], state, onChange, rawErrors } = props; const ownerItems: SelectItem[] = allowedOwners ? allowedOwners.map(i => ({ label: i, value: i })) diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/GithubRepoPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/GithubRepoPicker.tsx index ec59d89ef8..5d46dc4333 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/GithubRepoPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/GithubRepoPicker.tsx @@ -19,14 +19,13 @@ 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'; +import { BaseRepoUrlPickerProps } from './types'; -export const GithubRepoPicker = (props: { - allowedOwners?: string[]; - rawErrors: string[]; - state: RepoUrlPickerState; - onChange: (state: RepoUrlPickerState) => void; -}) => { +export const GithubRepoPicker = ( + props: BaseRepoUrlPickerProps<{ + allowedOwners?: string[]; + }>, +) => { const { allowedOwners = [], rawErrors, state, onChange } = props; const ownerItems: SelectItem[] = allowedOwners ? allowedOwners.map(i => ({ label: i, value: i })) diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/GitlabRepoPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/GitlabRepoPicker.tsx index fbcc13c846..12ae37bf15 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/GitlabRepoPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/GitlabRepoPicker.tsx @@ -19,15 +19,14 @@ 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'; +import { BaseRepoUrlPickerProps } from './types'; -export const GitlabRepoPicker = (props: { - allowedOwners?: string[]; - allowedRepos?: string[]; - state: RepoUrlPickerState; - onChange: (state: RepoUrlPickerState) => void; - rawErrors: string[]; -}) => { +export const GitlabRepoPicker = ( + props: BaseRepoUrlPickerProps<{ + allowedOwners?: string[]; + allowedRepos?: string[]; + }>, +) => { const { allowedOwners = [], state, onChange, rawErrors } = props; const ownerItems: SelectItem[] = allowedOwners ? allowedOwners.map(i => ({ label: i, value: i })) diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/types.ts b/plugins/scaffolder/src/components/fields/RepoUrlPicker/types.ts index 1430b10b84..9489901d61 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/types.ts +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/types.ts @@ -22,3 +22,9 @@ export interface RepoUrlPickerState { project?: string; availableRepos?: string[]; } + +export type BaseRepoUrlPickerProps = T & { + onChange: (state: RepoUrlPickerState) => void; + state: RepoUrlPickerState; + rawErrors: string[]; +}; From 6b8bab93beaee731a7db18b818cb13af21e848c3 Mon Sep 17 00:00:00 2001 From: Benjamin Janssens Date: Mon, 15 Jul 2024 10:40:19 +0200 Subject: [PATCH 273/510] refactor: use useCallback for autocompletion updates in BitbucketRepoPicker Signed-off-by: Benjamin Janssens --- .../RepoUrlPicker/BitbucketRepoPicker.tsx | 153 +++++++++--------- 1 file changed, 75 insertions(+), 78 deletions(-) diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx index 5d627e9512..0b7ee49525 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React, { useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import FormControl from '@material-ui/core/FormControl'; import FormHelperText from '@material-ui/core/FormHelperText'; import { Select, SelectItem } from '@backstage/core-components'; @@ -68,93 +68,90 @@ export const BitbucketRepoPicker = ( const [availableProjects, setAvailableProjects] = useState([]); // Update available workspaces when client is available - useDebounce( - () => { - const updateAvailableWorkspaces = async () => { - if ( - host === 'bitbucket.org' && - accessToken && - scaffolderApi.autocomplete - ) { - const { results } = await scaffolderApi.autocomplete({ - token: accessToken, - resource: 'workspaces', - context: {}, - provider: 'bitbucket-cloud', - }); + const updateAvailableWorkspaces = useCallback(() => { + if ( + !scaffolderApi.autocomplete || + !accessToken || + host !== 'bitbucket.org' + ) { + setAvailableWorkspaces([]); + return; + } - setAvailableWorkspaces(results.map(r => r.title)); - } else { - setAvailableWorkspaces([]); - } - }; + scaffolderApi + .autocomplete({ + token: accessToken, + resource: 'workspaces', + provider: 'bitbucket-cloud', + }) + .then(({ results }) => { + setAvailableWorkspaces(results.map(r => r.title)); + }) + .catch(() => { + setAvailableWorkspaces([]); + }); + }, [scaffolderApi, accessToken, host]); - updateAvailableWorkspaces().catch(() => setAvailableWorkspaces([])); - }, - 500, - [host, accessToken], - ); + useDebounce(updateAvailableWorkspaces, 500, [updateAvailableWorkspaces]); // Update available projects when client is available and workspace changes - useDebounce( - () => { - const updateAvailableProjects = async () => { - if ( - host === 'bitbucket.org' && - accessToken && - workspace && - scaffolderApi.autocomplete - ) { - const { results } = await scaffolderApi.autocomplete({ - token: accessToken, - resource: 'projects', - context: { workspace }, - provider: 'bitbucket-cloud', - }); + const updateAvailableProjects = useCallback(() => { + if ( + !scaffolderApi.autocomplete || + !accessToken || + host !== 'bitbucket.org' || + !workspace + ) { + setAvailableProjects([]); + return; + } - setAvailableProjects(results.map(r => r.title)); - } else { - setAvailableProjects([]); - } - }; + scaffolderApi + .autocomplete({ + token: accessToken, + resource: 'projects', + context: { workspace }, + provider: 'bitbucket-cloud', + }) + .then(({ results }) => { + setAvailableProjects(results.map(r => r.title)); + }) + .catch(() => { + setAvailableProjects([]); + }); + }, [scaffolderApi, accessToken, host, workspace]); - updateAvailableProjects().catch(() => setAvailableProjects([])); - }, - 500, - [host, accessToken, workspace], - ); + useDebounce(updateAvailableProjects, 500, [updateAvailableProjects]); // Update available repositories when client is available and workspace or project changes - useDebounce( - () => { - const updateAvailableRepositories = async () => { - if ( - host === 'bitbucket.org' && - accessToken && - workspace && - project && - scaffolderApi.autocomplete - ) { - const { results } = await scaffolderApi.autocomplete({ - token: accessToken, - resource: 'repositories', - context: { workspace, project }, - provider: 'bitbucket-cloud', - }); + const updateAvailableRepositories = useCallback(() => { + if ( + !scaffolderApi.autocomplete || + !accessToken || + host !== 'bitbucket.org' || + !workspace || + !project + ) { + onChange({ availableRepos: [] }); + return; + } - onChange({ availableRepos: results.map(r => r.title) }); - } else { - onChange({ availableRepos: [] }); - } - }; + scaffolderApi + .autocomplete({ + token: accessToken, + resource: 'repositories', + context: { workspace, project }, + provider: 'bitbucket-cloud', + }) + .then(({ results }) => { + onChange({ availableRepos: results.map(r => r.title) }); + }) + .catch(() => { + onChange({ availableRepos: [] }); + }); + }, [scaffolderApi, accessToken, host, workspace, project, onChange]); - updateAvailableRepositories().catch(() => - onChange({ availableRepos: [] }), - ); - }, - 500, - [host, accessToken, workspace, project], - ); + useDebounce(updateAvailableRepositories, 500, [updateAvailableRepositories]); return ( <> From 7f153f94c1c3d1849e418109e097b03914941113 Mon Sep 17 00:00:00 2001 From: Benjamin Janssens Date: Mon, 15 Jul 2024 10:44:22 +0200 Subject: [PATCH 274/510] test: simplify checking for the secret in the document; remove SecretsComponent from test that didn't use it Signed-off-by: Benjamin Janssens --- .../RepoUrlPicker/RepoUrlPicker.test.tsx | 47 ++++++------------- 1 file changed, 15 insertions(+), 32 deletions(-) diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.test.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.test.tsx index 002652cfab..f0e47a2504 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.test.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.test.tsx @@ -214,13 +214,14 @@ describe('RepoUrlPicker', () => { describe('requestUserCredentials', () => { it('should call the scmAuthApi with the correct params', async () => { + const secretsKey = 'testKey'; + const SecretsComponent = () => { const { secrets } = useTemplateSecrets(); - return ( -
      {JSON.stringify({ secrets })}
      - ); + const secret = secrets[secretsKey]; + return secret ?
      {secret}
      : null; }; - const { getByTestId } = await renderInTestApp( + const { getByText } = await renderInTestApp( { 'ui:field': 'RepoUrlPicker', 'ui:options': { requestUserCredentials: { - secretsKey: 'testKey', + secretsKey, additionalScopes: { github: ['workflow'] }, }, }, @@ -265,21 +266,9 @@ describe('RepoUrlPicker', () => { }, }); - const currentSecrets = JSON.parse( - getByTestId('current-secrets').textContent!, - ); - - expect(currentSecrets).toEqual({ - secrets: { testKey: 'abc123' }, - }); + expect(getByText('abc123')).toBeInTheDocument(); }); it('should call the scmAuthApi with the correct params if workspace is nested', async () => { - const SecretsComponent = () => { - const { secrets } = useTemplateSecrets(); - return ( -
      {JSON.stringify({ secrets })}
      - ); - }; await renderInTestApp( { RepoUrlPicker: RepoUrlPicker as ScaffolderRJSFField, }} /> - , ); @@ -324,13 +312,14 @@ describe('RepoUrlPicker', () => { }); it('should not call the scmAuthApi if secret is available in the state', async () => { + const secretsKey = 'testKey'; + const SecretsComponent = () => { const { secrets } = useTemplateSecrets(); - return ( -
      {JSON.stringify({ secrets })}
      - ); + const secret = secrets[secretsKey]; + return secret ?
      {secret}
      : null; }; - const { getByTestId } = await renderInTestApp( + const { getByText } = await renderInTestApp( { [scaffolderApiRef, mockScaffolderApi], ]} > - +
      { 'ui:field': 'RepoUrlPicker', 'ui:options': { requestUserCredentials: { - secretsKey: 'testKey', + secretsKey, additionalScopes: { github: ['workflow'] }, }, }, @@ -368,13 +357,7 @@ describe('RepoUrlPicker', () => { // as we already have a secret in the state, getCredentials should not be called again. expect(mockScmAuthApi.getCredentials).toHaveBeenCalledTimes(0); - const currentSecrets = JSON.parse( - getByTestId('current-secrets').textContent!, - ); - - expect(currentSecrets).toEqual({ - secrets: { testKey: 'abc123' }, - }); + expect(getByText('abc123')).toBeInTheDocument(); }); }); }); From bbd9f56c764b3fc22c79a279bca48f70d6c83dea Mon Sep 17 00:00:00 2001 From: Benjamin Janssens Date: Mon, 15 Jul 2024 10:49:56 +0200 Subject: [PATCH 275/510] chore: add changeset Signed-off-by: Benjamin Janssens --- .changeset/spotty-planets-accept.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/spotty-planets-accept.md diff --git a/.changeset/spotty-planets-accept.md b/.changeset/spotty-planets-accept.md new file mode 100644 index 0000000000..db262dd8b5 --- /dev/null +++ b/.changeset/spotty-planets-accept.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Cleaned up codebase From 9a5e7f1c36934b6eca39c8c13fbc35bcc43fefb2 Mon Sep 17 00:00:00 2001 From: Benjamin Janssens Date: Mon, 15 Jul 2024 10:51:24 +0200 Subject: [PATCH 276/510] chore: update changeset Signed-off-by: Benjamin Janssens --- .changeset/spotty-planets-accept.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/spotty-planets-accept.md b/.changeset/spotty-planets-accept.md index db262dd8b5..7342f89bd1 100644 --- a/.changeset/spotty-planets-accept.md +++ b/.changeset/spotty-planets-accept.md @@ -2,4 +2,4 @@ '@backstage/plugin-scaffolder': patch --- -Cleaned up codebase +Cleaned up codebase of RepoUrlPicker From c4a4a69912e004dbfa622d9f2107410af8fffd34 Mon Sep 17 00:00:00 2001 From: Benjamin Janssens Date: Mon, 15 Jul 2024 11:15:21 +0200 Subject: [PATCH 277/510] test: fix BitbucketRepoPicker tests Signed-off-by: Benjamin Janssens --- .../fields/RepoUrlPicker/BitbucketRepoPicker.test.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.test.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.test.tsx index 2ae89233ff..570c5bd664 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.test.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.test.tsx @@ -27,9 +27,11 @@ import { act } from 'react-dom/test-utils'; describe('BitbucketRepoPicker', () => { const scaffolderApiMock: Partial = { - autocomplete: jest.fn().mockImplementation(opts => ({ - results: [{ title: `${opts.resource}_example` }], - })), + autocomplete: jest.fn().mockImplementation(opts => + Promise.resolve({ + results: [{ title: `${opts.resource}_example` }], + }), + ), }; it('renders a select if there is a list of allowed owners', async () => { From a5bcb9c4d59af4c50bff0160bec566e49753a3a0 Mon Sep 17 00:00:00 2001 From: Niall Thomson Date: Mon, 15 Jul 2024 05:58:02 -0600 Subject: [PATCH 278/510] Update plugins/catalog-backend-module-aws/src/awsOrganization/config.ts Co-authored-by: Vincenzo Scamporlino Signed-off-by: Niall Thomson --- plugins/catalog-backend-module-aws/src/awsOrganization/config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/catalog-backend-module-aws/src/awsOrganization/config.ts b/plugins/catalog-backend-module-aws/src/awsOrganization/config.ts index ff00af48e4..ea16394e0a 100644 --- a/plugins/catalog-backend-module-aws/src/awsOrganization/config.ts +++ b/plugins/catalog-backend-module-aws/src/awsOrganization/config.ts @@ -22,6 +22,7 @@ import { Config } from '@backstage/config'; export type AwsOrganizationProviderConfig = { /** * The role to assume for the processor. + * @deprecated Use `accountId` instead. */ roleArn?: string; From 133464cfe04566513fc26633fadd2874a9d61bdc Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 15 Jul 2024 13:14:03 +0200 Subject: [PATCH 279/510] cli: add initial experimental support for dynamic plugins Signed-off-by: Patrik Oldsberg --- .changeset/clever-carrots-refuse.md | 5 + .changeset/fair-meals-juggle.md | 5 + packages/cli-node/src/roles/PackageRoles.ts | 5 + packages/cli/package.json | 1 + .../cli/src/commands/build/buildFrontend.ts | 8 + packages/cli/src/commands/build/command.ts | 19 + packages/cli/src/lib/bundler/bundle.ts | 48 +- packages/cli/src/lib/bundler/config.ts | 92 ++- packages/cli/src/lib/bundler/optimization.ts | 7 + packages/cli/src/lib/bundler/types.ts | 9 + yarn.lock | 577 ++++++++++++++++-- 11 files changed, 696 insertions(+), 80 deletions(-) create mode 100644 .changeset/clever-carrots-refuse.md create mode 100644 .changeset/fair-meals-juggle.md diff --git a/.changeset/clever-carrots-refuse.md b/.changeset/clever-carrots-refuse.md new file mode 100644 index 0000000000..24217b1045 --- /dev/null +++ b/.changeset/clever-carrots-refuse.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli-node': patch +--- + +Added internal metadata for the new experimental `frontend-dynamic-container` role. diff --git a/.changeset/fair-meals-juggle.md b/.changeset/fair-meals-juggle.md new file mode 100644 index 0000000000..94db114170 --- /dev/null +++ b/.changeset/fair-meals-juggle.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Added experimental support for dynamic frontend plugin builds, enabled via setting `EXPERIMENTAL_MODULE_FEDERATION` for the app build, and using the `frontend-dynamic-container` package role to create a container. Both of these are experimental and will change in the future. diff --git a/packages/cli-node/src/roles/PackageRoles.ts b/packages/cli-node/src/roles/PackageRoles.ts index 401568ad6d..70b62e2479 100644 --- a/packages/cli-node/src/roles/PackageRoles.ts +++ b/packages/cli-node/src/roles/PackageRoles.ts @@ -58,6 +58,11 @@ const packageRoleInfos: PackageRoleInfo[] = [ platform: 'web', output: ['types', 'esm'], }, + { + role: 'frontend-dynamic-container' as PackageRole, // experimental + platform: 'web', + output: ['bundle'], + }, { role: 'backend-plugin', platform: 'node', diff --git a/packages/cli/package.json b/packages/cli/package.json index 393f1217e1..97c15b16f2 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -53,6 +53,7 @@ "@backstage/release-manifests": "workspace:^", "@backstage/types": "workspace:^", "@manypkg/get-packages": "^1.1.3", + "@module-federation/enhanced": "^0.1.19", "@octokit/graphql": "^5.0.0", "@octokit/graphql-schema": "^13.7.0", "@octokit/oauth-app": "^4.2.0", diff --git a/packages/cli/src/commands/build/buildFrontend.ts b/packages/cli/src/commands/build/buildFrontend.ts index 6d7ca2e6a9..931a3b376a 100644 --- a/packages/cli/src/commands/build/buildFrontend.ts +++ b/packages/cli/src/commands/build/buildFrontend.ts @@ -24,6 +24,7 @@ interface BuildAppOptions { targetDir: string; writeStats: boolean; configPaths: string[]; + moduleFederationMode?: 'host' | 'remote'; } export async function buildFrontend(options: BuildAppOptions) { @@ -34,6 +35,13 @@ export async function buildFrontend(options: BuildAppOptions) { entry: 'src/index', parallelism: getEnvironmentParallelism(), statsJsonEnabled: writeStats, + moduleFederation: options.moduleFederationMode && { + // The default output mode requires the name to be a usable as a code + // symbol, there might be better options here but for now we need to + // sanitize the name. + name: name.replaceAll('@', '').replaceAll(/[/\\_-]/g, '_'), + mode: options.moduleFederationMode, + }, ...(await loadCliConfig({ args: configPaths, fromPackage: name, diff --git a/packages/cli/src/commands/build/command.ts b/packages/cli/src/commands/build/command.ts index f15ae27ee0..285cba0e81 100644 --- a/packages/cli/src/commands/build/command.ts +++ b/packages/cli/src/commands/build/command.ts @@ -22,6 +22,7 @@ import { paths } from '../../lib/paths'; import { buildFrontend } from './buildFrontend'; import { buildBackend } from './buildBackend'; import { isValidUrl } from '../../lib/urls'; +import chalk from 'chalk'; export async function command(opts: OptionValues): Promise { const role = await findRoleFromCommand(opts); @@ -39,6 +40,9 @@ export async function command(opts: OptionValues): Promise { targetDir: paths.targetDir, configPaths, writeStats: Boolean(opts.stats), + moduleFederationMode: process.env.EXPERIMENTAL_MODULE_FEDERATION + ? 'host' + : undefined, }); } return buildBackend({ @@ -49,6 +53,21 @@ export async function command(opts: OptionValues): Promise { }); } + // experimental + if ((role as string) === 'frontend-dynamic-container') { + console.log( + chalk.yellow( + `⚠️ WARNING: The 'frontend-dynamic-container' package role is experimental and will receive immediate breaking changes in the future.`, + ), + ); + return buildFrontend({ + targetDir: paths.targetDir, + configPaths: [], + writeStats: Boolean(opts.stats), + moduleFederationMode: 'remote', + }); + } + const roleInfo = PackageRoles.getRoleInfo(role); const outputs = new Set(); diff --git a/packages/cli/src/lib/bundler/bundle.ts b/packages/cli/src/lib/bundler/bundle.ts index 232657a3f2..d24d4252f4 100644 --- a/packages/cli/src/lib/bundler/bundle.ts +++ b/packages/cli/src/lib/bundler/bundle.ts @@ -46,37 +46,45 @@ export async function buildBundle(options: BuildOptions) { dist: 'dist/public', }); - const detectedModulesEntryPoint = await createDetectedModulesEntryPoint({ - config: options.fullConfig, - targetPath: paths.targetPath, - }); - const commonConfigOptions = { ...options, checksEnabled: false, isDev: false, getFrontendAppConfigs: () => options.frontendAppConfigs, }; - const configs = [ - await createConfig(paths, { - ...commonConfigOptions, - additionalEntryPoints: detectedModulesEntryPoint, - appMode: publicPaths ? 'protected' : 'public', - }), - ]; - if (publicPaths) { - console.log( - chalk.yellow( - `⚠️ WARNING: The app /public entry point is an experimental feature that may receive immediate breaking changes.`, - ), - ); + const configs = []; + + if (options.moduleFederation?.mode === 'remote') { + // Package detection is disabled for remote bundles + configs.push(await createConfig(paths, commonConfigOptions)); + } else { + const detectedModulesEntryPoint = await createDetectedModulesEntryPoint({ + config: options.fullConfig, + targetPath: paths.targetPath, + }); + configs.push( - await createConfig(publicPaths, { + await createConfig(paths, { ...commonConfigOptions, - appMode: 'public', + additionalEntryPoints: detectedModulesEntryPoint, + appMode: publicPaths ? 'protected' : 'public', }), ); + + if (publicPaths) { + console.log( + chalk.yellow( + `⚠️ WARNING: The app /public entry point is an experimental feature that may receive immediate breaking changes.`, + ), + ); + configs.push( + await createConfig(publicPaths, { + ...commonConfigOptions, + appMode: 'public', + }), + ); + } } const isCi = yn(process.env.CI, { default: false }); diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index 53db7f3597..c2621b20a4 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -24,6 +24,7 @@ import { Config } from '@backstage/config'; import ESLintPlugin from 'eslint-webpack-plugin'; import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin'; import HtmlWebpackPlugin from 'html-webpack-plugin'; +import { ModuleFederationPlugin } from '@module-federation/enhanced'; import { LinkedPackageResolvePlugin } from './LinkedPackageResolvePlugin'; import ModuleScopePlugin from 'react-dev-utils/ModuleScopePlugin'; import { RunScriptWebpackPlugin } from 'run-script-webpack-plugin'; @@ -128,18 +129,81 @@ export async function createConfig( }), ); - plugins.push( - new HtmlWebpackPlugin({ - meta: { - 'backstage-app-mode': options?.appMode ?? 'public', - }, - template: paths.targetHtml, - templateParameters: { - publicPath, - config: frontendConfig, - }, - }), - ); + if (options.moduleFederation?.mode !== 'remote') { + plugins.push( + new HtmlWebpackPlugin({ + meta: { + 'backstage-app-mode': options?.appMode ?? 'public', + }, + template: paths.targetHtml, + templateParameters: { + publicPath, + config: frontendConfig, + }, + }), + ); + } + + if (options.moduleFederation) { + plugins.push( + new ModuleFederationPlugin({ + ...(options.moduleFederation?.mode === 'remote' && { + filename: 'remoteEntry.js', + exposes: { + '.': paths.targetEntry, + }, + }), + name: options.moduleFederation.name, + runtime: false, + shared: { + // React + react: { + singleton: true, + requiredVersion: '*', + eager: true, + }, + 'react-dom': { + singleton: true, + requiredVersion: '*', + eager: true, + }, + // React Router + 'react-router': { + singleton: true, + requiredVersion: '*', + eager: true, + }, + 'react-router-dom': { + singleton: true, + requiredVersion: '*', + eager: true, + }, + // MUI v4 + '@material-ui/core/styles': { + singleton: true, + requiredVersion: '*', + eager: true, + }, + '@material-ui/styles': { + singleton: true, + requiredVersion: '*', + eager: true, + }, + // MUI v5 + '@mui/material/styles/': { + singleton: true, + requiredVersion: '*', + eager: true, + }, + '@emotion/react': { + singleton: true, + requiredVersion: '*', + eager: true, + }, + }, + }), + ); + } const buildInfo = await readBuildInfo(); plugins.push( @@ -211,8 +275,10 @@ export async function createConfig( rules: loaders, }, output: { + uniqueName: options.moduleFederation?.name, path: paths.targetDist, - publicPath: `${publicPath}/`, + publicPath: + options.moduleFederation?.mode === 'remote' ? 'auto' : `${publicPath}/`, filename: isDev ? '[name].js' : 'static/[name].[fullhash:8].js', chunkFilename: isDev ? '[name].chunk.js' diff --git a/packages/cli/src/lib/bundler/optimization.ts b/packages/cli/src/lib/bundler/optimization.ts index 88a0343099..891e0793fe 100644 --- a/packages/cli/src/lib/bundler/optimization.ts +++ b/packages/cli/src/lib/bundler/optimization.ts @@ -30,6 +30,13 @@ export const optimization = ( new EsbuildPlugin({ target: 'es2019', format: 'iife', + exclude: 'remoteEntry.js', + }), + // Avoid iife wrapping of module federation remote entry as it breaks the variable assignment + new EsbuildPlugin({ + target: 'es2019', + format: undefined, + include: 'remoteEntry.js', }), ], runtimeChunk: 'single', diff --git a/packages/cli/src/lib/bundler/types.ts b/packages/cli/src/lib/bundler/types.ts index 85a641465f..7291ac0818 100644 --- a/packages/cli/src/lib/bundler/types.ts +++ b/packages/cli/src/lib/bundler/types.ts @@ -18,6 +18,13 @@ import { AppConfig, Config } from '@backstage/config'; import { BundlingPathsOptions } from './paths'; import { ConfigSchema } from '@backstage/config-loader'; +export type ModuleFederationOptions = { + // Unique name for this module federation bundle + name: string; + // Whether this is a host or remote bundle + mode: 'host' | 'remote'; +}; + export type BundlingOptions = { checksEnabled: boolean; isDev: boolean; @@ -29,6 +36,7 @@ export type BundlingOptions = { publicSubPath?: string; // Mode that the app is running in, 'protected' or 'public', default is 'public' appMode?: string; + moduleFederation?: ModuleFederationOptions; }; export type ServeOptions = BundlingPathsOptions & { @@ -46,6 +54,7 @@ export type BuildOptions = BundlingPathsOptions & { frontendConfig: Config; frontendAppConfigs: AppConfig[]; fullConfig: Config; + moduleFederation?: ModuleFederationOptions; }; export type BackendBundlingOptions = { diff --git a/yarn.lock b/yarn.lock index afe89e4263..14f731a803 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3917,6 +3917,7 @@ __metadata: "@backstage/theme": "workspace:^" "@backstage/types": "workspace:^" "@manypkg/get-packages": ^1.1.3 + "@module-federation/enhanced": ^0.1.19 "@octokit/graphql": ^5.0.0 "@octokit/graphql-schema": ^13.7.0 "@octokit/oauth-app": ^4.2.0 @@ -11038,6 +11039,145 @@ __metadata: languageName: node linkType: hard +"@module-federation/dts-plugin@npm:0.1.21": + version: 0.1.21 + resolution: "@module-federation/dts-plugin@npm:0.1.21" + dependencies: + "@module-federation/managers": 0.1.21 + "@module-federation/sdk": 0.1.21 + "@module-federation/third-party-dts-extractor": 0.1.21 + adm-zip: ^0.5.10 + ansi-colors: ^4.1.3 + axios: ^1.6.7 + chalk: 3.0.0 + fs-extra: 9.1.0 + isomorphic-ws: 5.0.0 + koa: 2.11.0 + lodash.clonedeepwith: 4.5.0 + log4js: 6.9.1 + node-schedule: 2.1.1 + rambda: ^9.1.0 + ws: 8.17.0 + peerDependencies: + typescript: ^4.9.0 || ^5.0.0 + vue-tsc: ^1.0.24 + peerDependenciesMeta: + vue-tsc: + optional: true + checksum: ec4cd030a25617698754cbac2da5463f8942cdd0a64bdc95f6ff5fd29fff6b88cf3db90e53e6b260cd3593893fe6ee2d6e149d0a46698eb7f9cc19a9df26193d + languageName: node + linkType: hard + +"@module-federation/enhanced@npm:^0.1.19": + version: 0.1.21 + resolution: "@module-federation/enhanced@npm:0.1.21" + dependencies: + "@module-federation/dts-plugin": 0.1.21 + "@module-federation/managers": 0.1.21 + "@module-federation/manifest": 0.1.21 + "@module-federation/rspack": 0.1.21 + "@module-federation/runtime-tools": 0.1.21 + "@module-federation/sdk": 0.1.21 + upath: 2.0.1 + peerDependencies: + typescript: ^4.9.0 || ^5.0.0 + vue-tsc: ^1.0.24 + webpack: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + vue-tsc: + optional: true + webpack: + optional: true + checksum: bc0ff541db1066b290b3ad9ab868437dc3d0754b9d06ab263f8fb7f54e08238eae9232a482a681dd6152e4a175578d65df9f27fe181fc8fb602d7cc1ae34807d + languageName: node + linkType: hard + +"@module-federation/managers@npm:0.1.21": + version: 0.1.21 + resolution: "@module-federation/managers@npm:0.1.21" + dependencies: + "@module-federation/sdk": 0.1.21 + find-pkg: 2.0.0 + fs-extra: 9.1.0 + checksum: 5f230d5795d86dfd68c404ee2b7a1264950c283a4b1c6f4ee9cc9579fabb413718dfbc1ff726b9c213f9d3223d944dd38dd9d04b700962e6398c3c3728d6323e + languageName: node + linkType: hard + +"@module-federation/manifest@npm:0.1.21": + version: 0.1.21 + resolution: "@module-federation/manifest@npm:0.1.21" + dependencies: + "@module-federation/dts-plugin": 0.1.21 + "@module-federation/managers": 0.1.21 + "@module-federation/sdk": 0.1.21 + chalk: 3.0.0 + find-pkg: 2.0.0 + checksum: cef2011875f14e853a355626ae1dbc8ae3b0714d31140e329b5dd71525782b08c2e1d6ca45276a563bb3c3b7f7c4e64a31f0698ef12606f05aa6da46e759f345 + languageName: node + linkType: hard + +"@module-federation/rspack@npm:0.1.21": + version: 0.1.21 + resolution: "@module-federation/rspack@npm:0.1.21" + dependencies: + "@module-federation/dts-plugin": 0.1.21 + "@module-federation/managers": 0.1.21 + "@module-federation/manifest": 0.1.21 + "@module-federation/runtime-tools": 0.1.21 + "@module-federation/sdk": 0.1.21 + checksum: 55516285e23f4ca7127afafb14af667defbe46dc3224f85d7e07edbc8937d7fac909dfebc2f9dd73120b99bbe5135372cf0fbbe282990d80e6953a60dfa4c93e + languageName: node + linkType: hard + +"@module-federation/runtime-tools@npm:0.1.21": + version: 0.1.21 + resolution: "@module-federation/runtime-tools@npm:0.1.21" + dependencies: + "@module-federation/runtime": 0.1.21 + "@module-federation/webpack-bundler-runtime": 0.1.21 + checksum: 628c0c4834093520f9c71481d587c9e18163f82e481b05b1900f04e2d5da4abb69af6d814ac5cd1951057b28d73f3adeb1cee7cd83628305b10cc7988405fbc5 + languageName: node + linkType: hard + +"@module-federation/runtime@npm:0.1.21": + version: 0.1.21 + resolution: "@module-federation/runtime@npm:0.1.21" + dependencies: + "@module-federation/sdk": 0.1.21 + checksum: ce4de8515b54f1cd07a3c7c4cbd35fea163294b9fb24be10827872f3ebb62cd5c289f3602efe4149d963282739f79b51947afa039ee6f36be7f66dea83d590fc + languageName: node + linkType: hard + +"@module-federation/sdk@npm:0.1.21": + version: 0.1.21 + resolution: "@module-federation/sdk@npm:0.1.21" + checksum: 6856dcfe2ef5ae939890b82010aaad911fa6c4330a05f290ae054c316c9b532d3691456a1f9e176fe05f1df2d6f2d8c7e0c842ca5648a0fd7abf270e44ed9ecb + languageName: node + linkType: hard + +"@module-federation/third-party-dts-extractor@npm:0.1.21": + version: 0.1.21 + resolution: "@module-federation/third-party-dts-extractor@npm:0.1.21" + dependencies: + find-pkg: 2.0.0 + fs-extra: 9.1.0 + resolve: 1.22.8 + checksum: e394fd7c2e6dbdf8df6937628680e7356ac897ee6f1309d7fbc38c00bcf4be9c0363f8bc1a75c29f7987a5a2f11f7855481813889b18e8b444ee9006aeb4a299 + languageName: node + linkType: hard + +"@module-federation/webpack-bundler-runtime@npm:0.1.21": + version: 0.1.21 + resolution: "@module-federation/webpack-bundler-runtime@npm:0.1.21" + dependencies: + "@module-federation/runtime": 0.1.21 + "@module-federation/sdk": 0.1.21 + checksum: 7d96002066e63bdb503964fd5fb2798be25f4135a599d87721f4d26ebe1de1affbf447c56b082f7ee850ae7798d0ac637f6a486f58591269065e114051b466e5 + languageName: node + linkType: hard + "@motionone/animation@npm:^10.12.0": version: 10.16.3 resolution: "@motionone/animation@npm:10.16.3" @@ -20325,7 +20465,7 @@ __metadata: languageName: node linkType: hard -"accepts@npm:^1.3.7, accepts@npm:~1.3.4, accepts@npm:~1.3.5, accepts@npm:~1.3.8": +"accepts@npm:^1.3.5, accepts@npm:^1.3.7, accepts@npm:~1.3.4, accepts@npm:~1.3.5, accepts@npm:~1.3.8": version: 1.3.8 resolution: "accepts@npm:1.3.8" dependencies: @@ -20402,6 +20542,13 @@ __metadata: languageName: node linkType: hard +"adm-zip@npm:^0.5.10": + version: 0.5.14 + resolution: "adm-zip@npm:0.5.14" + checksum: 83a4bc0bdff70f3276992810db96b10ffbf3c07667a9c3395e3dc60ca40ecbb920812dde212e1e21633b1508f1ea6fc427ac451aa68ee1a597b7251b2c1fc844 + languageName: node + linkType: hard + "agent-base@npm:6, agent-base@npm:^6.0.2": version: 6.0.2 resolution: "agent-base@npm:6.0.2" @@ -20695,7 +20842,7 @@ __metadata: languageName: node linkType: hard -"any-promise@npm:^1.0.0": +"any-promise@npm:^1.0.0, any-promise@npm:^1.1.0": version: 1.3.0 resolution: "any-promise@npm:1.3.0" checksum: 0ee8a9bdbe882c90464d75d1f55cf027f5458650c4bd1f0467e65aec38ccccda07ca5844969ee77ed46d04e7dded3eaceb027e8d32f385688523fe305fa7e1de @@ -21342,7 +21489,7 @@ __metadata: languageName: node linkType: hard -"axios@npm:1.6.8, axios@npm:^1.0.0, axios@npm:^1.4.0, axios@npm:^1.6.0": +"axios@npm:1.6.8": version: 1.6.8 resolution: "axios@npm:1.6.8" dependencies: @@ -21363,6 +21510,17 @@ __metadata: languageName: node linkType: hard +"axios@npm:^1.0.0, axios@npm:^1.4.0, axios@npm:^1.6.0, axios@npm:^1.6.7": + version: 1.7.2 + resolution: "axios@npm:1.7.2" + dependencies: + follow-redirects: ^1.15.6 + form-data: ^4.0.0 + proxy-from-env: ^1.1.0 + checksum: e457e2b0ab748504621f6fa6609074ac08c824bf0881592209dfa15098ece7e88495300e02cd22ba50b3468fd712fe687e629dcb03d6a3f6a51989727405aedf + languageName: node + linkType: hard + "axobject-query@npm:^3.2.1": version: 3.2.1 resolution: "axobject-query@npm:3.2.1" @@ -22292,6 +22450,16 @@ __metadata: languageName: node linkType: hard +"cache-content-type@npm:^1.0.0": + version: 1.0.1 + resolution: "cache-content-type@npm:1.0.1" + dependencies: + mime-types: ^2.1.18 + ylru: ^1.2.0 + checksum: 18db4d59452669ccbfd7146a1510a37eb28e9eccf18ca7a4eb603dff2edc5cccdca7498fc3042a2978f76f11151fba486eb9eb69d9afa3fb124957870aef4fd3 + languageName: node + linkType: hard + "cacheable-lookup@npm:^5.0.3": version: 5.0.3 resolution: "cacheable-lookup@npm:5.0.3" @@ -22457,6 +22625,16 @@ __metadata: languageName: node linkType: hard +"chalk@npm:3.0.0, chalk@npm:^3.0.0": + version: 3.0.0 + resolution: "chalk@npm:3.0.0" + dependencies: + ansi-styles: ^4.1.0 + supports-color: ^7.1.0 + checksum: 8e3ddf3981c4da405ddbd7d9c8d91944ddf6e33d6837756979f7840a29272a69a5189ecae0ff84006750d6d1e92368d413335eab4db5476db6e6703a1d1e0505 + languageName: node + linkType: hard + "chalk@npm:4.1.2, chalk@npm:^4.0.0, chalk@npm:^4.0.2, chalk@npm:^4.1.0, chalk@npm:^4.1.1, chalk@npm:^4.1.2": version: 4.1.2 resolution: "chalk@npm:4.1.2" @@ -22467,16 +22645,6 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^3.0.0": - version: 3.0.0 - resolution: "chalk@npm:3.0.0" - dependencies: - ansi-styles: ^4.1.0 - supports-color: ^7.1.0 - checksum: 8e3ddf3981c4da405ddbd7d9c8d91944ddf6e33d6837756979f7840a29272a69a5189ecae0ff84006750d6d1e92368d413335eab4db5476db6e6703a1d1e0505 - languageName: node - linkType: hard - "chalk@npm:~5.3.0": version: 5.3.0 resolution: "chalk@npm:5.3.0" @@ -23478,7 +23646,7 @@ __metadata: languageName: node linkType: hard -"content-disposition@npm:0.5.4, content-disposition@npm:^0.5.3": +"content-disposition@npm:0.5.4, content-disposition@npm:^0.5.3, content-disposition@npm:~0.5.2": version: 0.5.4 resolution: "content-disposition@npm:0.5.4" dependencies: @@ -23487,7 +23655,7 @@ __metadata: languageName: node linkType: hard -"content-type@npm:^1.0.5, content-type@npm:~1.0.4, content-type@npm:~1.0.5": +"content-type@npm:^1.0.4, content-type@npm:^1.0.5, content-type@npm:~1.0.4, content-type@npm:~1.0.5": version: 1.0.5 resolution: "content-type@npm:1.0.5" checksum: 566271e0a251642254cde0f845f9dd4f9856e52d988f4eb0d0dcffbb7a1f8ec98de7a5215fc628f3bce30fe2fb6fd2bc064b562d721658c59b544e2d34ea2766 @@ -23574,6 +23742,16 @@ __metadata: languageName: node linkType: hard +"cookies@npm:~0.8.0": + version: 0.8.0 + resolution: "cookies@npm:0.8.0" + dependencies: + depd: ~2.0.0 + keygrip: ~1.1.0 + checksum: 806055a44f128705265b1bc6a853058da18bf80dea3654ad99be20985b1fa1b14f86c1eef73644aab8071241f8a78acd57202b54c4c5c70769fc694fbb9c4edc + languageName: node + linkType: hard + "copy-to-clipboard@npm:^3.2.0, copy-to-clipboard@npm:^3.3.1": version: 3.3.1 resolution: "copy-to-clipboard@npm:3.3.1" @@ -23791,6 +23969,15 @@ __metadata: languageName: node linkType: hard +"cron-parser@npm:^4.2.0": + version: 4.9.0 + resolution: "cron-parser@npm:4.9.0" + dependencies: + luxon: ^3.2.1 + checksum: 3cf248fc5cae6c19ec7124962b1cd84b76f02b9bc4f58976b3bd07624db3ef10aaf1548efcc2d2dcdab0dad4f12029d640a55ecce05ea5e1596af9db585502cf + languageName: node + linkType: hard + "cron@npm:^3.0.0": version: 3.1.7 resolution: "cron@npm:3.1.7" @@ -24400,6 +24587,13 @@ __metadata: languageName: node linkType: hard +"date-format@npm:^4.0.14": + version: 4.0.14 + resolution: "date-format@npm:4.0.14" + checksum: dfe5139df6af5759b9dd3c007b899b3f60d45a9240ffeee6314ab74e6ab52e9b519a44ccf285888bdd6b626c66ee9b4c8a523075fa1140617b5beb1cbb9b18d1 + languageName: node + linkType: hard + "dateformat@npm:^3.0.3": version: 3.0.3 resolution: "dateformat@npm:3.0.3" @@ -24460,6 +24654,15 @@ __metadata: languageName: node linkType: hard +"debug@npm:~3.1.0": + version: 3.1.0 + resolution: "debug@npm:3.1.0" + dependencies: + ms: 2.0.0 + checksum: 0b52718ab957254a5b3ca07fc34543bc778f358620c206a08452251eb7fc193c3ea3505072acbf4350219c14e2d71ceb7bdaa0d3370aa630b50da790458d08b3 + languageName: node + linkType: hard + "debuglog@npm:^1.0.1": version: 1.0.1 resolution: "debuglog@npm:1.0.1" @@ -24529,6 +24732,13 @@ __metadata: languageName: node linkType: hard +"deep-equal@npm:~1.0.1": + version: 1.0.1 + resolution: "deep-equal@npm:1.0.1" + checksum: 5af8cbfcebf190491878a498caccc7dc9592f8ebd1685b976eacc3825619d222b5e929923163b92c4f414494e2b884f7ebf00c022e8198e8292deb70dd9785f4 + languageName: node + linkType: hard + "deep-extend@npm:0.6.0, deep-extend@npm:^0.6.0": version: 0.6.0 resolution: "deep-extend@npm:0.6.0" @@ -24735,7 +24945,7 @@ __metadata: languageName: node linkType: hard -"destroy@npm:1.2.0": +"destroy@npm:1.2.0, destroy@npm:^1.0.4": version: 1.2.0 resolution: "destroy@npm:1.2.0" checksum: 0acb300b7478a08b92d810ab229d5afe0d2f4399272045ab22affa0d99dbaf12637659411530a6fcd597a9bdac718fc94373a61a95b4651bbc7b83684a565e38 @@ -25401,7 +25611,7 @@ __metadata: languageName: node linkType: hard -"encodeurl@npm:~1.0.2": +"encodeurl@npm:^1.0.2, encodeurl@npm:~1.0.2": version: 1.0.2 resolution: "encodeurl@npm:1.0.2" checksum: e50e3d508cdd9c4565ba72d2012e65038e5d71bdc9198cb125beb6237b5b1ade6c0d343998da9e170fb2eae52c1bed37d4d6d98a46ea423a0cddbed5ac3f780c @@ -25490,6 +25700,13 @@ __metadata: languageName: node linkType: hard +"error-inject@npm:^1.0.0": + version: 1.0.0 + resolution: "error-inject@npm:1.0.0" + checksum: 258cb26c7c7e04d9b730d074926ff5e18755b6945781540fdd124cafc5015610d97e4b971eb3226469f407fd34fa899a60fbcf9ade8923ab42fa2a3c61e246cf + languageName: node + linkType: hard + "error-stack-parser@npm:^2.0.6": version: 2.0.6 resolution: "error-stack-parser@npm:2.0.6" @@ -26861,6 +27078,15 @@ __metadata: languageName: node linkType: hard +"expand-tilde@npm:^2.0.0, expand-tilde@npm:^2.0.2": + version: 2.0.2 + resolution: "expand-tilde@npm:2.0.2" + dependencies: + homedir-polyfill: ^1.0.1 + checksum: 2efe6ed407d229981b1b6ceb552438fbc9e5c7d6a6751ad6ced3e0aa5cf12f0b299da695e90d6c2ac79191b5c53c613e508f7149e4573abfbb540698ddb7301a + languageName: node + linkType: hard + "expect@npm:>28.1.3, expect@npm:^29.0.0, expect@npm:^29.7.0": version: 29.7.0 resolution: "expect@npm:29.7.0" @@ -27400,6 +27626,15 @@ __metadata: languageName: node linkType: hard +"find-file-up@npm:^2.0.1": + version: 2.0.1 + resolution: "find-file-up@npm:2.0.1" + dependencies: + resolve-dir: ^1.0.1 + checksum: dfe820bfb80e75bed5dd5080057858c0ad2393e1438c48a3bb682663e9ecdcfbe3224ed4768bfedd00776800b4ae76bc8953d250d15ae3feabf381d2c6d04268 + languageName: node + linkType: hard + "find-my-way@npm:^4.3.3": version: 4.5.1 resolution: "find-my-way@npm:4.5.1" @@ -27412,6 +27647,15 @@ __metadata: languageName: node linkType: hard +"find-pkg@npm:2.0.0": + version: 2.0.0 + resolution: "find-pkg@npm:2.0.0" + dependencies: + find-file-up: ^2.0.1 + checksum: 44785204c8bbbdfeaece6b834ba81a35163421c30e20f531281d26e6b5890663d7ac884b82a9aebf6ce23e479336cd6f70ea5597da35495c16abdeba2fd4f845 + languageName: node + linkType: hard + "find-process@npm:^1.4.5": version: 1.4.7 resolution: "find-process@npm:1.4.7" @@ -27497,7 +27741,7 @@ __metadata: languageName: node linkType: hard -"flatted@npm:3.3.1, flatted@npm:^3.1.0": +"flatted@npm:3.3.1, flatted@npm:^3.1.0, flatted@npm:^3.2.7": version: 3.3.1 resolution: "flatted@npm:3.3.1" checksum: 85ae7181650bb728c221e7644cbc9f4bf28bc556f2fc89bb21266962bdf0ce1029cc7acc44bb646cd469d9baac7c317f64e841c4c4c00516afa97320cdac7f94 @@ -27727,7 +27971,7 @@ __metadata: languageName: node linkType: hard -"fresh@npm:0.5.2, fresh@npm:^0.5.2": +"fresh@npm:0.5.2, fresh@npm:^0.5.2, fresh@npm:~0.5.2": version: 0.5.2 resolution: "fresh@npm:0.5.2" checksum: 13ea8b08f91e669a64e3ba3a20eb79d7ca5379a81f1ff7f4310d54e2320645503cc0c78daedc93dfb6191287295f6479544a649c64d8e41a1c0fb0c221552346 @@ -27769,6 +28013,18 @@ __metadata: languageName: node linkType: hard +"fs-extra@npm:9.1.0, fs-extra@npm:^9.0.0": + version: 9.1.0 + resolution: "fs-extra@npm:9.1.0" + dependencies: + at-least-node: ^1.0.0 + graceful-fs: ^4.2.0 + jsonfile: ^6.0.1 + universalify: ^2.0.0 + checksum: ba71ba32e0faa74ab931b7a0031d1523c66a73e225de7426e275e238e312d07313d2da2d33e34a52aa406c8763ade5712eb3ec9ba4d9edce652bcacdc29e6b20 + languageName: node + linkType: hard + "fs-extra@npm:^11.0.0, fs-extra@npm:^11.1.0, fs-extra@npm:^11.2.0": version: 11.2.0 resolution: "fs-extra@npm:11.2.0" @@ -27802,18 +28058,6 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:^9.0.0": - version: 9.1.0 - resolution: "fs-extra@npm:9.1.0" - dependencies: - at-least-node: ^1.0.0 - graceful-fs: ^4.2.0 - jsonfile: ^6.0.1 - universalify: ^2.0.0 - checksum: ba71ba32e0faa74ab931b7a0031d1523c66a73e225de7426e275e238e312d07313d2da2d33e34a52aa406c8763ade5712eb3ec9ba4d9edce652bcacdc29e6b20 - languageName: node - linkType: hard - "fs-minipass@npm:^2.0.0, fs-minipass@npm:^2.1.0": version: 2.1.0 resolution: "fs-minipass@npm:2.1.0" @@ -28265,6 +28509,17 @@ __metadata: languageName: node linkType: hard +"global-modules@npm:^1.0.0": + version: 1.0.0 + resolution: "global-modules@npm:1.0.0" + dependencies: + global-prefix: ^1.0.1 + is-windows: ^1.0.1 + resolve-dir: ^1.0.0 + checksum: 10be68796c1e1abc1e2ba87ec4ea507f5629873b119ab0cd29c07284ef2b930f1402d10df01beccb7391dedd9cd479611dd6a24311c71be58937beaf18edf85e + languageName: node + linkType: hard + "global-modules@npm:^2.0.0": version: 2.0.0 resolution: "global-modules@npm:2.0.0" @@ -28274,6 +28529,19 @@ __metadata: languageName: node linkType: hard +"global-prefix@npm:^1.0.1": + version: 1.0.2 + resolution: "global-prefix@npm:1.0.2" + dependencies: + expand-tilde: ^2.0.2 + homedir-polyfill: ^1.0.1 + ini: ^1.3.4 + is-windows: ^1.0.1 + which: ^1.2.14 + checksum: 061b43470fe498271bcd514e7746e8a8535032b17ab9570517014ae27d700ff0dca749f76bbde13ba384d185be4310d8ba5712cb0e74f7d54d59390db63dd9a0 + languageName: node + linkType: hard + "global-prefix@npm:^3.0.0": version: 3.0.0 resolution: "global-prefix@npm:3.0.0" @@ -28895,6 +29163,15 @@ __metadata: languageName: node linkType: hard +"homedir-polyfill@npm:^1.0.1": + version: 1.0.3 + resolution: "homedir-polyfill@npm:1.0.3" + dependencies: + parse-passwd: ^1.0.0 + checksum: 18dd4db87052c6a2179d1813adea0c4bfcfa4f9996f0e226fefb29eb3d548e564350fa28ec46b0bf1fbc0a1d2d6922ceceb80093115ea45ff8842a4990139250 + languageName: node + linkType: hard + "hoopy@npm:^0.1.4": version: 0.1.4 resolution: "hoopy@npm:0.1.4" @@ -29019,6 +29296,16 @@ __metadata: languageName: node linkType: hard +"http-assert@npm:^1.3.0": + version: 1.5.0 + resolution: "http-assert@npm:1.5.0" + dependencies: + deep-equal: ~1.0.1 + http-errors: ~1.8.0 + checksum: 69c9b3c14cf8b2822916360a365089ce936c883c49068f91c365eccba5c141a9964d19fdda589150a480013bf503bf37d8936c732e9635819339e730ab0e7527 + languageName: node + linkType: hard + "http-cache-semantics@npm:^4.0.0, http-cache-semantics@npm:^4.1.0, http-cache-semantics@npm:^4.1.1": version: 4.1.1 resolution: "http-cache-semantics@npm:4.1.1" @@ -29057,6 +29344,19 @@ __metadata: languageName: node linkType: hard +"http-errors@npm:^1.6.3, http-errors@npm:~1.8.0": + version: 1.8.1 + resolution: "http-errors@npm:1.8.1" + dependencies: + depd: ~1.1.2 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: ">= 1.5.0 < 2" + toidentifier: 1.0.1 + checksum: d3c7e7e776fd51c0a812baff570bdf06fe49a5dc448b700ab6171b1250e4cf7db8b8f4c0b133e4bfe2451022a5790c1ca6c2cae4094dedd6ac8304a1267f91d2 + languageName: node + linkType: hard + "http-errors@npm:~1.6.2": version: 1.6.3 resolution: "http-errors@npm:1.6.3" @@ -29520,7 +29820,7 @@ __metadata: languageName: node linkType: hard -"ini@npm:^1.3.5, ini@npm:~1.3.0": +"ini@npm:^1.3.4, ini@npm:^1.3.5, ini@npm:~1.3.0": version: 1.3.8 resolution: "ini@npm:1.3.8" checksum: dfd98b0ca3a4fc1e323e38a6c8eb8936e31a97a918d3b377649ea15bdb15d481207a0dda1021efbd86b464cae29a0d33c1d7dcaf6c5672bee17fa849bc50a1b3 @@ -30417,7 +30717,7 @@ __metadata: languageName: node linkType: hard -"is-windows@npm:^1.0.0, is-windows@npm:^1.0.2": +"is-windows@npm:^1.0.0, is-windows@npm:^1.0.1, is-windows@npm:^1.0.2": version: 1.0.2 resolution: "is-windows@npm:1.0.2" checksum: 438b7e52656fe3b9b293b180defb4e448088e7023a523ec21a91a80b9ff8cdb3377ddb5b6e60f7c7de4fa8b63ab56e121b6705fe081b3cf1b828b0a380009ad7 @@ -31989,6 +32289,15 @@ __metadata: languageName: node linkType: hard +"keygrip@npm:~1.1.0": + version: 1.1.0 + resolution: "keygrip@npm:1.1.0" + dependencies: + tsscmp: 1.0.6 + checksum: 078cd16a463d187121f0a27c1c9c95c52ad392b620f823431689f345a0501132cee60f6e96914b07d570105af470b96960402accd6c48a0b1f3cd8fac4fa2cae + languageName: node + linkType: hard + "keyv@npm:*, keyv@npm:^4.0.0, keyv@npm:^4.5.2": version: 4.5.4 resolution: "keyv@npm:4.5.4" @@ -32099,6 +32408,64 @@ __metadata: languageName: node linkType: hard +"koa-compose@npm:^3.0.0": + version: 3.2.1 + resolution: "koa-compose@npm:3.2.1" + dependencies: + any-promise: ^1.1.0 + checksum: ff8e5fc0348455acf751179c6c613eb030a5fac6406d3b49ae9e00460b7ee8770db3ef62633fd3db0306cd4a6d2a0b5152399ebd5bb5e684418f9eeeb251c2de + languageName: node + linkType: hard + +"koa-compose@npm:^4.1.0": + version: 4.1.0 + resolution: "koa-compose@npm:4.1.0" + checksum: 46cb16792d96425e977c2ae4e5cb04930280740e907242ec9c25e3fb8b4a1d7b54451d7432bc24f40ec62255edea71894d2ceeb8238501842b4e48014f2e83db + languageName: node + linkType: hard + +"koa-convert@npm:^1.2.0": + version: 1.2.0 + resolution: "koa-convert@npm:1.2.0" + dependencies: + co: ^4.6.0 + koa-compose: ^3.0.0 + checksum: a33944dbda4ed87565985f5b37ba1122a012db872724b216b6fd8f9176d4bba42c4a9bf3c129330e45f6474d28f50ca0ed28d41b9bccd2ab5d36d6436cf0d676 + languageName: node + linkType: hard + +"koa@npm:2.11.0": + version: 2.11.0 + resolution: "koa@npm:2.11.0" + dependencies: + accepts: ^1.3.5 + cache-content-type: ^1.0.0 + content-disposition: ~0.5.2 + content-type: ^1.0.4 + cookies: ~0.8.0 + debug: ~3.1.0 + delegates: ^1.0.0 + depd: ^1.1.2 + destroy: ^1.0.4 + encodeurl: ^1.0.2 + error-inject: ^1.0.0 + escape-html: ^1.0.3 + fresh: ~0.5.2 + http-assert: ^1.3.0 + http-errors: ^1.6.3 + is-generator-function: ^1.0.7 + koa-compose: ^4.1.0 + koa-convert: ^1.2.0 + on-finished: ^2.3.0 + only: ~0.0.2 + parseurl: ^1.3.2 + statuses: ^1.5.0 + type-is: ^1.6.16 + vary: ^1.1.2 + checksum: b08e1aea03e70fe4ff6e35dee9f9e979e8608461ee1002f6e8dd72f45fc49404873888ea9a3aab2904e24bf43522df7c601033522f4151189e4055e87f94a979 + languageName: node + linkType: hard + "kubernetes-models@npm:^4.1.0, kubernetes-models@npm:^4.3.1": version: 4.3.1 resolution: "kubernetes-models@npm:4.3.1" @@ -32445,6 +32812,13 @@ __metadata: languageName: node linkType: hard +"lodash.clonedeepwith@npm:4.5.0": + version: 4.5.0 + resolution: "lodash.clonedeepwith@npm:4.5.0" + checksum: 9fbf4ebfa04b381df226a2298eba680327bea3d0d5d19c5118de7ae218fd219186e30e9fd0d33b13729f34ffbc83c1cf09cb27aff265ba94cb602b8a2b1e71c9 + languageName: node + linkType: hard + "lodash.curry@npm:^4.0.1, lodash.curry@npm:^4.1.1": version: 4.1.1 resolution: "lodash.curry@npm:4.1.1" @@ -32689,6 +33063,19 @@ __metadata: languageName: node linkType: hard +"log4js@npm:6.9.1": + version: 6.9.1 + resolution: "log4js@npm:6.9.1" + dependencies: + date-format: ^4.0.14 + debug: ^4.3.4 + flatted: ^3.2.7 + rfdc: ^1.3.0 + streamroller: ^3.1.5 + checksum: 59d98c37d4163138dab5d9b06ae26965d1353106fece143973d57b1003b3a482791aa21374fd2cca81a953b8837b2f9756ac225404e60cbfa4dd3ab59f082e2e + languageName: node + linkType: hard + "log@npm:^6.3.1": version: 6.3.1 resolution: "log@npm:6.3.1" @@ -32725,6 +33112,13 @@ __metadata: languageName: node linkType: hard +"long-timeout@npm:0.1.1": + version: 0.1.1 + resolution: "long-timeout@npm:0.1.1" + checksum: 48668e5362cb74c4b77a6b833d59f149b9bb9e99c5a5097609807e2597cd0920613b2a42b89bd0870848298be3691064d95599a04ae010023d07dba39932afa7 + languageName: node + linkType: hard + "long@npm:^5.0.0, long@npm:^5.2.1": version: 5.2.3 resolution: "long@npm:5.2.3" @@ -32862,7 +33256,7 @@ __metadata: languageName: node linkType: hard -"luxon@npm:^3.0.0, luxon@npm:^3.4.3, luxon@npm:~3.4.0": +"luxon@npm:^3.0.0, luxon@npm:^3.2.1, luxon@npm:^3.4.3, luxon@npm:~3.4.0": version: 3.4.4 resolution: "luxon@npm:3.4.4" checksum: 36c1f99c4796ee4bfddf7dc94fa87815add43ebc44c8934c924946260a58512f0fd2743a629302885df7f35ccbd2d13f178c15df046d0e3b6eb71db178f1c60c @@ -33808,7 +34202,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:2.1.35, mime-types@npm:^2.1.12, mime-types@npm:^2.1.27, mime-types@npm:^2.1.31, mime-types@npm:~2.1.17, mime-types@npm:~2.1.19, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": +"mime-types@npm:2.1.35, mime-types@npm:^2.1.12, mime-types@npm:^2.1.18, mime-types@npm:^2.1.27, mime-types@npm:^2.1.31, mime-types@npm:~2.1.17, mime-types@npm:~2.1.19, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -34856,6 +35250,17 @@ __metadata: languageName: node linkType: hard +"node-schedule@npm:2.1.1": + version: 2.1.1 + resolution: "node-schedule@npm:2.1.1" + dependencies: + cron-parser: ^4.2.0 + long-timeout: 0.1.1 + sorted-array-functions: ^1.3.0 + checksum: 6a8822b16fb024277c42efe710bdb35b6f1f6ab3a2f826283640511247d693f34ebd5ddf2863cd91609e7f323574e36c81cd2084dc204fa521f931380f0f963f + languageName: node + linkType: hard + "node-stdlib-browser@npm:^1.2.0": version: 1.2.0 resolution: "node-stdlib-browser@npm:1.2.0" @@ -35450,6 +35855,13 @@ __metadata: languageName: node linkType: hard +"only@npm:~0.0.2": + version: 0.0.2 + resolution: "only@npm:0.0.2" + checksum: d399710db867a1ef436dd3ce74499c87ece794aa81ab0370b5d153968766ee4aed2f98d3f92fc87c963e45b7a74d400d6f463ef651a5e7cfb861b15e88e9efe6 + languageName: node + linkType: hard + "ono@npm:^7.1.3": version: 7.1.3 resolution: "ono@npm:7.1.3" @@ -35971,6 +36383,13 @@ __metadata: languageName: node linkType: hard +"parse-passwd@npm:^1.0.0": + version: 1.0.0 + resolution: "parse-passwd@npm:1.0.0" + checksum: 4e55e0231d58f828a41d0f1da2bf2ff7bcef8f4cb6146e69d16ce499190de58b06199e6bd9b17fbf0d4d8aef9052099cdf8c4f13a6294b1a522e8e958073066e + languageName: node + linkType: hard + "parse-path@npm:^7.0.0": version: 7.0.0 resolution: "parse-path@npm:7.0.0" @@ -36005,7 +36424,7 @@ __metadata: languageName: node linkType: hard -"parseurl@npm:^1.3.3, parseurl@npm:~1.3.2, parseurl@npm:~1.3.3": +"parseurl@npm:^1.3.2, parseurl@npm:^1.3.3, parseurl@npm:~1.3.2, parseurl@npm:~1.3.3": version: 1.3.3 resolution: "parseurl@npm:1.3.3" checksum: 407cee8e0a3a4c5cd472559bca8b6a45b82c124e9a4703302326e9ab60fc1081442ada4e02628efef1eb16197ddc7f8822f5a91fd7d7c86b51f530aedb17dfa2 @@ -37802,6 +38221,13 @@ __metadata: languageName: node linkType: hard +"rambda@npm:^9.1.0": + version: 9.2.1 + resolution: "rambda@npm:9.2.1" + checksum: d877b61f2c1e8a1878ca1e40a181702b360f6c3978bf0e55e62315a1aa215863b7ecb8f00077e2bc0f1ca0d455387fafd7a84b5c8dd004eb3cf071b15827cff7 + languageName: node + linkType: hard + "ramda-adjunct@npm:^5.0.0": version: 5.0.1 resolution: "ramda-adjunct@npm:5.0.1" @@ -39199,6 +39625,16 @@ __metadata: languageName: node linkType: hard +"resolve-dir@npm:^1.0.0, resolve-dir@npm:^1.0.1": + version: 1.0.1 + resolution: "resolve-dir@npm:1.0.1" + dependencies: + expand-tilde: ^2.0.0 + global-modules: ^1.0.0 + checksum: ef736b8ed60d6645c3b573da17d329bfb50ec4e1d6c5ffd6df49e3497acef9226f9810ea6823b8ece1560e01dcb13f77a9f6180d4f242d00cc9a8f4de909c65c + languageName: node + linkType: hard + "resolve-from@npm:5.0.0, resolve-from@npm:^5.0.0": version: 5.0.0 resolution: "resolve-from@npm:5.0.0" @@ -39227,7 +39663,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.1.6, resolve@npm:^1.14.2, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.4, resolve@npm:^1.22.8, resolve@npm:~1.22.1": +"resolve@npm:1.22.8, resolve@npm:^1.1.6, resolve@npm:^1.14.2, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.4, resolve@npm:^1.22.8, resolve@npm:~1.22.1": version: 1.22.8 resolution: "resolve@npm:1.22.8" dependencies: @@ -39263,7 +39699,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@^1.1.6#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.17.0#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.1#~builtin, resolve@patch:resolve@^1.22.4#~builtin, resolve@patch:resolve@^1.22.8#~builtin, resolve@patch:resolve@~1.22.1#~builtin": +"resolve@patch:resolve@1.22.8#~builtin, resolve@patch:resolve@^1.1.6#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.17.0#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.1#~builtin, resolve@patch:resolve@^1.22.4#~builtin, resolve@patch:resolve@^1.22.8#~builtin, resolve@patch:resolve@~1.22.1#~builtin": version: 1.22.8 resolution: "resolve@patch:resolve@npm%3A1.22.8#~builtin::version=1.22.8&hash=c3c19d" dependencies: @@ -39398,10 +39834,10 @@ __metadata: languageName: node linkType: hard -"rfdc@npm:^1.3.1": - version: 1.3.1 - resolution: "rfdc@npm:1.3.1" - checksum: d5d1e930aeac7e0e0a485f97db1356e388bdbeff34906d206fe524dd5ada76e95f186944d2e68307183fdc39a54928d4426bbb6734851692cfe9195efba58b79 +"rfdc@npm:^1.3.0, rfdc@npm:^1.3.1": + version: 1.4.1 + resolution: "rfdc@npm:1.4.1" + checksum: 3b05bd55062c1d78aaabfcea43840cdf7e12099968f368e9a4c3936beb744adb41cbdb315eac6d4d8c6623005d6f87fdf16d8a10e1ff3722e84afea7281c8d13 languageName: node linkType: hard @@ -40618,6 +41054,13 @@ __metadata: languageName: node linkType: hard +"sorted-array-functions@npm:^1.3.0": + version: 1.3.0 + resolution: "sorted-array-functions@npm:1.3.0" + checksum: 673fd39ca3b6c92644d4483eac1700bb7d7555713a536822a7522a35af559bef3e72f10d89356b75042dc394cd7c2e2ab6f40024385218ec3c85bb7335032857 + languageName: node + linkType: hard + "source-list-map@npm:^2.0.0": version: 2.0.1 resolution: "source-list-map@npm:2.0.1" @@ -40974,7 +41417,7 @@ __metadata: languageName: node linkType: hard -"statuses@npm:>= 1.4.0 < 2, statuses@npm:~1.5.0": +"statuses@npm:>= 1.4.0 < 2, statuses@npm:>= 1.5.0 < 2, statuses@npm:^1.5.0, statuses@npm:~1.5.0": version: 1.5.0 resolution: "statuses@npm:1.5.0" checksum: c469b9519de16a4bb19600205cffb39ee471a5f17b82589757ca7bd40a8d92ebb6ed9f98b5a540c5d302ccbc78f15dc03cc0280dd6e00df1335568a5d5758a5c @@ -41072,6 +41515,17 @@ __metadata: languageName: node linkType: hard +"streamroller@npm:^3.1.5": + version: 3.1.5 + resolution: "streamroller@npm:3.1.5" + dependencies: + date-format: ^4.0.14 + debug: ^4.3.4 + fs-extra: ^8.1.0 + checksum: c1df5612b785ffa4b6bbf16460590b62994c57265bc55a5166eebeeb0daf648e84bc52dc6d57e0cd4e5c7609bda93076753c63ff54589febd1e0b95590f0e443 + languageName: node + linkType: hard + "streamsearch@npm:^1.1.0": version: 1.1.0 resolution: "streamsearch@npm:1.1.0" @@ -42542,6 +42996,13 @@ __metadata: languageName: node linkType: hard +"tsscmp@npm:1.0.6": + version: 1.0.6 + resolution: "tsscmp@npm:1.0.6" + checksum: 1512384def36bccc9125cabbd4c3b0e68608d7ee08127ceaa0b84a71797263f1a01c7f82fa69be8a3bd3c1396e2965d2f7b52d581d3a5eeaf3967fbc52e3b3bf + languageName: node + linkType: hard + "tsutils@npm:^3.21.0": version: 3.21.0 resolution: "tsutils@npm:3.21.0" @@ -42678,7 +43139,7 @@ __metadata: languageName: node linkType: hard -"type-is@npm:^1.6.18, type-is@npm:^1.6.4, type-is@npm:~1.6.18": +"type-is@npm:^1.6.16, type-is@npm:^1.6.18, type-is@npm:^1.6.4, type-is@npm:~1.6.18": version: 1.6.18 resolution: "type-is@npm:1.6.18" dependencies: @@ -43228,7 +43689,7 @@ __metadata: languageName: node linkType: hard -"upath@npm:^2.0.1": +"upath@npm:2.0.1, upath@npm:^2.0.1": version: 2.0.1 resolution: "upath@npm:2.0.1" checksum: 2db04f24a03ef72204c7b969d6991abec9e2cb06fb4c13a1fd1c59bc33b46526b16c3325e55930a11ff86a77a8cbbcda8f6399bf914087028c5beae21ecdb33c @@ -43647,7 +44108,7 @@ __metadata: languageName: node linkType: hard -"vary@npm:^1, vary@npm:~1.1.2": +"vary@npm:^1, vary@npm:^1.1.2, vary@npm:~1.1.2": version: 1.1.2 resolution: "vary@npm:1.1.2" checksum: ae0123222c6df65b437669d63dfa8c36cee20a504101b2fcd97b8bf76f91259c17f9f2b4d70a1e3c6bbcee7f51b28392833adb6b2770b23b01abec84e369660b @@ -44234,7 +44695,7 @@ __metadata: languageName: node linkType: hard -"which@npm:^1.2.9, which@npm:^1.3.1": +"which@npm:^1.2.14, which@npm:^1.2.9, which@npm:^1.3.1": version: 1.3.1 resolution: "which@npm:1.3.1" dependencies: @@ -44443,6 +44904,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:8.17.0": + version: 8.17.0 + resolution: "ws@npm:8.17.0" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 147ef9eab0251364e1d2c55338ad0efb15e6913923ccbfdf20f7a8a6cb8f88432bcd7f4d8f66977135bfad35575644f9983201c1a361019594a4e53977bf6d4e + languageName: node + linkType: hard + "ws@npm:^7, ws@npm:^7.4.6, ws@npm:^7.5.5": version: 7.5.10 resolution: "ws@npm:7.5.10" @@ -44784,6 +45260,13 @@ __metadata: languageName: node linkType: hard +"ylru@npm:^1.2.0": + version: 1.4.0 + resolution: "ylru@npm:1.4.0" + checksum: e0bf797476487e3d57a6e8790cbb749cff2089e2afc87e46bc84ce7605c329d578ff422c8e8c2ddf167681ddd218af0f58e099733ae1044cba9e9472ebedc01d + languageName: node + linkType: hard + "yml-loader@npm:^2.1.0": version: 2.1.0 resolution: "yml-loader@npm:2.1.0" From b56723adf0afed281fb6d85c0efaf8fb731a466a Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 15 Jul 2024 14:00:23 +0200 Subject: [PATCH 280/510] cli: only eagely load shared dependencies in the host Signed-off-by: Patrik Oldsberg --- packages/cli/src/lib/bundler/config.ts | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index c2621b20a4..ee201ef2db 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -145,9 +145,11 @@ export async function createConfig( } if (options.moduleFederation) { + const isRemote = options.moduleFederation?.mode === 'remote'; + plugins.push( new ModuleFederationPlugin({ - ...(options.moduleFederation?.mode === 'remote' && { + ...(isRemote && { filename: 'remoteEntry.js', exposes: { '.': paths.targetEntry, @@ -160,45 +162,45 @@ export async function createConfig( react: { singleton: true, requiredVersion: '*', - eager: true, + eager: !isRemote, }, 'react-dom': { singleton: true, requiredVersion: '*', - eager: true, + eager: !isRemote, }, // React Router 'react-router': { singleton: true, requiredVersion: '*', - eager: true, + eager: !isRemote, }, 'react-router-dom': { singleton: true, requiredVersion: '*', - eager: true, + eager: !isRemote, }, // MUI v4 '@material-ui/core/styles': { singleton: true, requiredVersion: '*', - eager: true, + eager: !isRemote, }, '@material-ui/styles': { singleton: true, requiredVersion: '*', - eager: true, + eager: !isRemote, }, // MUI v5 '@mui/material/styles/': { singleton: true, requiredVersion: '*', - eager: true, + eager: !isRemote, }, '@emotion/react': { singleton: true, requiredVersion: '*', - eager: true, + eager: !isRemote, }, }, }), From 5e7f0491fa9c41a3c69c33c795e8d6f0ad16597c Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 15 Jul 2024 14:08:31 +0200 Subject: [PATCH 281/510] cli: update ModuleFederationPlugin import to avoid type error Signed-off-by: Patrik Oldsberg --- packages/cli/src/lib/bundler/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index ee201ef2db..60c8a7be66 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -24,7 +24,7 @@ import { Config } from '@backstage/config'; import ESLintPlugin from 'eslint-webpack-plugin'; import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin'; import HtmlWebpackPlugin from 'html-webpack-plugin'; -import { ModuleFederationPlugin } from '@module-federation/enhanced'; +import { ModuleFederationPlugin } from '@module-federation/enhanced/webpack'; import { LinkedPackageResolvePlugin } from './LinkedPackageResolvePlugin'; import ModuleScopePlugin from 'react-dev-utils/ModuleScopePlugin'; import { RunScriptWebpackPlugin } from 'run-script-webpack-plugin'; From 8e2aba9bd01343d72915a69148ccaa3d40658cbd Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 15 Jul 2024 17:25:11 +0200 Subject: [PATCH 282/510] cli: add a warning when app is build with module federation enabled Signed-off-by: Patrik Oldsberg --- packages/cli/src/commands/build/command.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/cli/src/commands/build/command.ts b/packages/cli/src/commands/build/command.ts index 285cba0e81..f868ca462c 100644 --- a/packages/cli/src/commands/build/command.ts +++ b/packages/cli/src/commands/build/command.ts @@ -36,13 +36,19 @@ export async function command(opts: OptionValues): Promise { }); if (role === 'frontend') { + const enableModuleFederation = process.env.EXPERIMENTAL_MODULE_FEDERATION; + if (enableModuleFederation) { + console.log( + chalk.yellow( + `⚠️ WARNING: Module federation is experimental and will receive immediate breaking changes in the future.`, + ), + ); + } return buildFrontend({ targetDir: paths.targetDir, configPaths, writeStats: Boolean(opts.stats), - moduleFederationMode: process.env.EXPERIMENTAL_MODULE_FEDERATION - ? 'host' - : undefined, + moduleFederationMode: enableModuleFederation ? 'host' : undefined, }); } return buildBackend({ From 59375fc411deb3e418893720875c6c697ae9a8c5 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 15 Jul 2024 17:36:58 +0200 Subject: [PATCH 283/510] cli: refactor module federation check to support all paths to calling buildFrontend Signed-off-by: Patrik Oldsberg --- .../cli/src/commands/build/buildFrontend.ts | 39 +++++++++++++++---- packages/cli/src/commands/build/command.ts | 11 +----- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/packages/cli/src/commands/build/buildFrontend.ts b/packages/cli/src/commands/build/buildFrontend.ts index 931a3b376a..62da74e6d3 100644 --- a/packages/cli/src/commands/build/buildFrontend.ts +++ b/packages/cli/src/commands/build/buildFrontend.ts @@ -19,29 +19,52 @@ import { resolve as resolvePath } from 'path'; import { buildBundle } from '../../lib/bundler'; import { getEnvironmentParallelism } from '../../lib/parallel'; import { loadCliConfig } from '../../lib/config'; +import chalk from 'chalk'; +import { BuildOptions } from '../../lib/bundler/types'; interface BuildAppOptions { targetDir: string; writeStats: boolean; configPaths: string[]; - moduleFederationMode?: 'host' | 'remote'; + isModuleFederationRemote?: true; +} + +function getModuleFederationOptions( + name: string, + isRemote?: boolean, +): BuildOptions['moduleFederation'] { + if (!isRemote && !process.env.EXPERIMENTAL_MODULE_FEDERATION) { + return undefined; + } + + console.log( + chalk.yellow( + `⚠️ WARNING: Module federation is experimental and will receive immediate breaking changes in the future.`, + ), + ); + + return { + mode: isRemote ? 'remote' : 'host', + // The default output mode requires the name to be a usable as a code + // symbol, there might be better options here but for now we need to + // sanitize the name. + name: name.replaceAll('@', '').replaceAll('/', '__').replaceAll('-', '_'), + }; } export async function buildFrontend(options: BuildAppOptions) { const { targetDir, writeStats, configPaths } = options; const { name } = await fs.readJson(resolvePath(targetDir, 'package.json')); + await buildBundle({ targetDir, entry: 'src/index', parallelism: getEnvironmentParallelism(), statsJsonEnabled: writeStats, - moduleFederation: options.moduleFederationMode && { - // The default output mode requires the name to be a usable as a code - // symbol, there might be better options here but for now we need to - // sanitize the name. - name: name.replaceAll('@', '').replaceAll(/[/\\_-]/g, '_'), - mode: options.moduleFederationMode, - }, + moduleFederation: getModuleFederationOptions( + name, + options.isModuleFederationRemote, + ), ...(await loadCliConfig({ args: configPaths, fromPackage: name, diff --git a/packages/cli/src/commands/build/command.ts b/packages/cli/src/commands/build/command.ts index f868ca462c..c0ad3c912b 100644 --- a/packages/cli/src/commands/build/command.ts +++ b/packages/cli/src/commands/build/command.ts @@ -36,19 +36,10 @@ export async function command(opts: OptionValues): Promise { }); if (role === 'frontend') { - const enableModuleFederation = process.env.EXPERIMENTAL_MODULE_FEDERATION; - if (enableModuleFederation) { - console.log( - chalk.yellow( - `⚠️ WARNING: Module federation is experimental and will receive immediate breaking changes in the future.`, - ), - ); - } return buildFrontend({ targetDir: paths.targetDir, configPaths, writeStats: Boolean(opts.stats), - moduleFederationMode: enableModuleFederation ? 'host' : undefined, }); } return buildBackend({ @@ -70,7 +61,7 @@ export async function command(opts: OptionValues): Promise { targetDir: paths.targetDir, configPaths: [], writeStats: Boolean(opts.stats), - moduleFederationMode: 'remote', + isModuleFederationRemote: true, }); } From 24a98c940b384efa245d044e07fae5ac37bc2ee7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Jul 2024 08:08:47 +0000 Subject: [PATCH 284/510] Bump ws from 8.8.1 to 8.18.0 in /storybook Bumps [ws](https://github.com/websockets/ws) from 8.8.1 to 8.18.0. - [Release notes](https://github.com/websockets/ws/releases) - [Commits](https://github.com/websockets/ws/compare/8.8.1...8.18.0) --- updated-dependencies: - dependency-name: ws dependency-type: indirect ... Signed-off-by: dependabot[bot] --- storybook/yarn.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/storybook/yarn.lock b/storybook/yarn.lock index 1702d6f4cc..28bbe4b144 100644 --- a/storybook/yarn.lock +++ b/storybook/yarn.lock @@ -11912,17 +11912,17 @@ __metadata: linkType: hard "ws@npm:^8.2.3": - version: 8.8.1 - resolution: "ws@npm:8.8.1" + version: 8.18.0 + resolution: "ws@npm:8.18.0" peerDependencies: bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 + utf-8-validate: ">=5.0.2" peerDependenciesMeta: bufferutil: optional: true utf-8-validate: optional: true - checksum: 2152cf862cae0693f3775bc688a6afb2e989d19d626d215e70f5fcd8eb55b1c3b0d3a6a4052905ec320e2d7734e20aeedbf9744496d62f15a26ad79cf4cf7dae + checksum: 91d4d35bc99ff6df483bdf029b9ea4bfd7af1f16fc91231a96777a63d263e1eabf486e13a2353970efc534f9faa43bdbf9ee76525af22f4752cbc5ebda333975 languageName: node linkType: hard From 419f3878bd519d40db3bbad21cb8760c0da64e97 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 11 Jul 2024 14:29:18 +0200 Subject: [PATCH 285/510] backend-defaults: refactor rootHttpRouterServiceFactory to define options on its own Signed-off-by: Patrik Oldsberg --- .changeset/lucky-wolves-pull.md | 5 +++++ packages/backend-app-api/api-report.md | 9 ++++----- .../backend-defaults/api-report-rootHttpRouter.md | 11 +++++------ .../rootHttpRouter/rootHttpRouterServiceFactory.ts | 14 ++++++++++---- packages/backend-test-utils/api-report.md | 9 ++++----- 5 files changed, 28 insertions(+), 20 deletions(-) create mode 100644 .changeset/lucky-wolves-pull.md diff --git a/.changeset/lucky-wolves-pull.md b/.changeset/lucky-wolves-pull.md new file mode 100644 index 0000000000..17ed4572b6 --- /dev/null +++ b/.changeset/lucky-wolves-pull.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': patch +--- + +Refactor of `rootHttpRouterServiceFactory` to allow it to be constructed with options, but without declaring options via `createServiceFactory`. diff --git a/packages/backend-app-api/api-report.md b/packages/backend-app-api/api-report.md index 54e2900cc2..7f9b54dd8f 100644 --- a/packages/backend-app-api/api-report.md +++ b/packages/backend-app-api/api-report.md @@ -292,11 +292,10 @@ export type RootHttpRouterConfigureContext = RootHttpRouterConfigureContext_2; export type RootHttpRouterFactoryOptions = RootHttpRouterFactoryOptions_2; // @public @deprecated (undocumented) -export const rootHttpRouterServiceFactory: ServiceFactoryCompat< - RootHttpRouterService, - 'root', - RootHttpRouterFactoryOptions_2 ->; +export const rootHttpRouterServiceFactory: (( + options?: RootHttpRouterFactoryOptions_2 | undefined, +) => ServiceFactory) & + ServiceFactory; // @public @deprecated export const rootLifecycleServiceFactory: ServiceFactoryCompat< diff --git a/packages/backend-defaults/api-report-rootHttpRouter.md b/packages/backend-defaults/api-report-rootHttpRouter.md index 9ea4cd7ebb..329398a7b8 100644 --- a/packages/backend-defaults/api-report-rootHttpRouter.md +++ b/packages/backend-defaults/api-report-rootHttpRouter.md @@ -19,7 +19,7 @@ import { RequestListener } from 'http'; import { RootConfigService } from '@backstage/backend-plugin-api'; import { RootHttpRouterService } from '@backstage/backend-plugin-api'; import type { Server } from 'node:http'; -import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; +import { ServiceFactory } from '@backstage/backend-plugin-api'; // @public export function createHttpServer( @@ -141,11 +141,10 @@ export type RootHttpRouterFactoryOptions = { }; // @public (undocumented) -export const rootHttpRouterServiceFactory: ServiceFactoryCompat< - RootHttpRouterService, - 'root', - RootHttpRouterFactoryOptions ->; +export const rootHttpRouterServiceFactory: (( + options?: RootHttpRouterFactoryOptions, +) => ServiceFactory) & + ServiceFactory; // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts index 22f5c2f310..c3a97737e4 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts @@ -69,9 +69,10 @@ function defaultConfigure({ applyDefaults }: RootHttpRouterConfigureContext) { applyDefaults(); } -/** @public */ -export const rootHttpRouterServiceFactory = createServiceFactory( - (options?: RootHttpRouterFactoryOptions) => ({ +const rootHttpRouterServiceFactoryWithOptions = ( + options?: RootHttpRouterFactoryOptions, +) => + createServiceFactory({ service: coreServices.rootHttpRouter, deps: { config: coreServices.rootConfig, @@ -122,5 +123,10 @@ export const rootHttpRouterServiceFactory = createServiceFactory( return router; }, - }), + })(); + +/** @public */ +export const rootHttpRouterServiceFactory = Object.assign( + rootHttpRouterServiceFactoryWithOptions, + rootHttpRouterServiceFactoryWithOptions(), ); diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index af7edba061..3439d37231 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -290,11 +290,10 @@ export namespace mockServices { // (undocumented) export namespace rootHttpRouter { const // (undocumented) - factory: ServiceFactoryCompat< - RootHttpRouterService, - 'root', - RootHttpRouterFactoryOptions - >; + factory: (( + options?: RootHttpRouterFactoryOptions | undefined, + ) => ServiceFactory) & + ServiceFactory; const // (undocumented) mock: ( partialImpl?: Partial | undefined, From e28af58b4ba24495d7d1db03feb53e5737fe33e7 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 11 Jul 2024 11:12:21 +0200 Subject: [PATCH 286/510] backend-defaults: deprecate config service options Signed-off-by: Patrik Oldsberg --- .changeset/wet-rivers-travel.md | 5 ++++ .../core-services/root-config.md | 30 ++++++++++++------- .../backend-defaults/api-report-rootConfig.md | 2 +- .../rootConfig/rootConfigServiceFactory.ts | 1 + 4 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 .changeset/wet-rivers-travel.md diff --git a/.changeset/wet-rivers-travel.md b/.changeset/wet-rivers-travel.md new file mode 100644 index 0000000000..44dedf3ccb --- /dev/null +++ b/.changeset/wet-rivers-travel.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': patch +--- + +The `RootConfigFactoryOptions` have been deprecated alongside the deprecation of service factory options. For more information on how to customize the config service, see the [Root Config Service docs](https://backstage.io/docs/backend-system/core-services/root-config#configuring-the-service). diff --git a/docs/backend-system/core-services/root-config.md b/docs/backend-system/core-services/root-config.md index 7cdc10f38c..9561a8f0cd 100644 --- a/docs/backend-system/core-services/root-config.md +++ b/docs/backend-system/core-services/root-config.md @@ -36,12 +36,12 @@ createBackendPlugin({ ## Configuring the service -There's additional configuration that you can optionally pass to setup the `config` core service. +There are several APIs from the `@backstage/config-loader` package that allow you to customize the implementation of the config service. The default implementation uses the `ConfigSources.default` method, which has several options, for example: - `argv` - Override the arguments that are passed to the config loader, instead of using `process.argv` - `remote` - Configure remote configuration loading -You can configure these additional options by adding an override for the core service when calling `createBackend` like follows: +You can use these to create your own config service implementation: ```ts import { rootConfigServiceFactory } from '@backstage/backend-app-api'; @@ -49,14 +49,24 @@ import { rootConfigServiceFactory } from '@backstage/backend-app-api'; const backend = createBackend(); backend.add( - rootConfigServiceFactory({ - argv: [ - '--config', - '/backstage/app-config.development.yaml', - '--config', - '/backstage/app-config.yaml', - ], - remote: { reloadIntervalSeconds: 60 }, + createServiceFactory({ + service: coreServices.rootConfig, + deps: {}, + async factory() { + const source = ConfigSources.default({ + argv: [ + '--config', + '/backstage/app-config.development.yaml', + '--config', + '/backstage/app-config.yaml', + ], + remote: { reloadIntervalSeconds: 60 }, + }); + console.log(`Loading config from ${source}`); + return await ConfigSources.toConfig(source); + }, }), ); ``` + +You can also use other config source such as `StaticConfigSource` and combine them with other sources using `ConfigSources.merge(...)`. You can also create your own config source by implementing the `ConfigSource` interface. diff --git a/packages/backend-defaults/api-report-rootConfig.md b/packages/backend-defaults/api-report-rootConfig.md index 24e827f520..8ad2e01a90 100644 --- a/packages/backend-defaults/api-report-rootConfig.md +++ b/packages/backend-defaults/api-report-rootConfig.md @@ -17,7 +17,7 @@ export function createConfigSecretEnumerator(options: { schema?: ConfigSchema; }): Promise<(config: Config) => Iterable>; -// @public +// @public @deprecated export interface RootConfigFactoryOptions { argv?: string[]; remote?: Pick; diff --git a/packages/backend-defaults/src/entrypoints/rootConfig/rootConfigServiceFactory.ts b/packages/backend-defaults/src/entrypoints/rootConfig/rootConfigServiceFactory.ts index 5752a9c634..7bcb9ef56b 100644 --- a/packages/backend-defaults/src/entrypoints/rootConfig/rootConfigServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/rootConfig/rootConfigServiceFactory.ts @@ -31,6 +31,7 @@ import { * for more information. * * @public + * @deprecated These service options will be removed, please use the `ConfigSources` API from `@backstage/config-loader` to implement your own version of the service factory instead. */ export interface RootConfigFactoryOptions { /** From e375bb93df617dc101df8bb8a7a2da7b743c752b Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 16 Jul 2024 10:20:11 +0200 Subject: [PATCH 287/510] backend-defaults: update root config implementation to use manual factory pattern + update docs Signed-off-by: Patrik Oldsberg --- .changeset/wet-rivers-travel.md | 2 +- .../core-services/root-config.md | 25 +++++++++++++++++-- .../backend-defaults/api-report-rootConfig.md | 13 +++++----- .../rootConfig/rootConfigServiceFactory.ts | 19 ++++++++------ 4 files changed, 42 insertions(+), 17 deletions(-) diff --git a/.changeset/wet-rivers-travel.md b/.changeset/wet-rivers-travel.md index 44dedf3ccb..1778a3db23 100644 --- a/.changeset/wet-rivers-travel.md +++ b/.changeset/wet-rivers-travel.md @@ -2,4 +2,4 @@ '@backstage/backend-defaults': patch --- -The `RootConfigFactoryOptions` have been deprecated alongside the deprecation of service factory options. For more information on how to customize the config service, see the [Root Config Service docs](https://backstage.io/docs/backend-system/core-services/root-config#configuring-the-service). +Refactor of `rootConfigServiceFactory` to allow it to be constructed with options, but without declaring options via `createServiceFactory`. diff --git a/docs/backend-system/core-services/root-config.md b/docs/backend-system/core-services/root-config.md index 9561a8f0cd..8505b9e7ec 100644 --- a/docs/backend-system/core-services/root-config.md +++ b/docs/backend-system/core-services/root-config.md @@ -36,18 +36,39 @@ createBackendPlugin({ ## Configuring the service -There are several APIs from the `@backstage/config-loader` package that allow you to customize the implementation of the config service. The default implementation uses the `ConfigSources.default` method, which has several options, for example: +There's additional configuration that you can optionally pass to setup the `config` core service. - `argv` - Override the arguments that are passed to the config loader, instead of using `process.argv` - `remote` - Configure remote configuration loading -You can use these to create your own config service implementation: +You can configure these additional options by adding an override for the core service when calling `createBackend` like follows: ```ts import { rootConfigServiceFactory } from '@backstage/backend-app-api'; const backend = createBackend(); +backend.add( + rootConfigServiceFactory({ + argv: [ + '--config', + '/backstage/app-config.development.yaml', + '--config', + '/backstage/app-config.yaml', + ], + remote: { reloadIntervalSeconds: 60 }, + }), +); +``` + +For more advanced customization, there are several APIs from the `@backstage/config-loader` package that allow you to customize the implementation of the config service. The default implementation uses the `ConfigSources.default` method, which has the same options as the `rootConfigServiceFactory` function. You can use these to create your own config service implementation: + +```ts +import { ConfigSources } from '@backstage/config-loader'; +import { createServiceFactory } from '@backstage/backend-plugin-api'; + +const backend = createBackend(); + backend.add( createServiceFactory({ service: coreServices.rootConfig, diff --git a/packages/backend-defaults/api-report-rootConfig.md b/packages/backend-defaults/api-report-rootConfig.md index 8ad2e01a90..61f5c9dc9d 100644 --- a/packages/backend-defaults/api-report-rootConfig.md +++ b/packages/backend-defaults/api-report-rootConfig.md @@ -8,7 +8,7 @@ import { ConfigSchema } from '@backstage/config-loader'; import { LoggerService } from '@backstage/backend-plugin-api'; import { RemoteConfigSourceOptions } from '@backstage/config-loader'; import { RootConfigService } from '@backstage/backend-plugin-api'; -import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; +import { ServiceFactory } from '@backstage/backend-plugin-api'; // @public (undocumented) export function createConfigSecretEnumerator(options: { @@ -17,7 +17,7 @@ export function createConfigSecretEnumerator(options: { schema?: ConfigSchema; }): Promise<(config: Config) => Iterable>; -// @public @deprecated +// @public export interface RootConfigFactoryOptions { argv?: string[]; remote?: Pick; @@ -26,11 +26,10 @@ export interface RootConfigFactoryOptions { } // @public (undocumented) -export const rootConfigServiceFactory: ServiceFactoryCompat< - RootConfigService, - 'root', - RootConfigFactoryOptions ->; +export const rootConfigServiceFactory: (( + options?: RootConfigFactoryOptions, +) => ServiceFactory) & + ServiceFactory; // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-defaults/src/entrypoints/rootConfig/rootConfigServiceFactory.ts b/packages/backend-defaults/src/entrypoints/rootConfig/rootConfigServiceFactory.ts index 7bcb9ef56b..63a7353241 100644 --- a/packages/backend-defaults/src/entrypoints/rootConfig/rootConfigServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/rootConfig/rootConfigServiceFactory.ts @@ -31,7 +31,6 @@ import { * for more information. * * @public - * @deprecated These service options will be removed, please use the `ConfigSources` API from `@backstage/config-loader` to implement your own version of the service factory instead. */ export interface RootConfigFactoryOptions { /** @@ -46,11 +45,10 @@ export interface RootConfigFactoryOptions { watch?: boolean; } -/** - * @public - */ -export const rootConfigServiceFactory = createServiceFactory( - (options?: RootConfigFactoryOptions) => ({ +export const rootConfigServiceFactoryWithOptions = ( + options?: RootConfigFactoryOptions, +) => + createServiceFactory({ service: coreServices.rootConfig, deps: {}, async factory() { @@ -62,5 +60,12 @@ export const rootConfigServiceFactory = createServiceFactory( console.log(`Loading config from ${source}`); return await ConfigSources.toConfig(source); }, - }), + })(); + +/** + * @public + */ +export const rootConfigServiceFactory = Object.assign( + rootConfigServiceFactoryWithOptions, + rootConfigServiceFactoryWithOptions(), ); From 98ccf0020a5ed6d8a3da2f7e1ff0ac7678f95297 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 11 Jul 2024 14:21:48 +0200 Subject: [PATCH 288/510] backend-test-utils: refactor httpAuth.factory to define options on its own Signed-off-by: Patrik Oldsberg --- .changeset/wicked-impalas-explode.md | 5 ++++ packages/backend-test-utils/api-report.md | 11 +++----- .../src/next/services/mockServices.ts | 25 +++++++++++-------- 3 files changed, 24 insertions(+), 17 deletions(-) create mode 100644 .changeset/wicked-impalas-explode.md diff --git a/.changeset/wicked-impalas-explode.md b/.changeset/wicked-impalas-explode.md new file mode 100644 index 0000000000..f8a01bc36e --- /dev/null +++ b/.changeset/wicked-impalas-explode.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-test-utils': patch +--- + +Internal refactor of `mockServices.httpAuth.factory` to allow it to still be constructed with options, but without declaring options via `createServiceFactory`. diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index af7edba061..d77aea09a8 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -206,13 +206,10 @@ export namespace mockServices { }): HttpAuthService; // (undocumented) export namespace httpAuth { - const factory: ServiceFactoryCompat< - HttpAuthService, - 'plugin', - { - defaultCredentials?: BackstageCredentials | undefined; - } - >; + const factory: ((options?: { + defaultCredentials?: BackstageCredentials; + }) => ServiceFactory) & + ServiceFactory; const // (undocumented) mock: ( partialImpl?: Partial | undefined, diff --git a/packages/backend-test-utils/src/next/services/mockServices.ts b/packages/backend-test-utils/src/next/services/mockServices.ts index d56179d958..38ff819228 100644 --- a/packages/backend-test-utils/src/next/services/mockServices.ts +++ b/packages/backend-test-utils/src/next/services/mockServices.ts @@ -270,15 +270,10 @@ export namespace mockServices { ); } export namespace httpAuth { - /** - * Creates a mock service factory for the `HttpAuthService`. - * - * By default all requests without credentials are treated as requests from - * the default mock user principal. This behavior can be configured with the - * `defaultCredentials` option. - */ - export const factory = createServiceFactory( - (options?: { defaultCredentials?: BackstageCredentials }) => ({ + const factoryWithOptions = (options?: { + defaultCredentials?: BackstageCredentials; + }) => + createServiceFactory({ service: coreServices.httpAuth, deps: { plugin: coreServices.pluginMetadata }, factory: ({ plugin }) => @@ -286,7 +281,17 @@ export namespace mockServices { plugin.getId(), options?.defaultCredentials ?? mockCredentials.user(), ), - }), + })(); + /** + * Creates a mock service factory for the `HttpAuthService`. + * + * By default all requests without credentials are treated as requests from + * the default mock user principal. This behavior can be configured with the + * `defaultCredentials` option. + */ + export const factory = Object.assign( + factoryWithOptions, + factoryWithOptions(), ); export const mock = simpleMock(coreServices.httpAuth, () => ({ credentials: jest.fn(), From fccc99b7d902ce1f4d062fa14d5d1fb2a935fac6 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 12 Jul 2024 11:07:51 +0200 Subject: [PATCH 289/510] backend-test-utils: refactor other services to declare options on their own too Signed-off-by: Patrik Oldsberg --- packages/backend-test-utils/api-report.md | 18 ++++--- .../src/next/services/mockServices.ts | 50 +++++++++++++------ 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index d77aea09a8..b888168827 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -229,7 +229,7 @@ export namespace mockServices { // (undocumented) export namespace identity { const // (undocumented) - factory: () => ServiceFactory; + factory: ServiceFactoryCompat; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -271,9 +271,10 @@ export namespace mockServices { data?: JsonObject; }; const // (undocumented) - factory: ( - options?: Options | undefined, - ) => ServiceFactory; + factory: ServiceFactory & + (( + options?: Options | undefined, + ) => ServiceFactory); } // (undocumented) export namespace rootHealth { @@ -315,9 +316,10 @@ export namespace mockServices { level?: 'none' | 'error' | 'warn' | 'info' | 'debug'; }; const // (undocumented) - factory: ( - options?: Options | undefined, - ) => ServiceFactory; + factory: ServiceFactory & + (( + options?: Options | undefined, + ) => ServiceFactory); const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -337,7 +339,7 @@ export namespace mockServices { // (undocumented) export namespace tokenManager { const // (undocumented) - factory: () => ServiceFactory; + factory: ServiceFactoryCompat; const // (undocumented) mock: ( partialImpl?: Partial | undefined, diff --git a/packages/backend-test-utils/src/next/services/mockServices.ts b/packages/backend-test-utils/src/next/services/mockServices.ts index 38ff819228..8d36fec50e 100644 --- a/packages/backend-test-utils/src/next/services/mockServices.ts +++ b/packages/backend-test-utils/src/next/services/mockServices.ts @@ -70,21 +70,28 @@ function createLoggerMock() { } /** @internal */ -function simpleFactory< +function simpleFactoryWithOptions< TService, TScope extends 'root' | 'plugin', TOptions extends [options?: object] = [], >( ref: ServiceRef, factory: (...options: TOptions) => TService, -): (...options: TOptions) => ServiceFactory { - return createServiceFactory((options: unknown) => ({ - service: ref as ServiceRef, - deps: {}, - async factory() { - return (factory as any)(options); - }, - })) as (...options: TOptions) => ServiceFactory; +): ServiceFactory & + ((...options: TOptions) => ServiceFactory) { + const factoryWithOptions = (...options: TOptions) => + createServiceFactory({ + service: ref as ServiceRef, + deps: {}, + async factory() { + return factory(...options); + }, + })(); + return Object.assign( + factoryWithOptions, + factoryWithOptions(...([undefined] as unknown as TOptions)), + ) as ServiceFactory & + ((...options: TOptions) => ServiceFactory); } /** @public */ @@ -134,7 +141,10 @@ export namespace mockServices { export namespace rootConfig { export type Options = { data?: JsonObject }; - export const factory = simpleFactory(coreServices.rootConfig, rootConfig); + export const factory = simpleFactoryWithOptions( + coreServices.rootConfig, + rootConfig, + ); } export function rootLogger(options?: rootLogger.Options): LoggerService { @@ -145,7 +155,10 @@ export namespace mockServices { level?: 'none' | 'error' | 'warn' | 'info' | 'debug'; }; - export const factory = simpleFactory(coreServices.rootLogger, rootLogger); + export const factory = simpleFactoryWithOptions( + coreServices.rootLogger, + rootLogger, + ); export const mock = simpleMock(coreServices.rootLogger, () => ({ child: jest.fn(), debug: jest.fn(), @@ -168,10 +181,11 @@ export namespace mockServices { }; } export namespace tokenManager { - export const factory = simpleFactory( - coreServices.tokenManager, - tokenManager, - ); + export const factory = createServiceFactory({ + service: coreServices.tokenManager, + deps: {}, + factory: () => tokenManager(), + }); export const mock = simpleMock(coreServices.tokenManager, () => ({ authenticate: jest.fn(), getToken: jest.fn(), @@ -182,7 +196,11 @@ export namespace mockServices { return new MockIdentityService(); } export namespace identity { - export const factory = simpleFactory(coreServices.identity, identity); + export const factory = createServiceFactory({ + service: coreServices.identity, + deps: {}, + factory: () => identity(), + }); export const mock = simpleMock(coreServices.identity, () => ({ getIdentity: jest.fn(), })); From 994211d1110410b6febb2c96fdc158dfaa16fac7 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 16 Jul 2024 10:49:24 +0200 Subject: [PATCH 290/510] changesets: exit prerelease Signed-off-by: Patrik Oldsberg --- .changeset/pre.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index acd37c2559..cebbc6e919 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -1,5 +1,5 @@ { - "mode": "pre", + "mode": "exit", "tag": "next", "initialVersions": { "example-app": "0.2.98", From 8e6ba753bc2da001c53edc79e387d443311d5fca Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 16 Jul 2024 10:58:31 +0200 Subject: [PATCH 291/510] docs: prepare 1.29 release notes Signed-off-by: Patrik Oldsberg --- docs/releases/v1.29.0.md | 40 ++++++++++++++++++++++++++++++++++ microsite/docusaurus.config.ts | 2 +- microsite/sidebars.json | 1 + 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 docs/releases/v1.29.0.md diff --git a/docs/releases/v1.29.0.md b/docs/releases/v1.29.0.md new file mode 100644 index 0000000000..7b17abd544 --- /dev/null +++ b/docs/releases/v1.29.0.md @@ -0,0 +1,40 @@ +--- +id: v1.29.0 +title: v1.29.0 +description: Backstage Release v1.29.0 +--- + +These are the release notes for the v1.29.0 release of [Backstage](https://backstage.io/). + +A huge thanks to the whole team of maintainers and contributors as well as the amazing Backstage Community for the hard work in getting this release developed and done. + +## Highlights + +### + +<short description>. Contributed by @<user> in [#<pr>](https://github.com/backstage/backstage/pull/<pr>) + +## Security Fixes + +This release does not contain any security fixes. + +<or> + +@backstage/<package-name>, please upgrade to the latest version if you are using this module. + +## Upgrade path + +We recommend that you keep your Backstage project up to date with this latest release. For more guidance on how to upgrade, check out the documentation for [keeping Backstage updated](https://backstage.io/docs/getting-started/keeping-backstage-updated). + +## Links and References + +Below you can find a list of links and references to help you learn about and start using this new release. + +- [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) +- [GitHub repository](https://github.com/backstage/backstage) +- Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support +- [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.29.0-changelog.md) +- Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) + +Sign up for our [newsletter](https://info.backstage.spotify.com/newsletter_subscribe) if you want to be informed about what is happening in the world of Backstage. diff --git a/microsite/docusaurus.config.ts b/microsite/docusaurus.config.ts index b1a6533ab9..67f6de4962 100644 --- a/microsite/docusaurus.config.ts +++ b/microsite/docusaurus.config.ts @@ -241,7 +241,7 @@ const config: Config = { position: 'left', }, { - to: 'docs/releases/v1.28.0', + to: 'docs/releases/v1.29.0', label: 'Releases', position: 'left', }, diff --git a/microsite/sidebars.json b/microsite/sidebars.json index 075025afbb..1a3a0eb4d3 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -1,6 +1,7 @@ { "releases": { "Release Notes": [ + "releases/v1.29.0", "releases/v1.28.0", "releases/v1.27.0", "releases/v1.26.0", From 2764d6453f91b4416e76e5fe923c6ed2552ea14a Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Tue, 16 Jul 2024 11:32:50 +0200 Subject: [PATCH 292/510] docs,changesets: update to mention the manual service factory options pattern Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/spotty-apricots-tan.md | 20 ++++++++++ .../architecture/03-services.md | 40 +++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/.changeset/spotty-apricots-tan.md b/.changeset/spotty-apricots-tan.md index 8eea2b1dce..a2be38d775 100644 --- a/.changeset/spotty-apricots-tan.md +++ b/.changeset/spotty-apricots-tan.md @@ -52,6 +52,26 @@ export const customFooServiceFactory = createServiceFactory<FooService>({ This is of course more verbose than the previous solution where the factory could be customized through `fooServiceFactory({ bar: 'baz' })`, but this is a simplified which in practice should be using static configuration instead. +In cases where the old options patterns significantly improves the usability of the service factory, the old pattern can still be implemented like this: + +```ts +const fooServiceFactoryWithOptions = (options?: { bar: string }) => + createServiceFactory<FooService>({ + service: fooServiceRef, + deps: { logger: coreServices.logger }, + factory({ logger }) { + return { + // Implementation of the foo service using the `bar` option. + }; + }, + }); + +export const fooServiceFactory = Object.assign( + fooServiceFactoryWithOptions, + fooServiceFactoryWithOptions(), +); +``` + This change is being made because the ability to define an options callback encourages bad design of services factories. When possible, a service should be configurable through static configuration, and the existence of options may discourage that. More importantly though, the existing options do not work well with the dependency injection system of services, which is a problem for callbacks an other more advanced options. This lead to a bad pattern where only a few explicit dependencies where made available in callbacks, rather than providing an API that allowed simple re-implementation of the service with full access to dependency injection. A separate benefit of this change is that it simplifies the TypeScript types in a way that allows TypeScript to provide a much better error message when a service factory doesn't properly implement the service interface. diff --git a/docs/backend-system/architecture/03-services.md b/docs/backend-system/architecture/03-services.md index e1d86164c3..95e3d5305a 100644 --- a/docs/backend-system/architecture/03-services.md +++ b/docs/backend-system/architecture/03-services.md @@ -223,3 +223,43 @@ export const customFooServiceFactory = createServiceFactory({ ``` This allows you to provide more advanced options for the service implementation that couldn't be expressed through static configuration. It also gives users of the service implementation access to other services through dependency injection, which can be useful for their customizations. + +## Service Factory Options Pattern + +:::note Note + +This pattern is discouraged, only use it when necessary. If possible you should prefer to make services configurable via static configuration or re-implementation instead. + +::: + +In some cases it might be beneficial to allow users of your service factory to pass options to the factory itself, rather than to the service implementation. This can be enabled by also defining the service factory as a function that returns a reconfigured factory. For example: + +```ts +const fooServiceFactoryWithOptions = (options?: { + transform: (foo: string) => string; +}) => + createServiceFactory<FooService>({ + service: fooServiceRef, + deps: {}, + factory() { + return DefaultFooService.create({ + transform: options?.transform, + }); + }, + }); + +export const fooServiceFactory = Object.assign( + fooServiceFactoryWithOptions, + fooServiceFactoryWithOptions(), +); +``` + +This makes it possible to use the `fooServiceFactory` directly, as well passing additional options to create a customized factory: + +```ts +backend.add(fooServiceFactory); +// OR +backend.add(fooServiceFactory({ transform: foo => foo.toLowerCase() })); +``` + +This pattern is discouraged due to the inability to access other services through dependency injection. It is however used in a few places in the Backstage framework where the ability to directly pass options without re-implementing the service is very convenient, such as the `mockServices` from `@backstage/backend-test-utils`. From 8dd6843f03c64f4a2b9abf40eb625eb2fc8f14b5 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Tue, 16 Jul 2024 12:39:55 +0200 Subject: [PATCH 293/510] docs: add root-health to sidebar Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- microsite/sidebars.json | 1 + 1 file changed, 1 insertion(+) diff --git a/microsite/sidebars.json b/microsite/sidebars.json index 075025afbb..6d34798f03 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -429,6 +429,7 @@ "backend-system/core-services/permissions", "backend-system/core-services/plugin-metadata", "backend-system/core-services/root-config", + "backend-system/core-services/root-health", "backend-system/core-services/root-http-router", "backend-system/core-services/root-lifecycle", "backend-system/core-services/root-logger", From 8f794cf022834c888b3440aef9dc6bf372c40225 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Tue, 16 Jul 2024 11:31:57 +0200 Subject: [PATCH 294/510] docs: 1.29 release notes Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- docs/releases/v1.29.0.md | 89 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 6 deletions(-) diff --git a/docs/releases/v1.29.0.md b/docs/releases/v1.29.0.md index 7b17abd544..5f7ed1db19 100644 --- a/docs/releases/v1.29.0.md +++ b/docs/releases/v1.29.0.md @@ -10,18 +10,95 @@ A huge thanks to the whole team of maintainers and contributors as well as the a ## Highlights -### <title> +### BREAKING: Backend System deprecations and removals -<short description>. Contributed by @<user> in [#<pr>](https://github.com/backstage/backstage/pull/<pr>) +As part of the [work towards a stable 1.0 release of the new backend system](https://github.com/backstage/backstage/issues/24493), there are several new deprecations and breaking changes in the backend system packages: + +**Breaking**: + +- The deprecated `token` option has been removed from `PermissionsService`, and the request options are now required and must contain a `credentials` object. +- The deprecated `getPath` option has been removed from `httpRouterServiceFactory`, the plugin paths are now always `/api/<pluginId>`. +- It is no longer possible to pass service factory callbacks to the `defaultServiceFactories` option of `createSpecializedBackend`. + +**Deprecations**: + +- The ability to define options for service factories through `createServiceFactory` has been deprecated. See the [service architecture documentation](https://backstage.io/docs/backend-system/architecture/services) for more information on how to define customizable services. +- The ability to install backend features in callback form, i.e. `() => BackendFeature`, has been deprecated. This also includes other usages such as `startTestBackend`, and dynamically imported backend features. No manual changes should be needed for this change, as all backend feature creators have been updated to return `BackendFeature` instances directly. +- The `ServiceFactoryTest.get` method has been renamed to `ServiceFactoryTest.getSubject`, and is now deprecated. +- The following types have been renamed to use an `*Options` suffix instead: `ServiceRefConfig`, `RootServiceFactoryConfig`, `PluginServiceFactoryConfig`. +- Deprecated all exports related to the legacy status checker in `@backstage/backend-common`. +- The `isDockerDisabledForTests` function exported by `@backstage/backend-test-utils` has been deprecated. + +### Backend Health Service + +A new health service as been added to the new backend system. This service provides health check endpoints for the backend, and replaces `createStatusCheckRouter` from `@backstage/backend-common`. + +The service helps implement the new `/.backstage/health/v1/readiness` and `/.backstage/health/v1/liveness` endpoints, which provide health checks for the entire backend instance. + +You can read more about this new service and how to customize it in the [Root Health Service documentation](https://backstage.io/docs/backend-system/core-services/root-health). + +### New Catalog Logs module + +This new `@backstage/plugin-catalog-backend-module-logs` module is a minimal module that will log any error events that are published by the catalog. This module is useful for making sure that catalog errors are visible in the logs, but you may want to replace it with a more customized solution if the resulting logs are too verbose. + +### Updates to the `@backstage/create-app` template + +New backstage projects created with `@backstage/create-app` will now include the Catalog Logs module for logging catalog error events, as well as support for the Postgres Search Engine. + +### Permission Policy deprecations + +The `PermissionPolicy` interface has been updated to align with the recent changes to the Backstage auth system. The second argument to the `handle` method is now of the new `PolicyQueryUser` type. This type maintains the old fields from the `BackstageIdentityResponse`, which are now all deprecated. Instead, two new fields have been added, which allows access to the same information: + +- `credentials` - A `BackstageCredentials` object, which is useful for making requests to other services on behalf of the user as part of evaluating the policy. This replaces the deprecated `token` field. See the [Auth Service documentation](https://backstage.io/docs/backend-system/core-services/auth#creating-request-tokens) for information about how to create a token using these credentials. +- `info` - A `BackstageUserInfo` object, which contains the same information as the deprecated `identity`, except for the `type` field that was redundant. + +Most existing policies can be updated by replacing the `BackstageIdentityResponse` type with `PolicyQueryUser`, which is exported from `@backstage/plugin-permission-node`, as well as replacing any occurrences of `user?.identity` with `user?.info`. + +### Renaming the `setupRequestMockHandlers` test utility + +The `setupRequestMockHandlers` utility function exported by `@backstage/test-utils` and `@backstage/backend-test-utils` has been renamed to `registerMswTestHooks`. This is done to better reflect the context and the purpose of the function. The old name is deprecated and will be removed in a future release. + +### Catalog GitHub module support for `repository` events + +The GitHub provider module and `GithubEntityProvider` for the Catalog now supports event driven ingestion of repositories by subscribing to `repository` events from GitHub. This includes the actions `archived`, `deleted`, `edited`, `renamed`, `transferred`, and `unarchived`. This is in addition to the existing support for `push` events, which you can read more about in the integration documentation for [GitHub Discovery](https://backstage.io/docs/integrations/github/discovery#events-support). + +Contributed by [@pjungermann](https://github.com/pjungermann) in [#25360](https://github.com/backstage/backstage/pull/25360) + +### Catalog i18n support + +The Catalog plugin as well as the Catalog React library now support internationalization (i18n). This means that you can customize the messaging in the catalog, as well as add translations. You can read more about this in the [i18n documentation](https://backstage.io/docs/plugins/internationalization/). + +Contributed by [@mario-mui](https://github.com/mario-mui) in [#23392](https://github.com/backstage/backstage/pull/23392) + +### Route Binding configuration improvements + +It is now possible to explicitly remove default route bindings, for cases where you don't want a plugin route to be bound to any target at all: + +```yaml +app: + routes: + bindings: + # This has the effect of removing the button for registering new + # catalog entities in the scaffolder template list view + scaffolder.registerComponent: false +``` + +### Scaffolder Fields performance improvements + +The `EntityPicker` and `MultiEntityPicker` fields have been updated to improve performance with large catalogs. Contributed by [@kmikko](https://github.com/kmikko) in [#25315](https://github.com/backstage/backstage/pull/25315), [#25380](https://github.com/backstage/backstage/pull/25380) + +### BREAKING: Catalog LDAP Module improvements + +The `@backstage/plugin-catalog-backend-module-ldap` module has been improved to support multiple or no declarations of both user and group configs. + +This change is breaking for `readLdapOrg` and `LdapProviderConfig`, which now both always accept arrays of `users` and `groups` configurations. + +Contributed by [@Jenson3210](https://github.com/Jenson3210) in [#25261](https://github.com/backstage/backstage/pull/25261) ## Security Fixes This release does not contain any security fixes. -<or> - -@backstage/<package-name>, please upgrade to the latest version if you are using this module. - ## Upgrade path We recommend that you keep your Backstage project up to date with this latest release. For more guidance on how to upgrade, check out the documentation for [keeping Backstage updated](https://backstage.io/docs/getting-started/keeping-backstage-updated). From e9c39485fffb0cc9cf9185208ac2906961055753 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Tue, 16 Jul 2024 13:23:40 +0200 Subject: [PATCH 295/510] create-app: add lock seed for @mui/material Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- packages/create-app/seed-yarn.lock | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/create-app/seed-yarn.lock b/packages/create-app/seed-yarn.lock index 2f41ba9ca3..b09a0ce1a7 100644 --- a/packages/create-app/seed-yarn.lock +++ b/packages/create-app/seed-yarn.lock @@ -21,3 +21,8 @@ ajv@^8.0.0, ajv@^8.10.0, ajv@^8.11.0, ajv@^8.12.0, ajv@^8.14.0, ajv@^8.6.0, ajv@ version "8.14.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.14.0.tgz#f514ddfd4756abb200e1704414963620a625ebbb" integrity sha512-oYs1UUtO97ZO2lJ4bwnWeQW8/zvOIQLGKcvPTsWmvc2SYgBb+upuNS5NxoLaMU4h8Ju3Nbj6Cq8mD2LQoqVKFA== + +"@mui/material@^5.12.2": + version "5.16.1" + resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.16.1.tgz#6fcef9b5709df5864cf0b0bc0ea7b453a9d9e420" + integrity sha512-BGTgJRb0d/hX9tus5CEb6N/Fo8pE4tYA+s9r4/S0PCrtZ3urCLXlTH4qrAvggQbiF1cYRAbHCkVHoQ+4Pdxl+w== From 8d2fe707cbd584f4492013b31bc52f968aab08b6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Jul 2024 12:06:55 +0000 Subject: [PATCH 296/510] Version Packages --- .changeset/bright-fireants-sit.md | 5 - .changeset/bright-panthers-leave.md | 6 - .changeset/brown-rats-judge.md | 5 - .changeset/calm-jeans-ring.md | 5 - .changeset/chatty-adults-boil.md | 5 - .changeset/chilly-coats-report.md | 7 - .changeset/chilly-rabbits-sneeze.md | 5 - .changeset/chilly-roses-trade.md | 5 - .changeset/clever-carrots-refuse.md | 5 - .changeset/clever-geese-jump.md | 5 - .changeset/clever-waves-judge.md | 5 - .changeset/cold-jars-punch.md | 6 - .changeset/create-app-1719320674.md | 5 - .changeset/curvy-teachers-smell.md | 8 - .changeset/dirty-wasps-do.md | 5 - .changeset/dry-wombats-type.md | 5 - .changeset/early-deers-beg.md | 7 - .changeset/eight-dancers-burn.md | 5 - .changeset/eighty-games-wink.md | 5 - .changeset/eleven-foxes-sip.md | 11 - .changeset/eleven-radios-begin.md | 5 - .changeset/fair-fans-flow.md | 6 - .changeset/fair-meals-juggle.md | 5 - .changeset/fair-pillows-know.md | 7 - .changeset/fair-rockets-leave.md | 6 - .changeset/fair-spoons-work.md | 5 - .changeset/famous-clocks-visit.md | 5 - .changeset/famous-dodos-crash.md | 15 - .changeset/fast-pens-smell.md | 5 - .changeset/fifty-pumpkins-smell.md | 5 - .changeset/forty-buttons-cover.md | 5 - .changeset/four-donuts-switch.md | 5 - .changeset/friendly-bulldogs-pay.md | 7 - .changeset/friendly-experts-fail.md | 5 - .changeset/friendly-masks-type.md | 5 - .changeset/friendly-oranges-greet.md | 6 - .changeset/friendly-stingrays-occur.md | 7 - .changeset/funny-laws-tease.md | 5 - .changeset/fuzzy-socks-do.md | 5 - .changeset/gentle-avocados-obey.md | 5 - .changeset/gold-worms-complain.md | 5 - .changeset/grumpy-wolves-hang.md | 5 - .changeset/heavy-moose-pull.md | 5 - .changeset/honest-pears-run.md | 7 - .changeset/hot-items-kick.md | 9 - .changeset/khaki-rivers-obey.md | 6 - .changeset/kind-dancers-boil.md | 5 - .changeset/light-avocados-worry.md | 6 - .changeset/little-games-fail.md | 7 - .changeset/lucky-wolves-pull.md | 5 - .changeset/metal-jokes-add.md | 5 - .changeset/metal-parents-brush.md | 5 - .changeset/metal-suits-drum.md | 5 - .changeset/mighty-keys-bow.md | 5 - .changeset/moody-llamas-breathe.md | 5 - .changeset/neat-dingos-tickle.md | 5 - .changeset/new-sheep-arrive.md | 5 - .changeset/nice-cats-nail.md | 5 - .changeset/poor-cheetahs-raise.md | 30 - .changeset/pre.json | 258 -- .changeset/rare-peas-dream.md | 5 - .changeset/renovate-7b61228.md | 6 - .changeset/renovate-ced359b.md | 11 - .changeset/rich-bears-march.md | 5 - .changeset/selfish-turtles-jog.md | 6 - .changeset/serious-kings-trade.md | 5 - .changeset/sharp-rice-tickle.md | 5 - .changeset/short-flowers-cry.md | 5 - .changeset/short-impalas-suffer.md | 5 - .changeset/shy-hounds-battle.md | 5 - .changeset/silent-experts-move.md | 5 - .changeset/silent-lobsters-tease.md | 5 - .changeset/silent-moose-eat.md | 5 - .changeset/smooth-pianos-argue.md | 5 - .changeset/soft-clocks-bake.md | 5 - .changeset/sour-jokes-sneeze.md | 5 - .changeset/spotty-apricots-tan.md | 77 - .changeset/spotty-crabs-shop.md | 5 - .changeset/stale-beds-sneeze.md | 5 - .changeset/swift-dots-cough.md | 5 - .changeset/swift-seals-drive.md | 5 - .changeset/tall-walls-learn.md | 9 - .changeset/ten-dancers-drum.md | 5 - .changeset/ten-nails-hear.md | 7 - .changeset/ten-pots-walk.md | 8 - .changeset/tender-turkeys-begin.md | 5 - .changeset/thick-lizards-divide.md | 6 - .changeset/thick-moose-decide.md | 5 - .changeset/three-carpets-smoke.md | 5 - .changeset/three-lizards-crash.md | 5 - .changeset/tiny-pianos-work.md | 5 - .changeset/tiny-schools-draw.md | 7 - .changeset/tough-lies-mate.md | 7 - .changeset/twenty-buses-carry.md | 5 - .changeset/weak-boats-float.md | 8 - .changeset/weak-emus-doubt.md | 7 - .changeset/wet-rivers-travel.md | 5 - .changeset/wicked-impalas-explode.md | 5 - .changeset/witty-keys-share.md | 5 - .changeset/yellow-cows-kick.md | 5 - .changeset/young-donuts-swim.md | 6 - .changeset/young-fishes-lie.md | 5 - .changeset/young-houses-unite.md | 5 - docs/releases/v1.29.0-changelog.md | 2495 +++++++++++++++++ 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 | 43 + packages/app-next/package.json | 2 +- packages/app/CHANGELOG.md | 41 + packages/app/package.json | 2 +- packages/backend-app-api/CHANGELOG.md | 28 + packages/backend-app-api/package.json | 2 +- packages/backend-common/CHANGELOG.md | 21 + packages/backend-common/package.json | 2 +- packages/backend-defaults/CHANGELOG.md | 32 + packages/backend-defaults/package.json | 2 +- .../CHANGELOG.md | 27 + .../package.json | 2 +- packages/backend-legacy/CHANGELOG.md | 42 + packages/backend-legacy/package.json | 2 +- packages/backend-openapi-utils/CHANGELOG.md | 8 + packages/backend-openapi-utils/package.json | 2 +- packages/backend-plugin-api/CHANGELOG.md | 98 + packages/backend-plugin-api/package.json | 2 +- packages/backend-tasks/CHANGELOG.md | 12 + packages/backend-tasks/package.json | 2 +- packages/backend-test-utils/CHANGELOG.md | 22 + packages/backend-test-utils/package.json | 2 +- packages/backend/CHANGELOG.md | 37 + packages/backend/package.json | 2 +- packages/cli-node/CHANGELOG.md | 10 + packages/cli-node/package.json | 2 +- packages/cli/CHANGELOG.md | 28 + packages/cli/package.json | 2 +- packages/core-app-api/CHANGELOG.md | 24 + packages/core-app-api/package.json | 2 +- packages/core-compat-api/CHANGELOG.md | 9 + packages/core-compat-api/package.json | 2 +- packages/core-components/CHANGELOG.md | 13 + packages/core-components/package.json | 2 +- packages/create-app/CHANGELOG.md | 11 + 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 | 26 + packages/frontend-app-api/package.json | 2 +- packages/frontend-plugin-api/CHANGELOG.md | 10 + packages/frontend-plugin-api/package.json | 2 +- packages/frontend-test-utils/CHANGELOG.md | 11 + packages/frontend-test-utils/package.json | 2 +- packages/integration-react/CHANGELOG.md | 9 + packages/integration-react/package.json | 2 +- packages/integration/CHANGELOG.md | 12 + packages/integration/package.json | 2 +- packages/repo-tools/CHANGELOG.md | 12 + packages/repo-tools/package.json | 2 +- .../techdocs-cli-embedded-app/CHANGELOG.md | 19 + .../techdocs-cli-embedded-app/package.json | 2 +- packages/techdocs-cli/CHANGELOG.md | 12 + packages/techdocs-cli/package.json | 2 +- packages/test-utils/CHANGELOG.md | 14 + packages/test-utils/package.json | 2 +- plugins/api-docs/CHANGELOG.md | 15 + plugins/api-docs/package.json | 2 +- plugins/app-backend/CHANGELOG.md | 14 + plugins/app-backend/package.json | 2 +- plugins/app-node/CHANGELOG.md | 8 + plugins/app-node/package.json | 2 +- plugins/app-visualizer/CHANGELOG.md | 9 + plugins/app-visualizer/package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- plugins/auth-backend/CHANGELOG.md | 30 + plugins/auth-backend/package.json | 2 +- plugins/auth-node/CHANGELOG.md | 14 + plugins/auth-node/package.json | 2 +- plugins/auth-react/CHANGELOG.md | 9 + plugins/auth-react/package.json | 2 +- plugins/bitbucket-cloud-common/CHANGELOG.md | 8 + plugins/bitbucket-cloud-common/package.json | 2 +- .../catalog-backend-module-aws/CHANGELOG.md | 18 + .../catalog-backend-module-aws/package.json | 2 +- .../catalog-backend-module-azure/CHANGELOG.md | 13 + .../catalog-backend-module-azure/package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 17 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../catalog-backend-module-gcp/CHANGELOG.md | 13 + .../catalog-backend-module-gcp/package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 44 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 16 + .../package.json | 2 +- .../CHANGELOG.md | 16 + .../package.json | 2 +- .../catalog-backend-module-ldap/CHANGELOG.md | 21 + .../catalog-backend-module-ldap/package.json | 2 +- .../catalog-backend-module-logs/CHANGELOG.md | 14 + .../catalog-backend-module-logs/package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../CHANGELOG.md | 15 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- plugins/catalog-backend/CHANGELOG.md | 26 + plugins/catalog-backend/package.json | 2 +- plugins/catalog-common/CHANGELOG.md | 9 + plugins/catalog-common/package.json | 2 +- plugins/catalog-graph/CHANGELOG.md | 14 + plugins/catalog-graph/package.json | 2 +- plugins/catalog-import/CHANGELOG.md | 18 + plugins/catalog-import/package.json | 2 +- plugins/catalog-node/CHANGELOG.md | 14 + plugins/catalog-node/package.json | 2 +- plugins/catalog-react/CHANGELOG.md | 20 + plugins/catalog-react/package.json | 2 +- .../CHANGELOG.md | 7 + .../package.json | 2 +- .../catalog-unprocessed-entities/CHANGELOG.md | 10 + .../catalog-unprocessed-entities/package.json | 2 +- plugins/catalog/CHANGELOG.md | 23 + plugins/catalog/package.json | 2 +- plugins/config-schema/CHANGELOG.md | 10 + plugins/config-schema/package.json | 2 +- plugins/devtools-backend/CHANGELOG.md | 16 + plugins/devtools-backend/package.json | 2 +- plugins/devtools-common/CHANGELOG.md | 8 + plugins/devtools-common/package.json | 2 +- plugins/devtools/CHANGELOG.md | 13 + plugins/devtools/package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../events-backend-module-azure/CHANGELOG.md | 8 + .../events-backend-module-azure/package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../events-backend-module-gerrit/CHANGELOG.md | 8 + .../events-backend-module-gerrit/package.json | 2 +- .../events-backend-module-github/CHANGELOG.md | 9 + .../events-backend-module-github/package.json | 2 +- .../events-backend-module-gitlab/CHANGELOG.md | 9 + .../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 | 10 + plugins/events-backend/package.json | 2 +- plugins/events-node/CHANGELOG.md | 8 + plugins/events-node/package.json | 2 +- .../example-todo-list-backend/CHANGELOG.md | 10 + .../example-todo-list-backend/package.json | 2 +- plugins/example-todo-list-common/CHANGELOG.md | 7 + plugins/example-todo-list-common/package.json | 2 +- plugins/example-todo-list/CHANGELOG.md | 8 + plugins/example-todo-list/package.json | 2 +- plugins/home-react/CHANGELOG.md | 12 + plugins/home-react/package.json | 2 +- plugins/home/CHANGELOG.md | 21 + plugins/home/package.json | 2 +- plugins/kubernetes-backend/CHANGELOG.md | 20 + plugins/kubernetes-backend/package.json | 2 +- plugins/kubernetes-cluster/CHANGELOG.md | 12 + plugins/kubernetes-cluster/package.json | 2 +- plugins/kubernetes-common/CHANGELOG.md | 9 + plugins/kubernetes-common/package.json | 2 +- plugins/kubernetes-node/CHANGELOG.md | 10 + plugins/kubernetes-node/package.json | 2 +- plugins/kubernetes-react/CHANGELOG.md | 14 + plugins/kubernetes-react/package.json | 2 +- plugins/kubernetes/CHANGELOG.md | 12 + plugins/kubernetes/package.json | 2 +- .../CHANGELOG.md | 16 + .../package.json | 2 +- plugins/notifications-backend/CHANGELOG.md | 18 + plugins/notifications-backend/package.json | 2 +- plugins/notifications-common/CHANGELOG.md | 8 + plugins/notifications-common/package.json | 2 +- plugins/notifications-node/CHANGELOG.md | 13 + plugins/notifications-node/package.json | 2 +- plugins/notifications/CHANGELOG.md | 14 + plugins/notifications/package.json | 2 +- plugins/org-react/CHANGELOG.md | 11 + plugins/org-react/package.json | 2 +- plugins/org/CHANGELOG.md | 18 + plugins/org/package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- plugins/permission-backend/CHANGELOG.md | 20 + plugins/permission-backend/package.json | 2 +- plugins/permission-common/CHANGELOG.md | 13 + plugins/permission-common/package.json | 2 +- plugins/permission-node/CHANGELOG.md | 24 + plugins/permission-node/package.json | 2 +- plugins/permission-react/CHANGELOG.md | 10 + plugins/permission-react/package.json | 2 +- plugins/proxy-backend/CHANGELOG.md | 10 + plugins/proxy-backend/package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../CHANGELOG.md | 15 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 26 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- plugins/scaffolder-backend/CHANGELOG.md | 40 + plugins/scaffolder-backend/package.json | 2 +- plugins/scaffolder-common/CHANGELOG.md | 9 + plugins/scaffolder-common/package.json | 2 +- .../scaffolder-node-test-utils/CHANGELOG.md | 11 + .../scaffolder-node-test-utils/package.json | 2 +- plugins/scaffolder-node/CHANGELOG.md | 16 + plugins/scaffolder-node/package.json | 2 +- plugins/scaffolder-react/CHANGELOG.md | 26 + plugins/scaffolder-react/package.json | 2 +- plugins/scaffolder/CHANGELOG.md | 34 + plugins/scaffolder/package.json | 2 +- .../CHANGELOG.md | 18 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- plugins/search-backend-module-pg/CHANGELOG.md | 12 + plugins/search-backend-module-pg/package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 18 + .../package.json | 2 +- plugins/search-backend-node/CHANGELOG.md | 13 + plugins/search-backend-node/package.json | 2 +- plugins/search-backend/CHANGELOG.md | 18 + plugins/search-backend/package.json | 2 +- plugins/search-common/CHANGELOG.md | 8 + plugins/search-common/package.json | 2 +- plugins/search-react/CHANGELOG.md | 13 + plugins/search-react/package.json | 2 +- plugins/search/CHANGELOG.md | 17 + plugins/search/package.json | 2 +- plugins/signals-backend/CHANGELOG.md | 13 + plugins/signals-backend/package.json | 2 +- plugins/signals-node/CHANGELOG.md | 12 + plugins/signals-node/package.json | 2 +- plugins/signals/CHANGELOG.md | 11 + plugins/signals/package.json | 2 +- .../techdocs-addons-test-utils/CHANGELOG.md | 15 + .../techdocs-addons-test-utils/package.json | 2 +- plugins/techdocs-backend/CHANGELOG.md | 18 + plugins/techdocs-backend/package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- plugins/techdocs-node/CHANGELOG.md | 16 + plugins/techdocs-node/package.json | 2 +- plugins/techdocs-react/CHANGELOG.md | 12 + plugins/techdocs-react/package.json | 2 +- plugins/techdocs/CHANGELOG.md | 25 + plugins/techdocs/package.json | 2 +- plugins/user-settings-backend/CHANGELOG.md | 14 + plugins/user-settings-backend/package.json | 2 +- plugins/user-settings/CHANGELOG.md | 17 + plugins/user-settings/package.json | 2 +- yarn.lock | 264 +- 436 files changed, 5209 insertions(+), 1305 deletions(-) delete mode 100644 .changeset/bright-fireants-sit.md delete mode 100644 .changeset/bright-panthers-leave.md delete mode 100644 .changeset/brown-rats-judge.md delete mode 100644 .changeset/calm-jeans-ring.md delete mode 100644 .changeset/chatty-adults-boil.md delete mode 100644 .changeset/chilly-coats-report.md delete mode 100644 .changeset/chilly-rabbits-sneeze.md delete mode 100644 .changeset/chilly-roses-trade.md delete mode 100644 .changeset/clever-carrots-refuse.md delete mode 100644 .changeset/clever-geese-jump.md delete mode 100644 .changeset/clever-waves-judge.md delete mode 100644 .changeset/cold-jars-punch.md delete mode 100644 .changeset/create-app-1719320674.md delete mode 100644 .changeset/curvy-teachers-smell.md delete mode 100644 .changeset/dirty-wasps-do.md delete mode 100644 .changeset/dry-wombats-type.md delete mode 100644 .changeset/early-deers-beg.md delete mode 100644 .changeset/eight-dancers-burn.md delete mode 100644 .changeset/eighty-games-wink.md delete mode 100644 .changeset/eleven-foxes-sip.md delete mode 100644 .changeset/eleven-radios-begin.md delete mode 100644 .changeset/fair-fans-flow.md delete mode 100644 .changeset/fair-meals-juggle.md delete mode 100644 .changeset/fair-pillows-know.md delete mode 100644 .changeset/fair-rockets-leave.md delete mode 100644 .changeset/fair-spoons-work.md delete mode 100644 .changeset/famous-clocks-visit.md delete mode 100644 .changeset/famous-dodos-crash.md delete mode 100644 .changeset/fast-pens-smell.md delete mode 100644 .changeset/fifty-pumpkins-smell.md delete mode 100644 .changeset/forty-buttons-cover.md delete mode 100644 .changeset/four-donuts-switch.md delete mode 100644 .changeset/friendly-bulldogs-pay.md delete mode 100644 .changeset/friendly-experts-fail.md delete mode 100644 .changeset/friendly-masks-type.md delete mode 100644 .changeset/friendly-oranges-greet.md delete mode 100644 .changeset/friendly-stingrays-occur.md delete mode 100644 .changeset/funny-laws-tease.md delete mode 100644 .changeset/fuzzy-socks-do.md delete mode 100644 .changeset/gentle-avocados-obey.md delete mode 100644 .changeset/gold-worms-complain.md delete mode 100644 .changeset/grumpy-wolves-hang.md delete mode 100644 .changeset/heavy-moose-pull.md delete mode 100644 .changeset/honest-pears-run.md delete mode 100644 .changeset/hot-items-kick.md delete mode 100644 .changeset/khaki-rivers-obey.md delete mode 100644 .changeset/kind-dancers-boil.md delete mode 100644 .changeset/light-avocados-worry.md delete mode 100644 .changeset/little-games-fail.md delete mode 100644 .changeset/lucky-wolves-pull.md delete mode 100644 .changeset/metal-jokes-add.md delete mode 100644 .changeset/metal-parents-brush.md delete mode 100644 .changeset/metal-suits-drum.md delete mode 100644 .changeset/mighty-keys-bow.md delete mode 100644 .changeset/moody-llamas-breathe.md delete mode 100644 .changeset/neat-dingos-tickle.md delete mode 100644 .changeset/new-sheep-arrive.md delete mode 100644 .changeset/nice-cats-nail.md delete mode 100644 .changeset/poor-cheetahs-raise.md delete mode 100644 .changeset/pre.json delete mode 100644 .changeset/rare-peas-dream.md delete mode 100644 .changeset/renovate-7b61228.md delete mode 100644 .changeset/renovate-ced359b.md delete mode 100644 .changeset/rich-bears-march.md delete mode 100644 .changeset/selfish-turtles-jog.md delete mode 100644 .changeset/serious-kings-trade.md delete mode 100644 .changeset/sharp-rice-tickle.md delete mode 100644 .changeset/short-flowers-cry.md delete mode 100644 .changeset/short-impalas-suffer.md delete mode 100644 .changeset/shy-hounds-battle.md delete mode 100644 .changeset/silent-experts-move.md delete mode 100644 .changeset/silent-lobsters-tease.md delete mode 100644 .changeset/silent-moose-eat.md delete mode 100644 .changeset/smooth-pianos-argue.md delete mode 100644 .changeset/soft-clocks-bake.md delete mode 100644 .changeset/sour-jokes-sneeze.md delete mode 100644 .changeset/spotty-apricots-tan.md delete mode 100644 .changeset/spotty-crabs-shop.md delete mode 100644 .changeset/stale-beds-sneeze.md delete mode 100644 .changeset/swift-dots-cough.md delete mode 100644 .changeset/swift-seals-drive.md delete mode 100644 .changeset/tall-walls-learn.md delete mode 100644 .changeset/ten-dancers-drum.md delete mode 100644 .changeset/ten-nails-hear.md delete mode 100644 .changeset/ten-pots-walk.md delete mode 100644 .changeset/tender-turkeys-begin.md delete mode 100644 .changeset/thick-lizards-divide.md delete mode 100644 .changeset/thick-moose-decide.md delete mode 100644 .changeset/three-carpets-smoke.md delete mode 100644 .changeset/three-lizards-crash.md delete mode 100644 .changeset/tiny-pianos-work.md delete mode 100644 .changeset/tiny-schools-draw.md delete mode 100644 .changeset/tough-lies-mate.md delete mode 100644 .changeset/twenty-buses-carry.md delete mode 100644 .changeset/weak-boats-float.md delete mode 100644 .changeset/weak-emus-doubt.md delete mode 100644 .changeset/wet-rivers-travel.md delete mode 100644 .changeset/wicked-impalas-explode.md delete mode 100644 .changeset/witty-keys-share.md delete mode 100644 .changeset/yellow-cows-kick.md delete mode 100644 .changeset/young-donuts-swim.md delete mode 100644 .changeset/young-fishes-lie.md delete mode 100644 .changeset/young-houses-unite.md create mode 100644 docs/releases/v1.29.0-changelog.md diff --git a/.changeset/bright-fireants-sit.md b/.changeset/bright-fireants-sit.md deleted file mode 100644 index 320bc69ff9..0000000000 --- a/.changeset/bright-fireants-sit.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Added `MyGroupsSidebarItem` to the sidebar in the `create-app` template diff --git a/.changeset/bright-panthers-leave.md b/.changeset/bright-panthers-leave.md deleted file mode 100644 index 35d9c0f869..0000000000 --- a/.changeset/bright-panthers-leave.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/backend-plugin-api': patch -'@backstage/backend-defaults': patch ---- - -Added a new Root Health Service which adds new endpoints for health checks. diff --git a/.changeset/brown-rats-judge.md b/.changeset/brown-rats-judge.md deleted file mode 100644 index 0076c65d77..0000000000 --- a/.changeset/brown-rats-judge.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-permission-backend-module-allow-all-policy': patch ---- - -Internal refactor to use new `PolicyQueryUser` type. diff --git a/.changeset/calm-jeans-ring.md b/.changeset/calm-jeans-ring.md deleted file mode 100644 index 3d1efcf7bd..0000000000 --- a/.changeset/calm-jeans-ring.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': minor ---- - -Use virtualization with `EntityPicker` as done earlier with `MultiEntityPicker` to fix performance issues with large data sets. `VirtualizedListbox` extracted into reusable component. diff --git a/.changeset/chatty-adults-boil.md b/.changeset/chatty-adults-boil.md deleted file mode 100644 index 76f3bddf41..0000000000 --- a/.changeset/chatty-adults-boil.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch ---- - -Fixed an issue that was causing techdocs pages unnecessarily re-render on navigate. diff --git a/.changeset/chilly-coats-report.md b/.changeset/chilly-coats-report.md deleted file mode 100644 index 2fd044b57c..0000000000 --- a/.changeset/chilly-coats-report.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/backend-test-utils': patch -'@backstage/backend-defaults': patch -'@backstage/backend-app-api': patch ---- - -The `ServiceFactoryTest.get` method was deprecated and the `ServiceFactoryTest.getSubject` should be used instead. The `getSubject` method has the same behavior, but has a better method name to indicate that the service instance returned is the subject currently being tested. diff --git a/.changeset/chilly-rabbits-sneeze.md b/.changeset/chilly-rabbits-sneeze.md deleted file mode 100644 index cbce80ebbc..0000000000 --- a/.changeset/chilly-rabbits-sneeze.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend-module-atlassian-provider': patch ---- - -Fix several issues with the Atlassian auth provider (type definition, profile url, profile transformation, scopes) diff --git a/.changeset/chilly-roses-trade.md b/.changeset/chilly-roses-trade.md deleted file mode 100644 index 73fc3ff766..0000000000 --- a/.changeset/chilly-roses-trade.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Deprecate legacy status check factory, handler and types. diff --git a/.changeset/clever-carrots-refuse.md b/.changeset/clever-carrots-refuse.md deleted file mode 100644 index 24217b1045..0000000000 --- a/.changeset/clever-carrots-refuse.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli-node': patch ---- - -Added internal metadata for the new experimental `frontend-dynamic-container` role. diff --git a/.changeset/clever-geese-jump.md b/.changeset/clever-geese-jump.md deleted file mode 100644 index 1c4694fa33..0000000000 --- a/.changeset/clever-geese-jump.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-msgraph': patch ---- - -Adds a dynamic provider for the plugin-catalog-backend-module-msgraph. Configuration is now runtime configurable through the ProviderConfigTransformer. diff --git a/.changeset/clever-waves-judge.md b/.changeset/clever-waves-judge.md deleted file mode 100644 index 100ab66f90..0000000000 --- a/.changeset/clever-waves-judge.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs-react': patch ---- - -Resolved the issue where changes in TechDoc add-ons, including the TextSize add-on, were not reapplying during navigation diff --git a/.changeset/cold-jars-punch.md b/.changeset/cold-jars-punch.md deleted file mode 100644 index 8708e1f670..0000000000 --- a/.changeset/cold-jars-punch.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/backend-defaults': minor -'@backstage/backend-app-api': minor ---- - -**BREAKING**: Removed the depreacted `getPath` option from `httpRouterServiceFactory`, as well as the `HttpRouterFactoryOptions` type. diff --git a/.changeset/create-app-1719320674.md b/.changeset/create-app-1719320674.md deleted file mode 100644 index b50d431d4b..0000000000 --- a/.changeset/create-app-1719320674.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Bumped create-app version. diff --git a/.changeset/curvy-teachers-smell.md b/.changeset/curvy-teachers-smell.md deleted file mode 100644 index 3f032f2177..0000000000 --- a/.changeset/curvy-teachers-smell.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-ldap': patch -'@backstage/backend-plugin-api': patch -'@backstage/backend-defaults': patch -'@backstage/backend-tasks': patch ---- - -Fix bug where ISO durations could no longer be used for schedules diff --git a/.changeset/dirty-wasps-do.md b/.changeset/dirty-wasps-do.md deleted file mode 100644 index f8b4e614eb..0000000000 --- a/.changeset/dirty-wasps-do.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Updated `catalog:write` scaffolder action to show correct file path location in log message diff --git a/.changeset/dry-wombats-type.md b/.changeset/dry-wombats-type.md deleted file mode 100644 index 31fed70293..0000000000 --- a/.changeset/dry-wombats-type.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-app-api': minor ---- - -**BREAKING**: Removed the ability to pass callback-form service factories through the `defaultServiceFactories` option of `createSpecializedBackend`. This is an immediate breaking change as usage of this function is expected to be very rare. diff --git a/.changeset/early-deers-beg.md b/.changeset/early-deers-beg.md deleted file mode 100644 index 735c68aace..0000000000 --- a/.changeset/early-deers-beg.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-github': patch ---- - -Fixed bug resulting from missing required owner and repo arguments in `getEnvironmentPublicKey` in action `github:environment:create`. - -Adding environment secrets now works as expected. diff --git a/.changeset/eight-dancers-burn.md b/.changeset/eight-dancers-burn.md deleted file mode 100644 index 228ff036ab..0000000000 --- a/.changeset/eight-dancers-burn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-permission-common': minor ---- - -**BREAKING**: Removed the deprecated and unused `token` option from `EvaluatorRequestOptions`. The `PermissionsClient` now has its own `PermissionClientRequestOptions` type that declares the `token` option instead. diff --git a/.changeset/eighty-games-wink.md b/.changeset/eighty-games-wink.md deleted file mode 100644 index e87dc56b5f..0000000000 --- a/.changeset/eighty-games-wink.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -Fixed bug where `<Select>` component with empty string as placeholder gave an error diff --git a/.changeset/eleven-foxes-sip.md b/.changeset/eleven-foxes-sip.md deleted file mode 100644 index 8b21ddb20f..0000000000 --- a/.changeset/eleven-foxes-sip.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@backstage/plugin-permission-backend': patch -'@backstage/plugin-permission-node': patch ---- - -The `PermissionPolicy` interface has been updated to align with the recent changes to the Backstage auth system. The second argument to the `handle` method is now of the new `PolicyQueryUser` type. This type maintains the old fields from the `BackstageIdentityResponse`, which are now all deprecated. Instead, two new fields have been added, which allows access to the same information: - -- `credentials` - A `BackstageCredentials` object, which is useful for making requests to other services on behalf of the user as part of evaluating the policy. This replaces the deprecated `token` field. See the [Auth Service documentation](https://backstage.io/docs/backend-system/core-services/auth#creating-request-tokens) for information about how to create a token using these credentials. -- `info` - A `BackstageUserInfo` object, which contains the same information as the deprecated `identity`, except for the `type` field that was redundant. - -Most existing policies can be updated by replacing the `BackstageIdentityResponse` type with `PolicyQueryUser`, which is exported from `@backstage/plugin-permission-node`, as well as replacing any occurrences of `user?.identity` with `user?.info`. diff --git a/.changeset/eleven-radios-begin.md b/.changeset/eleven-radios-begin.md deleted file mode 100644 index 3fc2dd7895..0000000000 --- a/.changeset/eleven-radios-begin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch ---- - -Improve default sorting of docs table diff --git a/.changeset/fair-fans-flow.md b/.changeset/fair-fans-flow.md deleted file mode 100644 index abdc22440b..0000000000 --- a/.changeset/fair-fans-flow.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-techdocs-backend': patch -'@backstage/plugin-techdocs-node': patch ---- - -Adds extension point for publishers to the techdocs backend diff --git a/.changeset/fair-meals-juggle.md b/.changeset/fair-meals-juggle.md deleted file mode 100644 index 94db114170..0000000000 --- a/.changeset/fair-meals-juggle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Added experimental support for dynamic frontend plugin builds, enabled via setting `EXPERIMENTAL_MODULE_FEDERATION` for the app build, and using the `frontend-dynamic-container` package role to create a container. Both of these are experimental and will change in the future. diff --git a/.changeset/fair-pillows-know.md b/.changeset/fair-pillows-know.md deleted file mode 100644 index f0e5034393..0000000000 --- a/.changeset/fair-pillows-know.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch -'@backstage/plugin-scaffolder-backend-module-gitlab': patch -'@backstage/plugin-scaffolder-backend-module-rails': patch ---- - -Updated configuration instructions diff --git a/.changeset/fair-rockets-leave.md b/.changeset/fair-rockets-leave.md deleted file mode 100644 index 20f2e97552..0000000000 --- a/.changeset/fair-rockets-leave.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-bitbucket-server': patch ---- - -Instead of using hardcoded `targetBranch` now fetch the default branch from Bitbucket repository. -This prevents from errors when no `targetBranch` is provided and the default repository branch is different from `master`, for example: `main`. diff --git a/.changeset/fair-spoons-work.md b/.changeset/fair-spoons-work.md deleted file mode 100644 index e4b94625db..0000000000 --- a/.changeset/fair-spoons-work.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Added the Catalog logs module to the `create-app` template diff --git a/.changeset/famous-clocks-visit.md b/.changeset/famous-clocks-visit.md deleted file mode 100644 index 66c2048872..0000000000 --- a/.changeset/famous-clocks-visit.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-permission-node': patch ---- - -Fix invalid cross-reference in API Reference docs diff --git a/.changeset/famous-dodos-crash.md b/.changeset/famous-dodos-crash.md deleted file mode 100644 index 5442c1b378..0000000000 --- a/.changeset/famous-dodos-crash.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -'@backstage/core-app-api': minor -'@backstage/frontend-app-api': patch ---- - -Allow for the disabling of external routes through config, which was rendered impossible after the introduction of default targets. - -```yaml -app: - routes: - bindings: - # This has the effect of removing the button for registering new - # catalog entities in the scaffolder template list view - scaffolder.registerComponent: false -``` diff --git a/.changeset/fast-pens-smell.md b/.changeset/fast-pens-smell.md deleted file mode 100644 index 6d909a397c..0000000000 --- a/.changeset/fast-pens-smell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-org': patch ---- - -The `useGetEntities` hook could result in requests to `/api/catalog/entities` where the headers exceed the default maximum Node.js header size of 16KB. The hook logic has been adjusted to batch the requests. diff --git a/.changeset/fifty-pumpkins-smell.md b/.changeset/fifty-pumpkins-smell.md deleted file mode 100644 index 95f4fd3fc1..0000000000 --- a/.changeset/fifty-pumpkins-smell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-gitlab': patch ---- - -The Gitlab configuration supports an additional optional boolean key `catalog.providers.gitlab.<your-org>.restrictUsersToGroup`. Setting this to `true` will make Backstage only import users from the group defined in the `group` key, instead of all users in the organisation (self-hosted) or of the root group (SaaS). It will default to false, keeping the original implementation intact, when not explicitly set. diff --git a/.changeset/forty-buttons-cover.md b/.changeset/forty-buttons-cover.md deleted file mode 100644 index 16e66df061..0000000000 --- a/.changeset/forty-buttons-cover.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-test-utils': patch ---- - -The function `isDockerDisabledForTests` is deprecated and will no longer be exported in the near future as it should only be used internally. diff --git a/.changeset/four-donuts-switch.md b/.changeset/four-donuts-switch.md deleted file mode 100644 index bb876a4341..0000000000 --- a/.changeset/four-donuts-switch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -enable resizing of the task log stream viewer diff --git a/.changeset/friendly-bulldogs-pay.md b/.changeset/friendly-bulldogs-pay.md deleted file mode 100644 index d77c739bb0..0000000000 --- a/.changeset/friendly-bulldogs-pay.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-ldap': minor ---- - -**BREAKING**: `readLdapOrg` and the `LdapProviderConfig` type now always accept arrays of user and group configs, not just single items. - -Added support for single ldap catalog provider to provide list and undefined user and group bindings next to standard single one. diff --git a/.changeset/friendly-experts-fail.md b/.changeset/friendly-experts-fail.md deleted file mode 100644 index df2d2e2b24..0000000000 --- a/.changeset/friendly-experts-fail.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-app-api': patch ---- - -Updated config schema to support app.routes.bindings diff --git a/.changeset/friendly-masks-type.md b/.changeset/friendly-masks-type.md deleted file mode 100644 index 6f38ddefa3..0000000000 --- a/.changeset/friendly-masks-type.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/integration': minor ---- - -Add support for `token` for `bitbucketCloud` integration diff --git a/.changeset/friendly-oranges-greet.md b/.changeset/friendly-oranges-greet.md deleted file mode 100644 index d327c40640..0000000000 --- a/.changeset/friendly-oranges-greet.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-catalog-react': patch -'@backstage/plugin-catalog': patch ---- - -Support i18n for catalog and catalog-react plugins diff --git a/.changeset/friendly-stingrays-occur.md b/.changeset/friendly-stingrays-occur.md deleted file mode 100644 index 3383203b40..0000000000 --- a/.changeset/friendly-stingrays-occur.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/cli': patch ---- - -- remove unused dependencies `winston` and `yn` from the template of backend plugins; -- update `msw` to version `2.3.1` in the template of backend plugins; - starting with v1 and switching later to v2 is tedious and not straight forward; it's easier to start with v2; diff --git a/.changeset/funny-laws-tease.md b/.changeset/funny-laws-tease.md deleted file mode 100644 index 8ecbc87b65..0000000000 --- a/.changeset/funny-laws-tease.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Updated the scaffolding output message for `plugin-common` in `backstage-cli`. Now, when executing `backstage-cli new` to create a new `plugin-common` package, the output message accurately reflects the action by displaying `Creating common plugin package...` instead of the previous, less accurate `Creating backend plugin...`. diff --git a/.changeset/fuzzy-socks-do.md b/.changeset/fuzzy-socks-do.md deleted file mode 100644 index aabc10f0cd..0000000000 --- a/.changeset/fuzzy-socks-do.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch ---- - -Allow for searching TechDocs by entity title diff --git a/.changeset/gentle-avocados-obey.md b/.changeset/gentle-avocados-obey.md deleted file mode 100644 index 80bf5f89c7..0000000000 --- a/.changeset/gentle-avocados-obey.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Only bootstrap global-agent if it's actually being used diff --git a/.changeset/gold-worms-complain.md b/.changeset/gold-worms-complain.md deleted file mode 100644 index 229293cc2f..0000000000 --- a/.changeset/gold-worms-complain.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-permission-node': minor ---- - -**BREAKING**: Updated the `ServerPermissionClient` to match the new `PermissionsService` interface, where the deprecated `token` option has been removed and the options are now required. diff --git a/.changeset/grumpy-wolves-hang.md b/.changeset/grumpy-wolves-hang.md deleted file mode 100644 index 8ab3740e74..0000000000 --- a/.changeset/grumpy-wolves-hang.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Fix issue with CLI that was preventing upgrading from 1.28 diff --git a/.changeset/heavy-moose-pull.md b/.changeset/heavy-moose-pull.md deleted file mode 100644 index 86b2753a28..0000000000 --- a/.changeset/heavy-moose-pull.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': minor ---- - -Use virtualization with `MultiEntityPicker`. Fixes performance issues with large data sets. diff --git a/.changeset/honest-pears-run.md b/.changeset/honest-pears-run.md deleted file mode 100644 index 65ea8d1721..0000000000 --- a/.changeset/honest-pears-run.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-azure': patch -'@backstage/plugin-scaffolder-node': patch -'@backstage/plugin-scaffolder': patch ---- - -Fixed a bug where the `RepoUrlPicker` would still require the `owner` field for `azure` diff --git a/.changeset/hot-items-kick.md b/.changeset/hot-items-kick.md deleted file mode 100644 index a3a9f129c1..0000000000 --- a/.changeset/hot-items-kick.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@backstage/backend-dynamic-feature-service': patch -'@backstage/backend-test-utils': patch -'@backstage/backend-defaults': patch -'@backstage/backend-app-api': patch -'@backstage/plugin-events-node': patch ---- - -Service factories exported by this package have been updated to use the new service factory format that doesn't use a callback. diff --git a/.changeset/khaki-rivers-obey.md b/.changeset/khaki-rivers-obey.md deleted file mode 100644 index 856c8caf09..0000000000 --- a/.changeset/khaki-rivers-obey.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/backend-common': patch -'@backstage/cli': patch ---- - -Update default backend plugin created by the cli to use non-deprecated error handling middleware diff --git a/.changeset/kind-dancers-boil.md b/.changeset/kind-dancers-boil.md deleted file mode 100644 index 4451cab4f4..0000000000 --- a/.changeset/kind-dancers-boil.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Added a documentation how to use checkpoints diff --git a/.changeset/light-avocados-worry.md b/.changeset/light-avocados-worry.md deleted file mode 100644 index a3605a1451..0000000000 --- a/.changeset/light-avocados-worry.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-bitbucket-cloud': patch -'@backstage/plugin-bitbucket-cloud-common': patch ---- - -Add support for `autocomplete` handler to provide autocomplete options for `RepoUrlPicker` diff --git a/.changeset/little-games-fail.md b/.changeset/little-games-fail.md deleted file mode 100644 index 199f983be8..0000000000 --- a/.changeset/little-games-fail.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-org': patch ---- - -Added `relationType` property to EntityMembersListCard component that allows for display users related to a group via some other relationship aside from `memberOf`. - -Also, as a side effect, the `relationsType` property has been deprecated in favor of a more accurately named `relationAggregation` property. diff --git a/.changeset/lucky-wolves-pull.md b/.changeset/lucky-wolves-pull.md deleted file mode 100644 index 17ed4572b6..0000000000 --- a/.changeset/lucky-wolves-pull.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-defaults': patch ---- - -Refactor of `rootHttpRouterServiceFactory` to allow it to be constructed with options, but without declaring options via `createServiceFactory`. diff --git a/.changeset/metal-jokes-add.md b/.changeset/metal-jokes-add.md deleted file mode 100644 index faef714d87..0000000000 --- a/.changeset/metal-jokes-add.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-react': patch ---- - -Make EntityOwnerPicker display metadata.title or spec.profile.displayName for mode=only-owners instead of metadata.name diff --git a/.changeset/metal-parents-brush.md b/.changeset/metal-parents-brush.md deleted file mode 100644 index f73b0040fd..0000000000 --- a/.changeset/metal-parents-brush.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch ---- - -Fix double scrollbar bug in reader diff --git a/.changeset/metal-suits-drum.md b/.changeset/metal-suits-drum.md deleted file mode 100644 index 4cc7e18ced..0000000000 --- a/.changeset/metal-suits-drum.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-notifications': patch ---- - -The toolbar on the Notifications page is hidden when there are no listed notifications. diff --git a/.changeset/mighty-keys-bow.md b/.changeset/mighty-keys-bow.md deleted file mode 100644 index 5f1bb408c9..0000000000 --- a/.changeset/mighty-keys-bow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-aws': patch ---- - -Export `defaultEksClusterEntityTransformer` to allow library consumers to layer additional changes on top of the default transformer. diff --git a/.changeset/moody-llamas-breathe.md b/.changeset/moody-llamas-breathe.md deleted file mode 100644 index 418cf7480e..0000000000 --- a/.changeset/moody-llamas-breathe.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Add dependencies that are needed by cross-imports from backend-defaults diff --git a/.changeset/neat-dingos-tickle.md b/.changeset/neat-dingos-tickle.md deleted file mode 100644 index 43929e532f..0000000000 --- a/.changeset/neat-dingos-tickle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs-node': patch ---- - -Bumps default version of techdocs docker image to latest diff --git a/.changeset/new-sheep-arrive.md b/.changeset/new-sheep-arrive.md deleted file mode 100644 index 00e759a187..0000000000 --- a/.changeset/new-sheep-arrive.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -Modified the `Select` component to take in a `data-testid` parameter ensuring backwards compatibility with default value corresponding to previously hardcoded `data-testid` of "select". diff --git a/.changeset/nice-cats-nail.md b/.changeset/nice-cats-nail.md deleted file mode 100644 index 0e9b1603b8..0000000000 --- a/.changeset/nice-cats-nail.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-app-api': patch ---- - -Internal refactor that avoids the use of service factory options. diff --git a/.changeset/poor-cheetahs-raise.md b/.changeset/poor-cheetahs-raise.md deleted file mode 100644 index 0ee2162a22..0000000000 --- a/.changeset/poor-cheetahs-raise.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-github': patch ---- - -Adds support for `repository` events. - -The provider adds a subscription to the topic `github.repository`. - -Hereby, it supports events of type `repository` with actions - -- `archived` -- `deleted` -- `edited` -- `renamed` -- `transferred` -- `unarchived` - -Actions skipped as they don't require entity changes: - -- `created` -- `privatized` -- `publicized` - -If the config option `validateLocationsExist` is enabled, an API request -is necessary and will be executed. -This affects the actions `renamed`, `transferred`, and `unarchive` -of event type `repository`. - -Catalog entities related to the `GithubEntityProvider` instance will be adjusted -according to action and its meaning for them. diff --git a/.changeset/pre.json b/.changeset/pre.json deleted file mode 100644 index cebbc6e919..0000000000 --- a/.changeset/pre.json +++ /dev/null @@ -1,258 +0,0 @@ -{ - "mode": "exit", - "tag": "next", - "initialVersions": { - "example-app": "0.2.98", - "@backstage/app-defaults": "1.5.6", - "example-app-next": "0.0.12", - "app-next-example-plugin": "0.0.12", - "example-backend": "0.0.27", - "@backstage/backend-app-api": "0.7.6", - "@backstage/backend-common": "0.23.0", - "@backstage/backend-defaults": "0.3.0", - "@backstage/backend-dev-utils": "0.1.4", - "@backstage/backend-dynamic-feature-service": "0.2.11", - "example-backend-legacy": "0.2.99", - "@backstage/backend-openapi-utils": "0.1.12", - "@backstage/backend-plugin-api": "0.6.19", - "@backstage/backend-tasks": "0.5.24", - "@backstage/backend-test-utils": "0.4.0", - "@backstage/catalog-client": "1.6.5", - "@backstage/catalog-model": "1.5.0", - "@backstage/cli": "0.26.7", - "@backstage/cli-common": "0.1.14", - "@backstage/cli-node": "0.2.6", - "@backstage/codemods": "0.1.49", - "@backstage/config": "1.2.0", - "@backstage/config-loader": "1.8.1", - "@backstage/core-app-api": "1.12.6", - "@backstage/core-compat-api": "0.2.6", - "@backstage/core-components": "0.14.8", - "@backstage/core-plugin-api": "1.9.3", - "@backstage/create-app": "0.5.16", - "@backstage/dev-utils": "1.0.33", - "e2e-test": "0.2.17", - "@backstage/e2e-test-utils": "0.1.1", - "@backstage/errors": "1.2.4", - "@backstage/eslint-plugin": "0.1.8", - "@backstage/frontend-app-api": "0.7.1", - "@backstage/frontend-plugin-api": "0.6.6", - "@backstage/frontend-test-utils": "0.1.8", - "@backstage/integration": "1.12.0", - "@backstage/integration-aws-node": "0.1.12", - "@backstage/integration-react": "1.1.28", - "@backstage/release-manifests": "0.0.11", - "@backstage/repo-tools": "0.9.1", - "@techdocs/cli": "1.8.12", - "techdocs-cli-embedded-app": "0.2.97", - "@backstage/test-utils": "1.5.6", - "@backstage/theme": "0.5.6", - "@backstage/types": "1.1.1", - "@backstage/version-bridge": "1.0.8", - "yarn-plugin-backstage": "0.0.1", - "@backstage/plugin-api-docs": "0.11.6", - "@backstage/plugin-api-docs-module-protoc-gen-doc": "0.1.7", - "@backstage/plugin-app-backend": "0.3.68", - "@backstage/plugin-app-node": "0.1.19", - "@backstage/plugin-app-visualizer": "0.1.7", - "@backstage/plugin-auth-backend": "0.22.6", - "@backstage/plugin-auth-backend-module-atlassian-provider": "0.2.0", - "@backstage/plugin-auth-backend-module-aws-alb-provider": "0.1.11", - "@backstage/plugin-auth-backend-module-azure-easyauth-provider": "0.1.2", - "@backstage/plugin-auth-backend-module-bitbucket-provider": "0.1.2", - "@backstage/plugin-auth-backend-module-cloudflare-access-provider": "0.1.2", - "@backstage/plugin-auth-backend-module-gcp-iap-provider": "0.2.14", - "@backstage/plugin-auth-backend-module-github-provider": "0.1.16", - "@backstage/plugin-auth-backend-module-gitlab-provider": "0.1.16", - "@backstage/plugin-auth-backend-module-google-provider": "0.1.16", - "@backstage/plugin-auth-backend-module-guest-provider": "0.1.5", - "@backstage/plugin-auth-backend-module-microsoft-provider": "0.1.14", - "@backstage/plugin-auth-backend-module-oauth2-provider": "0.2.0", - "@backstage/plugin-auth-backend-module-oauth2-proxy-provider": "0.1.12", - "@backstage/plugin-auth-backend-module-oidc-provider": "0.2.0", - "@backstage/plugin-auth-backend-module-okta-provider": "0.0.12", - "@backstage/plugin-auth-backend-module-onelogin-provider": "0.1.0", - "@backstage/plugin-auth-backend-module-pinniped-provider": "0.1.13", - "@backstage/plugin-auth-backend-module-vmware-cloud-provider": "0.2.0", - "@backstage/plugin-auth-node": "0.4.14", - "@backstage/plugin-auth-react": "0.1.3", - "@backstage/plugin-bitbucket-cloud-common": "0.2.20", - "@backstage/plugin-catalog": "1.21.0", - "@backstage/plugin-catalog-backend": "1.23.0", - "@backstage/plugin-catalog-backend-module-aws": "0.3.14", - "@backstage/plugin-catalog-backend-module-azure": "0.1.39", - "@backstage/plugin-catalog-backend-module-backstage-openapi": "0.2.2", - "@backstage/plugin-catalog-backend-module-bitbucket-cloud": "0.2.6", - "@backstage/plugin-catalog-backend-module-bitbucket-server": "0.1.33", - "@backstage/plugin-catalog-backend-module-gcp": "0.1.20", - "@backstage/plugin-catalog-backend-module-gerrit": "0.1.36", - "@backstage/plugin-catalog-backend-module-github": "0.6.2", - "@backstage/plugin-catalog-backend-module-github-org": "0.1.14", - "@backstage/plugin-catalog-backend-module-gitlab": "0.3.18", - "@backstage/plugin-catalog-backend-module-gitlab-org": "0.0.2", - "@backstage/plugin-catalog-backend-module-incremental-ingestion": "0.4.24", - "@backstage/plugin-catalog-backend-module-ldap": "0.6.0", - "@backstage/plugin-catalog-backend-module-msgraph": "0.5.27", - "@backstage/plugin-catalog-backend-module-openapi": "0.1.37", - "@backstage/plugin-catalog-backend-module-puppetdb": "0.1.25", - "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "0.1.17", - "@backstage/plugin-catalog-backend-module-unprocessed": "0.4.6", - "@backstage/plugin-catalog-common": "1.0.24", - "@backstage/plugin-catalog-graph": "0.4.6", - "@backstage/plugin-catalog-import": "0.12.0", - "@backstage/plugin-catalog-node": "1.12.1", - "@backstage/plugin-catalog-react": "1.12.1", - "@backstage/plugin-catalog-unprocessed-entities": "0.2.5", - "@backstage/plugin-catalog-unprocessed-entities-common": "0.0.2", - "@backstage/plugin-config-schema": "0.1.56", - "@backstage/plugin-devtools": "0.1.15", - "@backstage/plugin-devtools-backend": "0.3.5", - "@backstage/plugin-devtools-common": "0.1.10", - "@backstage/plugin-events-backend": "0.3.6", - "@backstage/plugin-events-backend-module-aws-sqs": "0.3.5", - "@backstage/plugin-events-backend-module-azure": "0.2.5", - "@backstage/plugin-events-backend-module-bitbucket-cloud": "0.2.5", - "@backstage/plugin-events-backend-module-gerrit": "0.2.5", - "@backstage/plugin-events-backend-module-github": "0.2.5", - "@backstage/plugin-events-backend-module-gitlab": "0.2.5", - "@backstage/plugin-events-backend-test-utils": "0.1.29", - "@backstage/plugin-events-node": "0.3.5", - "@internal/plugin-todo-list": "1.0.28", - "@internal/plugin-todo-list-backend": "1.0.28", - "@internal/plugin-todo-list-common": "1.0.19", - "@backstage/plugin-home": "0.7.5", - "@backstage/plugin-home-react": "0.1.14", - "@backstage/plugin-kubernetes": "0.11.11", - "@backstage/plugin-kubernetes-backend": "0.18.0", - "@backstage/plugin-kubernetes-cluster": "0.0.12", - "@backstage/plugin-kubernetes-common": "0.8.0", - "@backstage/plugin-kubernetes-node": "0.1.13", - "@backstage/plugin-kubernetes-react": "0.4.0", - "@backstage/plugin-notifications": "0.2.2", - "@backstage/plugin-notifications-backend": "0.3.0", - "@backstage/plugin-notifications-backend-module-email": "0.1.0", - "@backstage/plugin-notifications-common": "0.0.4", - "@backstage/plugin-notifications-node": "0.2.0", - "@backstage/plugin-org": "0.6.26", - "@backstage/plugin-org-react": "0.1.25", - "@backstage/plugin-permission-backend": "0.5.43", - "@backstage/plugin-permission-backend-module-allow-all-policy": "0.1.16", - "@backstage/plugin-permission-common": "0.7.14", - "@backstage/plugin-permission-node": "0.7.30", - "@backstage/plugin-permission-react": "0.4.23", - "@backstage/plugin-proxy-backend": "0.5.0", - "@backstage/plugin-scaffolder": "1.21.0", - "@backstage/plugin-scaffolder-backend": "1.22.9", - "@backstage/plugin-scaffolder-backend-module-azure": "0.1.11", - "@backstage/plugin-scaffolder-backend-module-bitbucket": "0.2.9", - "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "0.1.9", - "@backstage/plugin-scaffolder-backend-module-bitbucket-server": "0.1.9", - "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown": "0.2.20", - "@backstage/plugin-scaffolder-backend-module-cookiecutter": "0.2.43", - "@backstage/plugin-scaffolder-backend-module-gerrit": "0.1.11", - "@backstage/plugin-scaffolder-backend-module-gitea": "0.1.9", - "@backstage/plugin-scaffolder-backend-module-github": "0.3.0", - "@backstage/plugin-scaffolder-backend-module-gitlab": "0.4.1", - "@backstage/plugin-scaffolder-backend-module-notifications": "0.0.2", - "@backstage/plugin-scaffolder-backend-module-rails": "0.4.36", - "@backstage/plugin-scaffolder-backend-module-sentry": "0.1.27", - "@backstage/plugin-scaffolder-backend-module-yeoman": "0.3.2", - "@backstage/plugin-scaffolder-common": "1.5.3", - "@backstage/plugin-scaffolder-node": "0.4.5", - "@backstage/plugin-scaffolder-node-test-utils": "0.1.5", - "@backstage/plugin-scaffolder-react": "1.9.0", - "@backstage/plugin-search": "1.4.12", - "@backstage/plugin-search-backend": "1.5.10", - "@backstage/plugin-search-backend-module-catalog": "0.1.25", - "@backstage/plugin-search-backend-module-elasticsearch": "1.5.0", - "@backstage/plugin-search-backend-module-explore": "0.1.25", - "@backstage/plugin-search-backend-module-pg": "0.5.28", - "@backstage/plugin-search-backend-module-stack-overflow-collator": "0.1.12", - "@backstage/plugin-search-backend-module-techdocs": "0.1.24", - "@backstage/plugin-search-backend-node": "1.2.24", - "@backstage/plugin-search-common": "1.2.12", - "@backstage/plugin-search-react": "1.7.12", - "@backstage/plugin-signals": "0.0.7", - "@backstage/plugin-signals-backend": "0.1.5", - "@backstage/plugin-signals-node": "0.1.5", - "@backstage/plugin-signals-react": "0.0.4", - "@backstage/plugin-techdocs": "1.10.6", - "@backstage/plugin-techdocs-addons-test-utils": "1.0.33", - "@backstage/plugin-techdocs-backend": "1.10.6", - "@backstage/plugin-techdocs-module-addons-contrib": "1.1.11", - "@backstage/plugin-techdocs-node": "1.12.5", - "@backstage/plugin-techdocs-react": "1.2.5", - "@backstage/plugin-user-settings": "0.8.7", - "@backstage/plugin-user-settings-backend": "0.2.18", - "@backstage/plugin-user-settings-common": "0.0.1", - "@backstage/plugin-catalog-backend-module-logs": "0.0.0", - "@backstage/plugin-scaffolder-backend-module-gcp": "0.0.1-next.1" - }, - "changesets": [ - "bright-fireants-sit", - "bright-panthers-leave", - "calm-jeans-ring", - "chilly-roses-trade", - "clever-waves-judge", - "create-app-1719320674", - "curvy-teachers-smell", - "eighty-games-wink", - "eleven-radios-begin", - "fair-fans-flow", - "fair-pillows-know", - "fair-rockets-leave", - "fair-spoons-work", - "famous-dodos-crash", - "fast-pens-smell", - "fifty-pumpkins-smell", - "friendly-bulldogs-pay", - "friendly-experts-fail", - "friendly-masks-type", - "friendly-oranges-greet", - "friendly-stingrays-occur", - "funny-laws-tease", - "gentle-avocados-obey", - "grumpy-wolves-hang", - "heavy-moose-pull", - "honest-pears-run", - "khaki-rivers-obey", - "kind-dancers-boil", - "light-avocados-worry", - "little-games-fail", - "metal-jokes-add", - "metal-parents-brush", - "metal-suits-drum", - "moody-llamas-breathe", - "neat-dingos-tickle", - "new-sheep-arrive", - "poor-cheetahs-raise", - "rare-peas-dream", - "renovate-7b61228", - "renovate-ced359b", - "rich-bears-march", - "selfish-turtles-jog", - "serious-kings-trade", - "sharp-rice-tickle", - "short-flowers-cry", - "shy-hounds-battle", - "silent-experts-move", - "silent-lobsters-tease", - "silent-moose-eat", - "soft-clocks-bake", - "sour-jokes-sneeze", - "spotty-crabs-shop", - "swift-dots-cough", - "ten-dancers-drum", - "ten-nails-hear", - "ten-pots-walk", - "thick-lizards-divide", - "thick-moose-decide", - "three-carpets-smoke", - "tough-lies-mate", - "weak-boats-float", - "yellow-cows-kick", - "young-donuts-swim", - "young-fishes-lie", - "young-houses-unite" - ] -} diff --git a/.changeset/rare-peas-dream.md b/.changeset/rare-peas-dream.md deleted file mode 100644 index 443f8c566d..0000000000 --- a/.changeset/rare-peas-dream.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-defaults': patch ---- - -Repack the package to fix issues with typescript with named exports diff --git a/.changeset/renovate-7b61228.md b/.changeset/renovate-7b61228.md deleted file mode 100644 index 74794c2155..0000000000 --- a/.changeset/renovate-7b61228.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/cli': patch -'@backstage/plugin-scaffolder-backend': patch ---- - -Updated dependency `esbuild` to `^0.21.0`. diff --git a/.changeset/renovate-ced359b.md b/.changeset/renovate-ced359b.md deleted file mode 100644 index 2c100b6e23..0000000000 --- a/.changeset/renovate-ced359b.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@backstage/plugin-home-react': patch -'@backstage/plugin-home': patch -'@backstage/plugin-scaffolder-react': patch -'@backstage/plugin-scaffolder': patch ---- - -Updated dependency `@rjsf/utils` to `5.18.5`. -Updated dependency `@rjsf/core` to `5.18.5`. -Updated dependency `@rjsf/material-ui` to `5.18.5`. -Updated dependency `@rjsf/validator-ajv8` to `5.18.5`. diff --git a/.changeset/rich-bears-march.md b/.changeset/rich-bears-march.md deleted file mode 100644 index ec4a4a9404..0000000000 --- a/.changeset/rich-bears-march.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@techdocs/cli': patch ---- - -Import discovery from backend-defaults instead of backend-common diff --git a/.changeset/selfish-turtles-jog.md b/.changeset/selfish-turtles-jog.md deleted file mode 100644 index 02506ec068..0000000000 --- a/.changeset/selfish-turtles-jog.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': minor -'@backstage/plugin-scaffolder-node': patch ---- - -Add support for `autocomplete` extension point to provide additional `autocomplete` handlers diff --git a/.changeset/serious-kings-trade.md b/.changeset/serious-kings-trade.md deleted file mode 100644 index 826392bf98..0000000000 --- a/.changeset/serious-kings-trade.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-test-utils': patch ---- - -Added mock for the Root Health Service in `mockServices`. diff --git a/.changeset/sharp-rice-tickle.md b/.changeset/sharp-rice-tickle.md deleted file mode 100644 index 6104e11e75..0000000000 --- a/.changeset/sharp-rice-tickle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-react': patch ---- - -Add a namespace label to RolloutDrawer diff --git a/.changeset/short-flowers-cry.md b/.changeset/short-flowers-cry.md deleted file mode 100644 index bf2c354465..0000000000 --- a/.changeset/short-flowers-cry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-github': minor ---- - -Adds support for custom tag policies when creating GitHub environments. diff --git a/.changeset/short-impalas-suffer.md b/.changeset/short-impalas-suffer.md deleted file mode 100644 index 34bc31e85d..0000000000 --- a/.changeset/short-impalas-suffer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-react': patch ---- - -Fix the `HTML` markup of the `FixDialog` component, `ul` and `li` are not allowed inside a `p` tag. diff --git a/.changeset/shy-hounds-battle.md b/.changeset/shy-hounds-battle.md deleted file mode 100644 index bfcf46c076..0000000000 --- a/.changeset/shy-hounds-battle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Fix a few minor issues with the backend template that were causing failing linting checks in the main repo. diff --git a/.changeset/silent-experts-move.md b/.changeset/silent-experts-move.md deleted file mode 100644 index 06441a62c6..0000000000 --- a/.changeset/silent-experts-move.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Subpath export `package.json` should be of a unique name to avoid typescript resolution issues diff --git a/.changeset/silent-lobsters-tease.md b/.changeset/silent-lobsters-tease.md deleted file mode 100644 index 2dea26d8ff..0000000000 --- a/.changeset/silent-lobsters-tease.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -The `backendPlugin` and `backendModule` factory now includes a step for automatically adding the new backend plugin/module to the `index.ts` file of the backend. diff --git a/.changeset/silent-moose-eat.md b/.changeset/silent-moose-eat.md deleted file mode 100644 index bc66f55181..0000000000 --- a/.changeset/silent-moose-eat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Support `catalogFilter` array on `OwnedEntityPicker` diff --git a/.changeset/smooth-pianos-argue.md b/.changeset/smooth-pianos-argue.md deleted file mode 100644 index e7fc66dee4..0000000000 --- a/.changeset/smooth-pianos-argue.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-test-utils': patch ---- - -Updated `startTestBackend` and `ServiceFactoryTester` to only accept plain service factory or backend feature objects, no longer supporting the callback form. This lines up with the changes to `@backstage/backend-plugin-api` and should not require any code changes. diff --git a/.changeset/soft-clocks-bake.md b/.changeset/soft-clocks-bake.md deleted file mode 100644 index 29d7658869..0000000000 --- a/.changeset/soft-clocks-bake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog': patch ---- - -Added small notes to AboutCard to discourage customizability PRs diff --git a/.changeset/sour-jokes-sneeze.md b/.changeset/sour-jokes-sneeze.md deleted file mode 100644 index 5cafaea595..0000000000 --- a/.changeset/sour-jokes-sneeze.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-notifications-backend': patch ---- - -Added an option to filter notifications by topic diff --git a/.changeset/spotty-apricots-tan.md b/.changeset/spotty-apricots-tan.md deleted file mode 100644 index a2be38d775..0000000000 --- a/.changeset/spotty-apricots-tan.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -'@backstage/backend-plugin-api': patch ---- - -Deprecated the ability to define options for service factories through `createServiceFactory`. In the future all service factories will return a plain `ServiceFactory` object, rather than allowing users to pass options to the factory. To allow for customization of a service implementation one can instead export one or a few building blocks that allows for simple re-implementation of the service instead. - -For example, instead of: - -```ts -export const fooServiceFactory = createServiceFactory<FooService>( - (options?: { bar: string }) => ({ - service: fooServiceRef, - deps: { logger: coreServices.logger }, - factory({ logger }) { - return { - // Implementation of the foo service using the `bar` option. - }; - }, - }), -); -``` - -We instead encourage service implementations to provide an easy to use API for re-implementing the service for advanced use-cases: - -```ts -/** @public */ -export class DefaultFooService implements FooService { - static create(options: { bar: string; logger: LoggerService }) { - return new DefaultFooService(options.logger, options.bar ?? 'default'); - } - - private constructor( - private readonly logger: string, - private readonly bar: string, - ) {} - - // The rest of the implementation -} -``` - -A user that wishes to customize the service can then easily do so by defining their own factory: - -```ts -export const customFooServiceFactory = createServiceFactory<FooService>({ - service: fooServiceRef, - deps: { logger: coreServices.logger }, - factory({ logger }) { - return DefaultFooService.create({ logger, bar: 'baz' }); - }, -}); -``` - -This is of course more verbose than the previous solution where the factory could be customized through `fooServiceFactory({ bar: 'baz' })`, but this is a simplified which in practice should be using static configuration instead. - -In cases where the old options patterns significantly improves the usability of the service factory, the old pattern can still be implemented like this: - -```ts -const fooServiceFactoryWithOptions = (options?: { bar: string }) => - createServiceFactory<FooService>({ - service: fooServiceRef, - deps: { logger: coreServices.logger }, - factory({ logger }) { - return { - // Implementation of the foo service using the `bar` option. - }; - }, - }); - -export const fooServiceFactory = Object.assign( - fooServiceFactoryWithOptions, - fooServiceFactoryWithOptions(), -); -``` - -This change is being made because the ability to define an options callback encourages bad design of services factories. When possible, a service should be configurable through static configuration, and the existence of options may discourage that. More importantly though, the existing options do not work well with the dependency injection system of services, which is a problem for callbacks an other more advanced options. This lead to a bad pattern where only a few explicit dependencies where made available in callbacks, rather than providing an API that allowed simple re-implementation of the service with full access to dependency injection. - -A separate benefit of this change is that it simplifies the TypeScript types in a way that allows TypeScript to provide a much better error message when a service factory doesn't properly implement the service interface. diff --git a/.changeset/spotty-crabs-shop.md b/.changeset/spotty-crabs-shop.md deleted file mode 100644 index 6bc1bcfe0c..0000000000 --- a/.changeset/spotty-crabs-shop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-github': patch ---- - -Added action to enable GitHub Pages on a repo diff --git a/.changeset/stale-beds-sneeze.md b/.changeset/stale-beds-sneeze.md deleted file mode 100644 index 695e09a624..0000000000 --- a/.changeset/stale-beds-sneeze.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-node': patch ---- - -Fix issues with Atlassian OAuth provider: retrieve the email and photo that were not in arrays but rather in single props. diff --git a/.changeset/swift-dots-cough.md b/.changeset/swift-dots-cough.md deleted file mode 100644 index 255ee192a0..0000000000 --- a/.changeset/swift-dots-cough.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': minor ---- - -Improve validation error display text in scaffolder diff --git a/.changeset/swift-seals-drive.md b/.changeset/swift-seals-drive.md deleted file mode 100644 index a03f490d3f..0000000000 --- a/.changeset/swift-seals-drive.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-plugin-api': minor ---- - -**BREAKING**: The `PermissionsService` no longer supports passing the deprecated `token` option, and the request options are now required. diff --git a/.changeset/tall-walls-learn.md b/.changeset/tall-walls-learn.md deleted file mode 100644 index d79c439221..0000000000 --- a/.changeset/tall-walls-learn.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@backstage/backend-plugin-api': patch ---- - -All service config types were renamed to option types in order to standardize frontend and backend `create*` function signatures: - -- The `ServiceRefConfig` type was renamed to`ServiceRefOptions`; -- The `RootServiceFactoryConfig` type was renamed to `RootServiceFactoryOptions`; -- The `PluginServiceFactoryConfig` type was renamed to `PluginServiceFactoryOptions` diff --git a/.changeset/ten-dancers-drum.md b/.changeset/ten-dancers-drum.md deleted file mode 100644 index 3f54a7a6b3..0000000000 --- a/.changeset/ten-dancers-drum.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-github': patch ---- - -Fixed issue with octokit call missing owner and repo when creating environment variables and secrets using github:environment:create action diff --git a/.changeset/ten-nails-hear.md b/.changeset/ten-nails-hear.md deleted file mode 100644 index 8d3c4d59c3..0000000000 --- a/.changeset/ten-nails-hear.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-github': patch ---- - -Adds `requireLastPushApproval` input property to configure Branch Protection Settings in `github:publish` action - -Adds `requireLastPushApproval` input property to configure Branch Protection Settings in `github:repo:push` action diff --git a/.changeset/ten-pots-walk.md b/.changeset/ten-pots-walk.md deleted file mode 100644 index cf540fd0e2..0000000000 --- a/.changeset/ten-pots-walk.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-logs': patch ---- - -Creates a new module to make logging catalog errors simple. This module subscribes to catalog events and logs them. - -See [Backstage documentation](https://backstage.io/docs/features/software-catalog/configuration#subscribing-to-catalog-errors) for details on how to install -and configure the plugin. diff --git a/.changeset/tender-turkeys-begin.md b/.changeset/tender-turkeys-begin.md deleted file mode 100644 index 26e376cecf..0000000000 --- a/.changeset/tender-turkeys-begin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-permission-react': patch ---- - -Improve API Reference documentation diff --git a/.changeset/thick-lizards-divide.md b/.changeset/thick-lizards-divide.md deleted file mode 100644 index 84c1ab311a..0000000000 --- a/.changeset/thick-lizards-divide.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/backend-app-api': patch -'@backstage/backend-common': patch ---- - -Fixing exporting of classes properly from new packages diff --git a/.changeset/thick-moose-decide.md b/.changeset/thick-moose-decide.md deleted file mode 100644 index 194932979d..0000000000 --- a/.changeset/thick-moose-decide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search': patch ---- - -Update deps in search api extension to include fetch api diff --git a/.changeset/three-carpets-smoke.md b/.changeset/three-carpets-smoke.md deleted file mode 100644 index ab6d857f7d..0000000000 --- a/.changeset/three-carpets-smoke.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-gitlab': patch ---- - -Added support for passing `variables` to `gitlab:pipeline:trigger` diff --git a/.changeset/three-lizards-crash.md b/.changeset/three-lizards-crash.md deleted file mode 100644 index 5dffed0f3b..0000000000 --- a/.changeset/three-lizards-crash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-app-api': patch ---- - -The ability to install backend features in callback form (`() => BackendFeature`) has been deprecated. This typically means that you need to update the installed features to use the latest version of `@backstage/backend-plugin-api`. If the feature is from a third-party package, please reach out to the package maintainer to update it. diff --git a/.changeset/tiny-pianos-work.md b/.changeset/tiny-pianos-work.md deleted file mode 100644 index 033e8272e5..0000000000 --- a/.changeset/tiny-pianos-work.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search-backend': patch ---- - -The `AuthorizedSearchEngine` will now ignore the deprecated `token` option, and treat it as an unauthorized request. This will not have any effect in practice, since credentials are always provided by the router. diff --git a/.changeset/tiny-schools-draw.md b/.changeset/tiny-schools-draw.md deleted file mode 100644 index 2042f13fac..0000000000 --- a/.changeset/tiny-schools-draw.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/backend-test-utils': patch -'@backstage/frontend-test-utils': patch -'@backstage/test-utils': patch ---- - -Rename frontend and backend `setupRequestMockHandlers` methods to `registerMswTestHooks`. diff --git a/.changeset/tough-lies-mate.md b/.changeset/tough-lies-mate.md deleted file mode 100644 index 99edcf3616..0000000000 --- a/.changeset/tough-lies-mate.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-gcp': minor -'@backstage/plugin-scaffolder-backend': minor -'@backstage/plugin-scaffolder-node': patch ---- - -Serialization of the scaffolder workspace into GCP bucket diff --git a/.changeset/twenty-buses-carry.md b/.changeset/twenty-buses-carry.md deleted file mode 100644 index 00347e60d8..0000000000 --- a/.changeset/twenty-buses-carry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Added the Postgres Search Engine to the `create-app` template diff --git a/.changeset/weak-boats-float.md b/.changeset/weak-boats-float.md deleted file mode 100644 index 4fe6fe73a0..0000000000 --- a/.changeset/weak-boats-float.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': minor -'@backstage/backend-test-utils': patch -'@backstage/backend-defaults': patch -'@backstage/backend-common': patch ---- - -bumped better-sqlite3 from ^9.0.0 to ^11.0.0 diff --git a/.changeset/weak-emus-doubt.md b/.changeset/weak-emus-doubt.md deleted file mode 100644 index cd3b4a836b..0000000000 --- a/.changeset/weak-emus-doubt.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-notifications-backend-module-email': patch -'@backstage/plugin-notifications-common': patch -'@backstage/plugin-notifications-node': patch ---- - -Move notification processor filter parsing to common package diff --git a/.changeset/wet-rivers-travel.md b/.changeset/wet-rivers-travel.md deleted file mode 100644 index 1778a3db23..0000000000 --- a/.changeset/wet-rivers-travel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-defaults': patch ---- - -Refactor of `rootConfigServiceFactory` to allow it to be constructed with options, but without declaring options via `createServiceFactory`. diff --git a/.changeset/wicked-impalas-explode.md b/.changeset/wicked-impalas-explode.md deleted file mode 100644 index f8a01bc36e..0000000000 --- a/.changeset/wicked-impalas-explode.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-test-utils': patch ---- - -Internal refactor of `mockServices.httpAuth.factory` to allow it to still be constructed with options, but without declaring options via `createServiceFactory`. diff --git a/.changeset/witty-keys-share.md b/.changeset/witty-keys-share.md deleted file mode 100644 index 0ef89e56e2..0000000000 --- a/.changeset/witty-keys-share.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': patch ---- - -disables rendering of output box if no output is returned diff --git a/.changeset/yellow-cows-kick.md b/.changeset/yellow-cows-kick.md deleted file mode 100644 index 93c7e1cff1..0000000000 --- a/.changeset/yellow-cows-kick.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-node-test-utils': patch ---- - -Filename and imports correction for mockActionContext.ts diff --git a/.changeset/young-donuts-swim.md b/.changeset/young-donuts-swim.md deleted file mode 100644 index edd854f6dc..0000000000 --- a/.changeset/young-donuts-swim.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': minor -'@backstage/plugin-scaffolder': minor ---- - -Add support for `bitbucketCloud` autocomplete in `RepoUrlPicker` diff --git a/.changeset/young-fishes-lie.md b/.changeset/young-fishes-lie.md deleted file mode 100644 index 769d046375..0000000000 --- a/.changeset/young-fishes-lie.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Fix user entity not being fetched for scaffolder dry runner diff --git a/.changeset/young-houses-unite.md b/.changeset/young-houses-unite.md deleted file mode 100644 index 47ffe43c21..0000000000 --- a/.changeset/young-houses-unite.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-app-api': patch ---- - -Fixing issue with `MiddlewareFactory` deprecation wrapping diff --git a/docs/releases/v1.29.0-changelog.md b/docs/releases/v1.29.0-changelog.md new file mode 100644 index 0000000000..86cb84d1f1 --- /dev/null +++ b/docs/releases/v1.29.0-changelog.md @@ -0,0 +1,2495 @@ +# Release v1.29.0 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.29.0](https://backstage.github.io/upgrade-helper/?to=1.29.0) + +## @backstage/backend-app-api@0.8.0 + +### Minor Changes + +- 1cb84d7: **BREAKING**: Removed the depreacted `getPath` option from `httpRouterServiceFactory`, as well as the `HttpRouterFactoryOptions` type. +- f691c9b: **BREAKING**: Removed the ability to pass callback-form service factories through the `defaultServiceFactories` option of `createSpecializedBackend`. This is an immediate breaking change as usage of this function is expected to be very rare. + +### Patch Changes + +- 2f99178: The `ServiceFactoryTest.get` method was deprecated and the `ServiceFactoryTest.getSubject` should be used instead. The `getSubject` method has the same behavior, but has a better method name to indicate that the service instance returned is the subject currently being tested. +- b05e1e1: Service factories exported by this package have been updated to use the new service factory format that doesn't use a callback. +- 617a7d2: Internal refactor that avoids the use of service factory options. +- b60db08: Fixing exporting of classes properly from new packages +- 18b96b1: The ability to install backend features in callback form (`() => BackendFeature`) has been deprecated. This typically means that you need to update the installed features to use the latest version of `@backstage/backend-plugin-api`. If the feature is from a third-party package, please reach out to the package maintainer to update it. +- a63c4b6: Fixing issue with `MiddlewareFactory` deprecation wrapping +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/cli-node@0.2.7 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/config-loader@1.8.1 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/backend-defaults@0.4.0 + +### Minor Changes + +- 1cb84d7: **BREAKING**: Removed the depreacted `getPath` option from `httpRouterServiceFactory`, as well as the `HttpRouterFactoryOptions` type. + +### Patch Changes + +- 53ced70: Added a new Root Health Service which adds new endpoints for health checks. +- 2f99178: The `ServiceFactoryTest.get` method was deprecated and the `ServiceFactoryTest.getSubject` should be used instead. The `getSubject` method has the same behavior, but has a better method name to indicate that the service instance returned is the subject currently being tested. +- 083eaf9: Fix bug where ISO durations could no longer be used for schedules +- b05e1e1: Service factories exported by this package have been updated to use the new service factory format that doesn't use a callback. +- 419f387: Refactor of `rootHttpRouterServiceFactory` to allow it to be constructed with options, but without declaring options via `createServiceFactory`. +- cb14a05: Repack the package to fix issues with typescript with named exports +- b9ed1bb: bumped better-sqlite3 from ^9.0.0 to ^11.0.0 +- e28af58: Refactor of `rootConfigServiceFactory` to allow it to be constructed with options, but without declaring options via `createServiceFactory`. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-app-api@0.8.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/integration@1.13.0 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/config-loader@1.8.1 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + +## @backstage/backend-plugin-api@0.7.0 + +### Minor Changes + +- 36f91e8: **BREAKING**: The `PermissionsService` no longer supports passing the deprecated `token` option, and the request options are now required. + +### Patch Changes + +- 53ced70: Added a new Root Health Service which adds new endpoints for health checks. + +- 083eaf9: Fix bug where ISO durations could no longer be used for schedules + +- 062c01c: Deprecated the ability to define options for service factories through `createServiceFactory`. In the future all service factories will return a plain `ServiceFactory` object, rather than allowing users to pass options to the factory. To allow for customization of a service implementation one can instead export one or a few building blocks that allows for simple re-implementation of the service instead. + + For example, instead of: + + ```ts + export const fooServiceFactory = createServiceFactory<FooService>( + (options?: { bar: string }) => ({ + service: fooServiceRef, + deps: { logger: coreServices.logger }, + factory({ logger }) { + return { + // Implementation of the foo service using the `bar` option. + }; + }, + }), + ); + ``` + + We instead encourage service implementations to provide an easy to use API for re-implementing the service for advanced use-cases: + + ```ts + /** @public */ + export class DefaultFooService implements FooService { + static create(options: { bar: string; logger: LoggerService }) { + return new DefaultFooService(options.logger, options.bar ?? 'default'); + } + + private constructor( + private readonly logger: string, + private readonly bar: string, + ) {} + + // The rest of the implementation + } + ``` + + A user that wishes to customize the service can then easily do so by defining their own factory: + + ```ts + export const customFooServiceFactory = createServiceFactory<FooService>({ + service: fooServiceRef, + deps: { logger: coreServices.logger }, + factory({ logger }) { + return DefaultFooService.create({ logger, bar: 'baz' }); + }, + }); + ``` + + This is of course more verbose than the previous solution where the factory could be customized through `fooServiceFactory({ bar: 'baz' })`, but this is a simplified which in practice should be using static configuration instead. + + In cases where the old options patterns significantly improves the usability of the service factory, the old pattern can still be implemented like this: + + ```ts + const fooServiceFactoryWithOptions = (options?: { bar: string }) => + createServiceFactory<FooService>({ + service: fooServiceRef, + deps: { logger: coreServices.logger }, + factory({ logger }) { + return { + // Implementation of the foo service using the `bar` option. + }; + }, + }); + + export const fooServiceFactory = Object.assign( + fooServiceFactoryWithOptions, + fooServiceFactoryWithOptions(), + ); + ``` + + This change is being made because the ability to define an options callback encourages bad design of services factories. When possible, a service should be configurable through static configuration, and the existence of options may discourage that. More importantly though, the existing options do not work well with the dependency injection system of services, which is a problem for callbacks an other more advanced options. This lead to a bad pattern where only a few explicit dependencies where made available in callbacks, rather than providing an API that allowed simple re-implementation of the service with full access to dependency injection. + + A separate benefit of this change is that it simplifies the TypeScript types in a way that allows TypeScript to provide a much better error message when a service factory doesn't properly implement the service interface. + +- fe47a3e: All service config types were renamed to option types in order to standardize frontend and backend `create*` function signatures: + + - The `ServiceRefConfig` type was renamed to`ServiceRefOptions`; + - The `RootServiceFactoryConfig` type was renamed to `RootServiceFactoryOptions`; + - The `PluginServiceFactoryConfig` type was renamed to `PluginServiceFactoryOptions` + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/core-app-api@1.14.0 + +### Minor Changes + +- d3c39fc: Allow for the disabling of external routes through config, which was rendered impossible after the introduction of default targets. + + ```yaml + app: + routes: + bindings: + # This has the effect of removing the button for registering new + # catalog entities in the scaffolder template list view + scaffolder.registerComponent: false + ``` + +### Patch Changes + +- db2e2d5: Updated config schema to support app.routes.bindings +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/integration@1.13.0 + +### Minor Changes + +- b5deed0: Add support for `token` for `bitbucketCloud` integration + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend@1.24.0 + +### Minor Changes + +- b9ed1bb: bumped better-sqlite3 from ^9.0.0 to ^11.0.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/integration@1.13.0 + - @backstage/plugin-events-node@0.3.8 + - @backstage/backend-openapi-utils@0.1.15 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-search-backend-module-catalog@0.1.28 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend-module-ldap@0.7.0 + +### Minor Changes + +- cb32ca7: **BREAKING**: `readLdapOrg` and the `LdapProviderConfig` type now always accept arrays of user and group configs, not just single items. + + Added support for single ldap catalog provider to provide list and undefined user and group bindings next to standard single one. + +### Patch Changes + +- 083eaf9: Fix bug where ISO durations could no longer be used for schedules +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-permission-common@0.8.0 + +### Minor Changes + +- f4085b8: **BREAKING**: Removed the deprecated and unused `token` option from `EvaluatorRequestOptions`. The `PermissionsClient` now has its own `PermissionClientRequestOptions` type that declares the `token` option instead. + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-permission-node@0.8.0 + +### Minor Changes + +- 36f91e8: **BREAKING**: Updated the `ServerPermissionClient` to match the new `PermissionsService` interface, where the deprecated `token` option has been removed and the options are now required. + +### Patch Changes + +- ed10fd2: The `PermissionPolicy` interface has been updated to align with the recent changes to the Backstage auth system. The second argument to the `handle` method is now of the new `PolicyQueryUser` type. This type maintains the old fields from the `BackstageIdentityResponse`, which are now all deprecated. Instead, two new fields have been added, which allows access to the same information: + + - `credentials` - A `BackstageCredentials` object, which is useful for making requests to other services on behalf of the user as part of evaluating the policy. This replaces the deprecated `token` field. See the [Auth Service documentation](https://backstage.io/docs/backend-system/core-services/auth#creating-request-tokens) for information about how to create a token using these credentials. + - `info` - A `BackstageUserInfo` object, which contains the same information as the deprecated `identity`, except for the `type` field that was redundant. + + Most existing policies can be updated by replacing the `BackstageIdentityResponse` type with `PolicyQueryUser`, which is exported from `@backstage/plugin-permission-node`, as well as replacing any occurrences of `user?.identity` with `user?.info`. + +- 28b2cfb: Fix invalid cross-reference in API Reference docs + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder@1.23.0 + +### Minor Changes + +- 52b6db0: Use virtualization with `EntityPicker` as done earlier with `MultiEntityPicker` to fix performance issues with large data sets. `VirtualizedListbox` extracted into reusable component. +- 3583ce5: Use virtualization with `MultiEntityPicker`. Fixes performance issues with large data sets. +- b5deed0: Add support for `bitbucketCloud` autocomplete in `RepoUrlPicker` + +### Patch Changes + +- 4d7e11f: enable resizing of the task log stream viewer +- 661b354: Fixed a bug where the `RepoUrlPicker` would still require the `owner` field for `azure` +- cc81579: Updated dependency `@rjsf/utils` to `5.18.5`. + Updated dependency `@rjsf/core` to `5.18.5`. + Updated dependency `@rjsf/material-ui` to `5.18.5`. + Updated dependency `@rjsf/validator-ajv8` to `5.18.5`. +- 89c44b3: Support `catalogFilter` array on `OwnedEntityPicker` +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/integration@1.13.0 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-scaffolder-react@1.10.0 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-scaffolder-common@1.5.4 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/integration-react@1.1.29 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend@1.23.0 + +### Minor Changes + +- b5deed0: Add support for `autocomplete` extension point to provide additional `autocomplete` handlers +- 0b52438: Serialization of the scaffolder workspace into GCP bucket + +### Patch Changes + +- b9451dd: Updated `catalog:write` scaffolder action to show correct file path location in log message +- ff1bb4c: Added a documentation how to use checkpoints +- da90cce: Updated dependency `esbuild` to `^0.21.0`. +- 62d1fe3: Fix user entity not being fetched for scaffolder dry runner +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-scaffolder-backend-module-github@0.4.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.4.4 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.12 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.14 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.12 + - @backstage/plugin-bitbucket-cloud-common@0.2.21 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.20 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.12 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.14 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.12 + - @backstage/plugin-scaffolder-common@1.5.4 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.1.0 + +### Minor Changes + +- 0b52438: Serialization of the scaffolder workspace into GCP bucket + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-github@0.4.0 + +### Minor Changes + +- 70c4b36: Adds support for custom tag policies when creating GitHub environments. + +### Patch Changes + +- ccfc9d1: Fixed bug resulting from missing required owner and repo arguments in `getEnvironmentPublicKey` in action `github:environment:create`. + + Adding environment secrets now works as expected. + +- 141f366: Added action to enable GitHub Pages on a repo + +- 4410fed: Fixed issue with octokit call missing owner and repo when creating environment variables and secrets using github:environment:create action + +- dfaa28d: Adds `requireLastPushApproval` input property to configure Branch Protection Settings in `github:publish` action + + Adds `requireLastPushApproval` input property to configure Branch Protection Settings in `github:repo:push` action + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-react@1.10.0 + +### Minor Changes + +- 354e68c: Improve validation error display text in scaffolder +- b5deed0: Add support for `bitbucketCloud` autocomplete in `RepoUrlPicker` + +### Patch Changes + +- cc81579: Updated dependency `@rjsf/utils` to `5.18.5`. + Updated dependency `@rjsf/core` to `5.18.5`. + Updated dependency `@rjsf/material-ui` to `5.18.5`. + Updated dependency `@rjsf/validator-ajv8` to `5.18.5`. +- 4d7e11f: disables rendering of output box if no output is returned +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-scaffolder-common@1.5.4 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/app-defaults@1.5.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/core-app-api@1.14.0 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + +## @backstage/backend-common@0.23.3 + +### Patch Changes + +- 8c09c97: Deprecate legacy status check factory, handler and types. +- d228862: Update default backend plugin created by the cli to use non-deprecated error handling middleware +- c964a3d: Add dependencies that are needed by cross-imports from backend-defaults +- b60db08: Fixing exporting of classes properly from new packages +- b9ed1bb: bumped better-sqlite3 from ^9.0.0 to ^11.0.0 +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/integration@1.13.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/config-loader@1.8.1 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + +## @backstage/backend-dynamic-feature-service@0.2.15 + +### Patch Changes + +- b05e1e1: Service factories exported by this package have been updated to use the new service factory format that doesn't use a callback. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-app-api@0.8.0 + - @backstage/backend-common@0.23.3 + - @backstage/cli-node@0.2.7 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-catalog-backend@1.24.0 + - @backstage/plugin-app-node@0.1.22 + - @backstage/plugin-events-backend@0.3.9 + - @backstage/plugin-search-backend-node@1.2.27 + - @backstage/config-loader@1.8.1 + - @backstage/plugin-search-common@1.2.13 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/backend-openapi-utils@0.1.15 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/errors@1.2.4 + +## @backstage/backend-tasks@0.5.27 + +### Patch Changes + +- 083eaf9: Fix bug where ISO durations could no longer be used for schedules +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/backend-test-utils@0.4.4 + +### Patch Changes + +- 2f99178: The `ServiceFactoryTest.get` method was deprecated and the `ServiceFactoryTest.getSubject` should be used instead. The `getSubject` method has the same behavior, but has a better method name to indicate that the service instance returned is the subject currently being tested. +- edf5cc3: The function `isDockerDisabledForTests` is deprecated and will no longer be exported in the near future as it should only be used internally. +- b05e1e1: Service factories exported by this package have been updated to use the new service factory format that doesn't use a callback. +- fce7887: Added mock for the Root Health Service in `mockServices`. +- 906c817: Updated `startTestBackend` and `ServiceFactoryTester` to only accept plain service factory or backend feature objects, no longer supporting the callback form. This lines up with the changes to `@backstage/backend-plugin-api` and should not require any code changes. +- 95a3a0b: Rename frontend and backend `setupRequestMockHandlers` methods to `registerMswTestHooks`. +- b9ed1bb: bumped better-sqlite3 from ^9.0.0 to ^11.0.0 +- 98ccf00: Internal refactor of `mockServices.httpAuth.factory` to allow it to still be constructed with options, but without declaring options via `createServiceFactory`. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-defaults@0.4.0 + - @backstage/backend-app-api@0.8.0 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/cli@0.26.11 + +### Patch Changes + +- 133464c: Added experimental support for dynamic frontend plugin builds, enabled via setting `EXPERIMENTAL_MODULE_FEDERATION` for the app build, and using the `frontend-dynamic-container` package role to create a container. Both of these are experimental and will change in the future. +- e2e320c: - remove unused dependencies `winston` and `yn` from the template of backend plugins; + - update `msw` to version `2.3.1` in the template of backend plugins; + starting with v1 and switching later to v2 is tedious and not straight forward; it's easier to start with v2; +- 0540c5a: Updated the scaffolding output message for `plugin-common` in `backstage-cli`. Now, when executing `backstage-cli new` to create a new `plugin-common` package, the output message accurately reflects the action by displaying `Creating common plugin package...` instead of the previous, less accurate `Creating backend plugin...`. +- 7652db4: Only bootstrap global-agent if it's actually being used +- f0c0039: Fix issue with CLI that was preventing upgrading from 1.28 +- d228862: Update default backend plugin created by the cli to use non-deprecated error handling middleware +- da90cce: Updated dependency `esbuild` to `^0.21.0`. +- a60d73b: Fix a few minor issues with the backend template that were causing failing linting checks in the main repo. +- 0510d98: Subpath export `package.json` should be of a unique name to avoid typescript resolution issues +- 4baac0c: The `backendPlugin` and `backendModule` factory now includes a step for automatically adding the new backend plugin/module to the `index.ts` file of the backend. +- Updated dependencies + - @backstage/cli-node@0.2.7 + - @backstage/integration@1.13.0 + - @backstage/config-loader@1.8.1 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/eslint-plugin@0.1.8 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/cli-node@0.2.7 + +### Patch Changes + +- 133464c: Added internal metadata for the new experimental `frontend-dynamic-container` role. +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/core-compat-api@0.2.7 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/version-bridge@1.0.8 + +## @backstage/core-components@0.14.9 + +### Patch Changes + +- d4ffdbb: Fixed bug where `<Select>` component with empty string as placeholder gave an error +- 99d672d: Modified the `Select` component to take in a `data-testid` parameter ensuring backwards compatibility with default value corresponding to previously hardcoded `data-testid` of "select". +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/version-bridge@1.0.8 + +## @backstage/create-app@0.5.17 + +### Patch Changes + +- 780d994: Added `MyGroupsSidebarItem` to the sidebar in the `create-app` template +- f03d12a: Bumped create-app version. +- e90a2cd: Added the Catalog logs module to the `create-app` template +- 3ac2a6a: Added the Postgres Search Engine to the `create-app` template +- Updated dependencies + - @backstage/cli-common@0.1.14 + +## @backstage/dev-utils@1.0.35 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/core-app-api@1.14.0 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/app-defaults@1.5.8 + - @backstage/integration-react@1.1.29 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + +## @backstage/frontend-app-api@0.7.3 + +### Patch Changes + +- d3c39fc: Allow for the disabling of external routes through config, which was rendered impossible after the introduction of default targets. + + ```yaml + app: + routes: + bindings: + # This has the effect of removing the button for registering new + # catalog entities in the scaffolder template list view + scaffolder.registerComponent: false + ``` + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/core-app-api@1.14.0 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/frontend-plugin-api@0.6.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/frontend-test-utils@0.1.10 + +### Patch Changes + +- 95a3a0b: Rename frontend and backend `setupRequestMockHandlers` methods to `registerMswTestHooks`. +- Updated dependencies + - @backstage/frontend-app-api@0.7.3 + - @backstage/test-utils@1.5.8 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/types@1.1.1 + +## @backstage/integration-react@1.1.29 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.13.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/repo-tools@0.9.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/cli-node@0.2.7 + - @backstage/config-loader@1.8.1 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + +## @techdocs/cli@1.8.16 + +### Patch Changes + +- c964a3d: Import discovery from backend-defaults instead of backend-common +- Updated dependencies + - @backstage/backend-defaults@0.4.0 + - @backstage/plugin-techdocs-node@1.12.8 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## @backstage/test-utils@1.5.8 + +### Patch Changes + +- 95a3a0b: Rename frontend and backend `setupRequestMockHandlers` methods to `registerMswTestHooks`. +- Updated dependencies + - @backstage/plugin-permission-common@0.8.0 + - @backstage/core-app-api@1.14.0 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + +## @backstage/plugin-api-docs@0.11.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-catalog@1.21.1 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/catalog-model@1.5.0 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-app-backend@0.3.71 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-app-node@0.1.22 + - @backstage/config-loader@1.8.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-app-node@0.1.22 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/config-loader@1.8.1 + +## @backstage/plugin-app-visualizer@0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-auth-backend@0.22.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.2.3 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.14 + - @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.1.5 + - @backstage/plugin-auth-backend-module-bitbucket-provider@0.1.5 + - @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.1.5 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.17 + - @backstage/plugin-auth-backend-module-github-provider@0.1.19 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.19 + - @backstage/plugin-auth-backend-module-google-provider@0.1.19 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.1.17 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.2.3 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.15 + - @backstage/plugin-auth-backend-module-oidc-provider@0.2.3 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.15 + - @backstage/plugin-auth-backend-module-onelogin-provider@0.1.3 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.2.3 + +### Patch Changes + +- b9832ae: Fix several issues with the Atlassian auth provider (type definition, profile url, profile transformation, scopes) +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-auth-backend@0.22.9 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.17 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.1.19 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.1.19 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + +## @backstage/plugin-auth-backend-module-google-provider@0.1.19 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + +## @backstage/plugin-auth-backend-module-guest-provider@0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.1.17 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.2.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.15 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.2.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-auth-backend@0.22.9 + +## @backstage/plugin-auth-backend-module-okta-provider@0.0.15 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.1.16 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/config@1.2.0 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.2.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/catalog-model@1.5.0 + +## @backstage/plugin-auth-node@0.4.17 + +### Patch Changes + +- 55c1a72: Fix issues with Atlassian OAuth provider: retrieve the email and photo that were not in arrays but rather in single props. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-react@0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + +## @backstage/plugin-bitbucket-cloud-common@0.2.21 + +### Patch Changes + +- b5deed0: Add support for `autocomplete` handler to provide autocomplete options for `RepoUrlPicker` +- Updated dependencies + - @backstage/integration@1.13.0 + +## @backstage/plugin-catalog@1.21.1 + +### Patch Changes + +- 06c0956: Support i18n for catalog and catalog-react plugins +- d133eaa: Added small notes to AboutCard to discourage customizability PRs +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-scaffolder-common@1.5.4 + - @backstage/plugin-search-common@1.2.13 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/integration-react@1.1.29 + - @backstage/plugin-search-react@1.7.13 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend-module-aws@0.3.17 + +### Patch Changes + +- 4afa050: Export `defaultEksClusterEntityTransformer` to allow library consumers to layer additional changes on top of the default transformer. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/integration@1.13.0 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-kubernetes-common@0.8.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + +## @backstage/plugin-catalog-backend-module-azure@0.1.42 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/integration@1.13.0 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/config@1.2.0 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.2.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-tasks@0.5.27 + - @backstage/backend-openapi-utils@0.1.15 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.2.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/integration@1.13.0 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-bitbucket-cloud-common@0.2.21 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.36 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/integration@1.13.0 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-gcp@0.1.23 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-kubernetes-common@0.8.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.39 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/integration@1.13.0 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-github@0.6.5 + +### Patch Changes + +- 9112efc: Adds support for `repository` events. + + The provider adds a subscription to the topic `github.repository`. + + Hereby, it supports events of type `repository` with actions + + - `archived` + - `deleted` + - `edited` + - `renamed` + - `transferred` + - `unarchived` + + Actions skipped as they don't require entity changes: + + - `created` + - `privatized` + - `publicized` + + If the config option `validateLocationsExist` is enabled, an API request + is necessary and will be executed. + This affects the actions `renamed`, `transferred`, and `unarchive` + of event type `repository`. + + Catalog entities related to the `GithubEntityProvider` instance will be adjusted + according to action and its meaning for them. + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/integration@1.13.0 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-catalog-backend@1.24.0 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-catalog-backend-module-github-org@0.1.17 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-catalog-backend-module-github@0.6.5 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/config@1.2.0 + +## @backstage/plugin-catalog-backend-module-gitlab@0.3.21 + +### Patch Changes + +- 8db30ad: The Gitlab configuration supports an additional optional boolean key `catalog.providers.gitlab.<your-org>.restrictUsersToGroup`. Setting this to `true` will make Backstage only import users from the group defined in the `group` key, instead of all users in the organisation (self-hosted) or of the root group (SaaS). It will default to false, keeping the original implementation intact, when not explicitly set. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/integration@1.13.0 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.0.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-catalog-backend-module-gitlab@0.3.21 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-catalog-node@1.12.4 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.4.27 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-catalog-backend@1.24.0 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-logs@0.0.1 + +### Patch Changes + +- 97caf55: Creates a new module to make logging catalog errors simple. This module subscribes to catalog events and logs them. + + See [Backstage documentation](https://backstage.io/docs/features/software-catalog/configuration#subscribing-to-catalog-errors) for details on how to install + and configure the plugin. + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-catalog-backend@1.24.0 + +## @backstage/plugin-catalog-backend-module-msgraph@0.5.30 + +### Patch Changes + +- f7bdcea: Adds a dynamic provider for the plugin-catalog-backend-module-msgraph. Configuration is now runtime configurable through the ProviderConfigTransformer. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.40 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/integration@1.13.0 + - @backstage/plugin-catalog-backend@1.24.0 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.1.28 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.20 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-scaffolder-common@1.5.4 + - @backstage/catalog-model@1.5.0 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.4.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.3 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-common@1.0.25 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-search-common@1.2.13 + - @backstage/catalog-model@1.5.0 + +## @backstage/plugin-catalog-graph@0.4.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-import@0.12.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/integration@1.13.0 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/integration-react@1.1.29 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-node@1.12.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-react@1.12.2 + +### Patch Changes + +- 06c0956: Support i18n for catalog and catalog-react plugins +- 2030962: Make EntityOwnerPicker display metadata.title or spec.profile.displayName for mode=only-owners instead of metadata.name +- Updated dependencies + - @backstage/plugin-permission-common@0.8.0 + - @backstage/core-components@0.14.9 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/integration-react@1.1.29 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.6 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-unprocessed-entities-common@0.0.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.0 + +## @backstage/plugin-config-schema@0.1.57 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-devtools@0.1.16 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-devtools-common@0.1.11 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + +## @backstage/plugin-devtools-backend@0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/config-loader@1.8.1 + - @backstage/plugin-devtools-common@0.1.11 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-devtools-common@0.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-events-backend@0.3.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-events-node@0.3.8 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-module-aws-sqs@0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-events-node@0.3.8 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-events-backend-module-azure@0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-events-node@0.3.8 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-events-node@0.3.8 + +## @backstage/plugin-events-backend-module-gerrit@0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-events-node@0.3.8 + +## @backstage/plugin-events-backend-module-github@0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-events-node@0.3.8 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-module-gitlab@0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-events-node@0.3.8 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-test-utils@0.1.32 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.8 + +## @backstage/plugin-events-node@0.3.8 + +### Patch Changes + +- b05e1e1: Service factories exported by this package have been updated to use the new service factory format that doesn't use a callback. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + +## @backstage/plugin-home@0.7.7 + +### Patch Changes + +- cc81579: Updated dependency `@rjsf/utils` to `5.18.5`. + Updated dependency `@rjsf/core` to `5.18.5`. + Updated dependency `@rjsf/material-ui` to `5.18.5`. + Updated dependency `@rjsf/validator-ajv8` to `5.18.5`. +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/core-app-api@1.14.0 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-home-react@0.1.15 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + +## @backstage/plugin-home-react@0.1.15 + +### Patch Changes + +- cc81579: Updated dependency `@rjsf/utils` to `5.18.5`. + Updated dependency `@rjsf/core` to `5.18.5`. + Updated dependency `@rjsf/material-ui` to `5.18.5`. + Updated dependency `@rjsf/validator-ajv8` to `5.18.5`. +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-kubernetes@0.11.12 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-kubernetes-react@0.4.1 + - @backstage/plugin-kubernetes-common@0.8.1 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-kubernetes-backend@0.18.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-kubernetes-node@0.1.16 + - @backstage/plugin-kubernetes-common@0.8.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + +## @backstage/plugin-kubernetes-cluster@0.0.13 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-kubernetes-react@0.4.1 + - @backstage/plugin-kubernetes-common@0.8.1 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-kubernetes-common@0.8.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.0 + - @backstage/catalog-model@1.5.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-kubernetes-node@0.1.16 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-kubernetes-common@0.8.1 + - @backstage/catalog-model@1.5.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-kubernetes-react@0.4.1 + +### Patch Changes + +- e3cb6ab: Add a namespace label to RolloutDrawer +- 2414d86: Fix the `HTML` markup of the `FixDialog` component, `ul` and `li` are not allowed inside a `p` tag. +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-kubernetes-common@0.8.1 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-notifications@0.2.3 + +### Patch Changes + +- 3bf0697: The toolbar on the Notifications page is hidden when there are no listed notifications. +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.4 + +## @backstage/plugin-notifications-backend@0.3.3 + +### Patch Changes + +- d7b8ca5: Added an option to filter notifications by topic +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.3 + - @backstage/plugin-signals-node@0.1.8 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-notifications-backend-module-email@0.1.3 + +### Patch Changes + +- 4e4ef2b: Move notification processor filter parsing to common package +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + +## @backstage/plugin-notifications-common@0.0.5 + +### Patch Changes + +- 4e4ef2b: Move notification processor filter parsing to common package +- Updated dependencies + - @backstage/config@1.2.0 + +## @backstage/plugin-notifications-node@0.2.3 + +### Patch Changes + +- 4e4ef2b: Move notification processor filter parsing to common package +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-signals-node@0.1.8 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + +## @backstage/plugin-org@0.6.27 + +### Patch Changes + +- 5132d28: The `useGetEntities` hook could result in requests to `/api/catalog/entities` where the headers exceed the default maximum Node.js header size of 16KB. The hook logic has been adjusted to batch the requests. + +- c307ef4: Added `relationType` property to EntityMembersListCard component that allows for display users related to a group via some other relationship aside from `memberOf`. + + Also, as a side effect, the `relationsType` property has been deprecated in favor of a more accurately named `relationAggregation` property. + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/catalog-model@1.5.0 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-org-react@0.1.26 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-permission-backend@0.5.46 + +### Patch Changes + +- ed10fd2: The `PermissionPolicy` interface has been updated to align with the recent changes to the Backstage auth system. The second argument to the `handle` method is now of the new `PolicyQueryUser` type. This type maintains the old fields from the `BackstageIdentityResponse`, which are now all deprecated. Instead, two new fields have been added, which allows access to the same information: + + - `credentials` - A `BackstageCredentials` object, which is useful for making requests to other services on behalf of the user as part of evaluating the policy. This replaces the deprecated `token` field. See the [Auth Service documentation](https://backstage.io/docs/backend-system/core-services/auth#creating-request-tokens) for information about how to create a token using these credentials. + - `info` - A `BackstageUserInfo` object, which contains the same information as the deprecated `identity`, except for the `type` field that was redundant. + + Most existing policies can be updated by replacing the `BackstageIdentityResponse` type with `PolicyQueryUser`, which is exported from `@backstage/plugin-permission-node`, as well as replacing any occurrences of `user?.identity` with `user?.info`. + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.1.19 + +### Patch Changes + +- ed10fd2: Internal refactor to use new `PolicyQueryUser` type. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/plugin-auth-node@0.4.17 + +## @backstage/plugin-permission-react@0.4.24 + +### Patch Changes + +- 28b2cfb: Improve API Reference documentation +- Updated dependencies + - @backstage/plugin-permission-common@0.8.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-proxy-backend@0.5.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-azure@0.1.14 + +### Patch Changes + +- 661b354: Fixed a bug where the `RepoUrlPicker` would still require the `owner` field for `azure` +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.12 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.12 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.12 + +### Patch Changes + +- b5deed0: Add support for `autocomplete` handler to provide autocomplete options for `RepoUrlPicker` +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/plugin-bitbucket-cloud-common@0.2.21 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.12 + +### Patch Changes + +- 6a4ad4e: Instead of using hardcoded `targetBranch` now fetch the default branch from Bitbucket repository. + This prevents from errors when no `targetBranch` is provided and the default repository branch is different from `master`, for example: `main`. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.23 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.46 + +### Patch Changes + +- 0ac124b: Updated configuration instructions +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.1.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.4.4 + +### Patch Changes + +- 0ac124b: Updated configuration instructions +- 2fb0eb8: Added support for passing `variables` to `gitlab:pipeline:trigger` +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.0.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.3 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.39 + +### Patch Changes + +- 0ac124b: Updated configuration instructions +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.1.30 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/plugin-scaffolder-node-test-utils@0.1.9 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-common@1.5.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.0 + - @backstage/catalog-model@1.5.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-node@0.4.8 + +### Patch Changes + +- 661b354: Fixed a bug where the `RepoUrlPicker` would still require the `owner` field for `azure` +- b5deed0: Add support for `autocomplete` extension point to provide additional `autocomplete` handlers +- 0b52438: Serialization of the scaffolder workspace into GCP bucket +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-common@1.5.4 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-node-test-utils@0.1.9 + +### Patch Changes + +- 54429b5: Filename and imports correction for mockActionContext.ts +- Updated dependencies + - @backstage/backend-test-utils@0.4.4 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/types@1.1.1 + +## @backstage/plugin-search@1.4.14 + +### Patch Changes + +- 1117aba: Update deps in search api extension to include fetch api +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-search-common@1.2.13 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/plugin-search-react@1.7.13 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/plugin-search-backend@1.5.14 + +### Patch Changes + +- 343f656: The `AuthorizedSearchEngine` will now ignore the deprecated `token` option, and treat it as an unauthorized request. This will not have any effect in practice, since credentials are always provided by the router. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-defaults@0.4.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/backend-openapi-utils@0.1.15 + - @backstage/plugin-search-backend-node@1.2.27 + - @backstage/plugin-search-common@1.2.13 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-search-backend-module-catalog@0.1.28 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-search-backend-node@1.2.27 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-search-common@1.2.13 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-search-backend-module-elasticsearch@1.5.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-search-backend-node@1.2.27 + - @backstage/plugin-search-common@1.2.13 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + +## @backstage/plugin-search-backend-module-explore@0.1.28 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-search-backend-node@1.2.27 + - @backstage/plugin-search-common@1.2.13 + - @backstage/config@1.2.0 + +## @backstage/plugin-search-backend-module-pg@0.5.32 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-app-api@0.8.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-search-backend-node@1.2.27 + - @backstage/plugin-search-common@1.2.13 + - @backstage/config@1.2.0 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.15 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-search-backend-node@1.2.27 + - @backstage/plugin-search-common@1.2.13 + - @backstage/config@1.2.0 + +## @backstage/plugin-search-backend-module-techdocs@0.1.27 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-techdocs-node@1.12.8 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-search-backend-node@1.2.27 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-search-common@1.2.13 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-search-backend-node@1.2.27 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-search-common@1.2.13 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-search-common@1.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-search-react@1.7.13 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-search-common@1.2.13 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/plugin-signals@0.0.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.4 + +## @backstage/plugin-signals-backend@0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-signals-node@0.1.8 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals-node@0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-techdocs@1.10.7 + +### Patch Changes + +- 8fc2622: Fixed an issue that was causing techdocs pages unnecessarily re-render on navigate. +- 6fa652c: Improve default sorting of docs table +- 605b691: Allow for searching TechDocs by entity title +- 60caa92: Fix double scrollbar bug in reader +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.6 + - @backstage/core-components@0.14.9 + - @backstage/integration@1.13.0 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-search-common@1.2.13 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/integration-react@1.1.29 + - @backstage/plugin-auth-react@0.1.4 + - @backstage/plugin-search-react@1.7.13 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.35 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.7 + - @backstage/plugin-techdocs-react@1.2.6 + - @backstage/core-app-api@1.14.0 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-catalog@1.21.1 + - @backstage/test-utils@1.5.8 + - @backstage/integration-react@1.1.29 + - @backstage/plugin-search-react@1.7.13 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-techdocs-backend@1.10.9 + +### Patch Changes + +- 9ecf5fd: Adds extension point for publishers to the techdocs backend +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-techdocs-node@1.12.8 + - @backstage/integration@1.13.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.27 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.6 + - @backstage/core-components@0.14.9 + - @backstage/integration@1.13.0 + - @backstage/integration-react@1.1.29 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-techdocs-node@1.12.8 + +### Patch Changes + +- 9ecf5fd: Adds extension point for publishers to the techdocs backend +- 4c4d077: Bumps default version of techdocs docker image to latest +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/integration@1.13.0 + - @backstage/plugin-search-common@1.2.13 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + +## @backstage/plugin-techdocs-react@1.2.6 + +### Patch Changes + +- 8ac9ce5: Resolved the issue where changes in TechDoc add-ons, including the TextSize add-on, were not reapplying during navigation +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/version-bridge@1.0.8 + +## @backstage/plugin-user-settings@0.8.9 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/core-app-api@1.14.0 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.4 + - @backstage/plugin-user-settings-common@0.0.1 + +## @backstage/plugin-user-settings-backend@0.2.21 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-signals-node@0.1.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.99 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder@1.23.0 + - @backstage/plugin-techdocs@1.10.7 + - @backstage/plugin-techdocs-react@1.2.6 + - @backstage/core-components@0.14.9 + - @backstage/cli@0.26.11 + - @backstage/core-app-api@1.14.0 + - @backstage/frontend-app-api@0.7.3 + - @backstage/plugin-org@0.6.27 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-catalog@1.21.1 + - @backstage/plugin-notifications@0.2.3 + - @backstage/plugin-home@0.7.7 + - @backstage/plugin-scaffolder-react@1.10.0 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-search@1.4.14 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.12 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-search-common@1.2.13 + - @backstage/app-defaults@1.5.8 + - @backstage/integration-react@1.1.29 + - @backstage/plugin-api-docs@0.11.7 + - @backstage/plugin-auth-react@0.1.4 + - @backstage/plugin-catalog-graph@0.4.7 + - @backstage/plugin-catalog-import@0.12.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.6 + - @backstage/plugin-devtools@0.1.16 + - @backstage/plugin-kubernetes@0.11.12 + - @backstage/plugin-kubernetes-cluster@0.0.13 + - @backstage/plugin-search-react@1.7.13 + - @backstage/plugin-signals@0.0.8 + - @backstage/plugin-user-settings@0.8.9 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + +## example-app-next@0.0.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder@1.23.0 + - @backstage/plugin-techdocs@1.10.7 + - @backstage/plugin-techdocs-react@1.2.6 + - @backstage/core-components@0.14.9 + - @backstage/cli@0.26.11 + - @backstage/core-app-api@1.14.0 + - @backstage/frontend-app-api@0.7.3 + - @backstage/plugin-org@0.6.27 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-catalog@1.21.1 + - @backstage/plugin-notifications@0.2.3 + - @backstage/plugin-home@0.7.7 + - @backstage/plugin-scaffolder-react@1.10.0 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-search@1.4.14 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.12 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-search-common@1.2.13 + - @backstage/app-defaults@1.5.8 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/integration-react@1.1.29 + - @backstage/plugin-api-docs@0.11.7 + - @backstage/plugin-app-visualizer@0.1.8 + - @backstage/plugin-auth-react@0.1.4 + - @backstage/plugin-catalog-graph@0.4.7 + - @backstage/plugin-catalog-import@0.12.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.6 + - @backstage/plugin-kubernetes@0.11.12 + - @backstage/plugin-kubernetes-cluster@0.0.13 + - @backstage/plugin-search-react@1.7.13 + - @backstage/plugin-signals@0.0.8 + - @backstage/plugin-user-settings@0.8.9 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + +## app-next-example-plugin@0.0.13 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/frontend-plugin-api@0.6.7 + +## example-backend@0.0.28 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-defaults@0.4.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.19 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-scaffolder-backend@1.23.0 + - @backstage/plugin-scaffolder-backend-module-github@0.4.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-backend@0.5.46 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/plugin-techdocs-backend@1.10.9 + - @backstage/plugin-notifications-backend@0.3.3 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-search-backend@1.5.14 + - @backstage/plugin-catalog-backend@1.24.0 + - @backstage/plugin-app-backend@0.3.71 + - @backstage/plugin-auth-backend@0.22.9 + - @backstage/plugin-auth-backend-module-github-provider@0.1.19 + - @backstage/plugin-auth-backend-module-guest-provider@0.1.8 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.2.5 + - @backstage/plugin-catalog-backend-module-openapi@0.1.40 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.20 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.9 + - @backstage/plugin-devtools-backend@0.3.8 + - @backstage/plugin-kubernetes-backend@0.18.3 + - @backstage/plugin-proxy-backend@0.5.3 + - @backstage/plugin-search-backend-module-catalog@0.1.28 + - @backstage/plugin-search-backend-module-explore@0.1.28 + - @backstage/plugin-search-backend-module-techdocs@0.1.27 + - @backstage/plugin-search-backend-node@1.2.27 + - @backstage/plugin-signals-backend@0.1.8 + - @backstage/catalog-model@1.5.0 + +## example-backend-legacy@0.2.100 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-scaffolder-backend@1.23.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-backend@0.5.46 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/plugin-techdocs-backend@1.10.9 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.4.4 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.39 + - @backstage/integration@1.13.0 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-search-backend@1.5.14 + - @backstage/plugin-catalog-backend@1.24.0 + - @backstage/plugin-app-backend@0.3.71 + - @backstage/plugin-auth-backend@0.22.9 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.20 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.9 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-devtools-backend@0.3.8 + - @backstage/plugin-events-backend@0.3.9 + - @backstage/plugin-kubernetes-backend@0.18.3 + - @backstage/plugin-proxy-backend@0.5.3 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.23 + - @backstage/plugin-search-backend-module-catalog@0.1.28 + - @backstage/plugin-search-backend-module-elasticsearch@1.5.3 + - @backstage/plugin-search-backend-module-explore@0.1.28 + - @backstage/plugin-search-backend-module-pg@0.5.32 + - @backstage/plugin-search-backend-module-techdocs@0.1.27 + - @backstage/plugin-search-backend-node@1.2.27 + - @backstage/plugin-signals-backend@0.1.8 + - @backstage/plugin-signals-node@0.1.8 + - example-app@0.2.99 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + +## e2e-test@0.2.18 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.17 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + +## techdocs-cli-embedded-app@0.2.98 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.7 + - @backstage/plugin-techdocs-react@1.2.6 + - @backstage/core-components@0.14.9 + - @backstage/cli@0.26.11 + - @backstage/core-app-api@1.14.0 + - @backstage/plugin-catalog@1.21.1 + - @backstage/test-utils@1.5.8 + - @backstage/app-defaults@1.5.8 + - @backstage/integration-react@1.1.29 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + +## @internal/plugin-todo-list@1.0.29 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/core-plugin-api@1.9.3 + +## @internal/plugin-todo-list-backend@1.0.29 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/errors@1.2.4 + +## @internal/plugin-todo-list-common@1.0.20 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.0 diff --git a/package.json b/package.json index d3d042c2f5..07c9b2917b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "root", - "version": "1.29.0-next.2", + "version": "1.29.0", "private": true, "repository": { "type": "git", diff --git a/packages/app-defaults/CHANGELOG.md b/packages/app-defaults/CHANGELOG.md index 21fe959edb..a03034112c 100644 --- a/packages/app-defaults/CHANGELOG.md +++ b/packages/app-defaults/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/app-defaults +## 1.5.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/core-app-api@1.14.0 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + ## 1.5.8-next.2 ### Patch Changes diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json index 4393164fcd..8997ba860f 100644 --- a/packages/app-defaults/package.json +++ b/packages/app-defaults/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/app-defaults", - "version": "1.5.8-next.2", + "version": "1.5.8", "description": "Provides the default wiring of a Backstage App", "backstage": { "role": "web-library" diff --git a/packages/app-next-example-plugin/CHANGELOG.md b/packages/app-next-example-plugin/CHANGELOG.md index 5456da237c..fb61388f22 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.13 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/frontend-plugin-api@0.6.7 + ## 0.0.13-next.1 ### Patch Changes diff --git a/packages/app-next-example-plugin/package.json b/packages/app-next-example-plugin/package.json index c3faec66d6..c48d5a92be 100644 --- a/packages/app-next-example-plugin/package.json +++ b/packages/app-next-example-plugin/package.json @@ -1,6 +1,6 @@ { "name": "app-next-example-plugin", - "version": "0.0.13-next.1", + "version": "0.0.13", "description": "Backstage internal example plugin", "backstage": { "role": "frontend-plugin", diff --git a/packages/app-next/CHANGELOG.md b/packages/app-next/CHANGELOG.md index 22d53e4c78..3bbf698ebd 100644 --- a/packages/app-next/CHANGELOG.md +++ b/packages/app-next/CHANGELOG.md @@ -1,5 +1,48 @@ # example-app-next +## 0.0.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder@1.23.0 + - @backstage/plugin-techdocs@1.10.7 + - @backstage/plugin-techdocs-react@1.2.6 + - @backstage/core-components@0.14.9 + - @backstage/cli@0.26.11 + - @backstage/core-app-api@1.14.0 + - @backstage/frontend-app-api@0.7.3 + - @backstage/plugin-org@0.6.27 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-catalog@1.21.1 + - @backstage/plugin-notifications@0.2.3 + - @backstage/plugin-home@0.7.7 + - @backstage/plugin-scaffolder-react@1.10.0 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-search@1.4.14 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.12 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-search-common@1.2.13 + - @backstage/app-defaults@1.5.8 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/integration-react@1.1.29 + - @backstage/plugin-api-docs@0.11.7 + - @backstage/plugin-app-visualizer@0.1.8 + - @backstage/plugin-auth-react@0.1.4 + - @backstage/plugin-catalog-graph@0.4.7 + - @backstage/plugin-catalog-import@0.12.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.6 + - @backstage/plugin-kubernetes@0.11.12 + - @backstage/plugin-kubernetes-cluster@0.0.13 + - @backstage/plugin-search-react@1.7.13 + - @backstage/plugin-signals@0.0.8 + - @backstage/plugin-user-settings@0.8.9 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + ## 0.0.13-next.2 ### Patch Changes diff --git a/packages/app-next/package.json b/packages/app-next/package.json index c38eacfcd5..c0c19bc40c 100644 --- a/packages/app-next/package.json +++ b/packages/app-next/package.json @@ -1,6 +1,6 @@ { "name": "example-app-next", - "version": "0.0.13-next.2", + "version": "0.0.13", "private": true, "repository": { "type": "git", diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index 4977cc1d6d..a75cf24a07 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,46 @@ # example-app +## 0.2.99 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder@1.23.0 + - @backstage/plugin-techdocs@1.10.7 + - @backstage/plugin-techdocs-react@1.2.6 + - @backstage/core-components@0.14.9 + - @backstage/cli@0.26.11 + - @backstage/core-app-api@1.14.0 + - @backstage/frontend-app-api@0.7.3 + - @backstage/plugin-org@0.6.27 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-catalog@1.21.1 + - @backstage/plugin-notifications@0.2.3 + - @backstage/plugin-home@0.7.7 + - @backstage/plugin-scaffolder-react@1.10.0 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-search@1.4.14 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.12 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-search-common@1.2.13 + - @backstage/app-defaults@1.5.8 + - @backstage/integration-react@1.1.29 + - @backstage/plugin-api-docs@0.11.7 + - @backstage/plugin-auth-react@0.1.4 + - @backstage/plugin-catalog-graph@0.4.7 + - @backstage/plugin-catalog-import@0.12.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.6 + - @backstage/plugin-devtools@0.1.16 + - @backstage/plugin-kubernetes@0.11.12 + - @backstage/plugin-kubernetes-cluster@0.0.13 + - @backstage/plugin-search-react@1.7.13 + - @backstage/plugin-signals@0.0.8 + - @backstage/plugin-user-settings@0.8.9 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + ## 0.2.99-next.2 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index f15dbac9db..29cfbf0357 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "example-app", - "version": "0.2.99-next.2", + "version": "0.2.99", "backstage": { "role": "frontend" }, diff --git a/packages/backend-app-api/CHANGELOG.md b/packages/backend-app-api/CHANGELOG.md index 4456d8438b..70a163ee34 100644 --- a/packages/backend-app-api/CHANGELOG.md +++ b/packages/backend-app-api/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/backend-app-api +## 0.8.0 + +### Minor Changes + +- 1cb84d7: **BREAKING**: Removed the depreacted `getPath` option from `httpRouterServiceFactory`, as well as the `HttpRouterFactoryOptions` type. +- f691c9b: **BREAKING**: Removed the ability to pass callback-form service factories through the `defaultServiceFactories` option of `createSpecializedBackend`. This is an immediate breaking change as usage of this function is expected to be very rare. + +### Patch Changes + +- 2f99178: The `ServiceFactoryTest.get` method was deprecated and the `ServiceFactoryTest.getSubject` should be used instead. The `getSubject` method has the same behavior, but has a better method name to indicate that the service instance returned is the subject currently being tested. +- b05e1e1: Service factories exported by this package have been updated to use the new service factory format that doesn't use a callback. +- 617a7d2: Internal refactor that avoids the use of service factory options. +- b60db08: Fixing exporting of classes properly from new packages +- 18b96b1: The ability to install backend features in callback form (`() => BackendFeature`) has been deprecated. This typically means that you need to update the installed features to use the latest version of `@backstage/backend-plugin-api`. If the feature is from a third-party package, please reach out to the package maintainer to update it. +- a63c4b6: Fixing issue with `MiddlewareFactory` deprecation wrapping +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/cli-node@0.2.7 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/config-loader@1.8.1 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.7.10-next.1 ### Patch Changes diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index 4d3ffd874f..8bd156c3a4 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-app-api", - "version": "0.7.10-next.1", + "version": "0.8.0", "description": "Core API used by Backstage backend apps", "backstage": { "role": "node-library" diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md index d144d461b8..6d3218e0ed 100644 --- a/packages/backend-common/CHANGELOG.md +++ b/packages/backend-common/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/backend-common +## 0.23.3 + +### Patch Changes + +- 8c09c97: Deprecate legacy status check factory, handler and types. +- d228862: Update default backend plugin created by the cli to use non-deprecated error handling middleware +- c964a3d: Add dependencies that are needed by cross-imports from backend-defaults +- b60db08: Fixing exporting of classes properly from new packages +- b9ed1bb: bumped better-sqlite3 from ^9.0.0 to ^11.0.0 +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/integration@1.13.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/config-loader@1.8.1 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + ## 0.23.3-next.1 ### Patch Changes diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index f23f0d2ce9..553c800ea5 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-common", - "version": "0.23.3-next.1", + "version": "0.23.3", "description": "Common functionality library for Backstage backends", "backstage": { "role": "node-library" diff --git a/packages/backend-defaults/CHANGELOG.md b/packages/backend-defaults/CHANGELOG.md index a9b20bfbea..7d2ad7d6b7 100644 --- a/packages/backend-defaults/CHANGELOG.md +++ b/packages/backend-defaults/CHANGELOG.md @@ -1,5 +1,37 @@ # @backstage/backend-defaults +## 0.4.0 + +### Minor Changes + +- 1cb84d7: **BREAKING**: Removed the depreacted `getPath` option from `httpRouterServiceFactory`, as well as the `HttpRouterFactoryOptions` type. + +### Patch Changes + +- 53ced70: Added a new Root Health Service which adds new endpoints for health checks. +- 2f99178: The `ServiceFactoryTest.get` method was deprecated and the `ServiceFactoryTest.getSubject` should be used instead. The `getSubject` method has the same behavior, but has a better method name to indicate that the service instance returned is the subject currently being tested. +- 083eaf9: Fix bug where ISO durations could no longer be used for schedules +- b05e1e1: Service factories exported by this package have been updated to use the new service factory format that doesn't use a callback. +- 419f387: Refactor of `rootHttpRouterServiceFactory` to allow it to be constructed with options, but without declaring options via `createServiceFactory`. +- cb14a05: Repack the package to fix issues with typescript with named exports +- b9ed1bb: bumped better-sqlite3 from ^9.0.0 to ^11.0.0 +- e28af58: Refactor of `rootConfigServiceFactory` to allow it to be constructed with options, but without declaring options via `createServiceFactory`. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-app-api@0.8.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/integration@1.13.0 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/config-loader@1.8.1 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + ## 0.3.4-next.1 ### Patch Changes diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index 0606d942ff..87da6e0017 100644 --- a/packages/backend-defaults/package.json +++ b/packages/backend-defaults/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-defaults", - "version": "0.3.4-next.1", + "version": "0.4.0", "description": "Backend defaults used by Backstage backend apps", "backstage": { "role": "node-library" diff --git a/packages/backend-dynamic-feature-service/CHANGELOG.md b/packages/backend-dynamic-feature-service/CHANGELOG.md index 02f47ef7b4..3003a8e177 100644 --- a/packages/backend-dynamic-feature-service/CHANGELOG.md +++ b/packages/backend-dynamic-feature-service/CHANGELOG.md @@ -1,5 +1,32 @@ # @backstage/backend-dynamic-feature-service +## 0.2.15 + +### Patch Changes + +- b05e1e1: Service factories exported by this package have been updated to use the new service factory format that doesn't use a callback. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-app-api@0.8.0 + - @backstage/backend-common@0.23.3 + - @backstage/cli-node@0.2.7 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-catalog-backend@1.24.0 + - @backstage/plugin-app-node@0.1.22 + - @backstage/plugin-events-backend@0.3.9 + - @backstage/plugin-search-backend-node@1.2.27 + - @backstage/config-loader@1.8.1 + - @backstage/plugin-search-common@1.2.13 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.2.15-next.1 ### Patch Changes diff --git a/packages/backend-dynamic-feature-service/package.json b/packages/backend-dynamic-feature-service/package.json index 3e3e566879..0d05b97bd9 100644 --- a/packages/backend-dynamic-feature-service/package.json +++ b/packages/backend-dynamic-feature-service/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-dynamic-feature-service", "description": "Backstage dynamic feature service", - "version": "0.2.15-next.1", + "version": "0.2.15", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-legacy/CHANGELOG.md b/packages/backend-legacy/CHANGELOG.md index 35ed7a6c93..04538ca02e 100644 --- a/packages/backend-legacy/CHANGELOG.md +++ b/packages/backend-legacy/CHANGELOG.md @@ -1,5 +1,47 @@ # example-backend-legacy +## 0.2.100 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-scaffolder-backend@1.23.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-backend@0.5.46 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/plugin-techdocs-backend@1.10.9 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.4.4 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.39 + - @backstage/integration@1.13.0 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-search-backend@1.5.14 + - @backstage/plugin-catalog-backend@1.24.0 + - @backstage/plugin-app-backend@0.3.71 + - @backstage/plugin-auth-backend@0.22.9 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.20 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.9 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-devtools-backend@0.3.8 + - @backstage/plugin-events-backend@0.3.9 + - @backstage/plugin-kubernetes-backend@0.18.3 + - @backstage/plugin-proxy-backend@0.5.3 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.23 + - @backstage/plugin-search-backend-module-catalog@0.1.28 + - @backstage/plugin-search-backend-module-elasticsearch@1.5.3 + - @backstage/plugin-search-backend-module-explore@0.1.28 + - @backstage/plugin-search-backend-module-pg@0.5.32 + - @backstage/plugin-search-backend-module-techdocs@0.1.27 + - @backstage/plugin-search-backend-node@1.2.27 + - @backstage/plugin-signals-backend@0.1.8 + - @backstage/plugin-signals-node@0.1.8 + - example-app@0.2.99 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + ## 0.2.100-next.2 ### Patch Changes diff --git a/packages/backend-legacy/package.json b/packages/backend-legacy/package.json index a537361746..5861719455 100644 --- a/packages/backend-legacy/package.json +++ b/packages/backend-legacy/package.json @@ -1,6 +1,6 @@ { "name": "example-backend-legacy", - "version": "0.2.100-next.2", + "version": "0.2.100", "backstage": { "role": "backend" }, diff --git a/packages/backend-openapi-utils/CHANGELOG.md b/packages/backend-openapi-utils/CHANGELOG.md index 43a57f7d8c..540a239ad6 100644 --- a/packages/backend-openapi-utils/CHANGELOG.md +++ b/packages/backend-openapi-utils/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/backend-openapi-utils +## 0.1.15 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/errors@1.2.4 + ## 0.1.15-next.1 ### Patch Changes diff --git a/packages/backend-openapi-utils/package.json b/packages/backend-openapi-utils/package.json index f35863c6e3..3059af5ffe 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.15-next.1", + "version": "0.1.15", "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 cb341b218e..3f47354561 100644 --- a/packages/backend-plugin-api/CHANGELOG.md +++ b/packages/backend-plugin-api/CHANGELOG.md @@ -1,5 +1,103 @@ # @backstage/backend-plugin-api +## 0.7.0 + +### Minor Changes + +- 36f91e8: **BREAKING**: The `PermissionsService` no longer supports passing the deprecated `token` option, and the request options are now required. + +### Patch Changes + +- 53ced70: Added a new Root Health Service which adds new endpoints for health checks. +- 083eaf9: Fix bug where ISO durations could no longer be used for schedules +- 062c01c: Deprecated the ability to define options for service factories through `createServiceFactory`. In the future all service factories will return a plain `ServiceFactory` object, rather than allowing users to pass options to the factory. To allow for customization of a service implementation one can instead export one or a few building blocks that allows for simple re-implementation of the service instead. + + For example, instead of: + + ```ts + export const fooServiceFactory = createServiceFactory<FooService>( + (options?: { bar: string }) => ({ + service: fooServiceRef, + deps: { logger: coreServices.logger }, + factory({ logger }) { + return { + // Implementation of the foo service using the `bar` option. + }; + }, + }), + ); + ``` + + We instead encourage service implementations to provide an easy to use API for re-implementing the service for advanced use-cases: + + ```ts + /** @public */ + export class DefaultFooService implements FooService { + static create(options: { bar: string; logger: LoggerService }) { + return new DefaultFooService(options.logger, options.bar ?? 'default'); + } + + private constructor( + private readonly logger: string, + private readonly bar: string, + ) {} + + // The rest of the implementation + } + ``` + + A user that wishes to customize the service can then easily do so by defining their own factory: + + ```ts + export const customFooServiceFactory = createServiceFactory<FooService>({ + service: fooServiceRef, + deps: { logger: coreServices.logger }, + factory({ logger }) { + return DefaultFooService.create({ logger, bar: 'baz' }); + }, + }); + ``` + + This is of course more verbose than the previous solution where the factory could be customized through `fooServiceFactory({ bar: 'baz' })`, but this is a simplified which in practice should be using static configuration instead. + + In cases where the old options patterns significantly improves the usability of the service factory, the old pattern can still be implemented like this: + + ```ts + const fooServiceFactoryWithOptions = (options?: { bar: string }) => + createServiceFactory<FooService>({ + service: fooServiceRef, + deps: { logger: coreServices.logger }, + factory({ logger }) { + return { + // Implementation of the foo service using the `bar` option. + }; + }, + }); + + export const fooServiceFactory = Object.assign( + fooServiceFactoryWithOptions, + fooServiceFactoryWithOptions(), + ); + ``` + + This change is being made because the ability to define an options callback encourages bad design of services factories. When possible, a service should be configurable through static configuration, and the existence of options may discourage that. More importantly though, the existing options do not work well with the dependency injection system of services, which is a problem for callbacks an other more advanced options. This lead to a bad pattern where only a few explicit dependencies where made available in callbacks, rather than providing an API that allowed simple re-implementation of the service with full access to dependency injection. + + A separate benefit of this change is that it simplifies the TypeScript types in a way that allows TypeScript to provide a much better error message when a service factory doesn't properly implement the service interface. + +- fe47a3e: All service config types were renamed to option types in order to standardize frontend and backend `create*` function signatures: + + - The `ServiceRefConfig` type was renamed to`ServiceRefOptions`; + - The `RootServiceFactoryConfig` type was renamed to `RootServiceFactoryOptions`; + - The `PluginServiceFactoryConfig` type was renamed to `PluginServiceFactoryOptions` + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.6.22-next.1 ### Patch Changes diff --git a/packages/backend-plugin-api/package.json b/packages/backend-plugin-api/package.json index 631141a57f..52fbfb5806 100644 --- a/packages/backend-plugin-api/package.json +++ b/packages/backend-plugin-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-plugin-api", - "version": "0.6.22-next.1", + "version": "0.7.0", "description": "Core API used by Backstage backend plugins", "backstage": { "role": "node-library" diff --git a/packages/backend-tasks/CHANGELOG.md b/packages/backend-tasks/CHANGELOG.md index 590d824635..fef4fd56a9 100644 --- a/packages/backend-tasks/CHANGELOG.md +++ b/packages/backend-tasks/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/backend-tasks +## 0.5.27 + +### Patch Changes + +- 083eaf9: Fix bug where ISO durations could no longer be used for schedules +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.5.27-next.1 ### Patch Changes diff --git a/packages/backend-tasks/package.json b/packages/backend-tasks/package.json index df10190443..998e1d0650 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.27-next.1", + "version": "0.5.27", "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 9f3d84a906..9bee6fae55 100644 --- a/packages/backend-test-utils/CHANGELOG.md +++ b/packages/backend-test-utils/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/backend-test-utils +## 0.4.4 + +### Patch Changes + +- 2f99178: The `ServiceFactoryTest.get` method was deprecated and the `ServiceFactoryTest.getSubject` should be used instead. The `getSubject` method has the same behavior, but has a better method name to indicate that the service instance returned is the subject currently being tested. +- edf5cc3: The function `isDockerDisabledForTests` is deprecated and will no longer be exported in the near future as it should only be used internally. +- b05e1e1: Service factories exported by this package have been updated to use the new service factory format that doesn't use a callback. +- fce7887: Added mock for the Root Health Service in `mockServices`. +- 906c817: Updated `startTestBackend` and `ServiceFactoryTester` to only accept plain service factory or backend feature objects, no longer supporting the callback form. This lines up with the changes to `@backstage/backend-plugin-api` and should not require any code changes. +- 95a3a0b: Rename frontend and backend `setupRequestMockHandlers` methods to `registerMswTestHooks`. +- b9ed1bb: bumped better-sqlite3 from ^9.0.0 to ^11.0.0 +- 98ccf00: Internal refactor of `mockServices.httpAuth.factory` to allow it to still be constructed with options, but without declaring options via `createServiceFactory`. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-defaults@0.4.0 + - @backstage/backend-app-api@0.8.0 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.4.4-next.1 ### Patch Changes diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index e975dc01d9..875949c0a0 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-test-utils", - "version": "0.4.4-next.1", + "version": "0.4.4", "description": "Test helpers library for Backstage backends", "backstage": { "role": "node-library" diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index 4ceb786f2a..854993119c 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,42 @@ # example-backend +## 0.0.28 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-defaults@0.4.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.19 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-scaffolder-backend@1.23.0 + - @backstage/plugin-scaffolder-backend-module-github@0.4.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-backend@0.5.46 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/plugin-techdocs-backend@1.10.9 + - @backstage/plugin-notifications-backend@0.3.3 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-search-backend@1.5.14 + - @backstage/plugin-catalog-backend@1.24.0 + - @backstage/plugin-app-backend@0.3.71 + - @backstage/plugin-auth-backend@0.22.9 + - @backstage/plugin-auth-backend-module-github-provider@0.1.19 + - @backstage/plugin-auth-backend-module-guest-provider@0.1.8 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.2.5 + - @backstage/plugin-catalog-backend-module-openapi@0.1.40 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.20 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.9 + - @backstage/plugin-devtools-backend@0.3.8 + - @backstage/plugin-kubernetes-backend@0.18.3 + - @backstage/plugin-proxy-backend@0.5.3 + - @backstage/plugin-search-backend-module-catalog@0.1.28 + - @backstage/plugin-search-backend-module-explore@0.1.28 + - @backstage/plugin-search-backend-module-techdocs@0.1.27 + - @backstage/plugin-search-backend-node@1.2.27 + - @backstage/plugin-signals-backend@0.1.8 + - @backstage/catalog-model@1.5.0 + ## 0.0.28-next.2 ### Patch Changes diff --git a/packages/backend/package.json b/packages/backend/package.json index 459db3c317..ae47716326 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.0.28-next.2", + "version": "0.0.28", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/cli-node/CHANGELOG.md b/packages/cli-node/CHANGELOG.md index dcf9073277..21995e4812 100644 --- a/packages/cli-node/CHANGELOG.md +++ b/packages/cli-node/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/cli-node +## 0.2.7 + +### Patch Changes + +- 133464c: Added internal metadata for the new experimental `frontend-dynamic-container` role. +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.2.6 ### Patch Changes diff --git a/packages/cli-node/package.json b/packages/cli-node/package.json index 56cf50a096..c727918510 100644 --- a/packages/cli-node/package.json +++ b/packages/cli-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/cli-node", - "version": "0.2.6", + "version": "0.2.7", "description": "Node.js library for Backstage CLIs", "backstage": { "role": "node-library" diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index a2fae6e3c0..c062324abb 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/cli +## 0.26.11 + +### Patch Changes + +- 133464c: Added experimental support for dynamic frontend plugin builds, enabled via setting `EXPERIMENTAL_MODULE_FEDERATION` for the app build, and using the `frontend-dynamic-container` package role to create a container. Both of these are experimental and will change in the future. +- e2e320c: - remove unused dependencies `winston` and `yn` from the template of backend plugins; + - update `msw` to version `2.3.1` in the template of backend plugins; + starting with v1 and switching later to v2 is tedious and not straight forward; it's easier to start with v2; +- 0540c5a: Updated the scaffolding output message for `plugin-common` in `backstage-cli`. Now, when executing `backstage-cli new` to create a new `plugin-common` package, the output message accurately reflects the action by displaying `Creating common plugin package...` instead of the previous, less accurate `Creating backend plugin...`. +- 7652db4: Only bootstrap global-agent if it's actually being used +- f0c0039: Fix issue with CLI that was preventing upgrading from 1.28 +- d228862: Update default backend plugin created by the cli to use non-deprecated error handling middleware +- da90cce: Updated dependency `esbuild` to `^0.21.0`. +- a60d73b: Fix a few minor issues with the backend template that were causing failing linting checks in the main repo. +- 0510d98: Subpath export `package.json` should be of a unique name to avoid typescript resolution issues +- 4baac0c: The `backendPlugin` and `backendModule` factory now includes a step for automatically adding the new backend plugin/module to the `index.ts` file of the backend. +- Updated dependencies + - @backstage/cli-node@0.2.7 + - @backstage/integration@1.13.0 + - @backstage/config-loader@1.8.1 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/eslint-plugin@0.1.8 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + ## 0.26.11-next.1 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 97c15b16f2..ccc4818331 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/cli", - "version": "0.26.11-next.1", + "version": "0.26.11", "description": "CLI for developing Backstage plugins and apps", "backstage": { "role": "cli" diff --git a/packages/core-app-api/CHANGELOG.md b/packages/core-app-api/CHANGELOG.md index d80ed2fdcb..ff09befd63 100644 --- a/packages/core-app-api/CHANGELOG.md +++ b/packages/core-app-api/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/core-app-api +## 1.14.0 + +### Minor Changes + +- d3c39fc: Allow for the disabling of external routes through config, which was rendered impossible after the introduction of default targets. + + ```yaml + app: + routes: + bindings: + # This has the effect of removing the button for registering new + # catalog entities in the scaffolder template list view + scaffolder.registerComponent: false + ``` + +### Patch Changes + +- db2e2d5: Updated config schema to support app.routes.bindings +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 1.13.1-next.1 ### Patch Changes diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json index 35e32f9726..5f297b16d5 100644 --- a/packages/core-app-api/package.json +++ b/packages/core-app-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-app-api", "description": "Core app API used by Backstage apps", - "version": "1.13.1-next.1", + "version": "1.14.0", "publishConfig": { "access": "public" }, diff --git a/packages/core-compat-api/CHANGELOG.md b/packages/core-compat-api/CHANGELOG.md index 3ad2bd654e..829c6f41ff 100644 --- a/packages/core-compat-api/CHANGELOG.md +++ b/packages/core-compat-api/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/core-compat-api +## 0.2.7 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/version-bridge@1.0.8 + ## 0.2.7-next.1 ### Patch Changes diff --git a/packages/core-compat-api/package.json b/packages/core-compat-api/package.json index 0f164a6187..bbf131c761 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.2.7-next.1", + "version": "0.2.7", "backstage": { "role": "web-library" }, diff --git a/packages/core-components/CHANGELOG.md b/packages/core-components/CHANGELOG.md index 163406bbca..3d46390597 100644 --- a/packages/core-components/CHANGELOG.md +++ b/packages/core-components/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/core-components +## 0.14.9 + +### Patch Changes + +- d4ffdbb: Fixed bug where `<Select>` component with empty string as placeholder gave an error +- 99d672d: Modified the `Select` component to take in a `data-testid` parameter ensuring backwards compatibility with default value corresponding to previously hardcoded `data-testid` of "select". +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/version-bridge@1.0.8 + ## 0.14.9-next.1 ### Patch Changes diff --git a/packages/core-components/package.json b/packages/core-components/package.json index 21c4a19dbf..55faac9dba 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.14.9-next.1", + "version": "0.14.9", "publishConfig": { "access": "public" }, diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index 708a9b33f8..d7ad8037e6 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/create-app +## 0.5.17 + +### Patch Changes + +- 780d994: Added `MyGroupsSidebarItem` to the sidebar in the `create-app` template +- f03d12a: Bumped create-app version. +- e90a2cd: Added the Catalog logs module to the `create-app` template +- 3ac2a6a: Added the Postgres Search Engine to the `create-app` template +- Updated dependencies + - @backstage/cli-common@0.1.14 + ## 0.5.17-next.2 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index c1ca92f87b..7d33d03a4b 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.17-next.2", + "version": "0.5.17", "publishConfig": { "access": "public" }, diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index ee9f56dec7..f46a65827a 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/dev-utils +## 1.0.35 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/core-app-api@1.14.0 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/app-defaults@1.5.8 + - @backstage/integration-react@1.1.29 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + ## 1.0.35-next.2 ### Patch Changes diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index 50220c36e1..0902d7c322 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/dev-utils", - "version": "1.0.35-next.2", + "version": "1.0.35", "description": "Utilities for developing Backstage plugins.", "backstage": { "role": "web-library" diff --git a/packages/e2e-test/CHANGELOG.md b/packages/e2e-test/CHANGELOG.md index 5144d9fd86..ad76bf8b75 100644 --- a/packages/e2e-test/CHANGELOG.md +++ b/packages/e2e-test/CHANGELOG.md @@ -1,5 +1,14 @@ # e2e-test +## 0.2.18 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.17 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + ## 0.2.18-next.2 ### Patch Changes diff --git a/packages/e2e-test/package.json b/packages/e2e-test/package.json index 1d65314e83..7fa0349a46 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.18-next.2", + "version": "0.2.18", "private": true, "backstage": { "role": "cli" diff --git a/packages/frontend-app-api/CHANGELOG.md b/packages/frontend-app-api/CHANGELOG.md index dde282a831..7203efb8d8 100644 --- a/packages/frontend-app-api/CHANGELOG.md +++ b/packages/frontend-app-api/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/frontend-app-api +## 0.7.3 + +### Patch Changes + +- d3c39fc: Allow for the disabling of external routes through config, which was rendered impossible after the introduction of default targets. + + ```yaml + app: + routes: + bindings: + # This has the effect of removing the button for registering new + # catalog entities in the scaffolder template list view + scaffolder.registerComponent: false + ``` + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/core-app-api@1.14.0 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 0.7.3-next.2 ### Patch Changes diff --git a/packages/frontend-app-api/package.json b/packages/frontend-app-api/package.json index 68c2fd8fab..a55284ff68 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.7.3-next.2", + "version": "0.7.3", "backstage": { "role": "web-library" }, diff --git a/packages/frontend-plugin-api/CHANGELOG.md b/packages/frontend-plugin-api/CHANGELOG.md index dda46968a4..4c0e6fe9f8 100644 --- a/packages/frontend-plugin-api/CHANGELOG.md +++ b/packages/frontend-plugin-api/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/frontend-plugin-api +## 0.6.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 0.6.7-next.1 ### Patch Changes diff --git a/packages/frontend-plugin-api/package.json b/packages/frontend-plugin-api/package.json index b62fe36059..f02f3fdedf 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.6.7-next.1", + "version": "0.6.7", "backstage": { "role": "web-library" }, diff --git a/packages/frontend-test-utils/CHANGELOG.md b/packages/frontend-test-utils/CHANGELOG.md index 34d9b28143..de21194f4e 100644 --- a/packages/frontend-test-utils/CHANGELOG.md +++ b/packages/frontend-test-utils/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/frontend-test-utils +## 0.1.10 + +### Patch Changes + +- 95a3a0b: Rename frontend and backend `setupRequestMockHandlers` methods to `registerMswTestHooks`. +- Updated dependencies + - @backstage/frontend-app-api@0.7.3 + - @backstage/test-utils@1.5.8 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/types@1.1.1 + ## 0.1.10-next.2 ### Patch Changes diff --git a/packages/frontend-test-utils/package.json b/packages/frontend-test-utils/package.json index 2a366fa152..0816a25443 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.10-next.2", + "version": "0.1.10", "backstage": { "role": "web-library" }, diff --git a/packages/integration-react/CHANGELOG.md b/packages/integration-react/CHANGELOG.md index e5e5759f1e..ed54a92f5c 100644 --- a/packages/integration-react/CHANGELOG.md +++ b/packages/integration-react/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/integration-react +## 1.1.29 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.13.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + ## 1.1.29-next.0 ### Patch Changes diff --git a/packages/integration-react/package.json b/packages/integration-react/package.json index 375f99fba6..b04b603327 100644 --- a/packages/integration-react/package.json +++ b/packages/integration-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/integration-react", - "version": "1.1.29-next.0", + "version": "1.1.29", "description": "Frontend package for managing integrations towards external systems", "backstage": { "role": "web-library" diff --git a/packages/integration/CHANGELOG.md b/packages/integration/CHANGELOG.md index a76d031e35..3fb630ccfc 100644 --- a/packages/integration/CHANGELOG.md +++ b/packages/integration/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/integration +## 1.13.0 + +### Minor Changes + +- b5deed0: Add support for `token` for `bitbucketCloud` integration + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 1.13.0-next.0 ### Minor Changes diff --git a/packages/integration/package.json b/packages/integration/package.json index 6f4743fd13..810150cf2d 100644 --- a/packages/integration/package.json +++ b/packages/integration/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/integration", - "version": "1.13.0-next.0", + "version": "1.13.0", "description": "Helpers for managing integrations towards external systems", "backstage": { "role": "common-library" diff --git a/packages/repo-tools/CHANGELOG.md b/packages/repo-tools/CHANGELOG.md index daa0684e41..18c696a51c 100644 --- a/packages/repo-tools/CHANGELOG.md +++ b/packages/repo-tools/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/repo-tools +## 0.9.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/cli-node@0.2.7 + - @backstage/config-loader@1.8.1 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + ## 0.9.4-next.1 ### Patch Changes diff --git a/packages/repo-tools/package.json b/packages/repo-tools/package.json index cd1658b417..9f3a177b4f 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.9.4-next.1", + "version": "0.9.4", "publishConfig": { "access": "public" }, diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md index 123e82edf7..6c8cc3f4ac 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.98 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.7 + - @backstage/plugin-techdocs-react@1.2.6 + - @backstage/core-components@0.14.9 + - @backstage/cli@0.26.11 + - @backstage/core-app-api@1.14.0 + - @backstage/plugin-catalog@1.21.1 + - @backstage/test-utils@1.5.8 + - @backstage/app-defaults@1.5.8 + - @backstage/integration-react@1.1.29 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + ## 0.2.98-next.2 ### Patch Changes diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json index 979d18620f..6c395636b1 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.98-next.2", + "version": "0.2.98", "private": true, "backstage": { "role": "frontend" diff --git a/packages/techdocs-cli/CHANGELOG.md b/packages/techdocs-cli/CHANGELOG.md index 0097d35ef6..34f612932c 100644 --- a/packages/techdocs-cli/CHANGELOG.md +++ b/packages/techdocs-cli/CHANGELOG.md @@ -1,5 +1,17 @@ # @techdocs/cli +## 1.8.16 + +### Patch Changes + +- c964a3d: Import discovery from backend-defaults instead of backend-common +- Updated dependencies + - @backstage/backend-defaults@0.4.0 + - @backstage/plugin-techdocs-node@1.12.8 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + ## 1.8.16-next.1 ### Patch Changes diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index d947af0ee8..a44213abb7 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.16-next.1", + "version": "1.8.16", "publishConfig": { "access": "public" }, diff --git a/packages/test-utils/CHANGELOG.md b/packages/test-utils/CHANGELOG.md index 6a038fd0d8..3f40af6299 100644 --- a/packages/test-utils/CHANGELOG.md +++ b/packages/test-utils/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/test-utils +## 1.5.8 + +### Patch Changes + +- 95a3a0b: Rename frontend and backend `setupRequestMockHandlers` methods to `registerMswTestHooks`. +- Updated dependencies + - @backstage/plugin-permission-common@0.8.0 + - @backstage/core-app-api@1.14.0 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + ## 1.5.8-next.1 ### Patch Changes diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 9cf0c7a6a7..9d36217b46 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/test-utils", - "version": "1.5.8-next.1", + "version": "1.5.8", "description": "Utilities to test Backstage plugins and apps.", "backstage": { "role": "web-library" diff --git a/plugins/api-docs/CHANGELOG.md b/plugins/api-docs/CHANGELOG.md index 58d69f516d..b6d585c0f0 100644 --- a/plugins/api-docs/CHANGELOG.md +++ b/plugins/api-docs/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-api-docs +## 0.11.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-catalog@1.21.1 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/catalog-model@1.5.0 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + ## 0.11.7-next.2 ### Patch Changes diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 5a6d97b7ce..7cda749423 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-api-docs", - "version": "0.11.7-next.2", + "version": "0.11.7", "description": "A Backstage plugin that helps represent API entities in the frontend", "backstage": { "role": "frontend-plugin", diff --git a/plugins/app-backend/CHANGELOG.md b/plugins/app-backend/CHANGELOG.md index b472d51f0f..63265e33d9 100644 --- a/plugins/app-backend/CHANGELOG.md +++ b/plugins/app-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-app-backend +## 0.3.71 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-app-node@0.1.22 + - @backstage/config-loader@1.8.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.3.71-next.1 ### Patch Changes diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json index 0d44e3dc61..e6661f9d73 100644 --- a/plugins/app-backend/package.json +++ b/plugins/app-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-app-backend", - "version": "0.3.71-next.1", + "version": "0.3.71", "description": "A Backstage backend plugin that serves the Backstage frontend app", "backstage": { "role": "backend-plugin", diff --git a/plugins/app-node/CHANGELOG.md b/plugins/app-node/CHANGELOG.md index e5ff0eb99f..4dce17870a 100644 --- a/plugins/app-node/CHANGELOG.md +++ b/plugins/app-node/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-app-node +## 0.1.22 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/config-loader@1.8.1 + ## 0.1.22-next.1 ### Patch Changes diff --git a/plugins/app-node/package.json b/plugins/app-node/package.json index 11ddf46cf8..a846190f31 100644 --- a/plugins/app-node/package.json +++ b/plugins/app-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-app-node", - "version": "0.1.22-next.1", + "version": "0.1.22", "description": "Node.js library for the app plugin", "backstage": { "role": "node-library", diff --git a/plugins/app-visualizer/CHANGELOG.md b/plugins/app-visualizer/CHANGELOG.md index cdb8bab69e..ec24e1cc8b 100644 --- a/plugins/app-visualizer/CHANGELOG.md +++ b/plugins/app-visualizer/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-app-visualizer +## 0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/core-plugin-api@1.9.3 + ## 0.1.8-next.1 ### Patch Changes diff --git a/plugins/app-visualizer/package.json b/plugins/app-visualizer/package.json index 95df128040..6b10ffc220 100644 --- a/plugins/app-visualizer/package.json +++ b/plugins/app-visualizer/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-app-visualizer", - "version": "0.1.8-next.1", + "version": "0.1.8", "description": "Visualizes the Backstage app structure", "backstage": { "role": "frontend-plugin", diff --git a/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md b/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md index 0449bc6933..55287ebd46 100644 --- a/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-atlassian-provider +## 0.2.3 + +### Patch Changes + +- b9832ae: Fix several issues with the Atlassian auth provider (type definition, profile url, profile transformation, scopes) +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + ## 0.2.3-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 d938144603..309dff7f50 100644 --- a/plugins/auth-backend-module-atlassian-provider/package.json +++ b/plugins/auth-backend-module-atlassian-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-atlassian-provider", - "version": "0.2.3-next.1", + "version": "0.2.3", "description": "The atlassian-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md b/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md index f1ae8a4981..cc2db5e210 100644 --- a/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-auth-backend-module-aws-alb-provider +## 0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-auth-backend@0.22.9 + - @backstage/errors@1.2.4 + ## 0.1.14-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-aws-alb-provider/package.json b/plugins/auth-backend-module-aws-alb-provider/package.json index 6ee5c274c1..9d15f0ea09 100644 --- a/plugins/auth-backend-module-aws-alb-provider/package.json +++ b/plugins/auth-backend-module-aws-alb-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-aws-alb-provider", - "version": "0.1.14-next.1", + "version": "0.1.14", "description": "The aws-alb provider module for the Backstage auth backend.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md b/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md index 5e78ec6abb..26eb0d17b4 100644 --- a/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-azure-easyauth-provider +## 0.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + ## 0.1.5-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-azure-easyauth-provider/package.json b/plugins/auth-backend-module-azure-easyauth-provider/package.json index 287059eb8f..52293f2480 100644 --- a/plugins/auth-backend-module-azure-easyauth-provider/package.json +++ b/plugins/auth-backend-module-azure-easyauth-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-azure-easyauth-provider", - "version": "0.1.5-next.1", + "version": "0.1.5", "description": "The azure-easyauth-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md b/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md index 33b434f86e..86ec768727 100644 --- a/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-bitbucket-provider +## 0.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + ## 0.1.5-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-bitbucket-provider/package.json b/plugins/auth-backend-module-bitbucket-provider/package.json index 95189d2cea..8ddb0f8acd 100644 --- a/plugins/auth-backend-module-bitbucket-provider/package.json +++ b/plugins/auth-backend-module-bitbucket-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-bitbucket-provider", - "version": "0.1.5-next.1", + "version": "0.1.5", "description": "The bitbucket-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md b/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md index 9754e9a73a..2910ffccce 100644 --- a/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-cloudflare-access-provider +## 0.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.1.5-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-cloudflare-access-provider/package.json b/plugins/auth-backend-module-cloudflare-access-provider/package.json index b0cd52d022..30c60ed6a4 100644 --- a/plugins/auth-backend-module-cloudflare-access-provider/package.json +++ b/plugins/auth-backend-module-cloudflare-access-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-cloudflare-access-provider", - "version": "0.1.5-next.1", + "version": "0.1.5", "description": "The cloudflare-access-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md b/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md index 8fe2c331a4..19549dc23a 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-gcp-iap-provider +## 0.2.17 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.2.17-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 8e00b9e935..d0059e7a69 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/package.json +++ b/plugins/auth-backend-module-gcp-iap-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-gcp-iap-provider", - "version": "0.2.17-next.1", + "version": "0.2.17", "description": "A GCP IAP auth provider module for the Backstage auth backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-github-provider/CHANGELOG.md b/plugins/auth-backend-module-github-provider/CHANGELOG.md index f73e6adf3c..5d9704a86b 100644 --- a/plugins/auth-backend-module-github-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-github-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-github-provider +## 0.1.19 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + ## 0.1.19-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 138aaa4e02..42ef2ccd4e 100644 --- a/plugins/auth-backend-module-github-provider/package.json +++ b/plugins/auth-backend-module-github-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-github-provider", - "version": "0.1.19-next.1", + "version": "0.1.19", "description": "The github-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md b/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md index a8d5844847..57a6aa189b 100644 --- a/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-gitlab-provider +## 0.1.19 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + ## 0.1.19-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 97e680237c..b0e0d2e647 100644 --- a/plugins/auth-backend-module-gitlab-provider/package.json +++ b/plugins/auth-backend-module-gitlab-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-gitlab-provider", - "version": "0.1.19-next.1", + "version": "0.1.19", "description": "The gitlab-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-google-provider/CHANGELOG.md b/plugins/auth-backend-module-google-provider/CHANGELOG.md index e7eeb2779c..17efe0d1a5 100644 --- a/plugins/auth-backend-module-google-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-google-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-google-provider +## 0.1.19 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + ## 0.1.19-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 55b2616502..1153cbb37a 100644 --- a/plugins/auth-backend-module-google-provider/package.json +++ b/plugins/auth-backend-module-google-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-google-provider", - "version": "0.1.19-next.1", + "version": "0.1.19", "description": "A Google auth provider module for the Backstage auth backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-guest-provider/CHANGELOG.md b/plugins/auth-backend-module-guest-provider/CHANGELOG.md index fd046e8dca..7c9e48041d 100644 --- a/plugins/auth-backend-module-guest-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-guest-provider/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-auth-backend-module-guest-provider +## 0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + ## 0.1.8-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-guest-provider/package.json b/plugins/auth-backend-module-guest-provider/package.json index 78fbd098f6..1648ebea6a 100644 --- a/plugins/auth-backend-module-guest-provider/package.json +++ b/plugins/auth-backend-module-guest-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-guest-provider", - "version": "0.1.8-next.1", + "version": "0.1.8", "description": "The guest-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md b/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md index 668047c816..c4df7007f3 100644 --- a/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-microsoft-provider +## 0.1.17 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + ## 0.1.17-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 76d3236f8b..67a898cf80 100644 --- a/plugins/auth-backend-module-microsoft-provider/package.json +++ b/plugins/auth-backend-module-microsoft-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-microsoft-provider", - "version": "0.1.17-next.1", + "version": "0.1.17", "description": "The microsoft-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md b/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md index 9872a64385..edfcfa0bcb 100644 --- a/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-oauth2-provider +## 0.2.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + ## 0.2.3-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 71934913fe..c98a36d104 100644 --- a/plugins/auth-backend-module-oauth2-provider/package.json +++ b/plugins/auth-backend-module-oauth2-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-oauth2-provider", - "version": "0.2.3-next.1", + "version": "0.2.3", "description": "The oauth2-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md b/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md index 895ada0e6e..554468bcfe 100644 --- a/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-oauth2-proxy-provider +## 0.1.15 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/errors@1.2.4 + ## 0.1.15-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-oauth2-proxy-provider/package.json b/plugins/auth-backend-module-oauth2-proxy-provider/package.json index 4123403eb2..16b4126781 100644 --- a/plugins/auth-backend-module-oauth2-proxy-provider/package.json +++ b/plugins/auth-backend-module-oauth2-proxy-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-oauth2-proxy-provider", - "version": "0.1.15-next.1", + "version": "0.1.15", "description": "The oauth2-proxy-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-oidc-provider/CHANGELOG.md b/plugins/auth-backend-module-oidc-provider/CHANGELOG.md index b9f8ffc98d..5e0d6aeb5c 100644 --- a/plugins/auth-backend-module-oidc-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oidc-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-oidc-provider +## 0.2.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-auth-backend@0.22.9 + ## 0.2.3-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-oidc-provider/package.json b/plugins/auth-backend-module-oidc-provider/package.json index 34e6c6f296..d825bd2986 100644 --- a/plugins/auth-backend-module-oidc-provider/package.json +++ b/plugins/auth-backend-module-oidc-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-oidc-provider", - "version": "0.2.3-next.1", + "version": "0.2.3", "description": "The oidc-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-okta-provider/CHANGELOG.md b/plugins/auth-backend-module-okta-provider/CHANGELOG.md index dfb5f638bf..029892a34a 100644 --- a/plugins/auth-backend-module-okta-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-okta-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-okta-provider +## 0.0.15 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + ## 0.0.15-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 cf099d40ee..4070ffd31f 100644 --- a/plugins/auth-backend-module-okta-provider/package.json +++ b/plugins/auth-backend-module-okta-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-okta-provider", - "version": "0.0.15-next.1", + "version": "0.0.15", "description": "The okta-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md b/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md index 8e21a1868e..896f6b7e0c 100644 --- a/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-onelogin-provider +## 0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + ## 0.1.3-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-onelogin-provider/package.json b/plugins/auth-backend-module-onelogin-provider/package.json index ac6a38a4f5..045dce0392 100644 --- a/plugins/auth-backend-module-onelogin-provider/package.json +++ b/plugins/auth-backend-module-onelogin-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-onelogin-provider", - "version": "0.1.3-next.1", + "version": "0.1.3", "description": "The onelogin-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md b/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md index 4435efc501..c3ea4665e8 100644 --- a/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-pinniped-provider +## 0.1.16 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/config@1.2.0 + ## 0.1.16-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 2698a56a2e..e6f50e4008 100644 --- a/plugins/auth-backend-module-pinniped-provider/package.json +++ b/plugins/auth-backend-module-pinniped-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-pinniped-provider", - "version": "0.1.16-next.1", + "version": "0.1.16", "description": "The pinniped-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md b/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md index edfc30c099..f652d6135c 100644 --- a/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-vmware-cloud-provider +## 0.2.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/catalog-model@1.5.0 + ## 0.2.3-next.1 ### Patch Changes diff --git a/plugins/auth-backend-module-vmware-cloud-provider/package.json b/plugins/auth-backend-module-vmware-cloud-provider/package.json index d6b7eaf263..77dafe38e1 100644 --- a/plugins/auth-backend-module-vmware-cloud-provider/package.json +++ b/plugins/auth-backend-module-vmware-cloud-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-vmware-cloud-provider", - "version": "0.2.3-next.1", + "version": "0.2.3", "description": "The vmware-cloud-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md index 2bb083ed66..393820ec27 100644 --- a/plugins/auth-backend/CHANGELOG.md +++ b/plugins/auth-backend/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-auth-backend +## 0.22.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.2.3 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.14 + - @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.1.5 + - @backstage/plugin-auth-backend-module-bitbucket-provider@0.1.5 + - @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.1.5 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.17 + - @backstage/plugin-auth-backend-module-github-provider@0.1.19 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.19 + - @backstage/plugin-auth-backend-module-google-provider@0.1.19 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.1.17 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.2.3 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.15 + - @backstage/plugin-auth-backend-module-oidc-provider@0.2.3 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.15 + - @backstage/plugin-auth-backend-module-onelogin-provider@0.1.3 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.22.9-next.1 ### Patch Changes diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index cd31a18064..c9d437ceba 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend", - "version": "0.22.9-next.1", + "version": "0.22.9", "description": "A Backstage backend plugin that handles authentication", "backstage": { "role": "backend-plugin", diff --git a/plugins/auth-node/CHANGELOG.md b/plugins/auth-node/CHANGELOG.md index e931a1c26a..298f0e4472 100644 --- a/plugins/auth-node/CHANGELOG.md +++ b/plugins/auth-node/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-auth-node +## 0.4.17 + +### Patch Changes + +- 55c1a72: Fix issues with Atlassian OAuth provider: retrieve the email and photo that were not in arrays but rather in single props. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.4.17-next.1 ### Patch Changes diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index ab84eb7fe6..0f4b0f5a77 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.17-next.1", + "version": "0.4.17", "backstage": { "role": "node-library", "pluginId": "auth", diff --git a/plugins/auth-react/CHANGELOG.md b/plugins/auth-react/CHANGELOG.md index 84bfadc98c..4651cf7eae 100644 --- a/plugins/auth-react/CHANGELOG.md +++ b/plugins/auth-react/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-react +## 0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + ## 0.1.4-next.1 ### Patch Changes diff --git a/plugins/auth-react/package.json b/plugins/auth-react/package.json index 8af97a0b04..44a4ce9fd0 100644 --- a/plugins/auth-react/package.json +++ b/plugins/auth-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-react", - "version": "0.1.4-next.1", + "version": "0.1.4", "description": "Web library for the auth plugin", "backstage": { "role": "web-library", diff --git a/plugins/bitbucket-cloud-common/CHANGELOG.md b/plugins/bitbucket-cloud-common/CHANGELOG.md index 73060ebd4a..7b2b8a936b 100644 --- a/plugins/bitbucket-cloud-common/CHANGELOG.md +++ b/plugins/bitbucket-cloud-common/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-bitbucket-cloud-common +## 0.2.21 + +### Patch Changes + +- b5deed0: Add support for `autocomplete` handler to provide autocomplete options for `RepoUrlPicker` +- Updated dependencies + - @backstage/integration@1.13.0 + ## 0.2.21-next.0 ### Patch Changes diff --git a/plugins/bitbucket-cloud-common/package.json b/plugins/bitbucket-cloud-common/package.json index 0e98fcc505..d52122f995 100644 --- a/plugins/bitbucket-cloud-common/package.json +++ b/plugins/bitbucket-cloud-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bitbucket-cloud-common", - "version": "0.2.21-next.0", + "version": "0.2.21", "description": "Common functionalities for bitbucket-cloud plugins", "backstage": { "role": "common-library", diff --git a/plugins/catalog-backend-module-aws/CHANGELOG.md b/plugins/catalog-backend-module-aws/CHANGELOG.md index 15f944de19..f2dd32b7f2 100644 --- a/plugins/catalog-backend-module-aws/CHANGELOG.md +++ b/plugins/catalog-backend-module-aws/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-catalog-backend-module-aws +## 0.3.17 + +### Patch Changes + +- 4afa050: Export `defaultEksClusterEntityTransformer` to allow library consumers to layer additional changes on top of the default transformer. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/integration@1.13.0 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-kubernetes-common@0.8.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + ## 0.3.17-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-aws/package.json b/plugins/catalog-backend-module-aws/package.json index 7081b09d2b..91ac7c4eae 100644 --- a/plugins/catalog-backend-module-aws/package.json +++ b/plugins/catalog-backend-module-aws/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-aws", - "version": "0.3.17-next.1", + "version": "0.3.17", "description": "A Backstage catalog backend module that helps integrate towards AWS", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-azure/CHANGELOG.md b/plugins/catalog-backend-module-azure/CHANGELOG.md index 1f672302ac..e96ca2d650 100644 --- a/plugins/catalog-backend-module-azure/CHANGELOG.md +++ b/plugins/catalog-backend-module-azure/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-azure +## 0.1.42 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/integration@1.13.0 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/config@1.2.0 + ## 0.1.42-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-azure/package.json b/plugins/catalog-backend-module-azure/package.json index 1159aff6db..05b920bcb0 100644 --- a/plugins/catalog-backend-module-azure/package.json +++ b/plugins/catalog-backend-module-azure/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-azure", - "version": "0.1.42-next.1", + "version": "0.1.42", "description": "A Backstage catalog backend module that helps integrate towards Azure", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md b/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md index 125778b4b6..620ab36c40 100644 --- a/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-backstage-openapi +## 0.2.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-tasks@0.5.27 + - @backstage/backend-openapi-utils@0.1.15 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.2.5-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 fad1dc47c9..de6c2a8410 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.2.5-next.1", + "version": "0.2.5", "backstage": { "role": "backend-plugin-module", "pluginId": "catalog", diff --git a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md index 4ad56f2aa3..920d2bc111 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-catalog-backend-module-bitbucket-cloud +## 0.2.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/integration@1.13.0 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-bitbucket-cloud-common@0.2.21 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + ## 0.2.9-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 e691c2a3c3..9faa941fd6 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/package.json +++ b/plugins/catalog-backend-module-bitbucket-cloud/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-cloud", - "version": "0.2.9-next.1", + "version": "0.2.9", "description": "A Backstage catalog backend module that helps integrate towards Bitbucket Cloud", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md index a5901702ff..857d9a33d9 100644 --- a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-bitbucket-server +## 0.1.36 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/integration@1.13.0 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.1.36-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 4e47fcbdcc..793a4213f2 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.36-next.1", + "version": "0.1.36", "backstage": { "role": "backend-plugin-module", "pluginId": "catalog", diff --git a/plugins/catalog-backend-module-gcp/CHANGELOG.md b/plugins/catalog-backend-module-gcp/CHANGELOG.md index b76bc9d7a9..779039f858 100644 --- a/plugins/catalog-backend-module-gcp/CHANGELOG.md +++ b/plugins/catalog-backend-module-gcp/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-gcp +## 0.1.23 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-kubernetes-common@0.8.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + ## 0.1.23-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-gcp/package.json b/plugins/catalog-backend-module-gcp/package.json index 0888a9eb03..7ebe7cbefc 100644 --- a/plugins/catalog-backend-module-gcp/package.json +++ b/plugins/catalog-backend-module-gcp/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gcp", - "version": "0.1.23-next.1", + "version": "0.1.23", "description": "A Backstage catalog backend module that helps integrate towards GCP", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-gerrit/CHANGELOG.md b/plugins/catalog-backend-module-gerrit/CHANGELOG.md index 6492e65ffa..159c9bb550 100644 --- a/plugins/catalog-backend-module-gerrit/CHANGELOG.md +++ b/plugins/catalog-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-gerrit +## 0.1.39 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/integration@1.13.0 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.1.39-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-gerrit/package.json b/plugins/catalog-backend-module-gerrit/package.json index b99347e6f5..0732db4465 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.39-next.1", + "version": "0.1.39", "backstage": { "role": "backend-plugin-module", "pluginId": "catalog", diff --git a/plugins/catalog-backend-module-github-org/CHANGELOG.md b/plugins/catalog-backend-module-github-org/CHANGELOG.md index 0236b1d30c..424465d813 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.17 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-catalog-backend-module-github@0.6.5 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/config@1.2.0 + ## 0.1.17-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 abd92889a0..3fdcc2fedf 100644 --- a/plugins/catalog-backend-module-github-org/package.json +++ b/plugins/catalog-backend-module-github-org/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-github-org", - "version": "0.1.17-next.1", + "version": "0.1.17", "description": "The github-org backend module for the catalog plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-github/CHANGELOG.md b/plugins/catalog-backend-module-github/CHANGELOG.md index 02975d2b68..661712456b 100644 --- a/plugins/catalog-backend-module-github/CHANGELOG.md +++ b/plugins/catalog-backend-module-github/CHANGELOG.md @@ -1,5 +1,49 @@ # @backstage/plugin-catalog-backend-module-github +## 0.6.5 + +### Patch Changes + +- 9112efc: Adds support for `repository` events. + + The provider adds a subscription to the topic `github.repository`. + + Hereby, it supports events of type `repository` with actions + + - `archived` + - `deleted` + - `edited` + - `renamed` + - `transferred` + - `unarchived` + + Actions skipped as they don't require entity changes: + + - `created` + - `privatized` + - `publicized` + + If the config option `validateLocationsExist` is enabled, an API request + is necessary and will be executed. + This affects the actions `renamed`, `transferred`, and `unarchive` + of event type `repository`. + + Catalog entities related to the `GithubEntityProvider` instance will be adjusted + according to action and its meaning for them. + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/integration@1.13.0 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-catalog-backend@1.24.0 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + ## 0.6.5-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-github/package.json b/plugins/catalog-backend-module-github/package.json index c8b78c5e92..50b838be1d 100644 --- a/plugins/catalog-backend-module-github/package.json +++ b/plugins/catalog-backend-module-github/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-github", - "version": "0.6.5-next.1", + "version": "0.6.5", "description": "A Backstage catalog backend module that helps integrate towards GitHub", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md b/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md index d86cb76c24..b36bcb4d71 100644 --- a/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md +++ b/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-catalog-backend-module-gitlab-org +## 0.0.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-catalog-backend-module-gitlab@0.3.21 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-catalog-node@1.12.4 + ## 0.0.5-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-gitlab-org/package.json b/plugins/catalog-backend-module-gitlab-org/package.json index a08a42d1f3..9c4c1f725f 100644 --- a/plugins/catalog-backend-module-gitlab-org/package.json +++ b/plugins/catalog-backend-module-gitlab-org/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gitlab-org", - "version": "0.0.5-next.1", + "version": "0.0.5", "description": "The gitlab-org backend module for the catalog plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-gitlab/CHANGELOG.md b/plugins/catalog-backend-module-gitlab/CHANGELOG.md index 8d6eb4bfef..97ed683942 100644 --- a/plugins/catalog-backend-module-gitlab/CHANGELOG.md +++ b/plugins/catalog-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-catalog-backend-module-gitlab +## 0.3.21 + +### Patch Changes + +- 8db30ad: The Gitlab configuration supports an additional optional boolean key `catalog.providers.gitlab.<your-org>.restrictUsersToGroup`. Setting this to `true` will make Backstage only import users from the group defined in the `group` key, instead of all users in the organisation (self-hosted) or of the root group (SaaS). It will default to false, keeping the original implementation intact, when not explicitly set. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/integration@1.13.0 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + ## 0.3.21-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-gitlab/package.json b/plugins/catalog-backend-module-gitlab/package.json index 0780ccdd6a..fa21798a62 100644 --- a/plugins/catalog-backend-module-gitlab/package.json +++ b/plugins/catalog-backend-module-gitlab/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gitlab", - "version": "0.3.21-next.1", + "version": "0.3.21", "description": "A Backstage catalog backend module that helps integrate towards GitLab", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md index 9cd19e259e..0d04145063 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md +++ b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-catalog-backend-module-incremental-ingestion +## 0.4.27 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-catalog-backend@1.24.0 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.4.27-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 c9cf1f5a82..0180f36d03 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/package.json +++ b/plugins/catalog-backend-module-incremental-ingestion/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-incremental-ingestion", - "version": "0.4.27-next.1", + "version": "0.4.27", "description": "An entity provider for streaming large asset sources into the catalog", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-ldap/CHANGELOG.md b/plugins/catalog-backend-module-ldap/CHANGELOG.md index 6842b99282..9168ce0991 100644 --- a/plugins/catalog-backend-module-ldap/CHANGELOG.md +++ b/plugins/catalog-backend-module-ldap/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-catalog-backend-module-ldap +## 0.7.0 + +### Minor Changes + +- cb32ca7: **BREAKING**: `readLdapOrg` and the `LdapProviderConfig` type now always accept arrays of user and group configs, not just single items. + + Added support for single ldap catalog provider to provide list and undefined user and group bindings next to standard single one. + +### Patch Changes + +- 083eaf9: Fix bug where ISO durations could no longer be used for schedules +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.7.0-next.1 ### Minor Changes diff --git a/plugins/catalog-backend-module-ldap/package.json b/plugins/catalog-backend-module-ldap/package.json index 411f168fd8..62b3328de7 100644 --- a/plugins/catalog-backend-module-ldap/package.json +++ b/plugins/catalog-backend-module-ldap/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-ldap", - "version": "0.7.0-next.1", + "version": "0.7.0", "description": "A Backstage catalog backend module that helps integrate towards LDAP", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-logs/CHANGELOG.md b/plugins/catalog-backend-module-logs/CHANGELOG.md index c609fc369d..2712f4a134 100644 --- a/plugins/catalog-backend-module-logs/CHANGELOG.md +++ b/plugins/catalog-backend-module-logs/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-logs +## 0.0.1 + +### Patch Changes + +- 97caf55: Creates a new module to make logging catalog errors simple. This module subscribes to catalog events and logs them. + + See [Backstage documentation](https://backstage.io/docs/features/software-catalog/configuration#subscribing-to-catalog-errors) for details on how to install + and configure the plugin. + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-catalog-backend@1.24.0 + ## 0.0.1-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-logs/package.json b/plugins/catalog-backend-module-logs/package.json index fe3f09c29c..560b93737e 100644 --- a/plugins/catalog-backend-module-logs/package.json +++ b/plugins/catalog-backend-module-logs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-logs", - "version": "0.0.1-next.1", + "version": "0.0.1", "description": "A module that subscribes to catalog releated events and logs them.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-msgraph/CHANGELOG.md b/plugins/catalog-backend-module-msgraph/CHANGELOG.md index eb3591241f..a33bea94b8 100644 --- a/plugins/catalog-backend-module-msgraph/CHANGELOG.md +++ b/plugins/catalog-backend-module-msgraph/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-msgraph +## 0.5.30 + +### Patch Changes + +- f7bdcea: Adds a dynamic provider for the plugin-catalog-backend-module-msgraph. Configuration is now runtime configurable through the ProviderConfigTransformer. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + ## 0.5.30-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json index b04cd8788c..3f5fa722a8 100644 --- a/plugins/catalog-backend-module-msgraph/package.json +++ b/plugins/catalog-backend-module-msgraph/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-msgraph", - "version": "0.5.30-next.1", + "version": "0.5.30", "description": "A Backstage catalog backend module that helps integrate towards Microsoft Graph", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-openapi/CHANGELOG.md b/plugins/catalog-backend-module-openapi/CHANGELOG.md index bf35045dcc..6cc947ee17 100644 --- a/plugins/catalog-backend-module-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-openapi/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-backend-module-openapi +## 0.1.40 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/integration@1.13.0 + - @backstage/plugin-catalog-backend@1.24.0 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + ## 0.1.40-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-openapi/package.json b/plugins/catalog-backend-module-openapi/package.json index b37cb09b15..2dbe6612ac 100644 --- a/plugins/catalog-backend-module-openapi/package.json +++ b/plugins/catalog-backend-module-openapi/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-openapi", - "version": "0.1.40-next.1", + "version": "0.1.40", "description": "A Backstage catalog backend module that helps with OpenAPI specifications", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-puppetdb/CHANGELOG.md b/plugins/catalog-backend-module-puppetdb/CHANGELOG.md index ead44a56aa..cb4cd9664b 100644 --- a/plugins/catalog-backend-module-puppetdb/CHANGELOG.md +++ b/plugins/catalog-backend-module-puppetdb/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-puppetdb +## 0.1.28 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.1.28-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-puppetdb/package.json b/plugins/catalog-backend-module-puppetdb/package.json index 114daa45e8..cf2a739380 100644 --- a/plugins/catalog-backend-module-puppetdb/package.json +++ b/plugins/catalog-backend-module-puppetdb/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-puppetdb", - "version": "0.1.28-next.1", + "version": "0.1.28", "description": "A Backstage catalog backend module that helps integrate towards PuppetDB", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md b/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md index 758d59c7c0..87299358b7 100644 --- a/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md +++ b/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-catalog-backend-module-scaffolder-entity-model +## 0.1.20 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-scaffolder-common@1.5.4 + - @backstage/catalog-model@1.5.0 + ## 0.1.20-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 58bcdc6fb5..3aaa768f76 100644 --- a/plugins/catalog-backend-module-scaffolder-entity-model/package.json +++ b/plugins/catalog-backend-module-scaffolder-entity-model/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-scaffolder-entity-model", - "version": "0.1.20-next.1", + "version": "0.1.20", "description": "Adds support for the scaffolder specific entity model (e.g. the Template kind) to the catalog backend plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-unprocessed/CHANGELOG.md b/plugins/catalog-backend-module-unprocessed/CHANGELOG.md index afac0ebeed..a7d74143a1 100644 --- a/plugins/catalog-backend-module-unprocessed/CHANGELOG.md +++ b/plugins/catalog-backend-module-unprocessed/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-unprocessed +## 0.4.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.3 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + ## 0.4.9-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-unprocessed/package.json b/plugins/catalog-backend-module-unprocessed/package.json index c49a3d700d..6f1f4bb6bc 100644 --- a/plugins/catalog-backend-module-unprocessed/package.json +++ b/plugins/catalog-backend-module-unprocessed/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-unprocessed", - "version": "0.4.9-next.1", + "version": "0.4.9", "description": "Backstage Catalog module to view unprocessed entities", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md index 65ed28cb6d..8f99ab1f4c 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-catalog-backend +## 1.24.0 + +### Minor Changes + +- b9ed1bb: bumped better-sqlite3 from ^9.0.0 to ^11.0.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/integration@1.13.0 + - @backstage/plugin-events-node@0.3.8 + - @backstage/backend-openapi-utils@0.1.15 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-search-backend-module-catalog@0.1.28 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 1.24.0-next.1 ### Minor Changes diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index e554f0a334..19d40bd34c 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend", - "version": "1.24.0-next.1", + "version": "1.24.0", "description": "The Backstage backend plugin that provides the Backstage catalog", "backstage": { "role": "backend-plugin", diff --git a/plugins/catalog-common/CHANGELOG.md b/plugins/catalog-common/CHANGELOG.md index fd3c714f97..e2859fcc83 100644 --- a/plugins/catalog-common/CHANGELOG.md +++ b/plugins/catalog-common/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-catalog-common +## 1.0.25 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-search-common@1.2.13 + - @backstage/catalog-model@1.5.0 + ## 1.0.24 ### Patch Changes diff --git a/plugins/catalog-common/package.json b/plugins/catalog-common/package.json index 0ea4ce5e3e..865dc02f4c 100644 --- a/plugins/catalog-common/package.json +++ b/plugins/catalog-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-common", - "version": "1.0.24", + "version": "1.0.25", "description": "Common functionalities for the catalog plugin", "backstage": { "role": "common-library", diff --git a/plugins/catalog-graph/CHANGELOG.md b/plugins/catalog-graph/CHANGELOG.md index f397955e1c..332ea17dd0 100644 --- a/plugins/catalog-graph/CHANGELOG.md +++ b/plugins/catalog-graph/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-graph +## 0.4.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + ## 0.4.7-next.2 ### Patch Changes diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json index eb27725d45..1e7c376436 100644 --- a/plugins/catalog-graph/package.json +++ b/plugins/catalog-graph/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-graph", - "version": "0.4.7-next.2", + "version": "0.4.7", "backstage": { "role": "frontend-plugin", "pluginId": "catalog-graph", diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md index 455f094a86..29ec3631b4 100644 --- a/plugins/catalog-import/CHANGELOG.md +++ b/plugins/catalog-import/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-catalog-import +## 0.12.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/integration@1.13.0 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/integration-react@1.1.29 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + ## 0.12.1-next.2 ### Patch Changes diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index f41d239792..c3babc09a3 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-import", - "version": "0.12.1-next.2", + "version": "0.12.1", "description": "A Backstage plugin the helps you import entities into your catalog", "backstage": { "role": "frontend-plugin", diff --git a/plugins/catalog-node/CHANGELOG.md b/plugins/catalog-node/CHANGELOG.md index 54f39e9e51..74982e481f 100644 --- a/plugins/catalog-node/CHANGELOG.md +++ b/plugins/catalog-node/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-node +## 1.12.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 1.12.4-next.1 ### Patch Changes diff --git a/plugins/catalog-node/package.json b/plugins/catalog-node/package.json index 575a1c65f5..ccd83cd129 100644 --- a/plugins/catalog-node/package.json +++ b/plugins/catalog-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-node", - "version": "1.12.4-next.1", + "version": "1.12.4", "description": "The plugin-catalog-node module for @backstage/plugin-catalog-backend", "backstage": { "role": "node-library", diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md index b29a49e47d..38402e8824 100644 --- a/plugins/catalog-react/CHANGELOG.md +++ b/plugins/catalog-react/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-catalog-react +## 1.12.2 + +### Patch Changes + +- 06c0956: Support i18n for catalog and catalog-react plugins +- 2030962: Make EntityOwnerPicker display metadata.title or spec.profile.displayName for mode=only-owners instead of metadata.name +- Updated dependencies + - @backstage/plugin-permission-common@0.8.0 + - @backstage/core-components@0.14.9 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/integration-react@1.1.29 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 1.12.2-next.2 ### Patch Changes diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index f522a4f111..c6a725ecb6 100644 --- a/plugins/catalog-react/package.json +++ b/plugins/catalog-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-react", - "version": "1.12.2-next.2", + "version": "1.12.2", "description": "A frontend library that helps other Backstage plugins interact with the catalog", "backstage": { "role": "web-library", diff --git a/plugins/catalog-unprocessed-entities-common/CHANGELOG.md b/plugins/catalog-unprocessed-entities-common/CHANGELOG.md index f2f489b6a0..ca38c923bd 100644 --- a/plugins/catalog-unprocessed-entities-common/CHANGELOG.md +++ b/plugins/catalog-unprocessed-entities-common/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-catalog-unprocessed-entities-common +## 0.0.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.0 + ## 0.0.2 ### Patch Changes diff --git a/plugins/catalog-unprocessed-entities-common/package.json b/plugins/catalog-unprocessed-entities-common/package.json index f491d27157..990f75bbea 100644 --- a/plugins/catalog-unprocessed-entities-common/package.json +++ b/plugins/catalog-unprocessed-entities-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-unprocessed-entities-common", - "version": "0.0.2", + "version": "0.0.3", "description": "Common functionalities for the catalog-unprocessed-entities plugin", "backstage": { "role": "common-library", diff --git a/plugins/catalog-unprocessed-entities/CHANGELOG.md b/plugins/catalog-unprocessed-entities/CHANGELOG.md index fefeffe9d2..e3fd1b6b76 100644 --- a/plugins/catalog-unprocessed-entities/CHANGELOG.md +++ b/plugins/catalog-unprocessed-entities/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-catalog-unprocessed-entities +## 0.2.6 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + ## 0.2.6-next.1 ### Patch Changes diff --git a/plugins/catalog-unprocessed-entities/package.json b/plugins/catalog-unprocessed-entities/package.json index 142b850bd3..872ce7b11b 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.2.6-next.1", + "version": "0.2.6", "backstage": { "role": "frontend-plugin", "pluginId": "catalog-unprocessed-entities", diff --git a/plugins/catalog/CHANGELOG.md b/plugins/catalog/CHANGELOG.md index 08a70d4956..2667fdf638 100644 --- a/plugins/catalog/CHANGELOG.md +++ b/plugins/catalog/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-catalog +## 1.21.1 + +### Patch Changes + +- 06c0956: Support i18n for catalog and catalog-react plugins +- d133eaa: Added small notes to AboutCard to discourage customizability PRs +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-scaffolder-common@1.5.4 + - @backstage/plugin-search-common@1.2.13 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/integration-react@1.1.29 + - @backstage/plugin-search-react@1.7.13 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 1.21.1-next.2 ### Patch Changes diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index 0d101af3df..fc49a8c36b 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog", - "version": "1.21.1-next.2", + "version": "1.21.1", "description": "The Backstage plugin for browsing the Backstage catalog", "backstage": { "role": "frontend-plugin", diff --git a/plugins/config-schema/CHANGELOG.md b/plugins/config-schema/CHANGELOG.md index 8458a50aa3..2344473925 100644 --- a/plugins/config-schema/CHANGELOG.md +++ b/plugins/config-schema/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-config-schema +## 0.1.57 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.1.57-next.1 ### Patch Changes diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index 9a1971d80b..6f91094e5f 100644 --- a/plugins/config-schema/package.json +++ b/plugins/config-schema/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-config-schema", - "version": "0.1.57-next.1", + "version": "0.1.57", "description": "A Backstage plugin that lets you browse the configuration schema of your app", "backstage": { "role": "frontend-plugin", diff --git a/plugins/devtools-backend/CHANGELOG.md b/plugins/devtools-backend/CHANGELOG.md index cc0dc806c8..f027384637 100644 --- a/plugins/devtools-backend/CHANGELOG.md +++ b/plugins/devtools-backend/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-devtools-backend +## 0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/config-loader@1.8.1 + - @backstage/plugin-devtools-common@0.1.11 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.3.8-next.1 ### Patch Changes diff --git a/plugins/devtools-backend/package.json b/plugins/devtools-backend/package.json index bd3b61f22d..ce5e143f24 100644 --- a/plugins/devtools-backend/package.json +++ b/plugins/devtools-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-devtools-backend", - "version": "0.3.8-next.1", + "version": "0.3.8", "backstage": { "role": "backend-plugin", "pluginId": "devtools", diff --git a/plugins/devtools-common/CHANGELOG.md b/plugins/devtools-common/CHANGELOG.md index 3e060571ad..37923e3fc7 100644 --- a/plugins/devtools-common/CHANGELOG.md +++ b/plugins/devtools-common/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-devtools-common +## 0.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.0 + - @backstage/types@1.1.1 + ## 0.1.10 ### Patch Changes diff --git a/plugins/devtools-common/package.json b/plugins/devtools-common/package.json index 24b17d6742..f476580ac0 100644 --- a/plugins/devtools-common/package.json +++ b/plugins/devtools-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-devtools-common", - "version": "0.1.10", + "version": "0.1.11", "description": "Common functionalities for the devtools plugin", "backstage": { "role": "common-library", diff --git a/plugins/devtools/CHANGELOG.md b/plugins/devtools/CHANGELOG.md index 5bc6220aa3..3403b7f2fa 100644 --- a/plugins/devtools/CHANGELOG.md +++ b/plugins/devtools/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-devtools +## 0.1.16 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-devtools-common@0.1.11 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + ## 0.1.16-next.1 ### Patch Changes diff --git a/plugins/devtools/package.json b/plugins/devtools/package.json index 90d724692c..83d2a6b352 100644 --- a/plugins/devtools/package.json +++ b/plugins/devtools/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-devtools", - "version": "0.1.16-next.1", + "version": "0.1.16", "backstage": { "role": "frontend-plugin", "pluginId": "devtools", diff --git a/plugins/events-backend-module-aws-sqs/CHANGELOG.md b/plugins/events-backend-module-aws-sqs/CHANGELOG.md index 399ed2689d..e27fcefa6e 100644 --- a/plugins/events-backend-module-aws-sqs/CHANGELOG.md +++ b/plugins/events-backend-module-aws-sqs/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-events-backend-module-aws-sqs +## 0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-events-node@0.3.8 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + ## 0.3.8-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 b2c09d3b8a..983e15567b 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.3.8-next.1", + "version": "0.3.8", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-azure/CHANGELOG.md b/plugins/events-backend-module-azure/CHANGELOG.md index 5e5ccffc2a..225ee30beb 100644 --- a/plugins/events-backend-module-azure/CHANGELOG.md +++ b/plugins/events-backend-module-azure/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-events-backend-module-azure +## 0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-events-node@0.3.8 + ## 0.2.8-next.1 ### Patch Changes diff --git a/plugins/events-backend-module-azure/package.json b/plugins/events-backend-module-azure/package.json index 8bb6ac4f6b..49c9b9439f 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.2.8-next.1", + "version": "0.2.8", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md index 1a339c3807..4676feabbd 100644 --- a/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-events-backend-module-bitbucket-cloud +## 0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-events-node@0.3.8 + ## 0.2.8-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 7efffdd361..6fd443a3b1 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.2.8-next.1", + "version": "0.2.8", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-gerrit/CHANGELOG.md b/plugins/events-backend-module-gerrit/CHANGELOG.md index 78963fbbaf..eddce5d6c5 100644 --- a/plugins/events-backend-module-gerrit/CHANGELOG.md +++ b/plugins/events-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-events-backend-module-gerrit +## 0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-events-node@0.3.8 + ## 0.2.8-next.1 ### Patch Changes diff --git a/plugins/events-backend-module-gerrit/package.json b/plugins/events-backend-module-gerrit/package.json index f1bea2868c..7d870063df 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.2.8-next.1", + "version": "0.2.8", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-github/CHANGELOG.md b/plugins/events-backend-module-github/CHANGELOG.md index a095cf4ab3..4597583ea8 100644 --- a/plugins/events-backend-module-github/CHANGELOG.md +++ b/plugins/events-backend-module-github/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-events-backend-module-github +## 0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-events-node@0.3.8 + - @backstage/config@1.2.0 + ## 0.2.8-next.1 ### Patch Changes diff --git a/plugins/events-backend-module-github/package.json b/plugins/events-backend-module-github/package.json index 3b37f29022..955793ee6d 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.2.8-next.1", + "version": "0.2.8", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-gitlab/CHANGELOG.md b/plugins/events-backend-module-gitlab/CHANGELOG.md index dc8470bd7a..f22f90405e 100644 --- a/plugins/events-backend-module-gitlab/CHANGELOG.md +++ b/plugins/events-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-events-backend-module-gitlab +## 0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-events-node@0.3.8 + - @backstage/config@1.2.0 + ## 0.2.8-next.1 ### Patch Changes diff --git a/plugins/events-backend-module-gitlab/package.json b/plugins/events-backend-module-gitlab/package.json index 21c95448b1..c97a9e2f02 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.2.8-next.1", + "version": "0.2.8", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-test-utils/CHANGELOG.md b/plugins/events-backend-test-utils/CHANGELOG.md index 967ffc80da..4fcbcfc172 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.32 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.8 + ## 0.1.32-next.1 ### Patch Changes diff --git a/plugins/events-backend-test-utils/package.json b/plugins/events-backend-test-utils/package.json index 120c7f5fa6..09a36a7a1f 100644 --- a/plugins/events-backend-test-utils/package.json +++ b/plugins/events-backend-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-test-utils", - "version": "0.1.32-next.1", + "version": "0.1.32", "description": "The plugin-events-backend-test-utils for @backstage/plugin-events-node", "backstage": { "role": "node-library", diff --git a/plugins/events-backend/CHANGELOG.md b/plugins/events-backend/CHANGELOG.md index a4b4b550bb..4840d9a623 100644 --- a/plugins/events-backend/CHANGELOG.md +++ b/plugins/events-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-events-backend +## 0.3.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-events-node@0.3.8 + - @backstage/config@1.2.0 + ## 0.3.9-next.1 ### Patch Changes diff --git a/plugins/events-backend/package.json b/plugins/events-backend/package.json index 82066d5a91..f9f2a4b781 100644 --- a/plugins/events-backend/package.json +++ b/plugins/events-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend", - "version": "0.3.9-next.1", + "version": "0.3.9", "backstage": { "role": "backend-plugin", "pluginId": "events", diff --git a/plugins/events-node/CHANGELOG.md b/plugins/events-node/CHANGELOG.md index 022d50fdd1..d5b1c98372 100644 --- a/plugins/events-node/CHANGELOG.md +++ b/plugins/events-node/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-events-node +## 0.3.8 + +### Patch Changes + +- b05e1e1: Service factories exported by this package have been updated to use the new service factory format that doesn't use a callback. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + ## 0.3.8-next.1 ### Patch Changes diff --git a/plugins/events-node/package.json b/plugins/events-node/package.json index f89617dd14..965f317357 100644 --- a/plugins/events-node/package.json +++ b/plugins/events-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-node", - "version": "0.3.8-next.1", + "version": "0.3.8", "description": "The plugin-events-node module for @backstage/plugin-events-backend", "backstage": { "role": "node-library", diff --git a/plugins/example-todo-list-backend/CHANGELOG.md b/plugins/example-todo-list-backend/CHANGELOG.md index d1553258ed..dd1a2087dc 100644 --- a/plugins/example-todo-list-backend/CHANGELOG.md +++ b/plugins/example-todo-list-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @internal/plugin-todo-list-backend +## 1.0.29 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/errors@1.2.4 + ## 1.0.29-next.1 ### Patch Changes diff --git a/plugins/example-todo-list-backend/package.json b/plugins/example-todo-list-backend/package.json index 3d46a9f5f7..0ca987d30b 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.29-next.1", + "version": "1.0.29", "backstage": { "role": "backend-plugin", "pluginId": "todo-list", diff --git a/plugins/example-todo-list-common/CHANGELOG.md b/plugins/example-todo-list-common/CHANGELOG.md index 3761ead6a3..e30cb653df 100644 --- a/plugins/example-todo-list-common/CHANGELOG.md +++ b/plugins/example-todo-list-common/CHANGELOG.md @@ -1,5 +1,12 @@ # @internal/plugin-todo-list-common +## 1.0.20 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.0 + ## 1.0.19 ### Patch Changes diff --git a/plugins/example-todo-list-common/package.json b/plugins/example-todo-list-common/package.json index 317cfa991d..efccce611f 100644 --- a/plugins/example-todo-list-common/package.json +++ b/plugins/example-todo-list-common/package.json @@ -1,6 +1,6 @@ { "name": "@internal/plugin-todo-list-common", - "version": "1.0.19", + "version": "1.0.20", "backstage": { "role": "common-library", "pluginId": "todo-list", diff --git a/plugins/example-todo-list/CHANGELOG.md b/plugins/example-todo-list/CHANGELOG.md index f61f8b8d0a..e55f882b0a 100644 --- a/plugins/example-todo-list/CHANGELOG.md +++ b/plugins/example-todo-list/CHANGELOG.md @@ -1,5 +1,13 @@ # @internal/plugin-todo-list +## 1.0.29 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/core-plugin-api@1.9.3 + ## 1.0.29-next.1 ### Patch Changes diff --git a/plugins/example-todo-list/package.json b/plugins/example-todo-list/package.json index d008b73538..c8c0a90312 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.29-next.1", + "version": "1.0.29", "backstage": { "role": "frontend-plugin", "pluginId": "todo-list", diff --git a/plugins/home-react/CHANGELOG.md b/plugins/home-react/CHANGELOG.md index 1f1c9a0e2e..c4db30307f 100644 --- a/plugins/home-react/CHANGELOG.md +++ b/plugins/home-react/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-home-react +## 0.1.15 + +### Patch Changes + +- cc81579: Updated dependency `@rjsf/utils` to `5.18.5`. + Updated dependency `@rjsf/core` to `5.18.5`. + Updated dependency `@rjsf/material-ui` to `5.18.5`. + Updated dependency `@rjsf/validator-ajv8` to `5.18.5`. +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/core-plugin-api@1.9.3 + ## 0.1.15-next.2 ### Patch Changes diff --git a/plugins/home-react/package.json b/plugins/home-react/package.json index ec05852818..433a91b475 100644 --- a/plugins/home-react/package.json +++ b/plugins/home-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-home-react", - "version": "0.1.15-next.2", + "version": "0.1.15", "description": "A Backstage plugin that contains react components helps you build a home page", "backstage": { "role": "web-library", diff --git a/plugins/home/CHANGELOG.md b/plugins/home/CHANGELOG.md index e65b3dec1c..eb49e3217b 100644 --- a/plugins/home/CHANGELOG.md +++ b/plugins/home/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-home +## 0.7.7 + +### Patch Changes + +- cc81579: Updated dependency `@rjsf/utils` to `5.18.5`. + Updated dependency `@rjsf/core` to `5.18.5`. + Updated dependency `@rjsf/material-ui` to `5.18.5`. + Updated dependency `@rjsf/validator-ajv8` to `5.18.5`. +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/core-app-api@1.14.0 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-home-react@0.1.15 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + ## 0.7.7-next.2 ### Patch Changes diff --git a/plugins/home/package.json b/plugins/home/package.json index 01dd27a295..189aeec2ac 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-home", - "version": "0.7.7-next.2", + "version": "0.7.7", "description": "A Backstage plugin that helps you build a home page", "backstage": { "role": "frontend-plugin", diff --git a/plugins/kubernetes-backend/CHANGELOG.md b/plugins/kubernetes-backend/CHANGELOG.md index 7b8d3fb534..6a41d014f5 100644 --- a/plugins/kubernetes-backend/CHANGELOG.md +++ b/plugins/kubernetes-backend/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-kubernetes-backend +## 0.18.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-kubernetes-node@0.1.16 + - @backstage/plugin-kubernetes-common@0.8.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + ## 0.18.3-next.1 ### Patch Changes diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index c9d8733319..0e439ecd91 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-backend", - "version": "0.18.3-next.1", + "version": "0.18.3", "description": "A Backstage backend plugin that integrates towards Kubernetes", "backstage": { "role": "backend-plugin", diff --git a/plugins/kubernetes-cluster/CHANGELOG.md b/plugins/kubernetes-cluster/CHANGELOG.md index 8932454b3c..a4b12a0556 100644 --- a/plugins/kubernetes-cluster/CHANGELOG.md +++ b/plugins/kubernetes-cluster/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-kubernetes-cluster +## 0.0.13 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-kubernetes-react@0.4.1 + - @backstage/plugin-kubernetes-common@0.8.1 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + ## 0.0.13-next.2 ### Patch Changes diff --git a/plugins/kubernetes-cluster/package.json b/plugins/kubernetes-cluster/package.json index 3c6e6c8f1b..af63bf4102 100644 --- a/plugins/kubernetes-cluster/package.json +++ b/plugins/kubernetes-cluster/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-cluster", - "version": "0.0.13-next.2", + "version": "0.0.13", "description": "A Backstage plugin that shows details of Kubernetes clusters", "backstage": { "role": "frontend-plugin", diff --git a/plugins/kubernetes-common/CHANGELOG.md b/plugins/kubernetes-common/CHANGELOG.md index e4de39bfd9..a9cabafdd0 100644 --- a/plugins/kubernetes-common/CHANGELOG.md +++ b/plugins/kubernetes-common/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-kubernetes-common +## 0.8.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.0 + - @backstage/catalog-model@1.5.0 + - @backstage/types@1.1.1 + ## 0.8.0 ### Minor Changes diff --git a/plugins/kubernetes-common/package.json b/plugins/kubernetes-common/package.json index 9005c5ffe9..db94d165e4 100644 --- a/plugins/kubernetes-common/package.json +++ b/plugins/kubernetes-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-common", - "version": "0.8.0", + "version": "0.8.1", "description": "Common functionalities for kubernetes, to be shared between kubernetes and kubernetes-backend plugin", "backstage": { "role": "common-library", diff --git a/plugins/kubernetes-node/CHANGELOG.md b/plugins/kubernetes-node/CHANGELOG.md index 4a6514a2d0..608fe97cd2 100644 --- a/plugins/kubernetes-node/CHANGELOG.md +++ b/plugins/kubernetes-node/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-kubernetes-node +## 0.1.16 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-kubernetes-common@0.8.1 + - @backstage/catalog-model@1.5.0 + - @backstage/types@1.1.1 + ## 0.1.16-next.1 ### Patch Changes diff --git a/plugins/kubernetes-node/package.json b/plugins/kubernetes-node/package.json index 461bf1bbbe..798978b5d2 100644 --- a/plugins/kubernetes-node/package.json +++ b/plugins/kubernetes-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-node", - "version": "0.1.16-next.1", + "version": "0.1.16", "description": "Node.js library for the kubernetes plugin", "backstage": { "role": "node-library", diff --git a/plugins/kubernetes-react/CHANGELOG.md b/plugins/kubernetes-react/CHANGELOG.md index 3755d259a8..0fd0cfd07e 100644 --- a/plugins/kubernetes-react/CHANGELOG.md +++ b/plugins/kubernetes-react/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-kubernetes-react +## 0.4.1 + +### Patch Changes + +- e3cb6ab: Add a namespace label to RolloutDrawer +- 2414d86: Fix the `HTML` markup of the `FixDialog` component, `ul` and `li` are not allowed inside a `p` tag. +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-kubernetes-common@0.8.1 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.4.1-next.1 ### Patch Changes diff --git a/plugins/kubernetes-react/package.json b/plugins/kubernetes-react/package.json index fc6f382d3d..42ef4f7913 100644 --- a/plugins/kubernetes-react/package.json +++ b/plugins/kubernetes-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-react", - "version": "0.4.1-next.1", + "version": "0.4.1", "description": "Web library for the kubernetes-react plugin", "backstage": { "role": "web-library", diff --git a/plugins/kubernetes/CHANGELOG.md b/plugins/kubernetes/CHANGELOG.md index a6d07dc706..fcb80b7b26 100644 --- a/plugins/kubernetes/CHANGELOG.md +++ b/plugins/kubernetes/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-kubernetes +## 0.11.12 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-kubernetes-react@0.4.1 + - @backstage/plugin-kubernetes-common@0.8.1 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + ## 0.11.12-next.2 ### Patch Changes diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index d0ee97a882..1ab92f5b3c 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes", - "version": "0.11.12-next.2", + "version": "0.11.12", "description": "A Backstage plugin that integrates towards Kubernetes", "backstage": { "role": "frontend-plugin", diff --git a/plugins/notifications-backend-module-email/CHANGELOG.md b/plugins/notifications-backend-module-email/CHANGELOG.md index c536369352..4bfbfbd05d 100644 --- a/plugins/notifications-backend-module-email/CHANGELOG.md +++ b/plugins/notifications-backend-module-email/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-notifications-backend-module-email +## 0.1.3 + +### Patch Changes + +- 4e4ef2b: Move notification processor filter parsing to common package +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + ## 0.1.3-next.1 ### Patch Changes diff --git a/plugins/notifications-backend-module-email/package.json b/plugins/notifications-backend-module-email/package.json index c47a65d4f4..b7107a4c6b 100644 --- a/plugins/notifications-backend-module-email/package.json +++ b/plugins/notifications-backend-module-email/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications-backend-module-email", - "version": "0.1.3-next.1", + "version": "0.1.3", "description": "The email backend module for the notifications plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/notifications-backend/CHANGELOG.md b/plugins/notifications-backend/CHANGELOG.md index a4be935628..b4fe307f15 100644 --- a/plugins/notifications-backend/CHANGELOG.md +++ b/plugins/notifications-backend/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-notifications-backend +## 0.3.3 + +### Patch Changes + +- d7b8ca5: Added an option to filter notifications by topic +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.3 + - @backstage/plugin-signals-node@0.1.8 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.3.3-next.1 ### Patch Changes diff --git a/plugins/notifications-backend/package.json b/plugins/notifications-backend/package.json index bfa1f2f0bd..abd0a1bbfe 100644 --- a/plugins/notifications-backend/package.json +++ b/plugins/notifications-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications-backend", - "version": "0.3.3-next.1", + "version": "0.3.3", "backstage": { "role": "backend-plugin", "pluginId": "notifications", diff --git a/plugins/notifications-common/CHANGELOG.md b/plugins/notifications-common/CHANGELOG.md index 17231f0147..6e10272c36 100644 --- a/plugins/notifications-common/CHANGELOG.md +++ b/plugins/notifications-common/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-notifications-common +## 0.0.5 + +### Patch Changes + +- 4e4ef2b: Move notification processor filter parsing to common package +- Updated dependencies + - @backstage/config@1.2.0 + ## 0.0.4 ### Patch Changes diff --git a/plugins/notifications-common/package.json b/plugins/notifications-common/package.json index 3802d6535c..139681e6c6 100644 --- a/plugins/notifications-common/package.json +++ b/plugins/notifications-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications-common", - "version": "0.0.4", + "version": "0.0.5", "description": "Common functionalities for the notifications plugin", "backstage": { "role": "common-library", diff --git a/plugins/notifications-node/CHANGELOG.md b/plugins/notifications-node/CHANGELOG.md index 69e594b513..764ee3affb 100644 --- a/plugins/notifications-node/CHANGELOG.md +++ b/plugins/notifications-node/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-notifications-node +## 0.2.3 + +### Patch Changes + +- 4e4ef2b: Move notification processor filter parsing to common package +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-signals-node@0.1.8 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + ## 0.2.3-next.1 ### Patch Changes diff --git a/plugins/notifications-node/package.json b/plugins/notifications-node/package.json index f18ce420f7..04564da21e 100644 --- a/plugins/notifications-node/package.json +++ b/plugins/notifications-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications-node", - "version": "0.2.3-next.1", + "version": "0.2.3", "description": "Node.js library for the notifications plugin", "backstage": { "role": "node-library", diff --git a/plugins/notifications/CHANGELOG.md b/plugins/notifications/CHANGELOG.md index 97e6c50b44..263bd9ba70 100644 --- a/plugins/notifications/CHANGELOG.md +++ b/plugins/notifications/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-notifications +## 0.2.3 + +### Patch Changes + +- 3bf0697: The toolbar on the Notifications page is hidden when there are no listed notifications. +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.4 + ## 0.2.3-next.2 ### Patch Changes diff --git a/plugins/notifications/package.json b/plugins/notifications/package.json index 4ef28f9508..1575c48c5e 100644 --- a/plugins/notifications/package.json +++ b/plugins/notifications/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications", - "version": "0.2.3-next.2", + "version": "0.2.3", "backstage": { "role": "frontend-plugin", "pluginId": "notifications", diff --git a/plugins/org-react/CHANGELOG.md b/plugins/org-react/CHANGELOG.md index d13578fd32..d6e117d579 100644 --- a/plugins/org-react/CHANGELOG.md +++ b/plugins/org-react/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-org-react +## 0.1.26 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + ## 0.1.26-next.2 ### Patch Changes diff --git a/plugins/org-react/package.json b/plugins/org-react/package.json index e6494eaa28..9405b38b59 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.26-next.2", + "version": "0.1.26", "backstage": { "role": "web-library", "pluginId": "org", diff --git a/plugins/org/CHANGELOG.md b/plugins/org/CHANGELOG.md index aa4bd9a93f..6d1fb352f8 100644 --- a/plugins/org/CHANGELOG.md +++ b/plugins/org/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-org +## 0.6.27 + +### Patch Changes + +- 5132d28: The `useGetEntities` hook could result in requests to `/api/catalog/entities` where the headers exceed the default maximum Node.js header size of 16KB. The hook logic has been adjusted to batch the requests. +- c307ef4: Added `relationType` property to EntityMembersListCard component that allows for display users related to a group via some other relationship aside from `memberOf`. + + Also, as a side effect, the `relationsType` property has been deprecated in favor of a more accurately named `relationAggregation` property. + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/catalog-model@1.5.0 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + ## 0.6.27-next.2 ### Patch Changes diff --git a/plugins/org/package.json b/plugins/org/package.json index c2d43bc5ed..2530ca2ea1 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-org", - "version": "0.6.27-next.2", + "version": "0.6.27", "description": "A Backstage plugin that helps you create entity pages for your organization", "backstage": { "role": "frontend-plugin", diff --git a/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md b/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md index 616c6acda2..e06db25a91 100644 --- a/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md +++ b/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-permission-backend-module-allow-all-policy +## 0.1.19 + +### Patch Changes + +- ed10fd2: Internal refactor to use new `PolicyQueryUser` type. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/plugin-auth-node@0.4.17 + ## 0.1.19-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 60e11825f4..27303483f7 100644 --- a/plugins/permission-backend-module-policy-allow-all/package.json +++ b/plugins/permission-backend-module-policy-allow-all/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-backend-module-allow-all-policy", - "version": "0.1.19-next.1", + "version": "0.1.19", "description": "Allow all policy backend module for the permission plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/permission-backend/CHANGELOG.md b/plugins/permission-backend/CHANGELOG.md index 39ae10e557..e5a826f67a 100644 --- a/plugins/permission-backend/CHANGELOG.md +++ b/plugins/permission-backend/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-permission-backend +## 0.5.46 + +### Patch Changes + +- ed10fd2: The `PermissionPolicy` interface has been updated to align with the recent changes to the Backstage auth system. The second argument to the `handle` method is now of the new `PolicyQueryUser` type. This type maintains the old fields from the `BackstageIdentityResponse`, which are now all deprecated. Instead, two new fields have been added, which allows access to the same information: + + - `credentials` - A `BackstageCredentials` object, which is useful for making requests to other services on behalf of the user as part of evaluating the policy. This replaces the deprecated `token` field. See the [Auth Service documentation](https://backstage.io/docs/backend-system/core-services/auth#creating-request-tokens) for information about how to create a token using these credentials. + - `info` - A `BackstageUserInfo` object, which contains the same information as the deprecated `identity`, except for the `type` field that was redundant. + + Most existing policies can be updated by replacing the `BackstageIdentityResponse` type with `PolicyQueryUser`, which is exported from `@backstage/plugin-permission-node`, as well as replacing any occurrences of `user?.identity` with `user?.info`. + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.5.46-next.1 ### Patch Changes diff --git a/plugins/permission-backend/package.json b/plugins/permission-backend/package.json index 43a57407e1..95647ba82b 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.46-next.1", + "version": "0.5.46", "backstage": { "role": "backend-plugin", "pluginId": "permission", diff --git a/plugins/permission-common/CHANGELOG.md b/plugins/permission-common/CHANGELOG.md index e6b637a092..92a33afea2 100644 --- a/plugins/permission-common/CHANGELOG.md +++ b/plugins/permission-common/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-permission-common +## 0.8.0 + +### Minor Changes + +- f4085b8: **BREAKING**: Removed the deprecated and unused `token` option from `EvaluatorRequestOptions`. The `PermissionsClient` now has its own `PermissionClientRequestOptions` type that declares the `token` option instead. + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.7.14 ### Patch Changes diff --git a/plugins/permission-common/package.json b/plugins/permission-common/package.json index ee54459589..8d6f54fac0 100644 --- a/plugins/permission-common/package.json +++ b/plugins/permission-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-common", - "version": "0.7.14", + "version": "0.8.0", "description": "Isomorphic types and client for Backstage permissions and authorization", "backstage": { "role": "common-library", diff --git a/plugins/permission-node/CHANGELOG.md b/plugins/permission-node/CHANGELOG.md index a63abb1d95..326dfb99d3 100644 --- a/plugins/permission-node/CHANGELOG.md +++ b/plugins/permission-node/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-permission-node +## 0.8.0 + +### Minor Changes + +- 36f91e8: **BREAKING**: Updated the `ServerPermissionClient` to match the new `PermissionsService` interface, where the deprecated `token` option has been removed and the options are now required. + +### Patch Changes + +- ed10fd2: The `PermissionPolicy` interface has been updated to align with the recent changes to the Backstage auth system. The second argument to the `handle` method is now of the new `PolicyQueryUser` type. This type maintains the old fields from the `BackstageIdentityResponse`, which are now all deprecated. Instead, two new fields have been added, which allows access to the same information: + + - `credentials` - A `BackstageCredentials` object, which is useful for making requests to other services on behalf of the user as part of evaluating the policy. This replaces the deprecated `token` field. See the [Auth Service documentation](https://backstage.io/docs/backend-system/core-services/auth#creating-request-tokens) for information about how to create a token using these credentials. + - `info` - A `BackstageUserInfo` object, which contains the same information as the deprecated `identity`, except for the `type` field that was redundant. + + Most existing policies can be updated by replacing the `BackstageIdentityResponse` type with `PolicyQueryUser`, which is exported from `@backstage/plugin-permission-node`, as well as replacing any occurrences of `user?.identity` with `user?.info`. + +- 28b2cfb: Fix invalid cross-reference in API Reference docs +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.7.33-next.1 ### Patch Changes diff --git a/plugins/permission-node/package.json b/plugins/permission-node/package.json index db3c067088..4bbf4d5faf 100644 --- a/plugins/permission-node/package.json +++ b/plugins/permission-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-node", - "version": "0.7.33-next.1", + "version": "0.8.0", "description": "Common permission and authorization utilities for backend plugins", "backstage": { "role": "node-library", diff --git a/plugins/permission-react/CHANGELOG.md b/plugins/permission-react/CHANGELOG.md index 1eb951e625..2b19b7e849 100644 --- a/plugins/permission-react/CHANGELOG.md +++ b/plugins/permission-react/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-permission-react +## 0.4.24 + +### Patch Changes + +- 28b2cfb: Improve API Reference documentation +- Updated dependencies + - @backstage/plugin-permission-common@0.8.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + ## 0.4.23 ### Patch Changes diff --git a/plugins/permission-react/package.json b/plugins/permission-react/package.json index 9ebb13e633..c119be8eb9 100644 --- a/plugins/permission-react/package.json +++ b/plugins/permission-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-react", - "version": "0.4.23", + "version": "0.4.24", "backstage": { "role": "web-library", "pluginId": "permission", diff --git a/plugins/proxy-backend/CHANGELOG.md b/plugins/proxy-backend/CHANGELOG.md index a6c1ef02d2..30cacb1d02 100644 --- a/plugins/proxy-backend/CHANGELOG.md +++ b/plugins/proxy-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-proxy-backend +## 0.5.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + ## 0.5.3-next.1 ### Patch Changes diff --git a/plugins/proxy-backend/package.json b/plugins/proxy-backend/package.json index 23acc935f3..2e7bd08550 100644 --- a/plugins/proxy-backend/package.json +++ b/plugins/proxy-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-proxy-backend", - "version": "0.5.3-next.1", + "version": "0.5.3", "description": "A Backstage backend plugin that helps you set up proxy endpoints in the backend", "backstage": { "role": "backend-plugin", diff --git a/plugins/scaffolder-backend-module-azure/CHANGELOG.md b/plugins/scaffolder-backend-module-azure/CHANGELOG.md index c634d8c8ca..e386b5d9b8 100644 --- a/plugins/scaffolder-backend-module-azure/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-azure/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder-backend-module-azure +## 0.1.14 + +### Patch Changes + +- 661b354: Fixed a bug where the `RepoUrlPicker` would still require the `owner` field for `azure` +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.1.14-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-azure/package.json b/plugins/scaffolder-backend-module-azure/package.json index c0e00e8ffe..205beae578 100644 --- a/plugins/scaffolder-backend-module-azure/package.json +++ b/plugins/scaffolder-backend-module-azure/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-azure", - "version": "0.1.14-next.1", + "version": "0.1.14", "description": "The azure module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md index 4e1e2b9531..c8c79a302b 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-backend-module-bitbucket-cloud +## 0.1.12 + +### Patch Changes + +- b5deed0: Add support for `autocomplete` handler to provide autocomplete options for `RepoUrlPicker` +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/plugin-bitbucket-cloud-common@0.2.21 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.1.12-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/package.json b/plugins/scaffolder-backend-module-bitbucket-cloud/package.json index 5ce826ff1a..67f275462b 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/package.json +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud", - "version": "0.1.12-next.1", + "version": "0.1.12", "description": "The Bitbucket Cloud module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md b/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md index 3443242e91..5d2a0754cd 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-backend-module-bitbucket-server +## 0.1.12 + +### Patch Changes + +- 6a4ad4e: Instead of using hardcoded `targetBranch` now fetch the default branch from Bitbucket repository. + This prevents from errors when no `targetBranch` is provided and the default repository branch is different from `master`, for example: `main`. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.1.12-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-bitbucket-server/package.json b/plugins/scaffolder-backend-module-bitbucket-server/package.json index b396faa5e5..a33bf90040 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/package.json +++ b/plugins/scaffolder-backend-module-bitbucket-server/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-bitbucket-server", - "version": "0.1.12-next.1", + "version": "0.1.12", "description": "The Bitbucket Server module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md b/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md index 35f5382652..414f8b7bd8 100644 --- a/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-backend-module-bitbucket +## 0.2.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.12 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.12 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.2.12-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-bitbucket/package.json b/plugins/scaffolder-backend-module-bitbucket/package.json index bca6e94878..95d92c39b8 100644 --- a/plugins/scaffolder-backend-module-bitbucket/package.json +++ b/plugins/scaffolder-backend-module-bitbucket/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-bitbucket", - "version": "0.2.12-next.1", + "version": "0.2.12", "description": "The bitbucket module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md b/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md index b3c7bfbe36..1613f1881c 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.23 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.2.23-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 f607696136..9fe6781eff 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/package.json +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown", - "version": "0.2.23-next.1", + "version": "0.2.23", "description": "The confluence-to-markdown module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md index 5854e9ff47..f2dc2a822d 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-scaffolder-backend-module-cookiecutter +## 0.2.46 + +### Patch Changes + +- 0ac124b: Updated configuration instructions +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.2.46-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-cookiecutter/package.json b/plugins/scaffolder-backend-module-cookiecutter/package.json index 43a7e348a4..0b0036ee5a 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/package.json +++ b/plugins/scaffolder-backend-module-cookiecutter/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-cookiecutter", - "version": "0.2.46-next.1", + "version": "0.2.46", "description": "A module for the scaffolder backend that lets you template projects using cookiecutter", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-gcp/CHANGELOG.md b/plugins/scaffolder-backend-module-gcp/CHANGELOG.md index e32c2ef08f..51dd92b2cf 100644 --- a/plugins/scaffolder-backend-module-gcp/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gcp/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-scaffolder-backend-module-gcp +## 0.1.0 + +### Minor Changes + +- 0b52438: Serialization of the scaffolder workspace into GCP bucket + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.1.0-next.3 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gcp/package.json b/plugins/scaffolder-backend-module-gcp/package.json index c441acb21a..ae64d1de61 100644 --- a/plugins/scaffolder-backend-module-gcp/package.json +++ b/plugins/scaffolder-backend-module-gcp/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gcp", - "version": "0.1.0-next.3", + "version": "0.1.0", "description": "The GCP Bucket module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md b/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md index dd26e1d5a8..7b95a80811 100644 --- a/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-scaffolder-backend-module-gerrit +## 0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.1.14-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gerrit/package.json b/plugins/scaffolder-backend-module-gerrit/package.json index 31a30c3f7e..96c069ea97 100644 --- a/plugins/scaffolder-backend-module-gerrit/package.json +++ b/plugins/scaffolder-backend-module-gerrit/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gerrit", - "version": "0.1.14-next.1", + "version": "0.1.14", "description": "The gerrit module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-gitea/CHANGELOG.md b/plugins/scaffolder-backend-module-gitea/CHANGELOG.md index f3ceb7ce8c..4c03220562 100644 --- a/plugins/scaffolder-backend-module-gitea/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gitea/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-scaffolder-backend-module-gitea +## 0.1.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.1.12-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gitea/package.json b/plugins/scaffolder-backend-module-gitea/package.json index 3cacbc66db..69a84f43e7 100644 --- a/plugins/scaffolder-backend-module-gitea/package.json +++ b/plugins/scaffolder-backend-module-gitea/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gitea", - "version": "0.1.12-next.1", + "version": "0.1.12", "description": "The gitea module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-github/CHANGELOG.md b/plugins/scaffolder-backend-module-github/CHANGELOG.md index 2d3c6ff0f2..680cb0469d 100644 --- a/plugins/scaffolder-backend-module-github/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-github/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-scaffolder-backend-module-github +## 0.4.0 + +### Minor Changes + +- 70c4b36: Adds support for custom tag policies when creating GitHub environments. + +### Patch Changes + +- ccfc9d1: Fixed bug resulting from missing required owner and repo arguments in `getEnvironmentPublicKey` in action `github:environment:create`. + + Adding environment secrets now works as expected. + +- 141f366: Added action to enable GitHub Pages on a repo +- 4410fed: Fixed issue with octokit call missing owner and repo when creating environment variables and secrets using github:environment:create action +- dfaa28d: Adds `requireLastPushApproval` input property to configure Branch Protection Settings in `github:publish` action + + Adds `requireLastPushApproval` input property to configure Branch Protection Settings in `github:repo:push` action + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.4.0-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-github/package.json b/plugins/scaffolder-backend-module-github/package.json index 500ec86f9f..7732c7c11a 100644 --- a/plugins/scaffolder-backend-module-github/package.json +++ b/plugins/scaffolder-backend-module-github/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-github", - "version": "0.4.0-next.1", + "version": "0.4.0", "description": "The github module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md b/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md index 0c8f0529a6..60e7f1bccf 100644 --- a/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-scaffolder-backend-module-gitlab +## 0.4.4 + +### Patch Changes + +- 0ac124b: Updated configuration instructions +- 2fb0eb8: Added support for passing `variables` to `gitlab:pipeline:trigger` +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.4.4-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gitlab/package.json b/plugins/scaffolder-backend-module-gitlab/package.json index 499cfd6872..8228a3ec0f 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.4.4-next.1", + "version": "0.4.4", "backstage": { "role": "backend-plugin-module", "pluginId": "scaffolder", diff --git a/plugins/scaffolder-backend-module-notifications/CHANGELOG.md b/plugins/scaffolder-backend-module-notifications/CHANGELOG.md index 6371124957..db52ded0c8 100644 --- a/plugins/scaffolder-backend-module-notifications/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-notifications/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-scaffolder-backend-module-notifications +## 0.0.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.3 + ## 0.0.5-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-notifications/package.json b/plugins/scaffolder-backend-module-notifications/package.json index 7c983c36ce..68e177abfa 100644 --- a/plugins/scaffolder-backend-module-notifications/package.json +++ b/plugins/scaffolder-backend-module-notifications/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-notifications", - "version": "0.0.5-next.1", + "version": "0.0.5", "description": "The notifications backend module for the scaffolder plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-rails/CHANGELOG.md b/plugins/scaffolder-backend-module-rails/CHANGELOG.md index 0db7584509..cd34152910 100644 --- a/plugins/scaffolder-backend-module-rails/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-rails/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-scaffolder-backend-module-rails +## 0.4.39 + +### Patch Changes + +- 0ac124b: Updated configuration instructions +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.4.39-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-rails/package.json b/plugins/scaffolder-backend-module-rails/package.json index c15815d2fa..496174d510 100644 --- a/plugins/scaffolder-backend-module-rails/package.json +++ b/plugins/scaffolder-backend-module-rails/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-rails", - "version": "0.4.39-next.1", + "version": "0.4.39", "description": "A module for the scaffolder backend that lets you template projects using Rails", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-sentry/CHANGELOG.md b/plugins/scaffolder-backend-module-sentry/CHANGELOG.md index 29e8c17b04..113a63222f 100644 --- a/plugins/scaffolder-backend-module-sentry/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-sentry/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-scaffolder-backend-module-sentry +## 0.1.30 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.1.30-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-sentry/package.json b/plugins/scaffolder-backend-module-sentry/package.json index c0866f979d..264736692a 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.30-next.1", + "version": "0.1.30", "backstage": { "role": "backend-plugin-module", "pluginId": "scaffolder", diff --git a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md index 4e99b51284..53d2369d85 100644 --- a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-scaffolder-backend-module-yeoman +## 0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/plugin-scaffolder-node-test-utils@0.1.9 + - @backstage/types@1.1.1 + ## 0.3.6-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-yeoman/package.json b/plugins/scaffolder-backend-module-yeoman/package.json index 76158fdc01..5c65315e22 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.3.6-next.1", + "version": "0.3.6", "backstage": { "role": "backend-plugin-module", "pluginId": "scaffolder", diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md index a4df9e72e9..27e4b4465e 100644 --- a/plugins/scaffolder-backend/CHANGELOG.md +++ b/plugins/scaffolder-backend/CHANGELOG.md @@ -1,5 +1,45 @@ # @backstage/plugin-scaffolder-backend +## 1.23.0 + +### Minor Changes + +- b5deed0: Add support for `autocomplete` extension point to provide additional `autocomplete` handlers +- 0b52438: Serialization of the scaffolder workspace into GCP bucket + +### Patch Changes + +- b9451dd: Updated `catalog:write` scaffolder action to show correct file path location in log message +- ff1bb4c: Added a documentation how to use checkpoints +- da90cce: Updated dependency `esbuild` to `^0.21.0`. +- 62d1fe3: Fix user entity not being fetched for scaffolder dry runner +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-scaffolder-backend-module-github@0.4.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.4.4 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.12 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.14 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.12 + - @backstage/plugin-bitbucket-cloud-common@0.2.21 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.20 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.12 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.14 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.12 + - @backstage/plugin-scaffolder-common@1.5.4 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 1.23.0-next.2 ### Patch Changes diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 10d827762e..c86a048d46 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend", - "version": "1.23.0-next.2", + "version": "1.23.0", "description": "The Backstage backend plugin that helps you create new things", "backstage": { "role": "backend-plugin", diff --git a/plugins/scaffolder-common/CHANGELOG.md b/plugins/scaffolder-common/CHANGELOG.md index 12f3f9e235..914faf70f3 100644 --- a/plugins/scaffolder-common/CHANGELOG.md +++ b/plugins/scaffolder-common/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-scaffolder-common +## 1.5.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.0 + - @backstage/catalog-model@1.5.0 + - @backstage/types@1.1.1 + ## 1.5.3 ### Patch Changes diff --git a/plugins/scaffolder-common/package.json b/plugins/scaffolder-common/package.json index 3e56510daf..d86f0d67c0 100644 --- a/plugins/scaffolder-common/package.json +++ b/plugins/scaffolder-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-common", - "version": "1.5.3", + "version": "1.5.4", "description": "Common functionalities for the scaffolder, to be shared between scaffolder and scaffolder-backend plugin", "backstage": { "role": "common-library", diff --git a/plugins/scaffolder-node-test-utils/CHANGELOG.md b/plugins/scaffolder-node-test-utils/CHANGELOG.md index 9104fbcb26..7d578a2b14 100644 --- a/plugins/scaffolder-node-test-utils/CHANGELOG.md +++ b/plugins/scaffolder-node-test-utils/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-scaffolder-node-test-utils +## 0.1.9 + +### Patch Changes + +- 54429b5: Filename and imports correction for mockActionContext.ts +- Updated dependencies + - @backstage/backend-test-utils@0.4.4 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-scaffolder-node@0.4.8 + - @backstage/types@1.1.1 + ## 0.1.9-next.1 ### Patch Changes diff --git a/plugins/scaffolder-node-test-utils/package.json b/plugins/scaffolder-node-test-utils/package.json index d361d0ae1d..827b654b4e 100644 --- a/plugins/scaffolder-node-test-utils/package.json +++ b/plugins/scaffolder-node-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-node-test-utils", - "version": "0.1.9-next.1", + "version": "0.1.9", "backstage": { "role": "node-library", "pluginId": "scaffolder", diff --git a/plugins/scaffolder-node/CHANGELOG.md b/plugins/scaffolder-node/CHANGELOG.md index f67c8c8cda..59658dcb11 100644 --- a/plugins/scaffolder-node/CHANGELOG.md +++ b/plugins/scaffolder-node/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-scaffolder-node +## 0.4.8 + +### Patch Changes + +- 661b354: Fixed a bug where the `RepoUrlPicker` would still require the `owner` field for `azure` +- b5deed0: Add support for `autocomplete` extension point to provide additional `autocomplete` handlers +- 0b52438: Serialization of the scaffolder workspace into GCP bucket +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/integration@1.13.0 + - @backstage/plugin-scaffolder-common@1.5.4 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.4.8-next.1 ### Patch Changes diff --git a/plugins/scaffolder-node/package.json b/plugins/scaffolder-node/package.json index 079eebfb00..07e468620b 100644 --- a/plugins/scaffolder-node/package.json +++ b/plugins/scaffolder-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-node", - "version": "0.4.8-next.1", + "version": "0.4.8", "description": "The plugin-scaffolder-node module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "node-library", diff --git a/plugins/scaffolder-react/CHANGELOG.md b/plugins/scaffolder-react/CHANGELOG.md index a1ed542bd5..68f94ac3fd 100644 --- a/plugins/scaffolder-react/CHANGELOG.md +++ b/plugins/scaffolder-react/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-scaffolder-react +## 1.10.0 + +### Minor Changes + +- 354e68c: Improve validation error display text in scaffolder +- b5deed0: Add support for `bitbucketCloud` autocomplete in `RepoUrlPicker` + +### Patch Changes + +- cc81579: Updated dependency `@rjsf/utils` to `5.18.5`. + Updated dependency `@rjsf/core` to `5.18.5`. + Updated dependency `@rjsf/material-ui` to `5.18.5`. + Updated dependency `@rjsf/validator-ajv8` to `5.18.5`. +- 4d7e11f: disables rendering of output box if no output is returned +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-scaffolder-common@1.5.4 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 1.10.0-next.2 ### Patch Changes diff --git a/plugins/scaffolder-react/package.json b/plugins/scaffolder-react/package.json index 36ee0870fc..f2d7d44a01 100644 --- a/plugins/scaffolder-react/package.json +++ b/plugins/scaffolder-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-react", - "version": "1.10.0-next.2", + "version": "1.10.0", "description": "A frontend library that helps other Backstage plugins interact with the Scaffolder", "backstage": { "role": "web-library", diff --git a/plugins/scaffolder/CHANGELOG.md b/plugins/scaffolder/CHANGELOG.md index 3c4cfe54ab..2da2802808 100644 --- a/plugins/scaffolder/CHANGELOG.md +++ b/plugins/scaffolder/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-scaffolder +## 1.23.0 + +### Minor Changes + +- 52b6db0: Use virtualization with `EntityPicker` as done earlier with `MultiEntityPicker` to fix performance issues with large data sets. `VirtualizedListbox` extracted into reusable component. +- 3583ce5: Use virtualization with `MultiEntityPicker`. Fixes performance issues with large data sets. +- b5deed0: Add support for `bitbucketCloud` autocomplete in `RepoUrlPicker` + +### Patch Changes + +- 4d7e11f: enable resizing of the task log stream viewer +- 661b354: Fixed a bug where the `RepoUrlPicker` would still require the `owner` field for `azure` +- cc81579: Updated dependency `@rjsf/utils` to `5.18.5`. + Updated dependency `@rjsf/core` to `5.18.5`. + Updated dependency `@rjsf/material-ui` to `5.18.5`. + Updated dependency `@rjsf/validator-ajv8` to `5.18.5`. +- 89c44b3: Support `catalogFilter` array on `OwnedEntityPicker` +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/integration@1.13.0 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-scaffolder-react@1.10.0 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-scaffolder-common@1.5.4 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/integration-react@1.1.29 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 1.22.1-next.2 ### Patch Changes diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index aaa681d174..5cc587fe4d 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder", - "version": "1.22.1-next.2", + "version": "1.23.0", "description": "The Backstage plugin that helps you create new things", "backstage": { "role": "frontend-plugin", diff --git a/plugins/search-backend-module-catalog/CHANGELOG.md b/plugins/search-backend-module-catalog/CHANGELOG.md index d064814ecb..29304c6cfd 100644 --- a/plugins/search-backend-module-catalog/CHANGELOG.md +++ b/plugins/search-backend-module-catalog/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-search-backend-module-catalog +## 0.1.28 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-search-backend-node@1.2.27 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-search-common@1.2.13 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.1.28-next.1 ### Patch Changes diff --git a/plugins/search-backend-module-catalog/package.json b/plugins/search-backend-module-catalog/package.json index 0f45f3ce43..6ec054f10d 100644 --- a/plugins/search-backend-module-catalog/package.json +++ b/plugins/search-backend-module-catalog/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-catalog", - "version": "0.1.28-next.1", + "version": "0.1.28", "description": "A module for the search backend that exports catalog modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-elasticsearch/CHANGELOG.md b/plugins/search-backend-module-elasticsearch/CHANGELOG.md index f0628d0254..d561b1127a 100644 --- a/plugins/search-backend-module-elasticsearch/CHANGELOG.md +++ b/plugins/search-backend-module-elasticsearch/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-search-backend-module-elasticsearch +## 1.5.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-search-backend-node@1.2.27 + - @backstage/plugin-search-common@1.2.13 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + ## 1.5.3-next.1 ### Patch Changes diff --git a/plugins/search-backend-module-elasticsearch/package.json b/plugins/search-backend-module-elasticsearch/package.json index 9cb61ee97b..d96b4c924d 100644 --- a/plugins/search-backend-module-elasticsearch/package.json +++ b/plugins/search-backend-module-elasticsearch/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-elasticsearch", - "version": "1.5.3-next.1", + "version": "1.5.3", "description": "A module for the search backend that implements search using ElasticSearch", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-explore/CHANGELOG.md b/plugins/search-backend-module-explore/CHANGELOG.md index 888be119be..f5b60fa87e 100644 --- a/plugins/search-backend-module-explore/CHANGELOG.md +++ b/plugins/search-backend-module-explore/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-search-backend-module-explore +## 0.1.28 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-search-backend-node@1.2.27 + - @backstage/plugin-search-common@1.2.13 + - @backstage/config@1.2.0 + ## 0.1.28-next.1 ### Patch Changes diff --git a/plugins/search-backend-module-explore/package.json b/plugins/search-backend-module-explore/package.json index f37c4d55d3..9fd252df66 100644 --- a/plugins/search-backend-module-explore/package.json +++ b/plugins/search-backend-module-explore/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-explore", - "version": "0.1.28-next.1", + "version": "0.1.28", "description": "A module for the search backend that exports explore modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-pg/CHANGELOG.md b/plugins/search-backend-module-pg/CHANGELOG.md index 3fe18213bb..c19c797bde 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.32 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-app-api@0.8.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-search-backend-node@1.2.27 + - @backstage/plugin-search-common@1.2.13 + - @backstage/config@1.2.0 + ## 0.5.32-next.1 ### Patch Changes diff --git a/plugins/search-backend-module-pg/package.json b/plugins/search-backend-module-pg/package.json index ec6782535f..8bdcf14306 100644 --- a/plugins/search-backend-module-pg/package.json +++ b/plugins/search-backend-module-pg/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-pg", - "version": "0.5.32-next.1", + "version": "0.5.32", "description": "A module for the search backend that implements search using PostgreSQL", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md b/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md index 96214102b7..6c86337062 100644 --- a/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md +++ b/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-search-backend-module-stack-overflow-collator +## 0.1.15 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-search-backend-node@1.2.27 + - @backstage/plugin-search-common@1.2.13 + - @backstage/config@1.2.0 + ## 0.1.15-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 dd09d75b11..4d06f928a0 100644 --- a/plugins/search-backend-module-stack-overflow-collator/package.json +++ b/plugins/search-backend-module-stack-overflow-collator/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-stack-overflow-collator", - "version": "0.1.15-next.1", + "version": "0.1.15", "description": "A module for the search backend that exports stack overflow modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-techdocs/CHANGELOG.md b/plugins/search-backend-module-techdocs/CHANGELOG.md index 706d178601..2c41ecda1f 100644 --- a/plugins/search-backend-module-techdocs/CHANGELOG.md +++ b/plugins/search-backend-module-techdocs/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-search-backend-module-techdocs +## 0.1.27 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-techdocs-node@1.12.8 + - @backstage/plugin-catalog-node@1.12.4 + - @backstage/plugin-search-backend-node@1.2.27 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-search-common@1.2.13 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + ## 0.1.27-next.1 ### Patch Changes diff --git a/plugins/search-backend-module-techdocs/package.json b/plugins/search-backend-module-techdocs/package.json index b26065cc60..a04f64756b 100644 --- a/plugins/search-backend-module-techdocs/package.json +++ b/plugins/search-backend-module-techdocs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-techdocs", - "version": "0.1.27-next.1", + "version": "0.1.27", "description": "A module for the search backend that exports techdocs modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-node/CHANGELOG.md b/plugins/search-backend-node/CHANGELOG.md index 26cd8e91eb..f43f3c4009 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.27 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/backend-tasks@0.5.27 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-search-common@1.2.13 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 1.2.27-next.1 ### Patch Changes diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index e8cc89d117..a236eff6c0 100644 --- a/plugins/search-backend-node/package.json +++ b/plugins/search-backend-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-node", - "version": "1.2.27-next.1", + "version": "1.2.27", "description": "A library for Backstage backend plugins that want to interact with the search backend plugin", "backstage": { "role": "node-library", diff --git a/plugins/search-backend/CHANGELOG.md b/plugins/search-backend/CHANGELOG.md index 2de90e3960..eb391c6bba 100644 --- a/plugins/search-backend/CHANGELOG.md +++ b/plugins/search-backend/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-search-backend +## 1.5.14 + +### Patch Changes + +- 343f656: The `AuthorizedSearchEngine` will now ignore the deprecated `token` option, and treat it as an unauthorized request. This will not have any effect in practice, since credentials are always provided by the router. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-defaults@0.4.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.0 + - @backstage/backend-openapi-utils@0.1.15 + - @backstage/plugin-search-backend-node@1.2.27 + - @backstage/plugin-search-common@1.2.13 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 1.5.14-next.1 ### Patch Changes diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index 8d266c63a8..a0e7b48f5b 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend", - "version": "1.5.14-next.1", + "version": "1.5.14", "description": "The Backstage backend plugin that provides your backstage app with search", "backstage": { "role": "backend-plugin", diff --git a/plugins/search-common/CHANGELOG.md b/plugins/search-common/CHANGELOG.md index e034c62315..5b163eab0d 100644 --- a/plugins/search-common/CHANGELOG.md +++ b/plugins/search-common/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-search-common +## 1.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.0 + - @backstage/types@1.1.1 + ## 1.2.12 ### Patch Changes diff --git a/plugins/search-common/package.json b/plugins/search-common/package.json index 61edfd13f3..8d0f4e9585 100644 --- a/plugins/search-common/package.json +++ b/plugins/search-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-common", - "version": "1.2.12", + "version": "1.2.13", "description": "Common functionalities for Search, to be shared between various search-enabled plugins", "backstage": { "role": "common-library", diff --git a/plugins/search-react/CHANGELOG.md b/plugins/search-react/CHANGELOG.md index 494ce07772..04d8bf312a 100644 --- a/plugins/search-react/CHANGELOG.md +++ b/plugins/search-react/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-search-react +## 1.7.13 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-search-common@1.2.13 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 1.7.13-next.1 ### Patch Changes diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index a0701e1f3b..b5c17c369a 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.13-next.1", + "version": "1.7.13", "backstage": { "role": "web-library", "pluginId": "search", diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md index a6cab671b5..bce322e95a 100644 --- a/plugins/search/CHANGELOG.md +++ b/plugins/search/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-search +## 1.4.14 + +### Patch Changes + +- 1117aba: Update deps in search api extension to include fetch api +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-search-common@1.2.13 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/plugin-search-react@1.7.13 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 1.4.14-next.2 ### Patch Changes diff --git a/plugins/search/package.json b/plugins/search/package.json index ad8210df4c..56271eca58 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search", - "version": "1.4.14-next.2", + "version": "1.4.14", "description": "The Backstage plugin that provides your backstage app with search", "backstage": { "role": "frontend-plugin", diff --git a/plugins/signals-backend/CHANGELOG.md b/plugins/signals-backend/CHANGELOG.md index aaf4a0c15f..e0525a0e78 100644 --- a/plugins/signals-backend/CHANGELOG.md +++ b/plugins/signals-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-signals-backend +## 0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-signals-node@0.1.8 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + ## 0.1.8-next.1 ### Patch Changes diff --git a/plugins/signals-backend/package.json b/plugins/signals-backend/package.json index 0bded11c2e..1e0ac41fcb 100644 --- a/plugins/signals-backend/package.json +++ b/plugins/signals-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals-backend", - "version": "0.1.8-next.1", + "version": "0.1.8", "backstage": { "role": "backend-plugin", "pluginId": "signals", diff --git a/plugins/signals-node/CHANGELOG.md b/plugins/signals-node/CHANGELOG.md index cbcdea7a98..0353548fe5 100644 --- a/plugins/signals-node/CHANGELOG.md +++ b/plugins/signals-node/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-signals-node +## 0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-events-node@0.3.8 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + ## 0.1.8-next.1 ### Patch Changes diff --git a/plugins/signals-node/package.json b/plugins/signals-node/package.json index 033dcb8246..1cea62c21b 100644 --- a/plugins/signals-node/package.json +++ b/plugins/signals-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals-node", - "version": "0.1.8-next.1", + "version": "0.1.8", "description": "Node.js library for the signals plugin", "backstage": { "role": "node-library", diff --git a/plugins/signals/CHANGELOG.md b/plugins/signals/CHANGELOG.md index 9ccdff8b97..a4a7daec35 100644 --- a/plugins/signals/CHANGELOG.md +++ b/plugins/signals/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-signals +## 0.0.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.4 + ## 0.0.8-next.1 ### Patch Changes diff --git a/plugins/signals/package.json b/plugins/signals/package.json index 58b82fab7a..88ca252c1f 100644 --- a/plugins/signals/package.json +++ b/plugins/signals/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals", - "version": "0.0.8-next.1", + "version": "0.0.8", "backstage": { "role": "frontend-plugin", "pluginId": "signals", diff --git a/plugins/techdocs-addons-test-utils/CHANGELOG.md b/plugins/techdocs-addons-test-utils/CHANGELOG.md index 5b247addab..3135cc5ffd 100644 --- a/plugins/techdocs-addons-test-utils/CHANGELOG.md +++ b/plugins/techdocs-addons-test-utils/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-techdocs-addons-test-utils +## 1.0.35 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.7 + - @backstage/plugin-techdocs-react@1.2.6 + - @backstage/core-app-api@1.14.0 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-catalog@1.21.1 + - @backstage/test-utils@1.5.8 + - @backstage/integration-react@1.1.29 + - @backstage/plugin-search-react@1.7.13 + - @backstage/core-plugin-api@1.9.3 + ## 1.0.35-next.2 ### Patch Changes diff --git a/plugins/techdocs-addons-test-utils/package.json b/plugins/techdocs-addons-test-utils/package.json index 966308ee94..57cd4d06a6 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.35-next.2", + "version": "1.0.35", "backstage": { "role": "web-library", "pluginId": "techdocs-addons", diff --git a/plugins/techdocs-backend/CHANGELOG.md b/plugins/techdocs-backend/CHANGELOG.md index d50062c744..571b0d68fc 100644 --- a/plugins/techdocs-backend/CHANGELOG.md +++ b/plugins/techdocs-backend/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-techdocs-backend +## 1.10.9 + +### Patch Changes + +- 9ecf5fd: Adds extension point for publishers to the techdocs backend +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-techdocs-node@1.12.8 + - @backstage/integration@1.13.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.27 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 1.10.9-next.1 ### Patch Changes diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index 1533cdc3fe..ce0df2ca78 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-backend", - "version": "1.10.9-next.1", + "version": "1.10.9", "description": "The Backstage backend plugin that renders technical documentation for your components", "backstage": { "role": "backend-plugin", diff --git a/plugins/techdocs-module-addons-contrib/CHANGELOG.md b/plugins/techdocs-module-addons-contrib/CHANGELOG.md index 2cc99a8158..4072d96d9f 100644 --- a/plugins/techdocs-module-addons-contrib/CHANGELOG.md +++ b/plugins/techdocs-module-addons-contrib/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-techdocs-module-addons-contrib +## 1.1.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.6 + - @backstage/core-components@0.14.9 + - @backstage/integration@1.13.0 + - @backstage/integration-react@1.1.29 + - @backstage/core-plugin-api@1.9.3 + ## 1.1.12-next.1 ### Patch Changes diff --git a/plugins/techdocs-module-addons-contrib/package.json b/plugins/techdocs-module-addons-contrib/package.json index f68df2a883..3c226f6a50 100644 --- a/plugins/techdocs-module-addons-contrib/package.json +++ b/plugins/techdocs-module-addons-contrib/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-module-addons-contrib", - "version": "1.1.12-next.1", + "version": "1.1.12", "description": "Plugin module for contributed TechDocs Addons", "backstage": { "role": "frontend-plugin-module", diff --git a/plugins/techdocs-node/CHANGELOG.md b/plugins/techdocs-node/CHANGELOG.md index 99240bd9d4..d392e3e662 100644 --- a/plugins/techdocs-node/CHANGELOG.md +++ b/plugins/techdocs-node/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-techdocs-node +## 1.12.8 + +### Patch Changes + +- 9ecf5fd: Adds extension point for publishers to the techdocs backend +- 4c4d077: Bumps default version of techdocs docker image to latest +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/integration@1.13.0 + - @backstage/plugin-search-common@1.2.13 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + ## 1.12.8-next.1 ### Patch Changes diff --git a/plugins/techdocs-node/package.json b/plugins/techdocs-node/package.json index 70d10aeed4..572b76e052 100644 --- a/plugins/techdocs-node/package.json +++ b/plugins/techdocs-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-node", - "version": "1.12.8-next.1", + "version": "1.12.8", "description": "Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", "backstage": { "role": "node-library", diff --git a/plugins/techdocs-react/CHANGELOG.md b/plugins/techdocs-react/CHANGELOG.md index 97677352df..5c9bd0004f 100644 --- a/plugins/techdocs-react/CHANGELOG.md +++ b/plugins/techdocs-react/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-techdocs-react +## 1.2.6 + +### Patch Changes + +- 8ac9ce5: Resolved the issue where changes in TechDoc add-ons, including the TextSize add-on, were not reapplying during navigation +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/version-bridge@1.0.8 + ## 1.2.6-next.1 ### Patch Changes diff --git a/plugins/techdocs-react/package.json b/plugins/techdocs-react/package.json index 1686b176ca..e65079b212 100644 --- a/plugins/techdocs-react/package.json +++ b/plugins/techdocs-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-react", - "version": "1.2.6-next.1", + "version": "1.2.6", "description": "Shared frontend utilities for TechDocs and Addons", "backstage": { "role": "web-library", diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index 34dc9a310f..08a841f25c 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-techdocs +## 1.10.7 + +### Patch Changes + +- 8fc2622: Fixed an issue that was causing techdocs pages unnecessarily re-render on navigate. +- 6fa652c: Improve default sorting of docs table +- 605b691: Allow for searching TechDocs by entity title +- 60caa92: Fix double scrollbar bug in reader +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.6 + - @backstage/core-components@0.14.9 + - @backstage/integration@1.13.0 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-search-common@1.2.13 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/integration-react@1.1.29 + - @backstage/plugin-auth-react@0.1.4 + - @backstage/plugin-search-react@1.7.13 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + ## 1.10.7-next.2 ### Patch Changes diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index cbf1f828ce..3a90078c72 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs", - "version": "1.10.7-next.2", + "version": "1.10.7", "description": "The Backstage plugin that renders technical documentation for your components", "backstage": { "role": "frontend-plugin", diff --git a/plugins/user-settings-backend/CHANGELOG.md b/plugins/user-settings-backend/CHANGELOG.md index c830df43e5..6a945081e8 100644 --- a/plugins/user-settings-backend/CHANGELOG.md +++ b/plugins/user-settings-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-user-settings-backend +## 0.2.21 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-auth-node@0.4.17 + - @backstage/plugin-signals-node@0.1.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-user-settings-common@0.0.1 + ## 0.2.21-next.1 ### Patch Changes diff --git a/plugins/user-settings-backend/package.json b/plugins/user-settings-backend/package.json index e975b38c08..e33bf0bd4b 100644 --- a/plugins/user-settings-backend/package.json +++ b/plugins/user-settings-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-user-settings-backend", - "version": "0.2.21-next.1", + "version": "0.2.21", "description": "The Backstage backend plugin to manage user settings", "backstage": { "role": "backend-plugin", diff --git a/plugins/user-settings/CHANGELOG.md b/plugins/user-settings/CHANGELOG.md index 8d886aee80..f10a4c0ea3 100644 --- a/plugins/user-settings/CHANGELOG.md +++ b/plugins/user-settings/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-user-settings +## 0.8.9 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9 + - @backstage/core-app-api@1.14.0 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.4 + - @backstage/plugin-user-settings-common@0.0.1 + ## 0.8.9-next.2 ### Patch Changes diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index 34c719d9df..5ae95e0e45 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-user-settings", - "version": "0.8.9-next.2", + "version": "0.8.9", "description": "A Backstage plugin that provides a settings page", "backstage": { "role": "frontend-plugin", diff --git a/yarn.lock b/yarn.lock index c7d871b1d9..c6a1d2139a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3839,7 +3839,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/catalog-client@^1.6.5, @backstage/catalog-client@workspace:^, @backstage/catalog-client@workspace:packages/catalog-client": +"@backstage/catalog-client@workspace:^, @backstage/catalog-client@workspace:packages/catalog-client": version: 0.0.0-use.local resolution: "@backstage/catalog-client@workspace:packages/catalog-client" dependencies: @@ -3852,7 +3852,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/catalog-model@^1.4.3, @backstage/catalog-model@^1.4.5, @backstage/catalog-model@^1.5.0, @backstage/catalog-model@workspace:^, @backstage/catalog-model@workspace:packages/catalog-model": +"@backstage/catalog-model@^1.4.3, @backstage/catalog-model@^1.4.5, @backstage/catalog-model@workspace:^, @backstage/catalog-model@workspace:packages/catalog-model": version: 0.0.0-use.local resolution: "@backstage/catalog-model@workspace:packages/catalog-model" dependencies: @@ -4105,7 +4105,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/config@^1.1.1, @backstage/config@^1.2.0, @backstage/config@workspace:^, @backstage/config@workspace:packages/config": +"@backstage/config@^1.1.1, @backstage/config@workspace:^, @backstage/config@workspace:packages/config": version: 0.0.0-use.local resolution: "@backstage/config@workspace:packages/config" dependencies: @@ -4177,107 +4177,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-components@npm:^0.13.10": - version: 0.13.10 - resolution: "@backstage/core-components@npm:0.13.10" - dependencies: - "@backstage/config": ^1.1.1 - "@backstage/core-plugin-api": ^1.8.2 - "@backstage/errors": ^1.2.3 - "@backstage/theme": ^0.5.0 - "@backstage/version-bridge": ^1.0.7 - "@date-io/core": ^1.3.13 - "@material-table/core": ^3.1.0 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@react-hookz/web": ^23.0.0 - "@types/react": ^16.13.1 || ^17.0.0 - "@types/react-sparklines": ^1.7.0 - "@types/react-text-truncate": ^0.14.0 - ansi-regex: ^6.0.1 - classnames: ^2.2.6 - d3-selection: ^3.0.0 - d3-shape: ^3.0.0 - d3-zoom: ^3.0.0 - dagre: ^0.8.5 - linkify-react: 4.1.3 - linkifyjs: 4.1.3 - lodash: ^4.17.21 - pluralize: ^8.0.0 - qs: ^6.9.4 - rc-progress: 3.5.1 - react-helmet: 6.1.0 - react-hook-form: ^7.12.2 - react-idle-timer: 5.6.2 - react-markdown: ^8.0.0 - react-sparklines: ^1.7.0 - react-syntax-highlighter: ^15.4.5 - react-text-truncate: ^0.19.0 - react-use: ^17.3.2 - react-virtualized-auto-sizer: ^1.0.11 - react-window: ^1.8.6 - remark-gfm: ^3.0.1 - zen-observable: ^0.10.0 - zod: ^3.22.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 - checksum: ec2a0d0a27bc4d6b9d4da97f0b4df600148529ee51bf2c8e7d3adc45c3950adac662535d3beabc451db346f2c7e3c412ceaa756fc774012b43dff5e2695f2271 - languageName: node - linkType: hard - -"@backstage/core-components@npm:^0.14.4, @backstage/core-components@npm:^0.14.8": - version: 0.14.8 - resolution: "@backstage/core-components@npm:0.14.8" - dependencies: - "@backstage/config": ^1.2.0 - "@backstage/core-plugin-api": ^1.9.3 - "@backstage/errors": ^1.2.4 - "@backstage/theme": ^0.5.6 - "@backstage/version-bridge": ^1.0.8 - "@date-io/core": ^1.3.13 - "@material-table/core": ^3.1.0 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@react-hookz/web": ^24.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - "@types/react-sparklines": ^1.7.0 - ansi-regex: ^6.0.1 - classnames: ^2.2.6 - d3-selection: ^3.0.0 - d3-shape: ^3.0.0 - d3-zoom: ^3.0.0 - dagre: ^0.8.5 - linkify-react: 4.1.3 - linkifyjs: 4.1.3 - lodash: ^4.17.21 - pluralize: ^8.0.0 - qs: ^6.9.4 - rc-progress: 3.5.1 - react-helmet: 6.1.0 - react-hook-form: ^7.12.2 - react-idle-timer: 5.7.2 - react-markdown: ^8.0.0 - react-sparklines: ^1.7.0 - react-syntax-highlighter: ^15.4.5 - react-use: ^17.3.2 - react-virtualized-auto-sizer: ^1.0.11 - react-window: ^1.8.6 - remark-gfm: ^3.0.1 - zen-observable: ^0.10.0 - zod: ^3.22.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 - checksum: b833e833c83f72e0cc695fe2726cbf01b58819ad062ed9ab1e604514bb398ade20e1abb208d2e39ab1f746fdbd4547486e3935bacb44b457a47070f9c77895dc - languageName: node - linkType: hard - -"@backstage/core-components@workspace:^, @backstage/core-components@workspace:packages/core-components": +"@backstage/core-components@^0.14.4, @backstage/core-components@workspace:^, @backstage/core-components@workspace:packages/core-components": version: 0.0.0-use.local resolution: "@backstage/core-components@workspace:packages/core-components" dependencies: @@ -4348,7 +4248,58 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-plugin-api@^1.8.2, @backstage/core-plugin-api@^1.9.2, @backstage/core-plugin-api@^1.9.3, @backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": +"@backstage/core-components@npm:^0.13.10": + version: 0.13.10 + resolution: "@backstage/core-components@npm:0.13.10" + dependencies: + "@backstage/config": ^1.1.1 + "@backstage/core-plugin-api": ^1.8.2 + "@backstage/errors": ^1.2.3 + "@backstage/theme": ^0.5.0 + "@backstage/version-bridge": ^1.0.7 + "@date-io/core": ^1.3.13 + "@material-table/core": ^3.1.0 + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": 4.0.0-alpha.61 + "@react-hookz/web": ^23.0.0 + "@types/react": ^16.13.1 || ^17.0.0 + "@types/react-sparklines": ^1.7.0 + "@types/react-text-truncate": ^0.14.0 + ansi-regex: ^6.0.1 + classnames: ^2.2.6 + d3-selection: ^3.0.0 + d3-shape: ^3.0.0 + d3-zoom: ^3.0.0 + dagre: ^0.8.5 + linkify-react: 4.1.3 + linkifyjs: 4.1.3 + lodash: ^4.17.21 + pluralize: ^8.0.0 + qs: ^6.9.4 + rc-progress: 3.5.1 + react-helmet: 6.1.0 + react-hook-form: ^7.12.2 + react-idle-timer: 5.6.2 + react-markdown: ^8.0.0 + react-sparklines: ^1.7.0 + react-syntax-highlighter: ^15.4.5 + react-text-truncate: ^0.19.0 + react-use: ^17.3.2 + react-virtualized-auto-sizer: ^1.0.11 + react-window: ^1.8.6 + remark-gfm: ^3.0.1 + zen-observable: ^0.10.0 + zod: ^3.22.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 + checksum: ec2a0d0a27bc4d6b9d4da97f0b4df600148529ee51bf2c8e7d3adc45c3950adac662535d3beabc451db346f2c7e3c412ceaa756fc774012b43dff5e2695f2271 + languageName: node + linkType: hard + +"@backstage/core-plugin-api@^1.8.2, @backstage/core-plugin-api@^1.9.2, @backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": version: 0.0.0-use.local resolution: "@backstage/core-plugin-api@workspace:packages/core-plugin-api" dependencies: @@ -4495,26 +4446,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/frontend-plugin-api@npm:^0.6.6": - version: 0.6.6 - resolution: "@backstage/frontend-plugin-api@npm:0.6.6" - dependencies: - "@backstage/core-components": ^0.14.8 - "@backstage/core-plugin-api": ^1.9.3 - "@backstage/types": ^1.1.1 - "@backstage/version-bridge": ^1.0.8 - "@material-ui/core": ^4.12.4 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - lodash: ^4.17.21 - zod: ^3.22.4 - zod-to-json-schema: ^3.21.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: c2af07bb73751f050937ba0f34941cc21639defdf13c6e219069ff4143324404229113874caef28f41b9a92a00121991da2a88782595e5221b48910e2f8be7c7 - languageName: node - linkType: hard - "@backstage/frontend-plugin-api@workspace:^, @backstage/frontend-plugin-api@workspace:packages/frontend-plugin-api": version: 0.0.0-use.local resolution: "@backstage/frontend-plugin-api@workspace:packages/frontend-plugin-api" @@ -4578,24 +4509,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/integration-react@npm:^1.1.28": - version: 1.1.28 - resolution: "@backstage/integration-react@npm:1.1.28" - dependencies: - "@backstage/config": ^1.2.0 - "@backstage/core-plugin-api": ^1.9.3 - "@backstage/integration": ^1.12.0 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@types/react": ^16.13.1 || ^17.0.0 - 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 - checksum: 15443a7ebc457114715651e652a40472085ca18ec10da078bad1e71e3aa9cac33d10704b164d09108f6195a9cb4d2eae11751d853598ef0dd0e4c160858f782d - languageName: node - linkType: hard - "@backstage/integration-react@workspace:^, @backstage/integration-react@workspace:packages/integration-react": version: 0.0.0-use.local resolution: "@backstage/integration-react@workspace:packages/integration-react" @@ -4620,23 +4533,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/integration@npm:^1.12.0": - version: 1.12.0 - resolution: "@backstage/integration@npm:1.12.0" - dependencies: - "@azure/identity": ^4.0.0 - "@backstage/config": ^1.2.0 - "@backstage/errors": ^1.2.4 - "@octokit/auth-app": ^4.0.0 - "@octokit/rest": ^19.0.3 - cross-fetch: ^4.0.0 - git-url-parse: ^14.0.0 - lodash: ^4.17.21 - luxon: ^3.0.0 - checksum: 603c08058dadfe54b5d1788db87bab951b53ea4d1b19f609873717e0ab514859cc8608d0d60755c91eaea000ad71f817c5dd50892a3215443d7eed5a1d24a849 - languageName: node - linkType: hard - "@backstage/integration@workspace:^, @backstage/integration@workspace:packages/integration": version: 0.0.0-use.local resolution: "@backstage/integration@workspace:packages/integration" @@ -5722,7 +5618,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-common@^1.0.20, @backstage/plugin-catalog-common@^1.0.24, @backstage/plugin-catalog-common@workspace:^, @backstage/plugin-catalog-common@workspace:plugins/catalog-common": +"@backstage/plugin-catalog-common@^1.0.20, @backstage/plugin-catalog-common@workspace:^, @backstage/plugin-catalog-common@workspace:plugins/catalog-common": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-common@workspace:plugins/catalog-common" dependencies: @@ -5831,43 +5727,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-react@npm:^1.11.3, @backstage/plugin-catalog-react@npm:^1.9.3": - version: 1.12.1 - resolution: "@backstage/plugin-catalog-react@npm:1.12.1" - dependencies: - "@backstage/catalog-client": ^1.6.5 - "@backstage/catalog-model": ^1.5.0 - "@backstage/core-components": ^0.14.8 - "@backstage/core-plugin-api": ^1.9.3 - "@backstage/errors": ^1.2.4 - "@backstage/frontend-plugin-api": ^0.6.6 - "@backstage/integration-react": ^1.1.28 - "@backstage/plugin-catalog-common": ^1.0.24 - "@backstage/plugin-permission-common": ^0.7.14 - "@backstage/plugin-permission-react": ^0.4.23 - "@backstage/types": ^1.1.1 - "@backstage/version-bridge": ^1.0.8 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@react-hookz/web": ^24.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - classnames: ^2.2.6 - lodash: ^4.17.21 - material-ui-popup-state: ^1.9.3 - qs: ^6.9.4 - react-use: ^17.2.4 - yaml: ^2.0.0 - zen-observable: ^0.10.0 - 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 - checksum: adbf967e978fa6bb4798d0620853e41f64cc08c39dd0056fc01b2146ca427d1bfab401b8972d7b551d4188b90f80f69db9254799bca095608b7079cec73da9c5 - languageName: node - linkType: hard - -"@backstage/plugin-catalog-react@workspace:^, @backstage/plugin-catalog-react@workspace:plugins/catalog-react": +"@backstage/plugin-catalog-react@^1.11.3, @backstage/plugin-catalog-react@^1.9.3, @backstage/plugin-catalog-react@workspace:^, @backstage/plugin-catalog-react@workspace:plugins/catalog-react": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-react@workspace:plugins/catalog-react" dependencies: @@ -6711,7 +6571,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-permission-common@^0.7.14, @backstage/plugin-permission-common@workspace:^, @backstage/plugin-permission-common@workspace:plugins/permission-common": +"@backstage/plugin-permission-common@workspace:^, @backstage/plugin-permission-common@workspace:plugins/permission-common": version: 0.0.0-use.local resolution: "@backstage/plugin-permission-common@workspace:plugins/permission-common" dependencies: @@ -6749,7 +6609,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-permission-react@^0.4.23, @backstage/plugin-permission-react@workspace:^, @backstage/plugin-permission-react@workspace:plugins/permission-react": +"@backstage/plugin-permission-react@workspace:^, @backstage/plugin-permission-react@workspace:plugins/permission-react": version: 0.0.0-use.local resolution: "@backstage/plugin-permission-react@workspace:plugins/permission-react" dependencies: @@ -8072,7 +7932,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/theme@^0.5.0, @backstage/theme@^0.5.6, @backstage/theme@workspace:^, @backstage/theme@workspace:packages/theme": +"@backstage/theme@^0.5.0, @backstage/theme@workspace:^, @backstage/theme@workspace:packages/theme": version: 0.0.0-use.local resolution: "@backstage/theme@workspace:packages/theme" dependencies: @@ -8103,7 +7963,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/version-bridge@^1.0.7, @backstage/version-bridge@^1.0.8, @backstage/version-bridge@workspace:^, @backstage/version-bridge@workspace:packages/version-bridge": +"@backstage/version-bridge@^1.0.7, @backstage/version-bridge@workspace:^, @backstage/version-bridge@workspace:packages/version-bridge": version: 0.0.0-use.local resolution: "@backstage/version-bridge@workspace:packages/version-bridge" dependencies: From 392b26a0ed848730e5c332136d391a6726763d41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Pi=C4=85tkiewicz?= <piatkiewicz.piotr@gmail.com> Date: Tue, 16 Jul 2024 15:17:07 +0200 Subject: [PATCH 297/510] Update writing-custom-actions.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Piotr Piątkiewicz <piatkiewicz.piotr@gmail.com> --- docs/features/software-templates/writing-custom-actions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/software-templates/writing-custom-actions.md b/docs/features/software-templates/writing-custom-actions.md index 6c1ea573db..98457d2e8d 100644 --- a/docs/features/software-templates/writing-custom-actions.md +++ b/docs/features/software-templates/writing-custom-actions.md @@ -195,7 +195,7 @@ const scaffolderModuleCustomExtensions = createBackendModule({ const backend = createBackend(); backend.add(import('@backstage/plugin-scaffolder-backend/alpha')); /* highlight-add-next-line */ -backend.add(scaffolderModuleCustomExtensions()); +backend.add(scaffolderModuleCustomExtensions); ``` If your custom action requires core services such as `config` or `cache` they can be imported in the dependencies and passed to the custom action function. From 5e6eccc84ca26e4dffe516f1eacc7d49da6d868f Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Tue, 16 Jul 2024 16:26:15 +0200 Subject: [PATCH 298/510] docs: sidebar label fix for root health Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- docs/backend-system/core-services/root-health.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/backend-system/core-services/root-health.md b/docs/backend-system/core-services/root-health.md index fc73ba9546..663dd699ae 100644 --- a/docs/backend-system/core-services/root-health.md +++ b/docs/backend-system/core-services/root-health.md @@ -1,7 +1,7 @@ --- id: root-health title: Root Health Service -sidebar_label: Health +sidebar_label: Root Health description: Documentation for the Health service --- From d5e567efff47e2756c6e17a85df9ea52812c4cf0 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Tue, 16 Jul 2024 17:27:24 +0200 Subject: [PATCH 299/510] docs: update threat model and auth docs to mention public entry point Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- docs/auth/index.md | 7 +------ docs/overview/threat-model.md | 2 ++ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/docs/auth/index.md b/docs/auth/index.md index 4a0e56a36e..5188d7e2a4 100644 --- a/docs/auth/index.md +++ b/docs/auth/index.md @@ -12,12 +12,7 @@ access to external resources. :::note Note -Identity management and the Sign-In page in Backstage is NOT a method for blocking -access for unauthorized users. The identity system only serves to provide a personalized -experience and access to a Backstage Identity Token, which can be passed to backend plugins. -This also means that your Backstage backend APIs are by default unauthenticated. -Thus, if your Backstage instance is exposed to the Internet, anyone can access -information in the Backstage. You can learn more [here](../overview/threat-model.md#integrator-responsibilities). +Identity management and the Sign-In page in Backstage will only block external access when using the new backend system, without setting `backend.auth.dangerouslyDisableDefaultAuthPolicy` in configuration. Even so, the frontend bundle is not protected from external access, protecting it requires the use of the [experimental public entry point](https://backstage.io/docs/tutorials/enable-public-entry/). You can learn more about this in the [Threat Model](../overview/threat-model.md#operator-responsibilities). ::: diff --git a/docs/overview/threat-model.md b/docs/overview/threat-model.md index da97f3fc83..c0e2d61e25 100644 --- a/docs/overview/threat-model.md +++ b/docs/overview/threat-model.md @@ -37,6 +37,8 @@ The operator is ultimately responsible for auditing usage of internal and extern The operator is also responsible for maintaining the resolved NPM dependencies of their Backstage project. This involves ensuring that `yarn.lock` receives updated versions of packages that have vulnerabilities, when those fixed versions are in range of what the Backstage packages request in their respective `package.json` files. This is commonly done by employing automated tooling such as [Dependabot](https://dependabot.com/), [Snyk](https://snyk.io/), and/or [Renovate](https://docs.renovatebot.com/) on your own repository. When fixed versions exist that are _not_ in range of what Backstage packages request, or when larger operations such as switching out an entire dependency for another one is required, maintainers collaborate with contributors to try to address those dependency declarations in the main project as soon as possible. +The built-in protection against unauthorized access does not by default include protection of the frontend bundle. The frontend bundle includes all the code of your frontend plugins and code in minified form, as well as any other frontend resources like images, fonts, etc. If this is a concern, you can use the [experimental public entry point](https://backstage.io/docs/tutorials/enable-public-entry/) to create two separate frontend builds, where authenticated users only have access to the full one. + ## Common Backend Configuration There are many common facilities that are configured centrally and available to all Backstage backend plugins. For example there is a `DatabaseManager` that provides access to a SQL database, `TaskScheduler` for scheduling long-running tasks, `Logger` as a general logging facility, and `UrlReader` for reading content from external sources. These are all configured either directly in code, or within the `backend` block of the static configuration. The appropriate care needs to be taken to ensure that any secrets remain confidential and no malicious configuration is injected. From 7e13b7af04b24105619e34b17ea2b2547b1a6e12 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Tue, 16 Jul 2024 15:30:50 +0200 Subject: [PATCH 300/510] backend-common: deprecate remaining methods Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/nine-cherries-decide.md | 14 ++++++++++++++ packages/backend-common/api-report.md | 12 ++++++------ .../src/compat/auth/createLegacyAuthAdapters.ts | 1 + .../src/compat/cache/cacheToPluginCacheManager.ts | 1 + .../backend-common/src/compat/legacy/legacy.ts | 3 +++ .../src/compat/logging/loggerToWinstonLogger.ts | 5 ++++- 6 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 .changeset/nine-cherries-decide.md diff --git a/.changeset/nine-cherries-decide.md b/.changeset/nine-cherries-decide.md new file mode 100644 index 0000000000..b20c24aa85 --- /dev/null +++ b/.changeset/nine-cherries-decide.md @@ -0,0 +1,14 @@ +--- +'@backstage/backend-common': patch +--- + +The remaining exports in the package have now been deprecated: + +- `cacheToPluginCacheManager` +- `createLegacyAuthAdapters` +- `LegacyCreateRouter` +- `legacyPlugin` +- `loggerToWinstonLogger` +- `makeLegacyPlugin` + +Users of these export should fully [migrate to the new backend system](https://backstage.io/docs/backend-system/building-backends/migrating). diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index 52b661bcaf..23ed13b62c 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -129,7 +129,7 @@ export class CacheManager extends CacheManager_2 {} // @public @deprecated (undocumented) export type CacheManagerOptions = CacheManagerOptions_2; -// @public +// @public @deprecated export function cacheToPluginCacheManager(cache: CacheService): { getClient(options?: CacheServiceOptions): CacheService; }; @@ -142,7 +142,7 @@ export interface ContainerRunner { runContainer(opts: RunContainerOptions): Promise<void>; } -// @public +// @public @deprecated export function createLegacyAuthAdapters< TOptions extends { auth?: AuthService; @@ -401,10 +401,10 @@ export type KubernetesContainerRunnerOptions = { timeoutMs?: number; }; -// @public (undocumented) +// @public @deprecated (undocumented) export type LegacyCreateRouter<TEnv> = (deps: TEnv) => Promise<RequestHandler>; -// @public +// @public @deprecated export const legacyPlugin: ( name: string, createRouterImport: Promise<{ @@ -447,13 +447,13 @@ export function loadBackendConfig(options: { watch?: boolean; }): Promise<Config>; -// @public (undocumented) +// @public @deprecated (undocumented) export function loggerToWinstonLogger( logger: LoggerService, opts?: TransportStreamOptions, ): Logger; -// @public +// @public @deprecated export function makeLegacyPlugin< TEnv extends Record<string, unknown>, TEnvTransforms extends { diff --git a/packages/backend-common/src/compat/auth/createLegacyAuthAdapters.ts b/packages/backend-common/src/compat/auth/createLegacyAuthAdapters.ts index 0f591eac6c..15cd881649 100644 --- a/packages/backend-common/src/compat/auth/createLegacyAuthAdapters.ts +++ b/packages/backend-common/src/compat/auth/createLegacyAuthAdapters.ts @@ -292,6 +292,7 @@ export class UserInfoCompat implements UserInfoService { /** * An adapter that ensures presence of the auth and/or httpAuth services. * @public + * @deprecated Migrate to use the new backend system and auth services instead. */ export function createLegacyAuthAdapters< TOptions extends { diff --git a/packages/backend-common/src/compat/cache/cacheToPluginCacheManager.ts b/packages/backend-common/src/compat/cache/cacheToPluginCacheManager.ts index 2654934804..2ae55b016f 100644 --- a/packages/backend-common/src/compat/cache/cacheToPluginCacheManager.ts +++ b/packages/backend-common/src/compat/cache/cacheToPluginCacheManager.ts @@ -24,6 +24,7 @@ import { * old-backend plugin cache manager. * * @public + * @deprecated Migrate to use the new CacheService instead. */ export function cacheToPluginCacheManager(cache: CacheService): { getClient(options?: CacheServiceOptions): CacheService; diff --git a/packages/backend-common/src/compat/legacy/legacy.ts b/packages/backend-common/src/compat/legacy/legacy.ts index 57220a8430..c779daacd2 100644 --- a/packages/backend-common/src/compat/legacy/legacy.ts +++ b/packages/backend-common/src/compat/legacy/legacy.ts @@ -27,6 +27,7 @@ import { TokenManager } from '../../deprecated'; /** * @public + * @deprecated Fully use the new backend system instead. */ export type LegacyCreateRouter<TEnv> = (deps: TEnv) => Promise<RequestHandler>; @@ -69,6 +70,7 @@ function wrapTokenManager(tokenManager: TokenManager, auth: AuthService) { * Creates a new custom plugin compatibility wrapper. * * @public + * @deprecated Fully use the new backend system instead. * @remarks * * Usually you can use {@link legacyPlugin} directly instead, but you might @@ -128,6 +130,7 @@ export function makeLegacyPlugin< * register it with the http router based on the plugin id. * * @public + * @deprecated Fully use the new backend system instead. * @remarks * * This is intended to be used by plugin authors to ease the transition to the diff --git a/packages/backend-common/src/compat/logging/loggerToWinstonLogger.ts b/packages/backend-common/src/compat/logging/loggerToWinstonLogger.ts index 4ba88358d2..83871f48e3 100644 --- a/packages/backend-common/src/compat/logging/loggerToWinstonLogger.ts +++ b/packages/backend-common/src/compat/logging/loggerToWinstonLogger.ts @@ -53,7 +53,10 @@ class BackstageLoggerTransport extends Transport { } } -/** @public */ +/** + * @public + * @deprecated Migrate to use the new LoggerService instead. + */ export function loggerToWinstonLogger( logger: LoggerService, opts?: TransportStreamOptions, From b3769f14b3f3fa767546d0d806e0a1967fc0a940 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Tue, 16 Jul 2024 18:37:01 +0200 Subject: [PATCH 301/510] changesets: enter prerelease Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/pre.json | 192 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 .changeset/pre.json diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 0000000000..be1b694c9e --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,192 @@ +{ + "mode": "pre", + "tag": "next", + "initialVersions": { + "example-app": "0.2.99", + "@backstage/app-defaults": "1.5.8", + "example-app-next": "0.0.13", + "app-next-example-plugin": "0.0.13", + "example-backend": "0.0.28", + "@backstage/backend-app-api": "0.8.0", + "@backstage/backend-common": "0.23.3", + "@backstage/backend-defaults": "0.4.0", + "@backstage/backend-dev-utils": "0.1.4", + "@backstage/backend-dynamic-feature-service": "0.2.15", + "example-backend-legacy": "0.2.100", + "@backstage/backend-openapi-utils": "0.1.15", + "@backstage/backend-plugin-api": "0.7.0", + "@backstage/backend-tasks": "0.5.27", + "@backstage/backend-test-utils": "0.4.4", + "@backstage/catalog-client": "1.6.5", + "@backstage/catalog-model": "1.5.0", + "@backstage/cli": "0.26.11", + "@backstage/cli-common": "0.1.14", + "@backstage/cli-node": "0.2.7", + "@backstage/codemods": "0.1.49", + "@backstage/config": "1.2.0", + "@backstage/config-loader": "1.8.1", + "@backstage/core-app-api": "1.14.0", + "@backstage/core-compat-api": "0.2.7", + "@backstage/core-components": "0.14.9", + "@backstage/core-plugin-api": "1.9.3", + "@backstage/create-app": "0.5.17", + "@backstage/dev-utils": "1.0.35", + "e2e-test": "0.2.18", + "@backstage/e2e-test-utils": "0.1.1", + "@backstage/errors": "1.2.4", + "@backstage/eslint-plugin": "0.1.8", + "@backstage/frontend-app-api": "0.7.3", + "@backstage/frontend-plugin-api": "0.6.7", + "@backstage/frontend-test-utils": "0.1.10", + "@backstage/integration": "1.13.0", + "@backstage/integration-aws-node": "0.1.12", + "@backstage/integration-react": "1.1.29", + "@backstage/release-manifests": "0.0.11", + "@backstage/repo-tools": "0.9.4", + "@techdocs/cli": "1.8.16", + "techdocs-cli-embedded-app": "0.2.98", + "@backstage/test-utils": "1.5.8", + "@backstage/theme": "0.5.6", + "@backstage/types": "1.1.1", + "@backstage/version-bridge": "1.0.8", + "yarn-plugin-backstage": "0.0.1", + "@backstage/plugin-api-docs": "0.11.7", + "@backstage/plugin-api-docs-module-protoc-gen-doc": "0.1.7", + "@backstage/plugin-app-backend": "0.3.71", + "@backstage/plugin-app-node": "0.1.22", + "@backstage/plugin-app-visualizer": "0.1.8", + "@backstage/plugin-auth-backend": "0.22.9", + "@backstage/plugin-auth-backend-module-atlassian-provider": "0.2.3", + "@backstage/plugin-auth-backend-module-aws-alb-provider": "0.1.14", + "@backstage/plugin-auth-backend-module-azure-easyauth-provider": "0.1.5", + "@backstage/plugin-auth-backend-module-bitbucket-provider": "0.1.5", + "@backstage/plugin-auth-backend-module-cloudflare-access-provider": "0.1.5", + "@backstage/plugin-auth-backend-module-gcp-iap-provider": "0.2.17", + "@backstage/plugin-auth-backend-module-github-provider": "0.1.19", + "@backstage/plugin-auth-backend-module-gitlab-provider": "0.1.19", + "@backstage/plugin-auth-backend-module-google-provider": "0.1.19", + "@backstage/plugin-auth-backend-module-guest-provider": "0.1.8", + "@backstage/plugin-auth-backend-module-microsoft-provider": "0.1.17", + "@backstage/plugin-auth-backend-module-oauth2-provider": "0.2.3", + "@backstage/plugin-auth-backend-module-oauth2-proxy-provider": "0.1.15", + "@backstage/plugin-auth-backend-module-oidc-provider": "0.2.3", + "@backstage/plugin-auth-backend-module-okta-provider": "0.0.15", + "@backstage/plugin-auth-backend-module-onelogin-provider": "0.1.3", + "@backstage/plugin-auth-backend-module-pinniped-provider": "0.1.16", + "@backstage/plugin-auth-backend-module-vmware-cloud-provider": "0.2.3", + "@backstage/plugin-auth-node": "0.4.17", + "@backstage/plugin-auth-react": "0.1.4", + "@backstage/plugin-bitbucket-cloud-common": "0.2.21", + "@backstage/plugin-catalog": "1.21.1", + "@backstage/plugin-catalog-backend": "1.24.0", + "@backstage/plugin-catalog-backend-module-aws": "0.3.17", + "@backstage/plugin-catalog-backend-module-azure": "0.1.42", + "@backstage/plugin-catalog-backend-module-backstage-openapi": "0.2.5", + "@backstage/plugin-catalog-backend-module-bitbucket-cloud": "0.2.9", + "@backstage/plugin-catalog-backend-module-bitbucket-server": "0.1.36", + "@backstage/plugin-catalog-backend-module-gcp": "0.1.23", + "@backstage/plugin-catalog-backend-module-gerrit": "0.1.39", + "@backstage/plugin-catalog-backend-module-github": "0.6.5", + "@backstage/plugin-catalog-backend-module-github-org": "0.1.17", + "@backstage/plugin-catalog-backend-module-gitlab": "0.3.21", + "@backstage/plugin-catalog-backend-module-gitlab-org": "0.0.5", + "@backstage/plugin-catalog-backend-module-incremental-ingestion": "0.4.27", + "@backstage/plugin-catalog-backend-module-ldap": "0.7.0", + "@backstage/plugin-catalog-backend-module-logs": "0.0.1", + "@backstage/plugin-catalog-backend-module-msgraph": "0.5.30", + "@backstage/plugin-catalog-backend-module-openapi": "0.1.40", + "@backstage/plugin-catalog-backend-module-puppetdb": "0.1.28", + "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "0.1.20", + "@backstage/plugin-catalog-backend-module-unprocessed": "0.4.9", + "@backstage/plugin-catalog-common": "1.0.25", + "@backstage/plugin-catalog-graph": "0.4.7", + "@backstage/plugin-catalog-import": "0.12.1", + "@backstage/plugin-catalog-node": "1.12.4", + "@backstage/plugin-catalog-react": "1.12.2", + "@backstage/plugin-catalog-unprocessed-entities": "0.2.6", + "@backstage/plugin-catalog-unprocessed-entities-common": "0.0.3", + "@backstage/plugin-config-schema": "0.1.57", + "@backstage/plugin-devtools": "0.1.16", + "@backstage/plugin-devtools-backend": "0.3.8", + "@backstage/plugin-devtools-common": "0.1.11", + "@backstage/plugin-events-backend": "0.3.9", + "@backstage/plugin-events-backend-module-aws-sqs": "0.3.8", + "@backstage/plugin-events-backend-module-azure": "0.2.8", + "@backstage/plugin-events-backend-module-bitbucket-cloud": "0.2.8", + "@backstage/plugin-events-backend-module-gerrit": "0.2.8", + "@backstage/plugin-events-backend-module-github": "0.2.8", + "@backstage/plugin-events-backend-module-gitlab": "0.2.8", + "@backstage/plugin-events-backend-test-utils": "0.1.32", + "@backstage/plugin-events-node": "0.3.8", + "@internal/plugin-todo-list": "1.0.29", + "@internal/plugin-todo-list-backend": "1.0.29", + "@internal/plugin-todo-list-common": "1.0.20", + "@backstage/plugin-home": "0.7.7", + "@backstage/plugin-home-react": "0.1.15", + "@backstage/plugin-kubernetes": "0.11.12", + "@backstage/plugin-kubernetes-backend": "0.18.3", + "@backstage/plugin-kubernetes-cluster": "0.0.13", + "@backstage/plugin-kubernetes-common": "0.8.1", + "@backstage/plugin-kubernetes-node": "0.1.16", + "@backstage/plugin-kubernetes-react": "0.4.1", + "@backstage/plugin-notifications": "0.2.3", + "@backstage/plugin-notifications-backend": "0.3.3", + "@backstage/plugin-notifications-backend-module-email": "0.1.3", + "@backstage/plugin-notifications-common": "0.0.5", + "@backstage/plugin-notifications-node": "0.2.3", + "@backstage/plugin-org": "0.6.27", + "@backstage/plugin-org-react": "0.1.26", + "@backstage/plugin-permission-backend": "0.5.46", + "@backstage/plugin-permission-backend-module-allow-all-policy": "0.1.19", + "@backstage/plugin-permission-common": "0.8.0", + "@backstage/plugin-permission-node": "0.8.0", + "@backstage/plugin-permission-react": "0.4.24", + "@backstage/plugin-proxy-backend": "0.5.3", + "@backstage/plugin-scaffolder": "1.23.0", + "@backstage/plugin-scaffolder-backend": "1.23.0", + "@backstage/plugin-scaffolder-backend-module-azure": "0.1.14", + "@backstage/plugin-scaffolder-backend-module-bitbucket": "0.2.12", + "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "0.1.12", + "@backstage/plugin-scaffolder-backend-module-bitbucket-server": "0.1.12", + "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown": "0.2.23", + "@backstage/plugin-scaffolder-backend-module-cookiecutter": "0.2.46", + "@backstage/plugin-scaffolder-backend-module-gcp": "0.1.0", + "@backstage/plugin-scaffolder-backend-module-gerrit": "0.1.14", + "@backstage/plugin-scaffolder-backend-module-gitea": "0.1.12", + "@backstage/plugin-scaffolder-backend-module-github": "0.4.0", + "@backstage/plugin-scaffolder-backend-module-gitlab": "0.4.4", + "@backstage/plugin-scaffolder-backend-module-notifications": "0.0.5", + "@backstage/plugin-scaffolder-backend-module-rails": "0.4.39", + "@backstage/plugin-scaffolder-backend-module-sentry": "0.1.30", + "@backstage/plugin-scaffolder-backend-module-yeoman": "0.3.6", + "@backstage/plugin-scaffolder-common": "1.5.4", + "@backstage/plugin-scaffolder-node": "0.4.8", + "@backstage/plugin-scaffolder-node-test-utils": "0.1.9", + "@backstage/plugin-scaffolder-react": "1.10.0", + "@backstage/plugin-search": "1.4.14", + "@backstage/plugin-search-backend": "1.5.14", + "@backstage/plugin-search-backend-module-catalog": "0.1.28", + "@backstage/plugin-search-backend-module-elasticsearch": "1.5.3", + "@backstage/plugin-search-backend-module-explore": "0.1.28", + "@backstage/plugin-search-backend-module-pg": "0.5.32", + "@backstage/plugin-search-backend-module-stack-overflow-collator": "0.1.15", + "@backstage/plugin-search-backend-module-techdocs": "0.1.27", + "@backstage/plugin-search-backend-node": "1.2.27", + "@backstage/plugin-search-common": "1.2.13", + "@backstage/plugin-search-react": "1.7.13", + "@backstage/plugin-signals": "0.0.8", + "@backstage/plugin-signals-backend": "0.1.8", + "@backstage/plugin-signals-node": "0.1.8", + "@backstage/plugin-signals-react": "0.0.4", + "@backstage/plugin-techdocs": "1.10.7", + "@backstage/plugin-techdocs-addons-test-utils": "1.0.35", + "@backstage/plugin-techdocs-backend": "1.10.9", + "@backstage/plugin-techdocs-module-addons-contrib": "1.1.12", + "@backstage/plugin-techdocs-node": "1.12.8", + "@backstage/plugin-techdocs-react": "1.2.6", + "@backstage/plugin-user-settings": "0.8.9", + "@backstage/plugin-user-settings-backend": "0.2.21", + "@backstage/plugin-user-settings-common": "0.0.1" + }, + "changesets": [] +} From 669d742d38359fed15ab03bad494ed73e3e3c7ce Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Tue, 16 Jul 2024 19:32:32 +0200 Subject: [PATCH 302/510] create-app: remove unnecessary yarn.lock seeds Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- packages/create-app/seed-yarn.lock | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/packages/create-app/seed-yarn.lock b/packages/create-app/seed-yarn.lock index b09a0ce1a7..00a86105cc 100644 --- a/packages/create-app/seed-yarn.lock +++ b/packages/create-app/seed-yarn.lock @@ -16,13 +16,3 @@ // package: the name of the package, e.g. @testing-library/react // query: the version query to pin the version for, e.g. ^14.0.0 // version: the version to pin to, must be in range of the query, e.g. 14.11.0 - -ajv@^8.0.0, ajv@^8.10.0, ajv@^8.11.0, ajv@^8.12.0, ajv@^8.14.0, ajv@^8.6.0, ajv@^8.6.3, ajv@^8.8.2, ajv@^8.9.0: - version "8.14.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.14.0.tgz#f514ddfd4756abb200e1704414963620a625ebbb" - integrity sha512-oYs1UUtO97ZO2lJ4bwnWeQW8/zvOIQLGKcvPTsWmvc2SYgBb+upuNS5NxoLaMU4h8Ju3Nbj6Cq8mD2LQoqVKFA== - -"@mui/material@^5.12.2": - version "5.16.1" - resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.16.1.tgz#6fcef9b5709df5864cf0b0bc0ea7b453a9d9e420" - integrity sha512-BGTgJRb0d/hX9tus5CEb6N/Fo8pE4tYA+s9r4/S0PCrtZ3urCLXlTH4qrAvggQbiF1cYRAbHCkVHoQ+4Pdxl+w== From 8e967da7a0c9cf380f458672340c6fe2e1399621 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Tue, 16 Jul 2024 21:28:51 +0200 Subject: [PATCH 303/510] backend-defaults: fixed routing of health endpoints Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/selfish-bees-think.md | 5 +++++ .../src/entrypoints/rootHttpRouter/createHealthRouter.ts | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 .changeset/selfish-bees-think.md diff --git a/.changeset/selfish-bees-think.md b/.changeset/selfish-bees-think.md new file mode 100644 index 0000000000..15598ea551 --- /dev/null +++ b/.changeset/selfish-bees-think.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': patch +--- + +Fixed the routing of the new health check service, the health endpoints should now properly be available at `/.backstage/health/v1/readiness` and `/.backstage/health/v1/liveness`. diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/createHealthRouter.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/createHealthRouter.ts index 13691ede28..007d1dd9cd 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/createHealthRouter.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/createHealthRouter.ts @@ -23,7 +23,7 @@ export function createHealthRouter(options: { health: RootHealthService }) { const router = Router(); router.get( - '.backstage/health/v1/readiness', + '/.backstage/health/v1/readiness', async (_request: Request, response: Response) => { const { status, payload } = await options.health.getReadiness(); response.status(status).json(payload); @@ -31,7 +31,7 @@ export function createHealthRouter(options: { health: RootHealthService }) { ); router.get( - '.backstage/health/v1/liveness', + '/.backstage/health/v1/liveness', async (_request: Request, response: Response) => { const { status, payload } = await options.health.getLiveness(); response.status(status).json(payload); From 4670f06f72877aa20faf7f24021a977b22598754 Mon Sep 17 00:00:00 2001 From: Matt Benson <gudnabrsam@gmail.com> Date: Wed, 6 Mar 2024 17:31:38 -0600 Subject: [PATCH 304/510] support ajv-errors for scaffolder validation Signed-off-by: Matt Benson <gudnabrsam@gmail.com> --- .changeset/modern-parrots-protect.md | 5 +++++ .../config/vocabularies/Backstage/accept.txt | 1 + .../software-templates/input-examples.md | 19 +++++++++++++++++++ .../software-templates/writing-templates.md | 5 +++++ plugins/scaffolder-react/package.json | 1 + .../src/next/components/Stepper/Stepper.tsx | 6 +++++- yarn.lock | 1 + 7 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 .changeset/modern-parrots-protect.md diff --git a/.changeset/modern-parrots-protect.md b/.changeset/modern-parrots-protect.md new file mode 100644 index 0000000000..7fccff1bef --- /dev/null +++ b/.changeset/modern-parrots-protect.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-react': patch +--- + +support ajv-errors for scaffolder validation diff --git a/.github/vale/config/vocabularies/Backstage/accept.txt b/.github/vale/config/vocabularies/Backstage/accept.txt index 6ff0ef56da..1092947245 100644 --- a/.github/vale/config/vocabularies/Backstage/accept.txt +++ b/.github/vale/config/vocabularies/Backstage/accept.txt @@ -7,6 +7,7 @@ ADRs airbrake Airbrake Airbrakes +ajv Alaria Alef allowlisted diff --git a/docs/features/software-templates/input-examples.md b/docs/features/software-templates/input-examples.md index f49e76e469..dd1228290f 100644 --- a/docs/features/software-templates/input-examples.md +++ b/docs/features/software-templates/input-examples.md @@ -26,6 +26,25 @@ parameters: ui:help: 'Hint: additional description...' ``` +#### Custom validation error message + +```yaml +parameters: + - title: Fill in some steps + properties: + name: + title: Simple text input + type: string + description: Description about input + maxLength: 8 + pattern: '^([a-zA-Z][a-zA-Z0-9]*)(-[a-zA-Z0-9]+)*$' + ui:autofocus: true + ui:help: 'Hint: additional description...' + errorMessage: + properties: + name: '1-8 alphanumeric tokens (first starts with letter) delimited by -' +``` + ### Multi line text input ```yaml diff --git a/docs/features/software-templates/writing-templates.md b/docs/features/software-templates/writing-templates.md index 15591eeb67..075fe0bb08 100644 --- a/docs/features/software-templates/writing-templates.md +++ b/docs/features/software-templates/writing-templates.md @@ -533,6 +533,11 @@ catalogFilter: metadata.annotations.github.com/team-slug: { exists: true } ``` +#### Custom validation messages + +You may specify custom JSON Schema validation messages as supported by the +[ajv-errors](https://github.com/ajv-validator/ajv-errors) plugin library to [ajv](https://github.com/ajv-validator/ajv). + ## `spec.steps` - `Action[]` The `steps` is an array of the things that you want to happen part of this diff --git a/plugins/scaffolder-react/package.json b/plugins/scaffolder-react/package.json index f2d7d44a01..9c50900c05 100644 --- a/plugins/scaffolder-react/package.json +++ b/plugins/scaffolder-react/package.json @@ -78,6 +78,7 @@ "@rjsf/validator-ajv8": "5.18.5", "@types/json-schema": "^7.0.9", "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "ajv-errors": "^3.0.0", "classnames": "^2.2.6", "flatted": "3.3.1", "humanize-duration": "^3.25.1", diff --git a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx index 269b6a11d5..788c7cd715 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx @@ -35,7 +35,7 @@ import { } from './createAsyncValidators'; import { ReviewState, type ReviewStateProps } from '../ReviewState'; import { useTemplateSchema, useFormDataFromQuery } from '../../hooks'; -import validator from '@rjsf/validator-ajv8'; +import { customizeValidator } from '@rjsf/validator-ajv8'; import { useTransformSchemaToProps } from '../../hooks/useTransformSchemaToProps'; import { hasErrors } from './utils'; import * as FieldOverrides from './FieldOverrides'; @@ -50,6 +50,10 @@ import { ReviewStepProps } from '@backstage/plugin-scaffolder-react'; import { ErrorListTemplate } from './ErrorListTemplate'; import { makeStyles } from '@material-ui/core/styles'; import { PasswordWidget } from '../PasswordWidget/PasswordWidget'; +import ajvErrors from 'ajv-errors'; + +const validator = customizeValidator(); +ajvErrors(validator.ajv); const useStyles = makeStyles(theme => ({ backButton: { diff --git a/yarn.lock b/yarn.lock index c6a1d2139a..fe7bc4b2c8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7110,6 +7110,7 @@ __metadata: "@types/json-schema": ^7.0.9 "@types/luxon": ^3.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + ajv-errors: ^3.0.0 classnames: ^2.2.6 flatted: 3.3.1 humanize-duration: ^3.25.1 From 8b808fd1a92389395668596a18942502816610aa Mon Sep 17 00:00:00 2001 From: Matt Benson <gudnabrsam@gmail.com> Date: Mon, 15 Jul 2024 10:48:22 -0500 Subject: [PATCH 305/510] add errorMessage test Signed-off-by: Matt Benson <gudnabrsam@gmail.com> --- .../next/components/Stepper/Stepper.test.tsx | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) 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 d7e271f8b3..df58d971fb 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx @@ -392,6 +392,46 @@ describe('Stepper', () => { expect(getByText('invalid postcode')).toBeInTheDocument(); }); + it('should render ajv-errors message', async () => { + const manifest: TemplateParameterSchema = { + steps: [ + { + title: 'Step 1', + schema: { + properties: { + postcode: { + type: 'string', + pattern: '[A-Z][0-9][A-Z] [0-9][A-Z][0-9]', + }, + }, + errorMessage: { + properties: { + postcode: 'invalid postcode', + }, + }, + }, + }, + ], + title: 'transformErrors Form Test', + }; + + const { getByText, getByRole } = await renderInTestApp( + <SecretsContextProvider> + <Stepper manifest={manifest} extensions={[]} onCreate={jest.fn()} /> + </SecretsContextProvider>, + ); + + await fireEvent.change(getByRole('textbox', { name: 'postcode' }), { + target: { value: 'invalid' }, + }); + + await act(async () => { + await fireEvent.click(getByRole('button', { name: 'Review' })); + }); + + expect(getByText('invalid postcode')).toBeInTheDocument(); + }); + it('should grab the initial formData from the query', async () => { const manifest: TemplateParameterSchema = { steps: [ From 896a22d26c4190379e8b9b6625c0dbb520d0f9bf Mon Sep 17 00:00:00 2001 From: Stephen Glass <stephen@stephen.glass> Date: Tue, 16 Jul 2024 20:55:32 -0400 Subject: [PATCH 306/510] Fix margin for EntityTagsPicker and EntityNamePicker Signed-off-by: Stephen Glass <stephen@stephen.glass> --- .changeset/spicy-lies-listen.md | 5 +++++ .../components/fields/EntityNamePicker/EntityNamePicker.tsx | 1 + .../components/fields/EntityTagsPicker/EntityTagsPicker.tsx | 1 + 3 files changed, 7 insertions(+) create mode 100644 .changeset/spicy-lies-listen.md diff --git a/.changeset/spicy-lies-listen.md b/.changeset/spicy-lies-listen.md new file mode 100644 index 0000000000..b293345e3b --- /dev/null +++ b/.changeset/spicy-lies-listen.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Fix helper text margin for scaffolder EntityNamePicker and EntityTagsPicker when using outlined textfield diff --git a/plugins/scaffolder/src/components/fields/EntityNamePicker/EntityNamePicker.tsx b/plugins/scaffolder/src/components/fields/EntityNamePicker/EntityNamePicker.tsx index bc3ca95ae0..9f49fc2b94 100644 --- a/plugins/scaffolder/src/components/fields/EntityNamePicker/EntityNamePicker.tsx +++ b/plugins/scaffolder/src/components/fields/EntityNamePicker/EntityNamePicker.tsx @@ -46,6 +46,7 @@ export const EntityNamePicker = (props: EntityNamePickerProps) => { margin="normal" error={rawErrors?.length > 0 && !formData} inputProps={{ autoFocus }} + FormHelperTextProps={{ margin: 'dense', style: { marginLeft: 0 } }} /> ); }; diff --git a/plugins/scaffolder/src/components/fields/EntityTagsPicker/EntityTagsPicker.tsx b/plugins/scaffolder/src/components/fields/EntityTagsPicker/EntityTagsPicker.tsx index 876b5c161d..bf95a08c85 100644 --- a/plugins/scaffolder/src/components/fields/EntityTagsPicker/EntityTagsPicker.tsx +++ b/plugins/scaffolder/src/components/fields/EntityTagsPicker/EntityTagsPicker.tsx @@ -116,6 +116,7 @@ export const EntityTagsPicker = (props: EntityTagsPickerProps) => { helperText ?? "Add any relevant tags, hit 'Enter' to add new tags. Valid format: [a-z0-9+#] separated by [-], at most 63 characters" } + FormHelperTextProps={{ margin: 'dense', style: { marginLeft: 0 } }} /> )} /> From 7ab4983ed28943636a913eaf7992e437a1e2ade4 Mon Sep 17 00:00:00 2001 From: parmar-abhinav <abhinav.parmar@infosys.com> Date: Wed, 17 Jul 2024 15:00:39 +0530 Subject: [PATCH 307/510] Chore:Add error handling for YAML parsing to improve robustness Signed-off-by: parmar-abhinav <abhinav.parmar@infosys.com> --- .../fetch/rails/index.examples.test.ts | 70 ++++++++++++++++--- 1 file changed, 60 insertions(+), 10 deletions(-) diff --git a/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.examples.test.ts b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.examples.test.ts index a80985321e..37e678ab6a 100644 --- a/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.examples.test.ts +++ b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.examples.test.ts @@ -90,7 +90,12 @@ describe('fetch:rails', () => { }); it(`should ${examples[0].description}`, async () => { - const input = yaml.parse(examples[0].example).steps[0].input; + let input; + try { + input = yaml.parse(examples[0].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } await action.handler({ ...mockContext, @@ -110,7 +115,12 @@ describe('fetch:rails', () => { }); it(`should ${examples[1].description}`, async () => { - const input = yaml.parse(examples[1].example).steps[0].input; + let input; + try { + input = yaml.parse(examples[1].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } await action.handler({ ...mockContext, @@ -130,7 +140,12 @@ describe('fetch:rails', () => { }); it(`should ${examples[2].description}`, async () => { - const input = yaml.parse(examples[2].example).steps[0].input; + let input; + try { + input = yaml.parse(examples[2].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } await action.handler({ ...mockContext, @@ -150,7 +165,12 @@ describe('fetch:rails', () => { }); it(`should ${examples[3].description}`, async () => { - const input = yaml.parse(examples[3].example).steps[0].input; + let input; + try { + input = yaml.parse(examples[3].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } await action.handler({ ...mockContext, @@ -170,7 +190,12 @@ describe('fetch:rails', () => { }); it(`should ${examples[4].description}`, async () => { - const input = yaml.parse(examples[4].example).steps[0].input; + let input; + try { + input = yaml.parse(examples[4].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } await action.handler({ ...mockContext, @@ -190,7 +215,12 @@ describe('fetch:rails', () => { }); it(`should ${examples[5].description}`, async () => { - const input = yaml.parse(examples[5].example).steps[0].input; + let input; + try { + input = yaml.parse(examples[5].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } await action.handler({ ...mockContext, @@ -210,7 +240,12 @@ describe('fetch:rails', () => { }); it(`should ${examples[6].description}`, async () => { - const input = yaml.parse(examples[6].example).steps[0].input; + let input; + try { + input = yaml.parse(examples[6].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } await action.handler({ ...mockContext, @@ -230,7 +265,12 @@ describe('fetch:rails', () => { }); it(`should ${examples[7].description}`, async () => { - const input = yaml.parse(examples[7].example).steps[0].input; + let input; + try { + input = yaml.parse(examples[7].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } await action.handler({ ...mockContext, @@ -250,7 +290,12 @@ describe('fetch:rails', () => { }); it(`should ${examples[8].description}`, async () => { - const input = yaml.parse(examples[8].example).steps[0].input; + let input; + try { + input = yaml.parse(examples[8].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } await action.handler({ ...mockContext, @@ -270,7 +315,12 @@ describe('fetch:rails', () => { }); it(`should ${examples[9].description}`, async () => { - const input = yaml.parse(examples[9].example).steps[0].input; + let input; + try { + input = yaml.parse(examples[9].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } await action.handler({ ...mockContext, From 31fd39b4dce1c39d258ed72c43dabe8de38e1c38 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Wed, 17 Jul 2024 12:22:36 +0200 Subject: [PATCH 308/510] chore: fixing discord link Signed-off-by: blam <ben@blam.sh> --- microsite/blog/2022-12-19-backstage-wrapped-2022.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microsite/blog/2022-12-19-backstage-wrapped-2022.mdx b/microsite/blog/2022-12-19-backstage-wrapped-2022.mdx index e92c9f2265..c15b9fe208 100644 --- a/microsite/blog/2022-12-19-backstage-wrapped-2022.mdx +++ b/microsite/blog/2022-12-19-backstage-wrapped-2022.mdx @@ -20,7 +20,7 @@ Last year we celebrated 75 [public adopters](https://github.com/backstage/backst ![Accelerated growth of Public Backstage Adopters, from January 2021–December 2022.](assets/2022-12-19/public-backstage-adopters-2022.png) -Not only are our adopters growing at an exponential rate, but so too are our contributors. Our [Discord server](https://discord.gg/backstage-687207715902193673-687207715902193673) is a perfect example of the worlds of our adopters and contributors melding. On average, at any given hour of the day or night, there are more than 500 people online available to talk and provide support on any Backstage topic. Discord discussions run a full gamut of topics – from technical support questions to best practices for onboarding engineers to Backstage – basically, anything and everything an adopter may be interested to know and learn. At the very beginning of 2022, we “only” had 4k Discord members. Today, we have a growing membership of 8.2k. +Not only are our adopters growing at an exponential rate, but so too are our contributors. Our [Discord server](https://discord.gg/backstage-687207715902193673) is a perfect example of the worlds of our adopters and contributors melding. On average, at any given hour of the day or night, there are more than 500 people online available to talk and provide support on any Backstage topic. Discord discussions run a full gamut of topics – from technical support questions to best practices for onboarding engineers to Backstage – basically, anything and everything an adopter may be interested to know and learn. At the very beginning of 2022, we “only” had 4k Discord members. Today, we have a growing membership of 8.2k. Isn’t it what we can call a great and vibrant community of enthusiasts? From c8f1cae0efb32b4b859bd7fa12d65e85c6dd5dbd Mon Sep 17 00:00:00 2001 From: Boris Bera <bbera@coveo.com> Date: Wed, 17 Jul 2024 11:31:12 -0400 Subject: [PATCH 309/510] Add `signIn.resolvers` to auth providers config schema Signed-off-by: Boris Bera <bbera@coveo.com> --- .changeset/breezy-jeans-tie.md | 18 ++++++++++++++++++ .../config.d.ts | 7 +++++++ .../config.d.ts | 6 ++++++ .../config.d.ts | 7 +++++++ .../config.d.ts | 6 ++++++ .../config.d.ts | 9 +++++++++ .../config.d.ts | 7 +++++++ .../config.d.ts | 7 +++++++ .../config.d.ts | 7 +++++++ .../config.d.ts | 7 +++++++ .../config.d.ts | 7 +++++++ .../config.d.ts | 6 ++++++ .../config.d.ts | 7 +++++++ .../config.d.ts | 7 +++++++ .../config.d.ts | 7 +++++++ 15 files changed, 115 insertions(+) create mode 100644 .changeset/breezy-jeans-tie.md diff --git a/.changeset/breezy-jeans-tie.md b/.changeset/breezy-jeans-tie.md new file mode 100644 index 0000000000..4601389a4c --- /dev/null +++ b/.changeset/breezy-jeans-tie.md @@ -0,0 +1,18 @@ +--- +'@backstage/plugin-auth-backend-module-cloudflare-access-provider': patch +'@backstage/plugin-auth-backend-module-vmware-cloud-provider': patch +'@backstage/plugin-auth-backend-module-atlassian-provider': patch +'@backstage/plugin-auth-backend-module-bitbucket-provider': patch +'@backstage/plugin-auth-backend-module-microsoft-provider': patch +'@backstage/plugin-auth-backend-module-onelogin-provider': patch +'@backstage/plugin-auth-backend-module-aws-alb-provider': patch +'@backstage/plugin-auth-backend-module-gcp-iap-provider': patch +'@backstage/plugin-auth-backend-module-github-provider': patch +'@backstage/plugin-auth-backend-module-gitlab-provider': patch +'@backstage/plugin-auth-backend-module-google-provider': patch +'@backstage/plugin-auth-backend-module-oauth2-provider': patch +'@backstage/plugin-auth-backend-module-oidc-provider': patch +'@backstage/plugin-auth-backend-module-okta-provider': patch +--- + +Add `signIn` to authentication provider configuration schema diff --git a/plugins/auth-backend-module-atlassian-provider/config.d.ts b/plugins/auth-backend-module-atlassian-provider/config.d.ts index d2c8a249c1..b6ca96d62f 100644 --- a/plugins/auth-backend-module-atlassian-provider/config.d.ts +++ b/plugins/auth-backend-module-atlassian-provider/config.d.ts @@ -28,6 +28,13 @@ export interface Config { audience?: string; callbackUrl?: string; additionalScopes?: string | string[]; + signIn?: { + resolvers: Array< + | { resolver: 'usernameMatchingUserEntityName' } + | { resolver: 'emailLocalPartMatchingUserEntityName' } + | { resolver: 'emailMatchingUserEntityProfileEmail' } + >; + }; }; }; }; diff --git a/plugins/auth-backend-module-aws-alb-provider/config.d.ts b/plugins/auth-backend-module-aws-alb-provider/config.d.ts index 1978e5a4df..5a3e90cf6b 100644 --- a/plugins/auth-backend-module-aws-alb-provider/config.d.ts +++ b/plugins/auth-backend-module-aws-alb-provider/config.d.ts @@ -21,6 +21,12 @@ export interface Config { awsalb?: { issuer?: string; region: string; + signIn?: { + resolvers: Array< + | { resolver: 'emailLocalPartMatchingUserEntityName' } + | { resolver: 'emailMatchingUserEntityProfileEmail' } + >; + }; }; }; }; diff --git a/plugins/auth-backend-module-bitbucket-provider/config.d.ts b/plugins/auth-backend-module-bitbucket-provider/config.d.ts index 17cac1c194..df68209469 100644 --- a/plugins/auth-backend-module-bitbucket-provider/config.d.ts +++ b/plugins/auth-backend-module-bitbucket-provider/config.d.ts @@ -26,6 +26,13 @@ export interface Config { */ clientSecret: string; additionalScopes?: string | string[]; + signIn?: { + resolvers: Array< + | { resolver: 'userIdMatchingUserEntityAnnotation' } + | { resolver: 'emailLocalPartMatchingUserEntityName' } + | { resolver: 'emailMatchingUserEntityProfileEmail' } + >; + }; }; }; }; diff --git a/plugins/auth-backend-module-cloudflare-access-provider/config.d.ts b/plugins/auth-backend-module-cloudflare-access-provider/config.d.ts index ff7d722d48..1300eb8c57 100644 --- a/plugins/auth-backend-module-cloudflare-access-provider/config.d.ts +++ b/plugins/auth-backend-module-cloudflare-access-provider/config.d.ts @@ -27,6 +27,12 @@ export interface Config { token: string; subject: string; }>; + signIn?: { + resolvers: Array< + | { resolver: 'emailLocalPartMatchingUserEntityName' } + | { resolver: 'emailMatchingUserEntityProfileEmail' } + >; + }; }; /** * The backstage token expiration. diff --git a/plugins/auth-backend-module-gcp-iap-provider/config.d.ts b/plugins/auth-backend-module-gcp-iap-provider/config.d.ts index 945378ada6..452f9819c3 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/config.d.ts +++ b/plugins/auth-backend-module-gcp-iap-provider/config.d.ts @@ -32,6 +32,15 @@ export interface Config { * The name of the header to read the JWT token from, defaults to `'x-goog-iap-jwt-assertion'`. */ jwtHeader?: string; + + signIn?: { + resolvers: Array< + | { resolver: 'emailMatchingUserEntityAnnotation' } + | { resolver: 'idMatchingUserEntityAnnotation' } + | { resolver: 'emailLocalPartMatchingUserEntityName' } + | { resolver: 'emailMatchingUserEntityProfileEmail' } + >; + }; }; }; }; diff --git a/plugins/auth-backend-module-github-provider/config.d.ts b/plugins/auth-backend-module-github-provider/config.d.ts index f60d4c239d..2ca17998f0 100644 --- a/plugins/auth-backend-module-github-provider/config.d.ts +++ b/plugins/auth-backend-module-github-provider/config.d.ts @@ -28,6 +28,13 @@ export interface Config { callbackUrl?: string; enterpriseInstanceUrl?: string; additionalScopes?: string | string[]; + signIn?: { + resolvers: Array< + | { resolver: 'usernameMatchingUserEntityName' } + | { resolver: 'emailLocalPartMatchingUserEntityName' } + | { resolver: 'emailMatchingUserEntityProfileEmail' } + >; + }; }; }; }; diff --git a/plugins/auth-backend-module-gitlab-provider/config.d.ts b/plugins/auth-backend-module-gitlab-provider/config.d.ts index 18f7cb5005..d21c2bd62a 100644 --- a/plugins/auth-backend-module-gitlab-provider/config.d.ts +++ b/plugins/auth-backend-module-gitlab-provider/config.d.ts @@ -28,6 +28,13 @@ export interface Config { audience?: string; callbackUrl?: string; additionalScopes?: string | string[]; + signIn?: { + resolvers: Array< + | { resolver: 'usernameMatchingUserEntityName' } + | { resolver: 'emailLocalPartMatchingUserEntityName' } + | { resolver: 'emailMatchingUserEntityProfileEmail' } + >; + }; }; }; }; diff --git a/plugins/auth-backend-module-google-provider/config.d.ts b/plugins/auth-backend-module-google-provider/config.d.ts index 08a0e08f2b..3abab05cfe 100644 --- a/plugins/auth-backend-module-google-provider/config.d.ts +++ b/plugins/auth-backend-module-google-provider/config.d.ts @@ -27,6 +27,13 @@ export interface Config { clientSecret: string; callbackUrl?: string; additionalScopes?: string | string[]; + signIn?: { + resolvers: Array< + | { resolver: 'emailMatchingUserEntityAnnotation' } + | { resolver: 'emailLocalPartMatchingUserEntityName' } + | { resolver: 'emailMatchingUserEntityProfileEmail' } + >; + }; }; }; }; diff --git a/plugins/auth-backend-module-microsoft-provider/config.d.ts b/plugins/auth-backend-module-microsoft-provider/config.d.ts index a7ec027083..b1ed2d5766 100644 --- a/plugins/auth-backend-module-microsoft-provider/config.d.ts +++ b/plugins/auth-backend-module-microsoft-provider/config.d.ts @@ -29,6 +29,13 @@ export interface Config { domainHint?: string; callbackUrl?: string; additionalScopes?: string | string[]; + signIn?: { + resolvers: Array< + | { resolver: 'emailMatchingUserEntityAnnotation' } + | { resolver: 'emailLocalPartMatchingUserEntityName' } + | { resolver: 'emailMatchingUserEntityProfileEmail' } + >; + }; }; }; }; diff --git a/plugins/auth-backend-module-oauth2-provider/config.d.ts b/plugins/auth-backend-module-oauth2-provider/config.d.ts index 9b1ee18f1b..fa9dec7ce1 100644 --- a/plugins/auth-backend-module-oauth2-provider/config.d.ts +++ b/plugins/auth-backend-module-oauth2-provider/config.d.ts @@ -32,6 +32,13 @@ export interface Config { additionalScopes?: string | string[]; disableRefresh?: boolean; includeBasicAuth?: boolean; + signIn?: { + resolvers: Array< + | { resolver: 'usernameMatchingUserEntityName' } + | { resolver: 'emailLocalPartMatchingUserEntityName' } + | { resolver: 'emailMatchingUserEntityProfileEmail' } + >; + }; }; }; }; diff --git a/plugins/auth-backend-module-oidc-provider/config.d.ts b/plugins/auth-backend-module-oidc-provider/config.d.ts index 398e63c466..dbc06e51bb 100644 --- a/plugins/auth-backend-module-oidc-provider/config.d.ts +++ b/plugins/auth-backend-module-oidc-provider/config.d.ts @@ -31,6 +31,12 @@ export interface Config { tokenSignedResponseAlg?: string; additionalScopes?: string | string[]; prompt?: string; + signIn?: { + resolvers: Array< + | { resolver: 'emailLocalPartMatchingUserEntityName' } + | { resolver: 'emailMatchingUserEntityProfileEmail' } + >; + }; }; }; }; diff --git a/plugins/auth-backend-module-okta-provider/config.d.ts b/plugins/auth-backend-module-okta-provider/config.d.ts index aaf6ec1f91..0689171153 100644 --- a/plugins/auth-backend-module-okta-provider/config.d.ts +++ b/plugins/auth-backend-module-okta-provider/config.d.ts @@ -30,6 +30,13 @@ export interface Config { idp?: string; callbackUrl?: string; additionalScopes?: string | string[]; + signIn?: { + resolvers: Array< + | { resolver: 'emailMatchingUserEntityAnnotation' } + | { resolver: 'emailLocalPartMatchingUserEntityName' } + | { resolver: 'emailMatchingUserEntityProfileEmail' } + >; + }; }; }; }; diff --git a/plugins/auth-backend-module-onelogin-provider/config.d.ts b/plugins/auth-backend-module-onelogin-provider/config.d.ts index d4f1457461..8257e2ac71 100644 --- a/plugins/auth-backend-module-onelogin-provider/config.d.ts +++ b/plugins/auth-backend-module-onelogin-provider/config.d.ts @@ -27,6 +27,13 @@ export interface Config { clientSecret: string; issuer: string; callbackUrl?: string; + signIn?: { + resolvers: Array< + | { resolver: 'usernameMatchingUserEntityName' } + | { resolver: 'emailLocalPartMatchingUserEntityName' } + | { resolver: 'emailMatchingUserEntityProfileEmail' } + >; + }; }; }; }; diff --git a/plugins/auth-backend-module-vmware-cloud-provider/config.d.ts b/plugins/auth-backend-module-vmware-cloud-provider/config.d.ts index 6ea07f1936..a08451cff3 100644 --- a/plugins/auth-backend-module-vmware-cloud-provider/config.d.ts +++ b/plugins/auth-backend-module-vmware-cloud-provider/config.d.ts @@ -25,6 +25,13 @@ export interface Config { scope?: string; consoleEndpoint?: string; additionalScopes?: string | string[]; + signIn?: { + resolvers: Array< + | { resolver: 'profileEmailMatchingUserEntityEmail' } + | { resolver: 'emailLocalPartMatchingUserEntityName' } + | { resolver: 'emailMatchingUserEntityProfileEmail' } + >; + }; }; }; }; From ee2b0e54330409df51f9ed2ac78090c77afd8f53 Mon Sep 17 00:00:00 2001 From: MT Lewis <mtlewis@users.noreply.github.com> Date: Wed, 17 Jul 2024 17:08:02 +0100 Subject: [PATCH 310/510] cli: add support for forcing use of react development when building Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com> --- .changeset/little-bulldogs-guess.md | 8 +++++ packages/cli/src/lib/bundler/config.ts | 44 +++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 .changeset/little-bulldogs-guess.md diff --git a/.changeset/little-bulldogs-guess.md b/.changeset/little-bulldogs-guess.md new file mode 100644 index 0000000000..8d247a182b --- /dev/null +++ b/.changeset/little-bulldogs-guess.md @@ -0,0 +1,8 @@ +--- +'@backstage/cli': patch +--- + +Add ability to force use of the development versions of `react` and `react-dom` +by setting the `FORCE_REACT_DEVELOPMENT` environment variable to `true` when +building, for example by using a command like `FORCE_REACT_DEVELOPMENT=true yarn +build:all`. diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index 60c8a7be66..44cdc4a475 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -15,7 +15,8 @@ */ import { BackendBundlingOptions, BundlingOptions } from './types'; -import { posix as posixPath, resolve as resolvePath } from 'path'; +import { posix as posixPath, resolve as resolvePath, dirname } from 'path'; +import chalk from 'chalk'; import webpack, { ProvidePlugin } from 'webpack'; import { BackstagePackage } from '@backstage/cli-node'; @@ -33,7 +34,7 @@ import fs from 'fs-extra'; import { getPackages } from '@manypkg/get-packages'; import { isChildPath } from '@backstage/cli-common'; import nodeExternals from 'webpack-node-externals'; -import { optimization } from './optimization'; +import { optimization as optimizationConfig } from './optimization'; import pickBy from 'lodash/pickBy'; import { readEntryPoints } from '../entryPoints'; import { runPlain } from '../run'; @@ -232,12 +233,47 @@ export async function createConfig( require.resolve('react-refresh'), ]; + const mode = isDev ? 'development' : 'production'; + const optimization = optimizationConfig(options); + + if (process.env.FORCE_REACT_DEVELOPMENT === 'true') { + console.log( + chalk.yellow( + `⚠️ WARNING: Forcing react and react-dom into development mode. This build should not be used in production.`, + ), + ); + + const reactPackageDirs = [ + `${dirname(require.resolve('react/package.json'))}/`, + `${dirname(require.resolve('react-dom/package.json'))}/`, + ]; + + // Don't define process.env.NODE_ENV with value matching config.mode. + optimization.nodeEnv = false; + + // Instead, provide a custom definition which always uses "development" if + // the module is part of `react` or `react-dom`, and `config.mode` otherwise. + plugins.push( + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': webpack.DefinePlugin.runtimeValue( + ({ module }) => { + if (reactPackageDirs.some(val => module.resource.startsWith(val))) { + return '"development"'; + } + + return `"${mode}"`; + }, + ), + }), + ); + } + const withCache = yn(process.env[BUILD_CACHE_ENV_VAR], { default: false }); return { - mode: isDev ? 'development' : 'production', + mode, profile: false, - optimization: optimization(options), + optimization, bail: false, performance: { hints: false, // we check the gzip size instead From 7eb08a69dd0cdc11fdf363a07149a8ca9438eadd Mon Sep 17 00:00:00 2001 From: MT Lewis <mtlewis@users.noreply.github.com> Date: Wed, 17 Jul 2024 20:53:55 +0100 Subject: [PATCH 311/510] cli: allow linting packages with role dynamic-frontend-container Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com> --- .changeset/bright-trainers-brake.md | 5 +++++ packages/cli/config/eslint-factory.js | 1 + 2 files changed, 6 insertions(+) create mode 100644 .changeset/bright-trainers-brake.md diff --git a/.changeset/bright-trainers-brake.md b/.changeset/bright-trainers-brake.md new file mode 100644 index 0000000000..2299d83a32 --- /dev/null +++ b/.changeset/bright-trainers-brake.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Add frontend-dynamic-container role to eslint config factory diff --git a/packages/cli/config/eslint-factory.js b/packages/cli/config/eslint-factory.js index 6bc200cade..96d8478ec0 100644 --- a/packages/cli/config/eslint-factory.js +++ b/packages/cli/config/eslint-factory.js @@ -201,6 +201,7 @@ function createConfigForRole(dir, role, extraConfig = {}) { case 'frontend': case 'frontend-plugin': case 'frontend-plugin-module': + case 'frontend-dynamic-container': return createConfig(dir, { ...extraConfig, extends: [ From 46e949f5ed570aefcc6917f4e771f633aef714e3 Mon Sep 17 00:00:00 2001 From: Francisco Meneses <fmeneses@redhat.com> Date: Wed, 17 Jul 2024 17:16:29 -0400 Subject: [PATCH 312/510] fix Spanish welcomeTitle message Signed-off-by: Francisco Meneses <fmeneses@redhat.com> --- .../WelcomeTitle/locales/goodAfternoon.locales.json | 1 + .../WelcomeTitle/locales/goodEvening.locales.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/home/src/homePageComponents/WelcomeTitle/locales/goodAfternoon.locales.json b/plugins/home/src/homePageComponents/WelcomeTitle/locales/goodAfternoon.locales.json index 9010ba4359..ddb51654fa 100644 --- a/plugins/home/src/homePageComponents/WelcomeTitle/locales/goodAfternoon.locales.json +++ b/plugins/home/src/homePageComponents/WelcomeTitle/locales/goodAfternoon.locales.json @@ -103,6 +103,7 @@ "Sinhala": "සුභ දවාලක්", "Slovenian": "Dober dan", "Somali": "Galab wanaagsan", + "Spanish": "Buenas tardes", "Southern Sámi": "Buerie biejjie", "Sumerian": "𒄭𒌓𒁀", "Swahili": "Habari ya mchana", diff --git a/plugins/home/src/homePageComponents/WelcomeTitle/locales/goodEvening.locales.json b/plugins/home/src/homePageComponents/WelcomeTitle/locales/goodEvening.locales.json index 5a98abafaa..c8d8c7334e 100644 --- a/plugins/home/src/homePageComponents/WelcomeTitle/locales/goodEvening.locales.json +++ b/plugins/home/src/homePageComponents/WelcomeTitle/locales/goodEvening.locales.json @@ -85,7 +85,7 @@ "Slovak": "Dober vecher", "Slovenian": "Dober vecher", "Somali": "Habeen wanaagsan", - "Spanish": "Buenas tardes", + "Spanish": "Buenas noches", "Sumerian": "𒄭𒈪", "Swedish": "God afton", "Tagalog": "Magandang gabi", From fdcc05947fc7447a28d3090235d882896e37d10a Mon Sep 17 00:00:00 2001 From: Francisco Meneses <fmeneses@redhat.com> Date: Wed, 17 Jul 2024 17:34:17 -0400 Subject: [PATCH 313/510] add changeset Signed-off-by: Francisco Meneses <fmeneses@redhat.com> --- .changeset/slow-toes-jog.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/slow-toes-jog.md diff --git a/.changeset/slow-toes-jog.md b/.changeset/slow-toes-jog.md new file mode 100644 index 0000000000..245feab544 --- /dev/null +++ b/.changeset/slow-toes-jog.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-home': patch +--- + +Fixed a bug on the WelcomeTitle component where the welcome message wasn't correct when the language was set to Spanish From 644d4696c28ca675efc0f240c428b5f43547f734 Mon Sep 17 00:00:00 2001 From: MT Lewis <mtlewis@users.noreply.github.com> Date: Thu, 18 Jul 2024 10:35:40 +0100 Subject: [PATCH 314/510] cli: only allow forcing react development mode when module federation is enabled Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com> --- .changeset/little-bulldogs-guess.md | 15 ++++++++++++--- packages/cli/src/lib/bundler/config.ts | 5 ++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.changeset/little-bulldogs-guess.md b/.changeset/little-bulldogs-guess.md index 8d247a182b..1f86f0a67f 100644 --- a/.changeset/little-bulldogs-guess.md +++ b/.changeset/little-bulldogs-guess.md @@ -3,6 +3,15 @@ --- Add ability to force use of the development versions of `react` and `react-dom` -by setting the `FORCE_REACT_DEVELOPMENT` environment variable to `true` when -building, for example by using a command like `FORCE_REACT_DEVELOPMENT=true yarn -build:all`. +to allow for detailed error messages and use of fast-refresh. Note that builds +with the development versions of `react` and `react-dom` should not be +deployed in production. + +This feature can be used by setting the `FORCE_REACT_DEVELOPMENT` environment +variable to `true`: + +```bash +EXPERIMENTAL_MODULE_FEDERATION=true \ +FORCE_REACT_DEVELOPMENT=true \ +yarn build:all +``` diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index 44cdc4a475..8e3d7eee19 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -236,7 +236,10 @@ export async function createConfig( const mode = isDev ? 'development' : 'production'; const optimization = optimizationConfig(options); - if (process.env.FORCE_REACT_DEVELOPMENT === 'true') { + if ( + process.env.EXPERIMENTAL_MODULE_FEDERATION === 'true' && + process.env.FORCE_REACT_DEVELOPMENT === 'true' + ) { console.log( chalk.yellow( `⚠️ WARNING: Forcing react and react-dom into development mode. This build should not be used in production.`, From ec950c58caac142a311225af4463e50982f7ee11 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Thu, 18 Jul 2024 12:35:16 +0200 Subject: [PATCH 315/510] chore: remove app-api dependency Signed-off-by: blam <ben@blam.sh> --- plugins/search-backend-module-pg/package.json | 1 - yarn.lock | 1 - 2 files changed, 2 deletions(-) diff --git a/plugins/search-backend-module-pg/package.json b/plugins/search-backend-module-pg/package.json index 8bdcf14306..1693c14c8a 100644 --- a/plugins/search-backend-module-pg/package.json +++ b/plugins/search-backend-module-pg/package.json @@ -49,7 +49,6 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-app-api": "workspace:^", "@backstage/backend-common": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", diff --git a/yarn.lock b/yarn.lock index c6a1d2139a..9261d70f21 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7271,7 +7271,6 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-search-backend-module-pg@workspace:plugins/search-backend-module-pg" dependencies: - "@backstage/backend-app-api": "workspace:^" "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" From d3d6f5e9ec07a34dc9d6c66c84493629d75ea0a4 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Thu, 18 Jul 2024 12:42:16 +0200 Subject: [PATCH 316/510] chore: remove app-api dep Signed-off-by: blam <ben@blam.sh> --- packages/backend-dynamic-feature-service/package.json | 3 ++- .../src/schemas/rootLoggerServiceFactory.ts | 4 ++-- yarn.lock | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/backend-dynamic-feature-service/package.json b/packages/backend-dynamic-feature-service/package.json index 0d05b97bd9..c693135f30 100644 --- a/packages/backend-dynamic-feature-service/package.json +++ b/packages/backend-dynamic-feature-service/package.json @@ -41,8 +41,8 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-app-api": "workspace:^", "@backstage/backend-common": "workspace:^", + "@backstage/backend-defaults": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/backend-tasks": "workspace:^", "@backstage/cli-common": "workspace:^", @@ -70,6 +70,7 @@ "winston": "^3.2.1" }, "devDependencies": { + "@backstage/backend-app-api": "workspace:^", "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "wait-for-expect": "^3.0.2" diff --git a/packages/backend-dynamic-feature-service/src/schemas/rootLoggerServiceFactory.ts b/packages/backend-dynamic-feature-service/src/schemas/rootLoggerServiceFactory.ts index 6681a65a75..bf3df3ffe7 100644 --- a/packages/backend-dynamic-feature-service/src/schemas/rootLoggerServiceFactory.ts +++ b/packages/backend-dynamic-feature-service/src/schemas/rootLoggerServiceFactory.ts @@ -18,9 +18,9 @@ import { createServiceFactory, coreServices, } from '@backstage/backend-plugin-api'; -import { WinstonLogger } from '@backstage/backend-app-api'; +import { WinstonLogger } from '@backstage/backend-defaults/rootLogger'; import { transports, format } from 'winston'; -import { createConfigSecretEnumerator } from '@backstage/backend-app-api'; +import { createConfigSecretEnumerator } from '@backstage/backend-defaults/rootLogger'; import { loadConfigSchema } from '@backstage/config-loader'; import { getPackages } from '@manypkg/get-packages'; import { dynamicPluginsSchemasServiceRef } from './schemas'; diff --git a/yarn.lock b/yarn.lock index 9261d70f21..53bef5284a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3708,6 +3708,7 @@ __metadata: dependencies: "@backstage/backend-app-api": "workspace:^" "@backstage/backend-common": "workspace:^" + "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-tasks": "workspace:^" "@backstage/backend-test-utils": "workspace:^" From 7251567926578e77bddd0f87ec668b91209826e8 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Thu, 18 Jul 2024 12:43:24 +0200 Subject: [PATCH 317/510] chore: changeset Signed-off-by: blam <ben@blam.sh> --- .changeset/nine-glasses-nail.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/nine-glasses-nail.md diff --git a/.changeset/nine-glasses-nail.md b/.changeset/nine-glasses-nail.md new file mode 100644 index 0000000000..0d68da9f2b --- /dev/null +++ b/.changeset/nine-glasses-nail.md @@ -0,0 +1,6 @@ +--- +'@backstage/backend-dynamic-feature-service': patch +'@backstage/plugin-search-backend-module-pg': patch +--- + +Removing `@backstage/backend-app-api` dependency From 0a40f13580e9b6af226ab6bdbd49e2505d988a2c Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Thu, 18 Jul 2024 13:05:32 +0200 Subject: [PATCH 318/510] chore: wip Signed-off-by: blam <ben@blam.sh> --- .../src/components/TabbedLayout/RoutedTabs.tsx | 3 +++ .../src/layout/HeaderTabs/HeaderTabs.test.tsx | 9 --------- .../core-components/src/layout/HeaderTabs/HeaderTabs.tsx | 7 +------ 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/packages/core-components/src/components/TabbedLayout/RoutedTabs.tsx b/packages/core-components/src/components/TabbedLayout/RoutedTabs.tsx index 2c727efe1b..6a5bf2970f 100644 --- a/packages/core-components/src/components/TabbedLayout/RoutedTabs.tsx +++ b/packages/core-components/src/components/TabbedLayout/RoutedTabs.tsx @@ -96,6 +96,9 @@ export function RoutedTabs(props: { routes: SubRoute[] }) { tabs={headerTabs} selectedIndex={index} onChange={onTabChange} + tabProps={{ + component: Link, + }} /> <Content> <Helmet title={route?.title} /> diff --git a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.test.tsx b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.test.tsx index dad40c4615..5aec83bc2b 100644 --- a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.test.tsx +++ b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.test.tsx @@ -95,13 +95,4 @@ describe('<HeaderTabs />', () => { await user.click(rendered.getByText('Docs')); expect(mockOnChange).toHaveBeenCalledTimes(1); }); - - it('should render 2 nav tabs', async () => { - const rendered = await renderInTestApp(<HeaderTabs tabs={mockTabs} />); - const tabs = rendered.queryAllByTestId(id => id.startsWith('header-tab')); - expect(tabs).toHaveLength(2); - tabs.forEach(tab => { - expect(tab.tagName.toLocaleLowerCase('en-US')).toBe('a'); - }); - }); }); diff --git a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx index 9ee9c5525f..002c9fe1ea 100644 --- a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx +++ b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx @@ -18,7 +18,6 @@ import { makeStyles } from '@material-ui/core/styles'; import TabUI, { TabProps } from '@material-ui/core/Tab'; import Tabs from '@material-ui/core/Tabs'; import React, { useCallback, useEffect, useState } from 'react'; -import { Link } from '../../components/Link'; // TODO(blam): Remove this implementation when the Tabs are ready // This is just a temporary solution to implementing tabs for now @@ -96,9 +95,7 @@ export function HeaderTabs(props: HeaderTabsProps) { setSelectedTab(selectedIndex); } }, [selectedIndex]); - function removeLeadingSlash(path: string) { - return path.replace(/^\//, ''); - } + return ( <Box className={styles.tabsWrapper}> <Tabs @@ -115,8 +112,6 @@ export function HeaderTabs(props: HeaderTabsProps) { data-testid={`header-tab-${index}`} label={tab.label} key={tab.id} - component={Link} - to={removeLeadingSlash(tab.id)} value={index} className={styles.defaultTab} classes={{ selected: styles.selected, root: styles.tabRoot }} From 1f5094f1b70495aba6ee8d54bb86ed5dcea6b410 Mon Sep 17 00:00:00 2001 From: Ben Lambert <blam@spotify.com> Date: Wed, 26 Jun 2024 16:20:47 +0200 Subject: [PATCH 319/510] Update dry-squids-tap.md Signed-off-by: Ben Lambert <blam@spotify.com> Signed-off-by: blam <ben@blam.sh> --- .changeset/dry-squids-tap.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/dry-squids-tap.md b/.changeset/dry-squids-tap.md index 5193e1f204..9bd835d371 100644 --- a/.changeset/dry-squids-tap.md +++ b/.changeset/dry-squids-tap.md @@ -14,9 +14,9 @@ const TestExtensionKind = createExtensionKind({ output: { element: coreExtensionData.reactElement, }, - factory(_, props: { text: string }) { + factory(_, options: { text: string }) { return { - element: <h1>{props.text}</h1>, + element: <h1>{options.text}</h1>, }; }, }); From f749bb8fa989e5f4c29608a903cc9119cd745390 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Tue, 25 Jun 2024 14:25:22 +0200 Subject: [PATCH 320/510] chore: extension overrides spike Signed-off-by: blam <ben@blam.sh> --- .../core-compat-api/src/convertLegacyApp.ts | 72 ++++++++++- .../src/wiring/createExtension.test.ts | 33 +++++ .../src/wiring/createExtension.ts | 121 ++++++++++++++---- .../src/wiring/createExtensionKind.ts | 4 +- 4 files changed, 194 insertions(+), 36 deletions(-) diff --git a/packages/core-compat-api/src/convertLegacyApp.ts b/packages/core-compat-api/src/convertLegacyApp.ts index 72ce4b5e61..567e5efcad 100644 --- a/packages/core-compat-api/src/convertLegacyApp.ts +++ b/packages/core-compat-api/src/convertLegacyApp.ts @@ -26,6 +26,7 @@ import { coreExtensionData, createExtension, createExtensionInput, + createExtensionKind, createExtensionOverrides, } from '@backstage/frontend-plugin-api'; import { getComponentData } from '@backstage/core-plugin-api'; @@ -128,21 +129,80 @@ export function convertLegacyApp( }; }, }); - const CoreNavOverride = createExtension({ - namespace: 'app', - name: 'nav', - attachTo: { id: 'app/layout', input: 'nav' }, - output: {}, + + const CoreNavOverride = CurrentCoreNav.override({ + // namespace: 'app', + // name: 'nav', + // attachTo: { id: 'app/layout', input: 'nav' }, + // output: {}, factory: () => ({}), disabled: true, }); + createExtensionOverride({ + extension: CurrentCoreNav, + factory: () => null, + }); + const collectedRoutes = collectLegacyRoutes(routesEl); return [ ...collectedRoutes, createExtensionOverrides({ - extensions: [CoreLayoutOverride, CoreNavOverride], + extensions: [CoreNavOverride, CoreNavOverride], }), ]; } + +const EntityCardExtension = createExtensionKind({ + kind: 'entity-card', + attachTo: { id: 'entity-card', input: 'default' }, + inputs: { + loader: createExtensionInput({ + element: coreExtensionData.reactElement, + }), + }, + output: { + element: coreExtensionData.reactElement, + }, + factory({ inputs }, props: { title: string }) { + console.log(inputs.loader); + return { + element: React.createElement('h1'), + }; + }, +}); + +const GithubCard = EntityCardExtension.new({ + props: { + title: 'GitHub Card', + }, + factory({ inputs: { loader } }) { + console.log(loader); + return { + element: React.createElement('h2'), + }; + }, +}); + +GithubCard.override({ + attachTo: { id: 'entity-card', input: 'github' }, + inputs: { + loader: createExtensionInput( + { + element: coreExtensionData.reactElement, + }, + { singleton: false }, + ), + loader2: createExtensionInput({ + element: coreExtensionData.reactElement, + }), + }, + factory({ originalFactory, inputs }) { + inputs.loader2; + inputs.loader; + return originalFactory({ + inputsOverride: inputs, + }); + }, +}); diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts index 42ab21db80..cfef69b0fe 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts @@ -291,4 +291,37 @@ describe('createExtension', () => { 'ExtensionDefinition{namespace=test,attachTo=root@default}', ); }); + + describe('override', () => { + it('should create an extension override', () => { + const extension = createExtension({ + namespace: 'test', + attachTo: { id: 'root', input: 'default' }, + output: { + foo: stringData, + }, + factory() { + return { + foo: 'bar', + }; + }, + }); + + const override = extension.override({ + attachTo: { + id: 'root', + input: 'default2', + }, + factory() { + return { + foo: 'baz', + }; + }, + }); + + expect(String(override)).toBe( + 'ExtensionDefinition{namespace=test,attachTo=root@default2}', + ); + }); + }); }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index 28dc6a4e29..b56cc39fc9 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -99,7 +99,33 @@ export interface CreateExtensionOptions< } /** @public */ -export interface ExtensionDefinition<TConfig> { +export interface ExtensionDefinitionOverrides< + TOriginalConfig, + TOriginalInputs extends AnyExtensionInputMap, + TOverrideInputs extends AnyExtensionInputMap, +> { + readonly disabled?: boolean; + readonly attachTo?: { id: string; input: string }; + // TODO: inputs (only adding to the list? or redefine arity and superset of old type on existing input?) + // TODO: config (any merging needed on there?) + inputs?: TOverrideInputs; + factory?(options: { + node: AppNode; + config: TOriginalConfig; + inputs: Expand<ResolvedExtensionInputs<TOriginalInputs & TOverrideInputs>>; + originalFactory: (originalFactoryOptions?: { + inputsOverride?: ResolvedExtensionInputs< + TOriginalInputs & TOverrideInputs + >; + }) => ExtensionDataValues<any>; + }): ExtensionDataValues<any>; +} + +/** @public */ +export interface ExtensionDefinition< + TConfig, + TInputs extends AnyExtensionInputMap, +> { $$type: '@backstage/ExtensionDefinition'; readonly kind?: string; readonly namespace?: string; @@ -107,13 +133,18 @@ export interface ExtensionDefinition<TConfig> { readonly attachTo: { id: string; input: string }; readonly disabled: boolean; readonly configSchema?: PortableSchema<TConfig>; + override<TOverrideInputs extends AnyExtensionInputMap>( + overrides: ExtensionDefinitionOverrides<TConfig, TInputs, TOverrideInputs>, + ): ExtensionDefinition<TConfig, TInputs>; } /** @internal */ -export interface InternalExtensionDefinition<TConfig> - extends ExtensionDefinition<TConfig> { +export interface InternalExtensionDefinition< + TConfig, + TInputs extends AnyExtensionInputMap, +> extends ExtensionDefinition<TConfig, TInputs> { readonly version: 'v1'; - readonly inputs: AnyExtensionInputMap; + readonly inputs: TInputs; readonly output: AnyExtensionDataMap; factory(context: { node: AppNode; @@ -123,10 +154,13 @@ export interface InternalExtensionDefinition<TConfig> } /** @internal */ -export function toInternalExtensionDefinition<TConfig>( - overrides: ExtensionDefinition<TConfig>, -): InternalExtensionDefinition<TConfig> { - const internal = overrides as InternalExtensionDefinition<TConfig>; +export function toInternalExtensionDefinition< + TConfig, + TInputs extends AnyExtensionInputMap, +>( + overrides: ExtensionDefinition<TConfig, TInputs>, +): InternalExtensionDefinition<TConfig, TInputs> { + const internal = overrides as InternalExtensionDefinition<TConfig, TInputs>; if (internal.$$type !== '@backstage/ExtensionDefinition') { throw new Error( `Invalid extension definition instance, bad type '${internal.$$type}'`, @@ -147,38 +181,69 @@ export function createExtension< TConfig = never, >( options: CreateExtensionOptions<TOutput, TInputs, TConfig>, -): ExtensionDefinition<TConfig> { +): ExtensionDefinition<TConfig, TInputs> { + const { + kind, + namespace, + name, + attachTo, + disabled = false, + inputs = {} as TInputs, + output, + configSchema, + factory, + } = options; + return { $$type: '@backstage/ExtensionDefinition', version: 'v1', - kind: options.kind, - namespace: options.namespace, - name: options.name, - attachTo: options.attachTo, - disabled: options.disabled ?? false, - inputs: options.inputs ?? {}, - output: options.output, - configSchema: options.configSchema, - factory({ inputs, ...rest }) { + kind, + namespace, + name, + attachTo, + disabled, + inputs, + output, + configSchema, + factory({ inputs: factoryInputs, ...rest }) { // TODO: Simplify this, but TS wouldn't infer the input type for some reason - return options.factory({ - inputs: inputs as Expand<ResolvedExtensionInputs<TInputs>>, + return factory({ + inputs: factoryInputs as Expand<ResolvedExtensionInputs<TInputs>>, ...rest, }); }, toString() { const parts: string[] = []; - if (options.kind) { - parts.push(`kind=${options.kind}`); + if (kind) { + parts.push(`kind=${kind}`); } - if (options.namespace) { - parts.push(`namespace=${options.namespace}`); + if (namespace) { + parts.push(`namespace=${namespace}`); } - if (options.name) { - parts.push(`name=${options.name}`); + if (name) { + parts.push(`name=${name}`); } - parts.push(`attachTo=${options.attachTo.id}@${options.attachTo.input}`); + parts.push(`attachTo=${attachTo.id}@${attachTo.input}`); return `ExtensionDefinition{${parts.join(',')}}`; }, - } as InternalExtensionDefinition<TConfig>; + override<TOverrideInputs extends AnyExtensionInputMap>( + overrides: ExtensionDefinitionOverrides< + TConfig, + TInputs, + TOverrideInputs + >, + ): ExtensionDefinition<TConfig, TInputs> { + return createExtension({ + kind, + namespace, + name, + attachTo: overrides.attachTo ?? attachTo, + disabled: overrides.disabled ?? disabled, + inputs: { ...inputs, ...overrides.inputs }, + output, + configSchema, + factory, + }); + }, + } as InternalExtensionDefinition<TConfig, TInputs>; } diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts b/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts index 52bf711822..353fb8ab70 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - import { AppNode } from '../apis'; import { PortableSchema } from '../schema'; import { Expand } from '../types'; @@ -21,6 +20,7 @@ import { AnyExtensionDataMap, AnyExtensionInputMap, ExtensionDataValues, + ExtensionDefinition, ResolvedExtensionInputs, createExtension, } from './createExtension'; @@ -107,7 +107,7 @@ export class ExtensionKind< }, options: TOptions, ): Expand<ExtensionDataValues<TOutput>>; - }) { + }): ExtensionDefinition<TConfig, TInputs> { return createExtension({ kind: this.options.kind, namespace: args.namespace ?? this.options.namespace, From 966cca176bc0506034499ce2cb622ebdffe2ca1b Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Wed, 26 Jun 2024 16:31:25 +0200 Subject: [PATCH 321/510] chore: tidying up Signed-off-by: blam <ben@blam.sh> Signed-off-by: blam <ben@blam.sh> --- .../core-compat-api/src/convertLegacyApp.ts | 72 +---- packages/frontend-plugin-api/api-report.md | 214 ++++++++++----- .../src/wiring/createExtension.test.ts | 33 --- .../src/wiring/createExtension.ts | 125 +++------ .../src/wiring/createExtensionKind.test.tsx | 164 ++++++++++++ .../src/wiring/createExtensionKind.ts | 245 ++++++++++++++---- .../frontend-plugin-api/src/wiring/index.ts | 4 +- 7 files changed, 550 insertions(+), 307 deletions(-) diff --git a/packages/core-compat-api/src/convertLegacyApp.ts b/packages/core-compat-api/src/convertLegacyApp.ts index 567e5efcad..72ce4b5e61 100644 --- a/packages/core-compat-api/src/convertLegacyApp.ts +++ b/packages/core-compat-api/src/convertLegacyApp.ts @@ -26,7 +26,6 @@ import { coreExtensionData, createExtension, createExtensionInput, - createExtensionKind, createExtensionOverrides, } from '@backstage/frontend-plugin-api'; import { getComponentData } from '@backstage/core-plugin-api'; @@ -129,80 +128,21 @@ export function convertLegacyApp( }; }, }); - - const CoreNavOverride = CurrentCoreNav.override({ - // namespace: 'app', - // name: 'nav', - // attachTo: { id: 'app/layout', input: 'nav' }, - // output: {}, + const CoreNavOverride = createExtension({ + namespace: 'app', + name: 'nav', + attachTo: { id: 'app/layout', input: 'nav' }, + output: {}, factory: () => ({}), disabled: true, }); - createExtensionOverride({ - extension: CurrentCoreNav, - factory: () => null, - }); - const collectedRoutes = collectLegacyRoutes(routesEl); return [ ...collectedRoutes, createExtensionOverrides({ - extensions: [CoreNavOverride, CoreNavOverride], + extensions: [CoreLayoutOverride, CoreNavOverride], }), ]; } - -const EntityCardExtension = createExtensionKind({ - kind: 'entity-card', - attachTo: { id: 'entity-card', input: 'default' }, - inputs: { - loader: createExtensionInput({ - element: coreExtensionData.reactElement, - }), - }, - output: { - element: coreExtensionData.reactElement, - }, - factory({ inputs }, props: { title: string }) { - console.log(inputs.loader); - return { - element: React.createElement('h1'), - }; - }, -}); - -const GithubCard = EntityCardExtension.new({ - props: { - title: 'GitHub Card', - }, - factory({ inputs: { loader } }) { - console.log(loader); - return { - element: React.createElement('h2'), - }; - }, -}); - -GithubCard.override({ - attachTo: { id: 'entity-card', input: 'github' }, - inputs: { - loader: createExtensionInput( - { - element: coreExtensionData.reactElement, - }, - { singleton: false }, - ), - loader2: createExtensionInput({ - element: coreExtensionData.reactElement, - }), - }, - factory({ originalFactory, inputs }) { - inputs.loader2; - inputs.loader; - return originalFactory({ - inputsOverride: inputs, - }); - }, -}); diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index 48718f5375..6a04d04cd6 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -529,9 +529,91 @@ export function createExtensionKind< TOutput extends AnyExtensionDataMap, TConfig, >( - options: ExtensionKindOptions<TOptions, TInputs, TOutput, TConfig>, + options: CreateExtensionKindOptions<TOptions, TInputs, TOutput, TConfig>, ): ExtensionKind<TOptions, TInputs, TOutput, TConfig>; +// @public (undocumented) +export interface CreateExtensionKindInstanceOptions< + TOptions, + TInputs extends AnyExtensionInputMap, + TOutput extends AnyExtensionDataMap, + TConfig, +> { + // (undocumented) + attachTo?: { + id: string; + input: string; + }; + // (undocumented) + configSchema?: PortableSchema<TConfig>; + // (undocumented) + disabled?: boolean; + // (undocumented) + factory?( + context: { + node: AppNode; + config: TConfig; + inputs: Expand<ResolvedExtensionInputs<TInputs>>; + originalFactory( + context?: { + node?: AppNode; + config?: TConfig; + inputs?: Expand<ResolvedExtensionInputs<TInputs>>; + }, + options?: TOptions, + ): Expand<ExtensionDataValues<TOutput>>; + }, + options: TOptions, + ): Expand<ExtensionDataValues<TOutput>>; + // (undocumented) + inputs?: TInputs; + // (undocumented) + name?: string; + // (undocumented) + namespace?: string; + // (undocumented) + options: TOptions; + // (undocumented) + output?: TOutput; +} + +// @public (undocumented) +export interface CreateExtensionKindOptions< + TOptions, + TInputs extends AnyExtensionInputMap, + TOutput extends AnyExtensionDataMap, + TConfig, +> { + // (undocumented) + attachTo: { + id: string; + input: string; + }; + // (undocumented) + configSchema?: PortableSchema<TConfig>; + // (undocumented) + disabled?: boolean; + // (undocumented) + factory( + context: { + node: AppNode; + config: TConfig; + inputs: Expand<ResolvedExtensionInputs<TInputs>>; + }, + options: TOptions, + ): Expand<ExtensionDataValues<TOutput>>; + // (undocumented) + inputs?: TInputs; + // (undocumented) + kind: string; + // (undocumented) + name?: string; + // (undocumented) + namespace?: string; + // (undocumented) + output: TOutput; +} + // @public (undocumented) export interface CreateExtensionOptions< TOutput extends AnyExtensionDataMap, @@ -548,7 +630,7 @@ export interface CreateExtensionOptions< // (undocumented) disabled?: boolean; // (undocumented) - factory(context: { + factory(options: { node: AppNode; config: TConfig; inputs: Expand<ResolvedExtensionInputs<TInputs>>; @@ -565,6 +647,51 @@ export interface CreateExtensionOptions< output: TOutput; } +// @public (undocumented) +export interface CreateExtensionOverrideKindInstanceOptions< + TOptions, + TInputs extends AnyExtensionInputMap, + TOutput extends AnyExtensionDataMap, + TConfig, +> { + // (undocumented) + attachTo?: { + id: string; + input: string; + }; + // (undocumented) + configSchema?: PortableSchema<TConfig>; + // (undocumented) + disabled?: boolean; + // (undocumented) + factory?( + context: { + node: AppNode; + config: TConfig; + inputs: Expand<ResolvedExtensionInputs<TInputs>>; + originalFactory( + context?: { + node?: AppNode; + config?: TConfig; + inputs?: Expand<ResolvedExtensionInputs<TInputs>>; + }, + options?: TOptions, + ): Expand<ExtensionDataValues<TOutput>>; + }, + options: TOptions, + ): Expand<ExtensionDataValues<TOutput>>; + // (undocumented) + inputs?: TInputs; + // (undocumented) + name?: string; + // (undocumented) + namespace?: string; + // (undocumented) + options?: TOptions; + // (undocumented) + output?: TOutput; +} + // @public (undocumented) export function createExtensionOverrides( options: ExtensionOverridesOptions, @@ -937,75 +1064,26 @@ export class ExtensionKind< TOutput extends AnyExtensionDataMap, TConfig, >( - options: ExtensionKindOptions<TOptions, TInputs, TOutput, TConfig>, + options: CreateExtensionKindOptions<TOptions, TInputs, TOutput, TConfig>, ): ExtensionKind<TOptions, TInputs, TOutput, TConfig>; // (undocumented) - new(args: { - namespace?: string; - name?: string; - attachTo?: { - id: string; - input: string; - }; - disabled?: boolean; - inputs?: TInputs; - output?: TOutput; - configSchema?: PortableSchema<TConfig>; - options: TOptions; - factory?( - context: { - node: AppNode; - config: TConfig; - inputs: Expand<ResolvedExtensionInputs<TInputs>>; - orignalFactory( - context?: { - node?: AppNode; - config?: TConfig; - inputs?: Expand<ResolvedExtensionInputs<TInputs>>; - }, - options?: TOptions, - ): Expand<ExtensionDataValues<TOutput>>; - }, - options: TOptions, - ): Expand<ExtensionDataValues<TOutput>>; - }): ExtensionDefinition<TConfig>; -} - -// @public (undocumented) -export interface ExtensionKindOptions< - TOptions, - TInputs extends AnyExtensionInputMap, - TOutput extends AnyExtensionDataMap, - TConfig, -> { - // (undocumented) - attachTo: { - id: string; - input: string; + new( + instanceProperties: CreateExtensionKindInstanceOptions< + TOptions, + TInputs, + TOutput, + TConfig + >, + ): ExtensionDefinition<TConfig> & { + override: ( + overrides: CreateExtensionOverrideKindInstanceOptions< + TOptions, + TInputs, + TOutput, + TConfig + >, + ) => ExtensionDefinition<TConfig>; }; - // (undocumented) - configSchema?: PortableSchema<TConfig>; - // (undocumented) - disabled?: boolean; - // (undocumented) - factory( - context: { - node: AppNode; - config: TConfig; - inputs: Expand<ResolvedExtensionInputs<TInputs>>; - }, - options: TOptions, - ): Expand<ExtensionDataValues<TOutput>>; - // (undocumented) - inputs?: TInputs; - // (undocumented) - kind: string; - // (undocumented) - name?: string; - // (undocumented) - namespace?: string; - // (undocumented) - output: TOutput; } // @public (undocumented) diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts index cfef69b0fe..42ab21db80 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts @@ -291,37 +291,4 @@ describe('createExtension', () => { 'ExtensionDefinition{namespace=test,attachTo=root@default}', ); }); - - describe('override', () => { - it('should create an extension override', () => { - const extension = createExtension({ - namespace: 'test', - attachTo: { id: 'root', input: 'default' }, - output: { - foo: stringData, - }, - factory() { - return { - foo: 'bar', - }; - }, - }); - - const override = extension.override({ - attachTo: { - id: 'root', - input: 'default2', - }, - factory() { - return { - foo: 'baz', - }; - }, - }); - - expect(String(override)).toBe( - 'ExtensionDefinition{namespace=test,attachTo=root@default2}', - ); - }); - }); }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index b56cc39fc9..be76fbc069 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -91,7 +91,7 @@ export interface CreateExtensionOptions< inputs?: TInputs; output: TOutput; configSchema?: PortableSchema<TConfig>; - factory(context: { + factory(options: { node: AppNode; config: TConfig; inputs: Expand<ResolvedExtensionInputs<TInputs>>; @@ -99,33 +99,7 @@ export interface CreateExtensionOptions< } /** @public */ -export interface ExtensionDefinitionOverrides< - TOriginalConfig, - TOriginalInputs extends AnyExtensionInputMap, - TOverrideInputs extends AnyExtensionInputMap, -> { - readonly disabled?: boolean; - readonly attachTo?: { id: string; input: string }; - // TODO: inputs (only adding to the list? or redefine arity and superset of old type on existing input?) - // TODO: config (any merging needed on there?) - inputs?: TOverrideInputs; - factory?(options: { - node: AppNode; - config: TOriginalConfig; - inputs: Expand<ResolvedExtensionInputs<TOriginalInputs & TOverrideInputs>>; - originalFactory: (originalFactoryOptions?: { - inputsOverride?: ResolvedExtensionInputs< - TOriginalInputs & TOverrideInputs - >; - }) => ExtensionDataValues<any>; - }): ExtensionDataValues<any>; -} - -/** @public */ -export interface ExtensionDefinition< - TConfig, - TInputs extends AnyExtensionInputMap, -> { +export interface ExtensionDefinition<TConfig> { $$type: '@backstage/ExtensionDefinition'; readonly kind?: string; readonly namespace?: string; @@ -133,20 +107,15 @@ export interface ExtensionDefinition< readonly attachTo: { id: string; input: string }; readonly disabled: boolean; readonly configSchema?: PortableSchema<TConfig>; - override<TOverrideInputs extends AnyExtensionInputMap>( - overrides: ExtensionDefinitionOverrides<TConfig, TInputs, TOverrideInputs>, - ): ExtensionDefinition<TConfig, TInputs>; } /** @internal */ -export interface InternalExtensionDefinition< - TConfig, - TInputs extends AnyExtensionInputMap, -> extends ExtensionDefinition<TConfig, TInputs> { +export interface InternalExtensionDefinition<TConfig> + extends ExtensionDefinition<TConfig> { readonly version: 'v1'; - readonly inputs: TInputs; + readonly inputs: AnyExtensionInputMap; readonly output: AnyExtensionDataMap; - factory(context: { + factory(options: { node: AppNode; config: TConfig; inputs: ResolvedExtensionInputs<any>; @@ -154,13 +123,10 @@ export interface InternalExtensionDefinition< } /** @internal */ -export function toInternalExtensionDefinition< - TConfig, - TInputs extends AnyExtensionInputMap, ->( - overrides: ExtensionDefinition<TConfig, TInputs>, -): InternalExtensionDefinition<TConfig, TInputs> { - const internal = overrides as InternalExtensionDefinition<TConfig, TInputs>; +export function toInternalExtensionDefinition<TConfig>( + overrides: ExtensionDefinition<TConfig>, +): InternalExtensionDefinition<TConfig> { + const internal = overrides as InternalExtensionDefinition<TConfig>; if (internal.$$type !== '@backstage/ExtensionDefinition') { throw new Error( `Invalid extension definition instance, bad type '${internal.$$type}'`, @@ -181,69 +147,38 @@ export function createExtension< TConfig = never, >( options: CreateExtensionOptions<TOutput, TInputs, TConfig>, -): ExtensionDefinition<TConfig, TInputs> { - const { - kind, - namespace, - name, - attachTo, - disabled = false, - inputs = {} as TInputs, - output, - configSchema, - factory, - } = options; - +): ExtensionDefinition<TConfig> { return { $$type: '@backstage/ExtensionDefinition', version: 'v1', - kind, - namespace, - name, - attachTo, - disabled, - inputs, - output, - configSchema, - factory({ inputs: factoryInputs, ...rest }) { + kind: options.kind, + namespace: options.namespace, + name: options.name, + attachTo: options.attachTo, + disabled: options.disabled ?? false, + inputs: options.inputs ?? {}, + output: options.output, + configSchema: options.configSchema, + factory({ inputs, ...rest }) { // TODO: Simplify this, but TS wouldn't infer the input type for some reason - return factory({ - inputs: factoryInputs as Expand<ResolvedExtensionInputs<TInputs>>, + return options.factory({ + inputs: inputs as Expand<ResolvedExtensionInputs<TInputs>>, ...rest, }); }, toString() { const parts: string[] = []; - if (kind) { - parts.push(`kind=${kind}`); + if (options.kind) { + parts.push(`kind=${options.kind}`); } - if (namespace) { - parts.push(`namespace=${namespace}`); + if (options.namespace) { + parts.push(`namespace=${options.namespace}`); } - if (name) { - parts.push(`name=${name}`); + if (options.name) { + parts.push(`name=${options.name}`); } - parts.push(`attachTo=${attachTo.id}@${attachTo.input}`); + parts.push(`attachTo=${options.attachTo.id}@${options.attachTo.input}`); return `ExtensionDefinition{${parts.join(',')}}`; }, - override<TOverrideInputs extends AnyExtensionInputMap>( - overrides: ExtensionDefinitionOverrides< - TConfig, - TInputs, - TOverrideInputs - >, - ): ExtensionDefinition<TConfig, TInputs> { - return createExtension({ - kind, - namespace, - name, - attachTo: overrides.attachTo ?? attachTo, - disabled: overrides.disabled ?? disabled, - inputs: { ...inputs, ...overrides.inputs }, - output, - configSchema, - factory, - }); - }, - } as InternalExtensionDefinition<TConfig, TInputs>; + } as InternalExtensionDefinition<TConfig>; } diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx b/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx index 3bdcd3a7cc..30c3e6ca44 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx +++ b/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx @@ -64,6 +64,7 @@ describe('createExtensionKind', () => { }, factory: expect.any(Function), toString: expect.any(Function), + override: expect.any(Function), version: 'v1', }); @@ -102,4 +103,167 @@ describe('createExtensionKind', () => { const { container } = createExtensionTester(extension).render(); expect(container.querySelector('h2')).toHaveTextContent('Hello, world!'); }); + + it('should allow calling of the default value from override', () => { + const TestExtension = createExtensionKind({ + kind: 'test-extension', + attachTo: { id: 'test', input: 'default' }, + output: { + element: coreExtensionData.reactElement, + }, + factory(_, options: { text: string }) { + return { + element: <h1>{options.text}</h1>, + }; + }, + }); + + const extension = TestExtension.new({ + name: 'my-extension', + options: { + text: 'Hello, world!', + }, + factory({ originalFactory }, options: { text: string }) { + const { element } = originalFactory(); + return { + element: ( + <h2> + {options.text} + {element} + </h2> + ), + }; + }, + }); + + expect(extension).toBeDefined(); + + const { container } = createExtensionTester(extension).render(); + + expect(container.querySelector('h2 h1')).toHaveTextContent('Hello, world!'); + }); + + it('should allow overriding options of the default value from override', () => { + const TestExtension = createExtensionKind({ + kind: 'test-extension', + attachTo: { id: 'test', input: 'default' }, + output: { + element: coreExtensionData.reactElement, + }, + factory(_, options: { text: string }) { + return { + element: <h1>{options.text}</h1>, + }; + }, + }); + + const extension = TestExtension.new({ + name: 'my-extension', + options: { + text: 'Hello, world!', + }, + factory({ originalFactory }, options: { text: string }) { + const { element } = originalFactory(undefined, { text: 'nothing!' }); + return { + element: ( + <h2> + {options.text} + {element} + </h2> + ), + }; + }, + }); + + expect(extension).toBeDefined(); + + const { container } = createExtensionTester(extension).render(); + + expect(container.querySelector('h2 h1')).toHaveTextContent('nothing!'); + }); + + describe('override', () => { + it('should allow overriding of the default factory', () => { + const TestExtension = createExtensionKind({ + kind: 'test-extension', + attachTo: { id: 'test', input: 'default' }, + output: { + element: coreExtensionData.reactElement, + }, + factory(_, options: { text: string }) { + return { + element: <h1>{options.text}</h1>, + }; + }, + }); + + const extension = TestExtension.new({ + name: 'my-extension', + options: { + text: 'Hello, world!', + }, + factory(_, options: { text: string }) { + return { + element: <h2>{options.text}</h2>, + }; + }, + }); + + const overridden = extension.override({ + factory({ originalFactory }, { text }) { + return { + element: ( + <div> + {originalFactory().element} + <h3>{text}</h3> + </div> + ), + }; + }, + }); + + const { container } = createExtensionTester(overridden).render(); + expect(container.querySelector('h2')).toHaveTextContent('Hello, world!'); + expect(container.querySelector('h3')).toHaveTextContent('Hello, world!'); + }); + }); + + it('should allow calling the kind factory if another factory is not defined in the instance', () => { + const TestExtension = createExtensionKind({ + kind: 'test-extension', + attachTo: { id: 'test', input: 'default' }, + output: { + element: coreExtensionData.reactElement, + }, + factory(_, options: { text: string }) { + return { + element: <h1>{options.text}</h1>, + }; + }, + }); + + const extension = TestExtension.new({ + name: 'my-extension', + options: { + text: 'Hello, world!', + }, + }); + + const overridden = extension.override({ + factory({ originalFactory }, { text }) { + return { + element: ( + <div> + {originalFactory().element} + <h3>{text}</h3> + </div> + ), + }; + }, + }); + + const { container } = createExtensionTester(overridden).render(); + expect(container.querySelector('h1')).toHaveTextContent('Hello, world!'); + expect(container.querySelector('h3')).toHaveTextContent('Hello, world!'); + }); }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts b/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts index 353fb8ab70..9813c9e50c 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { AppNode } from '../apis'; import { PortableSchema } from '../schema'; import { Expand } from '../types'; @@ -52,6 +53,76 @@ export interface CreateExtensionKindOptions< ): Expand<ExtensionDataValues<TOutput>>; } +/** + * @public + */ +export interface CreateExtensionKindInstanceOptions< + TOptions, + TInputs extends AnyExtensionInputMap, + TOutput extends AnyExtensionDataMap, + TConfig, +> { + namespace?: string; + name?: string; + attachTo?: { id: string; input: string }; + disabled?: boolean; + inputs?: TInputs; + output?: TOutput; + configSchema?: PortableSchema<TConfig>; + options: TOptions; + factory?( + context: { + node: AppNode; + config: TConfig; + inputs: Expand<ResolvedExtensionInputs<TInputs>>; + originalFactory( + context?: { + node?: AppNode; + config?: TConfig; + inputs?: Expand<ResolvedExtensionInputs<TInputs>>; + }, + options?: TOptions, + ): Expand<ExtensionDataValues<TOutput>>; + }, + options: TOptions, + ): Expand<ExtensionDataValues<TOutput>>; +} + +/** + * @public + */ +export interface CreateExtensionOverrideKindInstanceOptions< + TOptions, + TInputs extends AnyExtensionInputMap, + TOutput extends AnyExtensionDataMap, + TConfig, +> { + namespace?: string; + name?: string; + attachTo?: { id: string; input: string }; + disabled?: boolean; + inputs?: TInputs; + output?: TOutput; + configSchema?: PortableSchema<TConfig>; + options?: TOptions; + factory?( + context: { + node: AppNode; + config: TConfig; + inputs: Expand<ResolvedExtensionInputs<TInputs>>; + originalFactory( + context?: { + node?: AppNode; + config?: TConfig; + inputs?: Expand<ResolvedExtensionInputs<TInputs>>; + }, + options?: TOptions, + ): Expand<ExtensionDataValues<TOutput>>; + }, + options: TOptions, + ): Expand<ExtensionDataValues<TOutput>>; +} + /** * TODO: should we export an interface instead of a concrete class? * @public @@ -74,7 +145,7 @@ export class ExtensionKind< } private constructor( - private readonly options: CreateExtensionKindOptions< + private readonly kindProperties: CreateExtensionKindOptions< TOptions, TInputs, TOutput, @@ -82,49 +153,41 @@ export class ExtensionKind< >, ) {} - public new(args: { - namespace?: string; - name?: string; - attachTo?: { id: string; input: string }; - disabled?: boolean; - inputs?: TInputs; - output?: TOutput; - configSchema?: PortableSchema<TConfig>; - options: TOptions; - factory?( - context: { - node: AppNode; - config: TConfig; - inputs: Expand<ResolvedExtensionInputs<TInputs>>; - orignalFactory( - context?: { - node?: AppNode; - config?: TConfig; - inputs?: Expand<ResolvedExtensionInputs<TInputs>>; - }, - options?: TOptions, - ): Expand<ExtensionDataValues<TOutput>>; - }, - options: TOptions, - ): Expand<ExtensionDataValues<TOutput>>; - }): ExtensionDefinition<TConfig, TInputs> { - return createExtension({ - kind: this.options.kind, - namespace: args.namespace ?? this.options.namespace, - name: args.name ?? this.options.name, - attachTo: args.attachTo ?? this.options.attachTo, - disabled: args.disabled ?? this.options.disabled, - inputs: args.inputs ?? this.options.inputs, - output: args.output ?? this.options.output, - configSchema: args.configSchema ?? this.options.configSchema, // TODO: some config merging or smth + public new( + instanceProperties: CreateExtensionKindInstanceOptions< + TOptions, + TInputs, + TOutput, + TConfig + >, + ): ExtensionDefinition<TConfig> & { + override: ( + overrides: CreateExtensionOverrideKindInstanceOptions< + TOptions, + TInputs, + TOutput, + TConfig + >, + ) => ExtensionDefinition<TConfig>; + } { + const extension = createExtension({ + kind: this.kindProperties.kind, + namespace: instanceProperties.namespace ?? this.kindProperties.namespace, + name: instanceProperties.name ?? this.kindProperties.name, + attachTo: instanceProperties.attachTo ?? this.kindProperties.attachTo, + disabled: instanceProperties.disabled ?? this.kindProperties.disabled, + inputs: instanceProperties.inputs ?? this.kindProperties.inputs, + output: instanceProperties.output ?? this.kindProperties.output, + configSchema: + instanceProperties.configSchema ?? this.kindProperties.configSchema, // TODO: some config merging or smth factory: ({ node, config, inputs }) => { - if (args.factory) { - return args.factory( + if (instanceProperties.factory) { + return instanceProperties.factory( { node, config, inputs, - orignalFactory: ( + originalFactory: ( innerContext?: { node?: AppNode; config?: TConfig; @@ -132,29 +195,123 @@ export class ExtensionKind< }, innerOptions?: TOptions, ) => - this.options.factory( + this.kindProperties.factory( { node: innerContext?.node ?? node, config: innerContext?.config ?? config, inputs: innerContext?.inputs ?? inputs, }, - innerOptions ?? args.options, + innerOptions ?? instanceProperties.options, ), }, - args.options, + instanceProperties.options, ); } - return this.options.factory( + return this.kindProperties.factory( { node, config, inputs, }, - args.options, + instanceProperties.options, ); }, }); + + return { + ...extension, + override: overrides => { + return createExtension({ + kind: this.kindProperties.kind, + namespace: + overrides.namespace ?? + instanceProperties.namespace ?? + this.kindProperties.namespace, + name: + overrides.name ?? + instanceProperties.name ?? + this.kindProperties.name, + attachTo: + overrides.attachTo ?? + instanceProperties.attachTo ?? + this.kindProperties.attachTo, + disabled: + overrides.disabled ?? + instanceProperties.disabled ?? + this.kindProperties.disabled, + inputs: + overrides.inputs ?? + instanceProperties.inputs ?? + this.kindProperties.inputs, + output: + overrides.output ?? + instanceProperties.output ?? + this.kindProperties.output, + configSchema: + overrides.configSchema ?? + instanceProperties.configSchema ?? + this.kindProperties.configSchema, // TODO: some config merging or smth + factory: ({ node, config, inputs }) => { + if (overrides.factory) { + return overrides.factory( + { + node, + config, + inputs, + originalFactory: ( + innerContext?: { + node?: AppNode; + config?: TConfig; + inputs?: Expand<ResolvedExtensionInputs<TInputs>>; + }, + innerOptions?: TOptions, + ) => + instanceProperties.factory?.( + { + node: innerContext?.node ?? node, + config: innerContext?.config ?? config, + inputs: innerContext?.inputs ?? inputs, + originalFactory: this.kindProperties.factory, + }, + innerOptions ?? instanceProperties.options, + ) ?? + this.kindProperties.factory( + { + node, + config, + inputs, + }, + innerOptions ?? instanceProperties.options, + ), + }, + instanceProperties.options, + ); + } + + return ( + instanceProperties.factory?.( + { + node, + config, + inputs, + originalFactory: this.kindProperties.factory, + }, + instanceProperties.options, + ) ?? + this.kindProperties.factory( + { + node, + config, + inputs, + }, + instanceProperties.options, + ) + ); + }, + }); + }, + }; } } diff --git a/packages/frontend-plugin-api/src/wiring/index.ts b/packages/frontend-plugin-api/src/wiring/index.ts index 8fe9dc3a54..a312c0f06f 100644 --- a/packages/frontend-plugin-api/src/wiring/index.ts +++ b/packages/frontend-plugin-api/src/wiring/index.ts @@ -49,7 +49,9 @@ export { type FrontendFeature, } from './types'; export { - type CreateExtensionKindOptions as ExtensionKindOptions, + type CreateExtensionKindOptions, + type CreateExtensionKindInstanceOptions, + type CreateExtensionOverrideKindInstanceOptions, ExtensionKind, createExtensionKind, } from './createExtensionKind'; From 6b6cbdaac5cf05702210e9c24ccb4272c3ba3e88 Mon Sep 17 00:00:00 2001 From: Ben Lambert <ben@blam.sh> Date: Thu, 18 Jul 2024 13:07:02 +0200 Subject: [PATCH 322/510] Revert "NFE: Make it possible to override existing extension instances" Signed-off-by: blam <ben@blam.sh> --- packages/frontend-plugin-api/api-report.md | 214 +++++---------- .../src/wiring/createExtension.ts | 4 +- .../src/wiring/createExtensionKind.test.tsx | 164 ------------ .../src/wiring/createExtensionKind.ts | 245 ++++-------------- .../frontend-plugin-api/src/wiring/index.ts | 4 +- 5 files changed, 115 insertions(+), 516 deletions(-) diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index 6a04d04cd6..48718f5375 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -529,91 +529,9 @@ export function createExtensionKind< TOutput extends AnyExtensionDataMap, TConfig, >( - options: CreateExtensionKindOptions<TOptions, TInputs, TOutput, TConfig>, + options: ExtensionKindOptions<TOptions, TInputs, TOutput, TConfig>, ): ExtensionKind<TOptions, TInputs, TOutput, TConfig>; -// @public (undocumented) -export interface CreateExtensionKindInstanceOptions< - TOptions, - TInputs extends AnyExtensionInputMap, - TOutput extends AnyExtensionDataMap, - TConfig, -> { - // (undocumented) - attachTo?: { - id: string; - input: string; - }; - // (undocumented) - configSchema?: PortableSchema<TConfig>; - // (undocumented) - disabled?: boolean; - // (undocumented) - factory?( - context: { - node: AppNode; - config: TConfig; - inputs: Expand<ResolvedExtensionInputs<TInputs>>; - originalFactory( - context?: { - node?: AppNode; - config?: TConfig; - inputs?: Expand<ResolvedExtensionInputs<TInputs>>; - }, - options?: TOptions, - ): Expand<ExtensionDataValues<TOutput>>; - }, - options: TOptions, - ): Expand<ExtensionDataValues<TOutput>>; - // (undocumented) - inputs?: TInputs; - // (undocumented) - name?: string; - // (undocumented) - namespace?: string; - // (undocumented) - options: TOptions; - // (undocumented) - output?: TOutput; -} - -// @public (undocumented) -export interface CreateExtensionKindOptions< - TOptions, - TInputs extends AnyExtensionInputMap, - TOutput extends AnyExtensionDataMap, - TConfig, -> { - // (undocumented) - attachTo: { - id: string; - input: string; - }; - // (undocumented) - configSchema?: PortableSchema<TConfig>; - // (undocumented) - disabled?: boolean; - // (undocumented) - factory( - context: { - node: AppNode; - config: TConfig; - inputs: Expand<ResolvedExtensionInputs<TInputs>>; - }, - options: TOptions, - ): Expand<ExtensionDataValues<TOutput>>; - // (undocumented) - inputs?: TInputs; - // (undocumented) - kind: string; - // (undocumented) - name?: string; - // (undocumented) - namespace?: string; - // (undocumented) - output: TOutput; -} - // @public (undocumented) export interface CreateExtensionOptions< TOutput extends AnyExtensionDataMap, @@ -630,7 +548,7 @@ export interface CreateExtensionOptions< // (undocumented) disabled?: boolean; // (undocumented) - factory(options: { + factory(context: { node: AppNode; config: TConfig; inputs: Expand<ResolvedExtensionInputs<TInputs>>; @@ -647,51 +565,6 @@ export interface CreateExtensionOptions< output: TOutput; } -// @public (undocumented) -export interface CreateExtensionOverrideKindInstanceOptions< - TOptions, - TInputs extends AnyExtensionInputMap, - TOutput extends AnyExtensionDataMap, - TConfig, -> { - // (undocumented) - attachTo?: { - id: string; - input: string; - }; - // (undocumented) - configSchema?: PortableSchema<TConfig>; - // (undocumented) - disabled?: boolean; - // (undocumented) - factory?( - context: { - node: AppNode; - config: TConfig; - inputs: Expand<ResolvedExtensionInputs<TInputs>>; - originalFactory( - context?: { - node?: AppNode; - config?: TConfig; - inputs?: Expand<ResolvedExtensionInputs<TInputs>>; - }, - options?: TOptions, - ): Expand<ExtensionDataValues<TOutput>>; - }, - options: TOptions, - ): Expand<ExtensionDataValues<TOutput>>; - // (undocumented) - inputs?: TInputs; - // (undocumented) - name?: string; - // (undocumented) - namespace?: string; - // (undocumented) - options?: TOptions; - // (undocumented) - output?: TOutput; -} - // @public (undocumented) export function createExtensionOverrides( options: ExtensionOverridesOptions, @@ -1064,26 +937,75 @@ export class ExtensionKind< TOutput extends AnyExtensionDataMap, TConfig, >( - options: CreateExtensionKindOptions<TOptions, TInputs, TOutput, TConfig>, + options: ExtensionKindOptions<TOptions, TInputs, TOutput, TConfig>, ): ExtensionKind<TOptions, TInputs, TOutput, TConfig>; // (undocumented) - new( - instanceProperties: CreateExtensionKindInstanceOptions< - TOptions, - TInputs, - TOutput, - TConfig - >, - ): ExtensionDefinition<TConfig> & { - override: ( - overrides: CreateExtensionOverrideKindInstanceOptions< - TOptions, - TInputs, - TOutput, - TConfig - >, - ) => ExtensionDefinition<TConfig>; + new(args: { + namespace?: string; + name?: string; + attachTo?: { + id: string; + input: string; + }; + disabled?: boolean; + inputs?: TInputs; + output?: TOutput; + configSchema?: PortableSchema<TConfig>; + options: TOptions; + factory?( + context: { + node: AppNode; + config: TConfig; + inputs: Expand<ResolvedExtensionInputs<TInputs>>; + orignalFactory( + context?: { + node?: AppNode; + config?: TConfig; + inputs?: Expand<ResolvedExtensionInputs<TInputs>>; + }, + options?: TOptions, + ): Expand<ExtensionDataValues<TOutput>>; + }, + options: TOptions, + ): Expand<ExtensionDataValues<TOutput>>; + }): ExtensionDefinition<TConfig>; +} + +// @public (undocumented) +export interface ExtensionKindOptions< + TOptions, + TInputs extends AnyExtensionInputMap, + TOutput extends AnyExtensionDataMap, + TConfig, +> { + // (undocumented) + attachTo: { + id: string; + input: string; }; + // (undocumented) + configSchema?: PortableSchema<TConfig>; + // (undocumented) + disabled?: boolean; + // (undocumented) + factory( + context: { + node: AppNode; + config: TConfig; + inputs: Expand<ResolvedExtensionInputs<TInputs>>; + }, + options: TOptions, + ): Expand<ExtensionDataValues<TOutput>>; + // (undocumented) + inputs?: TInputs; + // (undocumented) + kind: string; + // (undocumented) + name?: string; + // (undocumented) + namespace?: string; + // (undocumented) + output: TOutput; } // @public (undocumented) diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index be76fbc069..28dc6a4e29 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -91,7 +91,7 @@ export interface CreateExtensionOptions< inputs?: TInputs; output: TOutput; configSchema?: PortableSchema<TConfig>; - factory(options: { + factory(context: { node: AppNode; config: TConfig; inputs: Expand<ResolvedExtensionInputs<TInputs>>; @@ -115,7 +115,7 @@ export interface InternalExtensionDefinition<TConfig> readonly version: 'v1'; readonly inputs: AnyExtensionInputMap; readonly output: AnyExtensionDataMap; - factory(options: { + factory(context: { node: AppNode; config: TConfig; inputs: ResolvedExtensionInputs<any>; diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx b/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx index 30c3e6ca44..3bdcd3a7cc 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx +++ b/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx @@ -64,7 +64,6 @@ describe('createExtensionKind', () => { }, factory: expect.any(Function), toString: expect.any(Function), - override: expect.any(Function), version: 'v1', }); @@ -103,167 +102,4 @@ describe('createExtensionKind', () => { const { container } = createExtensionTester(extension).render(); expect(container.querySelector('h2')).toHaveTextContent('Hello, world!'); }); - - it('should allow calling of the default value from override', () => { - const TestExtension = createExtensionKind({ - kind: 'test-extension', - attachTo: { id: 'test', input: 'default' }, - output: { - element: coreExtensionData.reactElement, - }, - factory(_, options: { text: string }) { - return { - element: <h1>{options.text}</h1>, - }; - }, - }); - - const extension = TestExtension.new({ - name: 'my-extension', - options: { - text: 'Hello, world!', - }, - factory({ originalFactory }, options: { text: string }) { - const { element } = originalFactory(); - return { - element: ( - <h2> - {options.text} - {element} - </h2> - ), - }; - }, - }); - - expect(extension).toBeDefined(); - - const { container } = createExtensionTester(extension).render(); - - expect(container.querySelector('h2 h1')).toHaveTextContent('Hello, world!'); - }); - - it('should allow overriding options of the default value from override', () => { - const TestExtension = createExtensionKind({ - kind: 'test-extension', - attachTo: { id: 'test', input: 'default' }, - output: { - element: coreExtensionData.reactElement, - }, - factory(_, options: { text: string }) { - return { - element: <h1>{options.text}</h1>, - }; - }, - }); - - const extension = TestExtension.new({ - name: 'my-extension', - options: { - text: 'Hello, world!', - }, - factory({ originalFactory }, options: { text: string }) { - const { element } = originalFactory(undefined, { text: 'nothing!' }); - return { - element: ( - <h2> - {options.text} - {element} - </h2> - ), - }; - }, - }); - - expect(extension).toBeDefined(); - - const { container } = createExtensionTester(extension).render(); - - expect(container.querySelector('h2 h1')).toHaveTextContent('nothing!'); - }); - - describe('override', () => { - it('should allow overriding of the default factory', () => { - const TestExtension = createExtensionKind({ - kind: 'test-extension', - attachTo: { id: 'test', input: 'default' }, - output: { - element: coreExtensionData.reactElement, - }, - factory(_, options: { text: string }) { - return { - element: <h1>{options.text}</h1>, - }; - }, - }); - - const extension = TestExtension.new({ - name: 'my-extension', - options: { - text: 'Hello, world!', - }, - factory(_, options: { text: string }) { - return { - element: <h2>{options.text}</h2>, - }; - }, - }); - - const overridden = extension.override({ - factory({ originalFactory }, { text }) { - return { - element: ( - <div> - {originalFactory().element} - <h3>{text}</h3> - </div> - ), - }; - }, - }); - - const { container } = createExtensionTester(overridden).render(); - expect(container.querySelector('h2')).toHaveTextContent('Hello, world!'); - expect(container.querySelector('h3')).toHaveTextContent('Hello, world!'); - }); - }); - - it('should allow calling the kind factory if another factory is not defined in the instance', () => { - const TestExtension = createExtensionKind({ - kind: 'test-extension', - attachTo: { id: 'test', input: 'default' }, - output: { - element: coreExtensionData.reactElement, - }, - factory(_, options: { text: string }) { - return { - element: <h1>{options.text}</h1>, - }; - }, - }); - - const extension = TestExtension.new({ - name: 'my-extension', - options: { - text: 'Hello, world!', - }, - }); - - const overridden = extension.override({ - factory({ originalFactory }, { text }) { - return { - element: ( - <div> - {originalFactory().element} - <h3>{text}</h3> - </div> - ), - }; - }, - }); - - const { container } = createExtensionTester(overridden).render(); - expect(container.querySelector('h1')).toHaveTextContent('Hello, world!'); - expect(container.querySelector('h3')).toHaveTextContent('Hello, world!'); - }); }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts b/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts index 9813c9e50c..52bf711822 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts @@ -21,7 +21,6 @@ import { AnyExtensionDataMap, AnyExtensionInputMap, ExtensionDataValues, - ExtensionDefinition, ResolvedExtensionInputs, createExtension, } from './createExtension'; @@ -53,76 +52,6 @@ export interface CreateExtensionKindOptions< ): Expand<ExtensionDataValues<TOutput>>; } -/** - * @public - */ -export interface CreateExtensionKindInstanceOptions< - TOptions, - TInputs extends AnyExtensionInputMap, - TOutput extends AnyExtensionDataMap, - TConfig, -> { - namespace?: string; - name?: string; - attachTo?: { id: string; input: string }; - disabled?: boolean; - inputs?: TInputs; - output?: TOutput; - configSchema?: PortableSchema<TConfig>; - options: TOptions; - factory?( - context: { - node: AppNode; - config: TConfig; - inputs: Expand<ResolvedExtensionInputs<TInputs>>; - originalFactory( - context?: { - node?: AppNode; - config?: TConfig; - inputs?: Expand<ResolvedExtensionInputs<TInputs>>; - }, - options?: TOptions, - ): Expand<ExtensionDataValues<TOutput>>; - }, - options: TOptions, - ): Expand<ExtensionDataValues<TOutput>>; -} - -/** - * @public - */ -export interface CreateExtensionOverrideKindInstanceOptions< - TOptions, - TInputs extends AnyExtensionInputMap, - TOutput extends AnyExtensionDataMap, - TConfig, -> { - namespace?: string; - name?: string; - attachTo?: { id: string; input: string }; - disabled?: boolean; - inputs?: TInputs; - output?: TOutput; - configSchema?: PortableSchema<TConfig>; - options?: TOptions; - factory?( - context: { - node: AppNode; - config: TConfig; - inputs: Expand<ResolvedExtensionInputs<TInputs>>; - originalFactory( - context?: { - node?: AppNode; - config?: TConfig; - inputs?: Expand<ResolvedExtensionInputs<TInputs>>; - }, - options?: TOptions, - ): Expand<ExtensionDataValues<TOutput>>; - }, - options: TOptions, - ): Expand<ExtensionDataValues<TOutput>>; -} - /** * TODO: should we export an interface instead of a concrete class? * @public @@ -145,7 +74,7 @@ export class ExtensionKind< } private constructor( - private readonly kindProperties: CreateExtensionKindOptions< + private readonly options: CreateExtensionKindOptions< TOptions, TInputs, TOutput, @@ -153,41 +82,49 @@ export class ExtensionKind< >, ) {} - public new( - instanceProperties: CreateExtensionKindInstanceOptions< - TOptions, - TInputs, - TOutput, - TConfig - >, - ): ExtensionDefinition<TConfig> & { - override: ( - overrides: CreateExtensionOverrideKindInstanceOptions< - TOptions, - TInputs, - TOutput, - TConfig - >, - ) => ExtensionDefinition<TConfig>; - } { - const extension = createExtension({ - kind: this.kindProperties.kind, - namespace: instanceProperties.namespace ?? this.kindProperties.namespace, - name: instanceProperties.name ?? this.kindProperties.name, - attachTo: instanceProperties.attachTo ?? this.kindProperties.attachTo, - disabled: instanceProperties.disabled ?? this.kindProperties.disabled, - inputs: instanceProperties.inputs ?? this.kindProperties.inputs, - output: instanceProperties.output ?? this.kindProperties.output, - configSchema: - instanceProperties.configSchema ?? this.kindProperties.configSchema, // TODO: some config merging or smth + public new(args: { + namespace?: string; + name?: string; + attachTo?: { id: string; input: string }; + disabled?: boolean; + inputs?: TInputs; + output?: TOutput; + configSchema?: PortableSchema<TConfig>; + options: TOptions; + factory?( + context: { + node: AppNode; + config: TConfig; + inputs: Expand<ResolvedExtensionInputs<TInputs>>; + orignalFactory( + context?: { + node?: AppNode; + config?: TConfig; + inputs?: Expand<ResolvedExtensionInputs<TInputs>>; + }, + options?: TOptions, + ): Expand<ExtensionDataValues<TOutput>>; + }, + options: TOptions, + ): Expand<ExtensionDataValues<TOutput>>; + }) { + return createExtension({ + kind: this.options.kind, + namespace: args.namespace ?? this.options.namespace, + name: args.name ?? this.options.name, + attachTo: args.attachTo ?? this.options.attachTo, + disabled: args.disabled ?? this.options.disabled, + inputs: args.inputs ?? this.options.inputs, + output: args.output ?? this.options.output, + configSchema: args.configSchema ?? this.options.configSchema, // TODO: some config merging or smth factory: ({ node, config, inputs }) => { - if (instanceProperties.factory) { - return instanceProperties.factory( + if (args.factory) { + return args.factory( { node, config, inputs, - originalFactory: ( + orignalFactory: ( innerContext?: { node?: AppNode; config?: TConfig; @@ -195,123 +132,29 @@ export class ExtensionKind< }, innerOptions?: TOptions, ) => - this.kindProperties.factory( + this.options.factory( { node: innerContext?.node ?? node, config: innerContext?.config ?? config, inputs: innerContext?.inputs ?? inputs, }, - innerOptions ?? instanceProperties.options, + innerOptions ?? args.options, ), }, - instanceProperties.options, + args.options, ); } - return this.kindProperties.factory( + return this.options.factory( { node, config, inputs, }, - instanceProperties.options, + args.options, ); }, }); - - return { - ...extension, - override: overrides => { - return createExtension({ - kind: this.kindProperties.kind, - namespace: - overrides.namespace ?? - instanceProperties.namespace ?? - this.kindProperties.namespace, - name: - overrides.name ?? - instanceProperties.name ?? - this.kindProperties.name, - attachTo: - overrides.attachTo ?? - instanceProperties.attachTo ?? - this.kindProperties.attachTo, - disabled: - overrides.disabled ?? - instanceProperties.disabled ?? - this.kindProperties.disabled, - inputs: - overrides.inputs ?? - instanceProperties.inputs ?? - this.kindProperties.inputs, - output: - overrides.output ?? - instanceProperties.output ?? - this.kindProperties.output, - configSchema: - overrides.configSchema ?? - instanceProperties.configSchema ?? - this.kindProperties.configSchema, // TODO: some config merging or smth - factory: ({ node, config, inputs }) => { - if (overrides.factory) { - return overrides.factory( - { - node, - config, - inputs, - originalFactory: ( - innerContext?: { - node?: AppNode; - config?: TConfig; - inputs?: Expand<ResolvedExtensionInputs<TInputs>>; - }, - innerOptions?: TOptions, - ) => - instanceProperties.factory?.( - { - node: innerContext?.node ?? node, - config: innerContext?.config ?? config, - inputs: innerContext?.inputs ?? inputs, - originalFactory: this.kindProperties.factory, - }, - innerOptions ?? instanceProperties.options, - ) ?? - this.kindProperties.factory( - { - node, - config, - inputs, - }, - innerOptions ?? instanceProperties.options, - ), - }, - instanceProperties.options, - ); - } - - return ( - instanceProperties.factory?.( - { - node, - config, - inputs, - originalFactory: this.kindProperties.factory, - }, - instanceProperties.options, - ) ?? - this.kindProperties.factory( - { - node, - config, - inputs, - }, - instanceProperties.options, - ) - ); - }, - }); - }, - }; } } diff --git a/packages/frontend-plugin-api/src/wiring/index.ts b/packages/frontend-plugin-api/src/wiring/index.ts index a312c0f06f..8fe9dc3a54 100644 --- a/packages/frontend-plugin-api/src/wiring/index.ts +++ b/packages/frontend-plugin-api/src/wiring/index.ts @@ -49,9 +49,7 @@ export { type FrontendFeature, } from './types'; export { - type CreateExtensionKindOptions, - type CreateExtensionKindInstanceOptions, - type CreateExtensionOverrideKindInstanceOptions, + type CreateExtensionKindOptions as ExtensionKindOptions, ExtensionKind, createExtensionKind, } from './createExtensionKind'; From b20c067c61abcfff3f158b7f4b6c5857dfbf347a Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Thu, 18 Jul 2024 13:27:09 +0200 Subject: [PATCH 323/510] chore: fixing some code review comments Signed-off-by: blam <ben@blam.sh> --- .changeset/dry-squids-tap.md | 8 +- .../src/wiring/createExtensionKind.ts | 108 +++++++++++------- 2 files changed, 70 insertions(+), 46 deletions(-) diff --git a/.changeset/dry-squids-tap.md b/.changeset/dry-squids-tap.md index 9bd835d371..5a865395c0 100644 --- a/.changeset/dry-squids-tap.md +++ b/.changeset/dry-squids-tap.md @@ -14,17 +14,17 @@ const TestExtensionKind = createExtensionKind({ output: { element: coreExtensionData.reactElement, }, - factory(_, options: { text: string }) { + factory(_, params: { text: string }) { return { - element: <h1>{options.text}</h1>, + element: <h1>{params.text}</h1>, }; }, }); // create an instance of the extension kind with props -const testExtension = TestExtensionKind.new({ +const testExtension = TestExtensionKind.create({ name: 'foo', - options: { + params: { text: 'Hello World', }, }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts b/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts index 52bf711822..1212365712 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts @@ -21,6 +21,7 @@ import { AnyExtensionDataMap, AnyExtensionInputMap, ExtensionDataValues, + ExtensionDefinition, ResolvedExtensionInputs, createExtension, } from './createExtension'; @@ -29,14 +30,13 @@ import { * @public */ export interface CreateExtensionKindOptions< - TOptions, + TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfig, > { kind: string; namespace?: string; - name?: string; attachTo: { id: string; input: string }; disabled?: boolean; inputs?: TInputs; @@ -48,41 +48,20 @@ export interface CreateExtensionKindOptions< config: TConfig; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, - options: TOptions, + params: TParams, ): Expand<ExtensionDataValues<TOutput>>; } /** - * TODO: should we export an interface instead of a concrete class? * @public */ -export class ExtensionKind< - TOptions, +export interface ExtensionKind< + TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfig, > { - static create< - TOptions, - TInputs extends AnyExtensionInputMap, - TOutput extends AnyExtensionDataMap, - TConfig, - >( - options: CreateExtensionKindOptions<TOptions, TInputs, TOutput, TConfig>, - ): ExtensionKind<TOptions, TInputs, TOutput, TConfig> { - return new ExtensionKind(options); - } - - private constructor( - private readonly options: CreateExtensionKindOptions< - TOptions, - TInputs, - TOutput, - TConfig - >, - ) {} - - public new(args: { + create(args: { namespace?: string; name?: string; attachTo?: { id: string; input: string }; @@ -90,7 +69,7 @@ export class ExtensionKind< inputs?: TInputs; output?: TOutput; configSchema?: PortableSchema<TConfig>; - options: TOptions; + params: TParams; factory?( context: { node: AppNode; @@ -98,20 +77,64 @@ export class ExtensionKind< inputs: Expand<ResolvedExtensionInputs<TInputs>>; orignalFactory( context?: { - node?: AppNode; config?: TConfig; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, - options?: TOptions, + params?: TParams, ): Expand<ExtensionDataValues<TOutput>>; }, - options: TOptions, + params: TParams, ): Expand<ExtensionDataValues<TOutput>>; - }) { + }): ExtensionDefinition<TConfig>; +} + +/** + * @internal + */ +class ExtensionKindImpl< + TParams, + TInputs extends AnyExtensionInputMap, + TOutput extends AnyExtensionDataMap, + TConfig, +> { + constructor( + private readonly options: CreateExtensionKindOptions< + TParams, + TInputs, + TOutput, + TConfig + >, + ) {} + + public create(args: { + namespace?: string; + name?: string; + attachTo?: { id: string; input: string }; + disabled?: boolean; + inputs?: TInputs; + output?: TOutput; + configSchema?: PortableSchema<TConfig>; + params: TParams; + factory?( + context: { + node: AppNode; + config: TConfig; + inputs: Expand<ResolvedExtensionInputs<TInputs>>; + orignalFactory( + context?: { + config?: TConfig; + inputs?: Expand<ResolvedExtensionInputs<TInputs>>; + }, + params?: TParams, + ): Expand<ExtensionDataValues<TOutput>>; + }, + params: TParams, + ): Expand<ExtensionDataValues<TOutput>>; + }): ExtensionDefinition<TConfig> { return createExtension({ kind: this.options.kind, namespace: args.namespace ?? this.options.namespace, - name: args.name ?? this.options.name, + name: args.name, attachTo: args.attachTo ?? this.options.attachTo, disabled: args.disabled ?? this.options.disabled, inputs: args.inputs ?? this.options.inputs, @@ -126,22 +149,21 @@ export class ExtensionKind< inputs, orignalFactory: ( innerContext?: { - node?: AppNode; config?: TConfig; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, - innerOptions?: TOptions, + innerParams?: TParams, ) => this.options.factory( { - node: innerContext?.node ?? node, + node, config: innerContext?.config ?? config, inputs: innerContext?.inputs ?? inputs, }, - innerOptions ?? args.options, + innerParams ?? args.params, ), }, - args.options, + args.params, ); } @@ -151,7 +173,7 @@ export class ExtensionKind< config, inputs, }, - args.options, + args.params, ); }, }); @@ -165,10 +187,12 @@ export class ExtensionKind< * @public */ export function createExtensionKind< - TOptions, + TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfig, ->(options: CreateExtensionKindOptions<TOptions, TInputs, TOutput, TConfig>) { - return ExtensionKind.create(options); +>( + options: CreateExtensionKindOptions<TParams, TInputs, TOutput, TConfig>, +): ExtensionKind<TParams, TInputs, TOutput, TConfig> { + return new ExtensionKindImpl(options); } From 4e42e5112cd692ab40696b3970e016cba94b4456 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Thu, 18 Jul 2024 13:50:26 +0200 Subject: [PATCH 324/510] chore: smaller renames and code review Signed-off-by: blam <ben@blam.sh> --- .changeset/dry-squids-tap.md | 6 ++-- .../architecture/08-naming-patterns.md | 20 ++++++------- ....tsx => createExtensionBlueprint.test.tsx} | 30 +++++++++---------- ...ionKind.ts => createExtensionBlueprint.ts} | 22 +++++++------- .../frontend-plugin-api/src/wiring/index.ts | 8 ++--- 5 files changed, 43 insertions(+), 43 deletions(-) rename packages/frontend-plugin-api/src/wiring/{createExtensionKind.test.tsx => createExtensionBlueprint.test.tsx} (77%) rename packages/frontend-plugin-api/src/wiring/{createExtensionKind.ts => createExtensionBlueprint.ts} (90%) diff --git a/.changeset/dry-squids-tap.md b/.changeset/dry-squids-tap.md index 5a865395c0..879ecb5d14 100644 --- a/.changeset/dry-squids-tap.md +++ b/.changeset/dry-squids-tap.md @@ -8,8 +8,8 @@ This allows the creation of extension with the following pattern: ```tsx // create the extension kind -const TestExtensionKind = createExtensionKind({ - kind: 'test-extension', +const EntityCardBlueprint = createExtensionBlueprint({ + kind: 'entity-card', attachTo: { id: 'test', input: 'default' }, output: { element: coreExtensionData.reactElement, @@ -22,7 +22,7 @@ const TestExtensionKind = createExtensionKind({ }); // create an instance of the extension kind with props -const testExtension = TestExtensionKind.create({ +const testExtension = EntityCardBlueprint.make({ name: 'foo', params: { text: 'Hello World', diff --git a/docs/frontend-system/architecture/08-naming-patterns.md b/docs/frontend-system/architecture/08-naming-patterns.md index 0916d9fd51..a17525f3ce 100644 --- a/docs/frontend-system/architecture/08-naming-patterns.md +++ b/docs/frontend-system/architecture/08-naming-patterns.md @@ -38,33 +38,31 @@ Note that while we use this naming pattern for the plugin instance this is only | Description | Pattern | Examples | | ----------- | ------------------------------- | ------------------------------------------------------------------- | -| Creator | `create<Kind>Extension` | `createPageExtension`, `createEntityCardExtension` | +| Blueprint | `<Kind>Blueprint` | `PageBlueprint`, `EntityCardBlueprint` | | ID | `[<kind>:]<namespace>[/<name>]` | `'core.nav'`, `'page:user-settings'`, `'entity-card:catalog/about'` | | Symbol | `<namespace>[<Name>][<Kind>]` | `coreNav`, `userSettingsPage`, `catalogAboutEntityCard` | -When you create a new extension you never provide the ID directly. Instead, you indirectly or directly provide the kind, namespace, and name parts that make up the ID. The kind is always provided by the extension creator function 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. +When you create a new extension you never provide the ID directly. Instead, you indirectly or directly provide the kind, namespace, and name parts that make up the ID. The kind is always provided by the blueprint creator, 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 - }); -} +// This is an extension blueprint that is used to create an extension of the 'page' kind. +export const PageBlueprint = createExtensionBlueprint({ + kind: 'page', + // ... +}); // 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({ +const catalogEntityPage = PageBlueprint.make({ 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({ +const catalogSearchResultListItem = SearchResultListItemBlueprint.make({ // ... }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx similarity index 77% rename from packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx rename to packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx index 3bdcd3a7cc..b3e926e57c 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionKind.test.tsx +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx @@ -16,27 +16,27 @@ import React from 'react'; import { coreExtensionData } from './coreExtensionData'; -import { createExtensionKind } from './createExtensionKind'; +import { createExtensionBlueprint } from './createExtensionBlueprint'; import { createExtensionTester } from '@backstage/frontend-test-utils'; -describe('createExtensionKind', () => { - it('should allow creation of extension kinds', () => { - const TestExtension = createExtensionKind({ +describe('createExtensionBlueprint', () => { + it('should allow creation of extension blueprints', () => { + const TestExtensionBlueprint = createExtensionBlueprint({ kind: 'test-extension', attachTo: { id: 'test', input: 'default' }, output: { element: coreExtensionData.reactElement, }, - factory(_, options: { text: string }) { + factory(_, params: { text: string }) { return { - element: <h1>{options.text}</h1>, + element: <h1>{params.text}</h1>, }; }, }); - const extension = TestExtension.new({ + const extension = TestExtensionBlueprint.make({ name: 'my-extension', - options: { + params: { text: 'Hello, world!', }, }); @@ -72,27 +72,27 @@ describe('createExtensionKind', () => { }); it('should allow overriding of the default factory', () => { - const TestExtension = createExtensionKind({ + const TestExtensionBlueprint = createExtensionBlueprint({ kind: 'test-extension', attachTo: { id: 'test', input: 'default' }, output: { element: coreExtensionData.reactElement, }, - factory(_, options: { text: string }) { + factory(_, params: { text: string }) { return { - element: <h1>{options.text}</h1>, + element: <h1>{params.text}</h1>, }; }, }); - const extension = TestExtension.new({ + const extension = TestExtensionBlueprint.make({ name: 'my-extension', - options: { + params: { text: 'Hello, world!', }, - factory(_, options: { text: string }) { + factory(_, params: { text: string }) { return { - element: <h2>{options.text}</h2>, + element: <h2>{params.text}</h2>, }; }, }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts similarity index 90% rename from packages/frontend-plugin-api/src/wiring/createExtensionKind.ts rename to packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts index 1212365712..74d2eeadf1 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionKind.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts @@ -29,7 +29,7 @@ import { /** * @public */ -export interface CreateExtensionKindOptions< +export interface CreateExtensionBlueprintOptions< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, @@ -55,13 +55,13 @@ export interface CreateExtensionKindOptions< /** * @public */ -export interface ExtensionKind< +export interface ExtensionBlueprint< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfig, > { - create(args: { + make(args: { namespace?: string; name?: string; attachTo?: { id: string; input: string }; @@ -77,6 +77,7 @@ export interface ExtensionKind< inputs: Expand<ResolvedExtensionInputs<TInputs>>; orignalFactory( context?: { + node?: AppNode; config?: TConfig; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, @@ -91,14 +92,14 @@ export interface ExtensionKind< /** * @internal */ -class ExtensionKindImpl< +class ExtensionBlueprintImpl< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfig, > { constructor( - private readonly options: CreateExtensionKindOptions< + private readonly options: CreateExtensionBlueprintOptions< TParams, TInputs, TOutput, @@ -106,7 +107,7 @@ class ExtensionKindImpl< >, ) {} - public create(args: { + public make(args: { namespace?: string; name?: string; attachTo?: { id: string; input: string }; @@ -122,6 +123,7 @@ class ExtensionKindImpl< inputs: Expand<ResolvedExtensionInputs<TInputs>>; orignalFactory( context?: { + node?: AppNode; config?: TConfig; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, @@ -186,13 +188,13 @@ class ExtensionKindImpl< * * @public */ -export function createExtensionKind< +export function createExtensionBlueprint< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfig, >( - options: CreateExtensionKindOptions<TParams, TInputs, TOutput, TConfig>, -): ExtensionKind<TParams, TInputs, TOutput, TConfig> { - return new ExtensionKindImpl(options); + options: CreateExtensionBlueprintOptions<TParams, TInputs, TOutput, TConfig>, +): ExtensionBlueprint<TParams, TInputs, TOutput, TConfig> { + return new ExtensionBlueprintImpl(options); } diff --git a/packages/frontend-plugin-api/src/wiring/index.ts b/packages/frontend-plugin-api/src/wiring/index.ts index 8fe9dc3a54..6d20368225 100644 --- a/packages/frontend-plugin-api/src/wiring/index.ts +++ b/packages/frontend-plugin-api/src/wiring/index.ts @@ -49,7 +49,7 @@ export { type FrontendFeature, } from './types'; export { - type CreateExtensionKindOptions as ExtensionKindOptions, - ExtensionKind, - createExtensionKind, -} from './createExtensionKind'; + type CreateExtensionBlueprintOptions, + type ExtensionBlueprint, + createExtensionBlueprint, +} from './createExtensionBlueprint'; From 9b89b82f66b500dabc5493a51d2fd1144e4828a4 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Thu, 18 Jul 2024 12:08:15 +0200 Subject: [PATCH 325/510] frontend-plugin-api: infer ExtensionBoundary routable prop from outputs Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/early-trees-dance.md | 5 ++ .changeset/mighty-dolls-retire.md | 5 ++ .../architecture/03-extensions.md | 4 +- packages/frontend-plugin-api/api-report.md | 1 - .../src/components/ExtensionBoundary.test.tsx | 72 ++++++++++++++++--- .../src/components/ExtensionBoundary.tsx | 14 +++- .../src/extensions/createPageExtension.tsx | 2 +- plugins/catalog-react/src/alpha.tsx | 2 +- 8 files changed, 91 insertions(+), 14 deletions(-) create mode 100644 .changeset/early-trees-dance.md create mode 100644 .changeset/mighty-dolls-retire.md diff --git a/.changeset/early-trees-dance.md b/.changeset/early-trees-dance.md new file mode 100644 index 0000000000..5422bd2872 --- /dev/null +++ b/.changeset/early-trees-dance.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-plugin-api': patch +--- + +The `ExtensionBoundary` now by default infers whether its routable from whether it outputs a route path. diff --git a/.changeset/mighty-dolls-retire.md b/.changeset/mighty-dolls-retire.md new file mode 100644 index 0000000000..b31c443a38 --- /dev/null +++ b/.changeset/mighty-dolls-retire.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Internal refactor to remove unnecessary `routable` prop in the implementation of the `createEntityContentExtension` alpha export. diff --git a/docs/frontend-system/architecture/03-extensions.md b/docs/frontend-system/architecture/03-extensions.md index 19345e0b26..cdc73a17ec 100644 --- a/docs/frontend-system/architecture/03-extensions.md +++ b/docs/frontend-system/architecture/03-extensions.md @@ -337,7 +337,7 @@ Similar to plugins the `ErrorBoundary` for extension allows to pass in a fallbac ### Analytics -Analytics information are provided through the `AnalyticsContext`, which will give `extensionId` & `pluginId` as context to analytics event fired inside of the extension. Additionally `RouteTracker` will capture an analytics event for routable extension to inform which extension metadata gets associated with a navigation event when the route navigated to is a gathered `mountPoint`. +Analytics information are provided through the `AnalyticsContext`, which will give `extensionId` & `pluginId` as context to analytics event fired inside of the extension. Additionally `RouteTracker` will capture an analytics event for routable extension to inform which extension metadata gets associated with a navigation event when the route navigated to is a gathered `mountPoint`. Whether an extension is routable is inferred from its outputs, but you can also explicitly control this behavior by passing the `routable` prop to `ExtensionBoundary`. The `ExtensionBoundary` can be used like the following in an extension creator: @@ -359,7 +359,7 @@ export function createSomeExtension< path: config.path, routeRef: options.routeRef, element: ( - <ExtensionBoundary node={node} routable> + <ExtensionBoundary node={node}> <ExtensionComponent /> </ExtensionBoundary> ), diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index 3e19573d95..d50ef0dd03 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -844,7 +844,6 @@ export interface ExtensionBoundaryProps { children: ReactNode; // (undocumented) node: AppNode; - // (undocumented) routable?: boolean; } diff --git a/packages/frontend-plugin-api/src/components/ExtensionBoundary.test.tsx b/packages/frontend-plugin-api/src/components/ExtensionBoundary.test.tsx index 66fb3901fc..1f12f127e8 100644 --- a/packages/frontend-plugin-api/src/components/ExtensionBoundary.test.tsx +++ b/packages/frontend-plugin-api/src/components/ExtensionBoundary.test.tsx @@ -15,15 +15,24 @@ */ import React, { useEffect } from 'react'; -import { screen, waitFor } from '@testing-library/react'; -import { MockAnalyticsApi, TestApiProvider } from '@backstage/test-utils'; +import { act, screen, waitFor } from '@testing-library/react'; +import { + MockAnalyticsApi, + TestApiProvider, + withLogCollector, +} from '@backstage/test-utils'; import { ExtensionBoundary } from './ExtensionBoundary'; import { coreExtensionData, createExtension } from '../wiring'; -import { analyticsApiRef, useAnalytics } from '@backstage/core-plugin-api'; +import { + analyticsApiRef, + createApiFactory, + useAnalytics, +} from '@backstage/core-plugin-api'; import { createRouteRef } from '../routing'; import { createExtensionTester } from '@backstage/frontend-test-utils'; +import { createApiExtension } from '../extensions'; -const wrapInBoundaryExtension = (element: JSX.Element) => { +const wrapInBoundaryExtension = (element?: JSX.Element) => { const routeRef = createRouteRef(); return createExtension({ name: 'test', @@ -54,12 +63,25 @@ describe('ExtensionBoundary', () => { }); it('should show app error component when an error is thrown', async () => { - const error = 'Something went wrong'; + const errorMsg = 'Something went wrong'; const ErrorComponent = () => { - throw new Error(error); + throw new Error(errorMsg); }; - createExtensionTester(wrapInBoundaryExtension(<ErrorComponent />)).render(); - await waitFor(() => expect(screen.getByText(error)).toBeInTheDocument()); + const { error } = await withLogCollector(['error'], async () => { + createExtensionTester( + wrapInBoundaryExtension(<ErrorComponent />), + ).render(); + await waitFor(() => + expect(screen.getByText(errorMsg)).toBeInTheDocument(), + ); + }); + expect(error).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + message: expect.stringContaining(errorMsg), + }), + ]), + ); }); it('should wrap children with analytics context', async () => { @@ -97,4 +119,38 @@ describe('ExtensionBoundary', () => { }); }); }); + + // TODO(Rugvip): It's annoying to test the inverse of this currently, because the extension tester overrides the subject to always output a path + it('should emit analytics events if routable', async () => { + const Emitter = () => { + const analytics = useAnalytics(); + useEffect(() => { + analytics.captureEvent('dummy', 'dummy'); + }); + return null; + }; + const analyticsApiMock = new MockAnalyticsApi(); + + await act(async () => { + createExtensionTester(wrapInBoundaryExtension(<Emitter />)) + .add( + createApiExtension({ + factory: createApiFactory(analyticsApiRef, analyticsApiMock), + }), + ) + .render(); + }); + + expect(analyticsApiMock.getEvents()).toEqual([ + expect.objectContaining({ + action: 'navigate', + subject: '/', + context: expect.objectContaining({ + pluginId: 'root', + extensionId: 'test', + }), + }), + expect.objectContaining({ action: 'dummy' }), + ]); + }); }); diff --git a/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx b/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx index 768352b76e..b6269484b0 100644 --- a/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx +++ b/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx @@ -26,6 +26,7 @@ import { ErrorBoundary } from './ErrorBoundary'; import { routableExtensionRenderedEvent } from '../../../core-plugin-api/src/analytics/Tracker'; import { AppNode, useComponentRef } from '../apis'; import { coreComponentRefs } from './coreComponentRefs'; +import { coreExtensionData } from '../wiring'; type RouteTrackerProps = PropsWithChildren<{ disableTracking?: boolean; @@ -50,6 +51,11 @@ const RouteTracker = (props: RouteTrackerProps) => { /** @public */ export interface ExtensionBoundaryProps { node: AppNode; + /** + * This explicitly marks the extension as routable for the purpose of + * capturing analytics events. If not provided, the extension boundary will be + * marked as routable if it outputs a routePath. + */ routable?: boolean; children: ReactNode; } @@ -58,6 +64,10 @@ export interface ExtensionBoundaryProps { export function ExtensionBoundary(props: ExtensionBoundaryProps) { const { node, routable, children } = props; + const doesOutputRoutePath = Boolean( + node.instance?.getData(coreExtensionData.routePath), + ); + const plugin = node.spec.source; const Progress = useComponentRef(coreComponentRefs.progress); const fallback = useComponentRef(coreComponentRefs.errorBoundaryFallback); @@ -72,7 +82,9 @@ export function ExtensionBoundary(props: ExtensionBoundaryProps) { <Suspense fallback={<Progress />}> <ErrorBoundary plugin={plugin} Fallback={fallback}> <AnalyticsContext attributes={attributes}> - <RouteTracker disableTracking={!routable}>{children}</RouteTracker> + <RouteTracker disableTracking={!(routable ?? doesOutputRoutePath)}> + {children} + </RouteTracker> </AnalyticsContext> </ErrorBoundary> </Suspense> diff --git a/packages/frontend-plugin-api/src/extensions/createPageExtension.tsx b/packages/frontend-plugin-api/src/extensions/createPageExtension.tsx index dfe549f32b..cd434a3ffc 100644 --- a/packages/frontend-plugin-api/src/extensions/createPageExtension.tsx +++ b/packages/frontend-plugin-api/src/extensions/createPageExtension.tsx @@ -87,7 +87,7 @@ export function createPageExtension< path: config.path, routeRef: options.routeRef, element: ( - <ExtensionBoundary node={node} routable> + <ExtensionBoundary node={node}> <ExtensionComponent /> </ExtensionBoundary> ), diff --git a/plugins/catalog-react/src/alpha.tsx b/plugins/catalog-react/src/alpha.tsx index b1650d1f5b..85712b358a 100644 --- a/plugins/catalog-react/src/alpha.tsx +++ b/plugins/catalog-react/src/alpha.tsx @@ -166,7 +166,7 @@ export function createEntityContentExtension< title: config.title, routeRef: options.routeRef, element: ( - <ExtensionBoundary node={node} routable> + <ExtensionBoundary node={node}> <ExtensionComponent /> </ExtensionBoundary> ), From 5eaaf807fade6caae1a874744140ea469a46dbcc Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Thu, 18 Jul 2024 14:15:03 +0200 Subject: [PATCH 326/510] chore: fixing api-reports and changeset Signed-off-by: blam <ben@blam.sh> --- .changeset/dry-squids-tap.md | 8 +- packages/frontend-plugin-api/api-report.md | 179 ++++++++++----------- 2 files changed, 88 insertions(+), 99 deletions(-) diff --git a/.changeset/dry-squids-tap.md b/.changeset/dry-squids-tap.md index 879ecb5d14..d0a737f4af 100644 --- a/.changeset/dry-squids-tap.md +++ b/.changeset/dry-squids-tap.md @@ -2,12 +2,12 @@ '@backstage/frontend-plugin-api': patch --- -Introduce a new way to create extension types and kinds, with `createExtensionKind`. +Introduce a new way to encapsulate extension kinds that replaces the extension creator pattern with `createExtensionBlueprint` -This allows the creation of extension with the following pattern: +This allows the creation of extension instances with the following pattern: ```tsx -// create the extension kind +// create the extension blueprint which is used to create instances const EntityCardBlueprint = createExtensionBlueprint({ kind: 'entity-card', attachTo: { id: 'test', input: 'default' }, @@ -21,7 +21,7 @@ const EntityCardBlueprint = createExtensionBlueprint({ }, }); -// create an instance of the extension kind with props +// create an instance of the extension blueprint with params const testExtension = EntityCardBlueprint.make({ name: 'foo', params: { diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index 48718f5375..858350044c 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -499,6 +499,51 @@ export function createExtension< options: CreateExtensionOptions<TOutput, TInputs, TConfig>, ): ExtensionDefinition<TConfig>; +// @public +export function createExtensionBlueprint< + TParams, + TInputs extends AnyExtensionInputMap, + TOutput extends AnyExtensionDataMap, + TConfig, +>( + options: CreateExtensionBlueprintOptions<TParams, TInputs, TOutput, TConfig>, +): ExtensionBlueprint<TParams, TInputs, TOutput, TConfig>; + +// @public (undocumented) +export interface CreateExtensionBlueprintOptions< + TParams, + TInputs extends AnyExtensionInputMap, + TOutput extends AnyExtensionDataMap, + TConfig, +> { + // (undocumented) + attachTo: { + id: string; + input: string; + }; + // (undocumented) + configSchema?: PortableSchema<TConfig>; + // (undocumented) + disabled?: boolean; + // (undocumented) + factory( + context: { + node: AppNode; + config: TConfig; + inputs: Expand<ResolvedExtensionInputs<TInputs>>; + }, + params: TParams, + ): Expand<ExtensionDataValues<TOutput>>; + // (undocumented) + inputs?: TInputs; + // (undocumented) + kind: string; + // (undocumented) + namespace?: string; + // (undocumented) + output: TOutput; +} + // @public (undocumented) export function createExtensionDataRef<TData>( id: string, @@ -522,16 +567,6 @@ export function createExtensionInput< } >; -// @public -export function createExtensionKind< - TOptions, - TInputs extends AnyExtensionInputMap, - TOutput extends AnyExtensionDataMap, - TConfig, ->( - options: ExtensionKindOptions<TOptions, TInputs, TOutput, TConfig>, -): ExtensionKind<TOptions, TInputs, TOutput, TConfig>; - // @public (undocumented) export interface CreateExtensionOptions< TOutput extends AnyExtensionDataMap, @@ -843,6 +878,45 @@ export interface Extension<TConfig> { readonly id: string; } +// @public (undocumented) +export interface ExtensionBlueprint< + TParams, + TInputs extends AnyExtensionInputMap, + TOutput extends AnyExtensionDataMap, + TConfig, +> { + // (undocumented) + make(args: { + namespace?: string; + name?: string; + attachTo?: { + id: string; + input: string; + }; + disabled?: boolean; + inputs?: TInputs; + output?: TOutput; + configSchema?: PortableSchema<TConfig>; + params: TParams; + factory?( + context: { + node: AppNode; + config: TConfig; + inputs: Expand<ResolvedExtensionInputs<TInputs>>; + orignalFactory( + context?: { + node?: AppNode; + config?: TConfig; + inputs?: Expand<ResolvedExtensionInputs<TInputs>>; + }, + params?: TParams, + ): Expand<ExtensionDataValues<TOutput>>; + }, + params: TParams, + ): Expand<ExtensionDataValues<TOutput>>; + }): ExtensionDefinition<TConfig>; +} + // @public (undocumented) export function ExtensionBoundary( props: ExtensionBoundaryProps, @@ -923,91 +997,6 @@ export interface ExtensionInput< extensionData: TExtensionData; } -// @public -export class ExtensionKind< - TOptions, - TInputs extends AnyExtensionInputMap, - TOutput extends AnyExtensionDataMap, - TConfig, -> { - // (undocumented) - static create< - TOptions, - TInputs extends AnyExtensionInputMap, - TOutput extends AnyExtensionDataMap, - TConfig, - >( - options: ExtensionKindOptions<TOptions, TInputs, TOutput, TConfig>, - ): ExtensionKind<TOptions, TInputs, TOutput, TConfig>; - // (undocumented) - new(args: { - namespace?: string; - name?: string; - attachTo?: { - id: string; - input: string; - }; - disabled?: boolean; - inputs?: TInputs; - output?: TOutput; - configSchema?: PortableSchema<TConfig>; - options: TOptions; - factory?( - context: { - node: AppNode; - config: TConfig; - inputs: Expand<ResolvedExtensionInputs<TInputs>>; - orignalFactory( - context?: { - node?: AppNode; - config?: TConfig; - inputs?: Expand<ResolvedExtensionInputs<TInputs>>; - }, - options?: TOptions, - ): Expand<ExtensionDataValues<TOutput>>; - }, - options: TOptions, - ): Expand<ExtensionDataValues<TOutput>>; - }): ExtensionDefinition<TConfig>; -} - -// @public (undocumented) -export interface ExtensionKindOptions< - TOptions, - TInputs extends AnyExtensionInputMap, - TOutput extends AnyExtensionDataMap, - TConfig, -> { - // (undocumented) - attachTo: { - id: string; - input: string; - }; - // (undocumented) - configSchema?: PortableSchema<TConfig>; - // (undocumented) - disabled?: boolean; - // (undocumented) - factory( - context: { - node: AppNode; - config: TConfig; - inputs: Expand<ResolvedExtensionInputs<TInputs>>; - }, - options: TOptions, - ): Expand<ExtensionDataValues<TOutput>>; - // (undocumented) - inputs?: TInputs; - // (undocumented) - kind: string; - // (undocumented) - name?: string; - // (undocumented) - namespace?: string; - // (undocumented) - output: TOutput; -} - // @public (undocumented) export interface ExtensionOverrides { // (undocumented) From 3f257d25e26c51f21f6d63c3feecec59862eadb8 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Thu, 18 Jul 2024 14:59:02 +0200 Subject: [PATCH 327/510] chore: switch around the params to the factories Signed-off-by: blam <ben@blam.sh> --- .changeset/dry-squids-tap.md | 2 +- packages/frontend-plugin-api/api-report.md | 6 +- .../wiring/createExtensionBlueprint.test.tsx | 6 +- .../src/wiring/createExtensionBlueprint.ts | 61 ++++++++----------- 4 files changed, 33 insertions(+), 42 deletions(-) diff --git a/.changeset/dry-squids-tap.md b/.changeset/dry-squids-tap.md index d0a737f4af..613ec4b7cb 100644 --- a/.changeset/dry-squids-tap.md +++ b/.changeset/dry-squids-tap.md @@ -14,7 +14,7 @@ const EntityCardBlueprint = createExtensionBlueprint({ output: { element: coreExtensionData.reactElement, }, - factory(_, params: { text: string }) { + factory(params: { text: string }) { return { element: <h1>{params.text}</h1>, }; diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index 858350044c..342907e096 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -527,12 +527,12 @@ export interface CreateExtensionBlueprintOptions< disabled?: boolean; // (undocumented) factory( + params: TParams, context: { node: AppNode; config: TConfig; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, - params: TParams, ): Expand<ExtensionDataValues<TOutput>>; // (undocumented) inputs?: TInputs; @@ -899,20 +899,20 @@ export interface ExtensionBlueprint< configSchema?: PortableSchema<TConfig>; params: TParams; factory?( + params: TParams, context: { node: AppNode; config: TConfig; inputs: Expand<ResolvedExtensionInputs<TInputs>>; orignalFactory( + params?: TParams, context?: { node?: AppNode; config?: TConfig; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, - params?: TParams, ): Expand<ExtensionDataValues<TOutput>>; }, - params: TParams, ): Expand<ExtensionDataValues<TOutput>>; }): ExtensionDefinition<TConfig>; } diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx index b3e926e57c..c7b077bdbd 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx @@ -27,7 +27,7 @@ describe('createExtensionBlueprint', () => { output: { element: coreExtensionData.reactElement, }, - factory(_, params: { text: string }) { + factory(params: { text: string }) { return { element: <h1>{params.text}</h1>, }; @@ -78,7 +78,7 @@ describe('createExtensionBlueprint', () => { output: { element: coreExtensionData.reactElement, }, - factory(_, params: { text: string }) { + factory(params: { text: string }) { return { element: <h1>{params.text}</h1>, }; @@ -90,7 +90,7 @@ describe('createExtensionBlueprint', () => { params: { text: 'Hello, world!', }, - factory(_, params: { text: string }) { + factory(params: { text: string }) { return { element: <h2>{params.text}</h2>, }; diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts index 74d2eeadf1..6c79017a0a 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts @@ -43,12 +43,12 @@ export interface CreateExtensionBlueprintOptions< output: TOutput; configSchema?: PortableSchema<TConfig>; factory( + params: TParams, context: { node: AppNode; config: TConfig; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, - params: TParams, ): Expand<ExtensionDataValues<TOutput>>; } @@ -71,20 +71,20 @@ export interface ExtensionBlueprint< configSchema?: PortableSchema<TConfig>; params: TParams; factory?( + params: TParams, context: { node: AppNode; config: TConfig; inputs: Expand<ResolvedExtensionInputs<TInputs>>; orignalFactory( + params?: TParams, context?: { node?: AppNode; config?: TConfig; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, - params?: TParams, ): Expand<ExtensionDataValues<TOutput>>; }, - params: TParams, ): Expand<ExtensionDataValues<TOutput>>; }): ExtensionDefinition<TConfig>; } @@ -117,20 +117,20 @@ class ExtensionBlueprintImpl< configSchema?: PortableSchema<TConfig>; params: TParams; factory?( + params: TParams, context: { node: AppNode; config: TConfig; inputs: Expand<ResolvedExtensionInputs<TInputs>>; orignalFactory( + params?: TParams, context?: { node?: AppNode; config?: TConfig; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, - params?: TParams, ): Expand<ExtensionDataValues<TOutput>>; }, - params: TParams, ): Expand<ExtensionDataValues<TOutput>>; }): ExtensionDefinition<TConfig> { return createExtension({ @@ -144,39 +144,30 @@ class ExtensionBlueprintImpl< configSchema: args.configSchema ?? this.options.configSchema, // TODO: some config merging or smth factory: ({ node, config, inputs }) => { if (args.factory) { - return args.factory( - { - node, - config, - inputs, - orignalFactory: ( - innerContext?: { - config?: TConfig; - inputs?: Expand<ResolvedExtensionInputs<TInputs>>; - }, - innerParams?: TParams, - ) => - this.options.factory( - { - node, - config: innerContext?.config ?? config, - inputs: innerContext?.inputs ?? inputs, - }, - innerParams ?? args.params, - ), - }, - args.params, - ); - } - - return this.options.factory( - { + return args.factory(args.params, { node, config, inputs, - }, - args.params, - ); + orignalFactory: ( + innerParams?: TParams, + innerContext?: { + config?: TConfig; + inputs?: Expand<ResolvedExtensionInputs<TInputs>>; + }, + ) => + this.options.factory(innerParams ?? args.params, { + node, + config: innerContext?.config ?? config, + inputs: innerContext?.inputs ?? inputs, + }), + }); + } + + return this.options.factory(args.params, { + node, + config, + inputs, + }); }, }); } From b1104f9bd5c8516e7d85a70660f394608d0057a2 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Thu, 18 Jul 2024 16:58:03 +0200 Subject: [PATCH 328/510] chore: skip backend dynamic Signed-off-by: blam <ben@blam.sh> --- .changeset/nine-glasses-nail.md | 1 - packages/backend-dynamic-feature-service/package.json | 3 +-- .../src/schemas/rootLoggerServiceFactory.ts | 4 ++-- yarn.lock | 1 - 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.changeset/nine-glasses-nail.md b/.changeset/nine-glasses-nail.md index 0d68da9f2b..138acce3dd 100644 --- a/.changeset/nine-glasses-nail.md +++ b/.changeset/nine-glasses-nail.md @@ -1,5 +1,4 @@ --- -'@backstage/backend-dynamic-feature-service': patch '@backstage/plugin-search-backend-module-pg': patch --- diff --git a/packages/backend-dynamic-feature-service/package.json b/packages/backend-dynamic-feature-service/package.json index c693135f30..0d05b97bd9 100644 --- a/packages/backend-dynamic-feature-service/package.json +++ b/packages/backend-dynamic-feature-service/package.json @@ -41,8 +41,8 @@ "start": "backstage-cli package start" }, "dependencies": { + "@backstage/backend-app-api": "workspace:^", "@backstage/backend-common": "workspace:^", - "@backstage/backend-defaults": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/backend-tasks": "workspace:^", "@backstage/cli-common": "workspace:^", @@ -70,7 +70,6 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/backend-app-api": "workspace:^", "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "wait-for-expect": "^3.0.2" diff --git a/packages/backend-dynamic-feature-service/src/schemas/rootLoggerServiceFactory.ts b/packages/backend-dynamic-feature-service/src/schemas/rootLoggerServiceFactory.ts index bf3df3ffe7..6681a65a75 100644 --- a/packages/backend-dynamic-feature-service/src/schemas/rootLoggerServiceFactory.ts +++ b/packages/backend-dynamic-feature-service/src/schemas/rootLoggerServiceFactory.ts @@ -18,9 +18,9 @@ import { createServiceFactory, coreServices, } from '@backstage/backend-plugin-api'; -import { WinstonLogger } from '@backstage/backend-defaults/rootLogger'; +import { WinstonLogger } from '@backstage/backend-app-api'; import { transports, format } from 'winston'; -import { createConfigSecretEnumerator } from '@backstage/backend-defaults/rootLogger'; +import { createConfigSecretEnumerator } from '@backstage/backend-app-api'; import { loadConfigSchema } from '@backstage/config-loader'; import { getPackages } from '@manypkg/get-packages'; import { dynamicPluginsSchemasServiceRef } from './schemas'; diff --git a/yarn.lock b/yarn.lock index 53bef5284a..9261d70f21 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3708,7 +3708,6 @@ __metadata: dependencies: "@backstage/backend-app-api": "workspace:^" "@backstage/backend-common": "workspace:^" - "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-tasks": "workspace:^" "@backstage/backend-test-utils": "workspace:^" From 73184b37beea314d63196229f28c11bb14c89315 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Thu, 18 Jul 2024 18:46:25 +0200 Subject: [PATCH 329/510] ' Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/early-trees-dance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/early-trees-dance.md b/.changeset/early-trees-dance.md index 5422bd2872..55b2c08f89 100644 --- a/.changeset/early-trees-dance.md +++ b/.changeset/early-trees-dance.md @@ -2,4 +2,4 @@ '@backstage/frontend-plugin-api': patch --- -The `ExtensionBoundary` now by default infers whether its routable from whether it outputs a route path. +The `ExtensionBoundary` now by default infers whether it's routable from whether it outputs a route path. From 6ecedfafbcdeedc529868b615d2597a6121a7f5c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jul 2024 17:03:48 +0000 Subject: [PATCH 330/510] fix(deps): update dependency stream-buffers to v3.0.3 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 6db9d6b8f4..b63d8d7d63 100644 --- a/yarn.lock +++ b/yarn.lock @@ -41326,9 +41326,9 @@ __metadata: linkType: hard "stream-buffers@npm:^3.0.2": - version: 3.0.2 - resolution: "stream-buffers@npm:3.0.2" - checksum: b09fdeea606e3113ebd0e07010ed0cf038608fa396130add9e45deaff5cc3ba845dc25c31ad24f8341f85907846344cb7c85f75ea52c6572e2ac646e9b6072d0 + version: 3.0.3 + resolution: "stream-buffers@npm:3.0.3" + checksum: 3f0bdc4b1fd3ff370cef5a2103dd930b8981d42d97741eeb087a660771e27f0fc35fa8a351bb36e15bbbbce0eea00fefed60d6cdff4c6c3f527580529f183807 languageName: node linkType: hard From ba8571efe953a343e08195cb586c2e1bd3b6adaa Mon Sep 17 00:00:00 2001 From: Yayun Feng <yayfen@amazon.com> Date: Sat, 1 Jun 2024 00:09:56 +0200 Subject: [PATCH 331/510] Setup user agent header for AWS sdk client Signed-off-by: Yayun Feng <yervant.feng@gmail.com> --- .changeset/chilly-trains-sleep.md | 7 +++++++ .../entrypoints/urlReader/lib/AwsCodeCommitUrlReader.ts | 1 + .../src/entrypoints/urlReader/lib/AwsS3UrlReader.ts | 1 + .../src/processors/AwsEKSClusterProcessor.ts | 1 + .../src/providers/AwsS3EntityProvider.ts | 1 + .../src/publisher/AwsSqsConsumingEventPublisher.ts | 1 + 6 files changed, 12 insertions(+) create mode 100644 .changeset/chilly-trains-sleep.md diff --git a/.changeset/chilly-trains-sleep.md b/.changeset/chilly-trains-sleep.md new file mode 100644 index 0000000000..cde7600c8b --- /dev/null +++ b/.changeset/chilly-trains-sleep.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-events-backend-module-aws-sqs': patch +'@backstage/plugin-catalog-backend-module-aws': patch +'@backstage/backend-common': patch +--- + +Setup user agent header for AWS sdk clients, this enables users to better track API calls made from Backstage to AWS APIs through things like CloudTrail. diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/AwsCodeCommitUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/AwsCodeCommitUrlReader.ts index 7f02f1468f..5a2655ad1c 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/AwsCodeCommitUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/AwsCodeCommitUrlReader.ts @@ -213,6 +213,7 @@ export class AwsCodeCommitUrlReader implements UrlReaderService { ); const codeCommit = new CodeCommitClient({ + customUserAgent: 'backstage-aws-codecommit-url-reader', region: region, credentials: credentials, }); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/AwsS3UrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/AwsS3UrlReader.ts index 27f60f5b77..324538add4 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/AwsS3UrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/AwsS3UrlReader.ts @@ -222,6 +222,7 @@ export class AwsS3UrlReader implements UrlReaderService { ); const s3 = new S3Client({ + customUserAgent: 'backstage-aws-s3-url-reader', region: region, credentials: credentials, endpoint: integration.config.endpoint, diff --git a/plugins/catalog-backend-module-aws/src/processors/AwsEKSClusterProcessor.ts b/plugins/catalog-backend-module-aws/src/processors/AwsEKSClusterProcessor.ts index a491dbab7d..a5f5ce2f6c 100644 --- a/plugins/catalog-backend-module-aws/src/processors/AwsEKSClusterProcessor.ts +++ b/plugins/catalog-backend-module-aws/src/processors/AwsEKSClusterProcessor.ts @@ -106,6 +106,7 @@ export class AwsEKSClusterProcessor implements CatalogProcessor { } const eksClient = new EKS({ + customUserAgent: 'backstage-aws-catalog-eks-cluster-processor', credentials, credentialDefaultProvider: providerFunction, region, diff --git a/plugins/catalog-backend-module-aws/src/providers/AwsS3EntityProvider.ts b/plugins/catalog-backend-module-aws/src/providers/AwsS3EntityProvider.ts index 91ba76b695..0c58fe3f3a 100644 --- a/plugins/catalog-backend-module-aws/src/providers/AwsS3EntityProvider.ts +++ b/plugins/catalog-backend-module-aws/src/providers/AwsS3EntityProvider.ts @@ -154,6 +154,7 @@ export class AwsS3EntityProvider implements EntityProvider { accountId ? { accountId } : undefined, ); this.s3 = new S3({ + customUserAgent: 'backstage-aws-catalog-s3-entity-provider', apiVersion: '2006-03-01', credentialDefaultProvider: () => credProvider.sdkCredentialProvider, endpoint: this.integration.config.endpoint, diff --git a/plugins/events-backend-module-aws-sqs/src/publisher/AwsSqsConsumingEventPublisher.ts b/plugins/events-backend-module-aws-sqs/src/publisher/AwsSqsConsumingEventPublisher.ts index 26eba88c18..de55dee017 100644 --- a/plugins/events-backend-module-aws-sqs/src/publisher/AwsSqsConsumingEventPublisher.ts +++ b/plugins/events-backend-module-aws-sqs/src/publisher/AwsSqsConsumingEventPublisher.ts @@ -76,6 +76,7 @@ export class AwsSqsConsumingEventPublisher { }; this.sqs = new SQSClient({ + customUserAgent: 'backstage-aws-events-sqs-publisher', region: config.region, endpoint: config.endpoint, }); From 1eb5e9f686bd52bf99af3f611415ce2ad8bd7dc7 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Fri, 19 Jul 2024 14:06:17 +0200 Subject: [PATCH 332/510] chore: attempt to fix the tabs Signed-off-by: blam <ben@blam.sh> --- .../TabbedLayout/RoutedTabs.test.tsx | 12 +++++ .../components/TabbedLayout/RoutedTabs.tsx | 51 ++++++++----------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/packages/core-components/src/components/TabbedLayout/RoutedTabs.test.tsx b/packages/core-components/src/components/TabbedLayout/RoutedTabs.test.tsx index ec91208eee..991276c5d3 100644 --- a/packages/core-components/src/components/TabbedLayout/RoutedTabs.test.tsx +++ b/packages/core-components/src/components/TabbedLayout/RoutedTabs.test.tsx @@ -160,4 +160,16 @@ describe('RoutedTabs', () => { rendered.queryByText('tabbed-test-content-2'), ).not.toBeInTheDocument(); }); + + it('should render the tabs as <a> links', async () => { + const routes = [testRoute2, testRoute1, testRoute3]; + const rendered = await renderInTestApp(<RoutedTabs routes={routes} />); + + const tabs = rendered.queryAllByRole('tab'); + + for (const [k, v] of Object.entries(tabs)) { + expect(v.tagName).toBe('A'); + expect(v).toHaveAttribute('href', routes[Number(k)].path); + } + }); }); diff --git a/packages/core-components/src/components/TabbedLayout/RoutedTabs.tsx b/packages/core-components/src/components/TabbedLayout/RoutedTabs.tsx index 6a5bf2970f..d6f6eab144 100644 --- a/packages/core-components/src/components/TabbedLayout/RoutedTabs.tsx +++ b/packages/core-components/src/components/TabbedLayout/RoutedTabs.tsx @@ -15,15 +15,11 @@ */ import React, { useMemo } from 'react'; import { Helmet } from 'react-helmet'; -import { - matchRoutes, - useNavigate, - useParams, - useRoutes, -} from 'react-router-dom'; +import { matchRoutes, useParams, useRoutes } from 'react-router-dom'; import { Content } from '../../layout/Content'; import { HeaderTabs } from '../../layout/HeaderTabs'; import { SubRoute } from './types'; +import { Link } from '../Link'; export function useSelectedSubRoute(subRoutes: SubRoute[]): { index: number; @@ -68,38 +64,33 @@ export function useSelectedSubRoute(subRoutes: SubRoute[]): { export function RoutedTabs(props: { routes: SubRoute[] }) { const { routes } = props; - const navigate = useNavigate(); + const { index, route, element } = useSelectedSubRoute(routes); const headerTabs = useMemo( () => - routes.map(t => ({ - id: t.path, - label: t.title, - tabProps: t.tabProps, - })), + routes.map(t => { + const { path, title, tabProps } = t; + let to = path; + // Remove trailing /* + to = to.replace(/\/\*$/, ''); + // And remove leading / for relative navigation + to = to.replace(/^\//, ''); + return { + id: path, + label: title, + tabProps: { + ...tabProps, + component: Link, + to, + }, + }; + }), [routes], ); - const onTabChange = (tabIndex: number) => { - let { path } = routes[tabIndex]; - // Remove trailing /* - path = path.replace(/\/\*$/, ''); - // And remove leading / for relative navigation - path = path.replace(/^\//, ''); - // Note! route resolves relative to the position in the React tree, - // not relative to current location - navigate(path); - }; return ( <> - <HeaderTabs - tabs={headerTabs} - selectedIndex={index} - onChange={onTabChange} - tabProps={{ - component: Link, - }} - /> + <HeaderTabs tabs={headerTabs} selectedIndex={index} /> <Content> <Helmet title={route?.title} /> {element} From 678971ad41380d5b958ed4b9f72e9372385d9380 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Fri, 19 Jul 2024 14:07:17 +0200 Subject: [PATCH 333/510] chore: added changeset Signed-off-by: blam <ben@blam.sh> --- .changeset/eighty-mirrors-flow.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/eighty-mirrors-flow.md diff --git a/.changeset/eighty-mirrors-flow.md b/.changeset/eighty-mirrors-flow.md new file mode 100644 index 0000000000..57e978a78c --- /dev/null +++ b/.changeset/eighty-mirrors-flow.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Move the `Link` component to the `RoutedTabs` instead of the `HeaderTabs` component From de4cd433c15a6cc2ba63448ff31542decedaf2bf Mon Sep 17 00:00:00 2001 From: MT Lewis <mtlewis@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:31:28 +0100 Subject: [PATCH 334/510] cli: simplify changeset Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com> Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com> --- .changeset/little-bulldogs-guess.md | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/.changeset/little-bulldogs-guess.md b/.changeset/little-bulldogs-guess.md index 1f86f0a67f..3e646a033f 100644 --- a/.changeset/little-bulldogs-guess.md +++ b/.changeset/little-bulldogs-guess.md @@ -2,16 +2,4 @@ '@backstage/cli': patch --- -Add ability to force use of the development versions of `react` and `react-dom` -to allow for detailed error messages and use of fast-refresh. Note that builds -with the development versions of `react` and `react-dom` should not be -deployed in production. - -This feature can be used by setting the `FORCE_REACT_DEVELOPMENT` environment -variable to `true`: - -```bash -EXPERIMENTAL_MODULE_FEDERATION=true \ -FORCE_REACT_DEVELOPMENT=true \ -yarn build:all -``` +The experimental module federation build now has the ability to force the use of development versions of `react` and `react-dom` by setting the `FORCE_REACT_DEVELOPMENT` flag. From 2e1a7f10e5f29af3e4f253ad62b7d61148c5f995 Mon Sep 17 00:00:00 2001 From: MT Lewis <mtlewis@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:48:20 +0100 Subject: [PATCH 335/510] cli: only check for truthiness of environment variables when forcing react mode Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com> --- packages/cli/src/lib/bundler/config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index 8e3d7eee19..3d3be4f485 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -237,8 +237,8 @@ export async function createConfig( const optimization = optimizationConfig(options); if ( - process.env.EXPERIMENTAL_MODULE_FEDERATION === 'true' && - process.env.FORCE_REACT_DEVELOPMENT === 'true' + !!process.env.EXPERIMENTAL_MODULE_FEDERATION && + !!process.env.FORCE_REACT_DEVELOPMENT ) { console.log( chalk.yellow( From 0983429447db996138e90c6168f82e47b405223e Mon Sep 17 00:00:00 2001 From: MT Lewis <mtlewis@users.noreply.github.com> Date: Fri, 19 Jul 2024 14:05:28 +0100 Subject: [PATCH 336/510] cli: expand comment Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com> --- packages/cli/src/lib/bundler/config.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index 3d3be4f485..e10ac0253e 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -251,7 +251,9 @@ export async function createConfig( `${dirname(require.resolve('react-dom/package.json'))}/`, ]; - // Don't define process.env.NODE_ENV with value matching config.mode. + // Don't define process.env.NODE_ENV with value matching config.mode. If we + // don't set this to false, webpack will define the value of + // process.env.NODE_ENV for us, and the definition below will be ignored. optimization.nodeEnv = false; // Instead, provide a custom definition which always uses "development" if From 232b134606d193c262d38892e86e41bc979305fd Mon Sep 17 00:00:00 2001 From: MT Lewis <mtlewis@users.noreply.github.com> Date: Fri, 19 Jul 2024 14:07:35 +0100 Subject: [PATCH 337/510] cli: skip forcing react to development mode if mode is development anyway Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com> --- packages/cli/src/lib/bundler/config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index e10ac0253e..1f29277676 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -237,6 +237,7 @@ export async function createConfig( const optimization = optimizationConfig(options); if ( + mode === 'production' && !!process.env.EXPERIMENTAL_MODULE_FEDERATION && !!process.env.FORCE_REACT_DEVELOPMENT ) { From 6c94522688dc49b850db6d23c57b1a794c4b0602 Mon Sep 17 00:00:00 2001 From: MT Lewis <mtlewis@users.noreply.github.com> Date: Fri, 19 Jul 2024 14:08:54 +0100 Subject: [PATCH 338/510] cli: remove explicit boolean coercions when forcing react mode Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com> --- packages/cli/src/lib/bundler/config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index 1f29277676..9a611a5954 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -238,8 +238,8 @@ export async function createConfig( if ( mode === 'production' && - !!process.env.EXPERIMENTAL_MODULE_FEDERATION && - !!process.env.FORCE_REACT_DEVELOPMENT + process.env.EXPERIMENTAL_MODULE_FEDERATION && + process.env.FORCE_REACT_DEVELOPMENT ) { console.log( chalk.yellow( From 0e706b3484998631a591b8a07a23b075781ffb25 Mon Sep 17 00:00:00 2001 From: Ben Lambert <blam@spotify.com> Date: Fri, 19 Jul 2024 15:40:42 +0200 Subject: [PATCH 339/510] Update modern-parrots-protect.md Signed-off-by: Ben Lambert <blam@spotify.com> --- .changeset/modern-parrots-protect.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/modern-parrots-protect.md b/.changeset/modern-parrots-protect.md index 7fccff1bef..bb4df2c248 100644 --- a/.changeset/modern-parrots-protect.md +++ b/.changeset/modern-parrots-protect.md @@ -2,4 +2,4 @@ '@backstage/plugin-scaffolder-react': patch --- -support ajv-errors for scaffolder validation +support `ajv-errors` for scaffolder validation to allow for customizing the error messages From b8600fe1650507c7b0e443ba58d8183e4a7413a8 Mon Sep 17 00:00:00 2001 From: Adam Letizia <LetiziaAdam@JohnDeere.com> Date: Fri, 19 Jul 2024 09:48:20 -0500 Subject: [PATCH 340/510] fix(scaffolder): refetch user credentials when selected host is changed in RepoUrlPicker Signed-off-by: Adam Letizia <LetiziaAdam@JohnDeere.com> --- .changeset/tough-lies-repair.md | 5 ++ .../RepoUrlPicker/RepoUrlPicker.test.tsx | 56 +++++++++++++++---- .../fields/RepoUrlPicker/RepoUrlPicker.tsx | 11 +++- 3 files changed, 58 insertions(+), 14 deletions(-) create mode 100644 .changeset/tough-lies-repair.md diff --git a/.changeset/tough-lies-repair.md b/.changeset/tough-lies-repair.md new file mode 100644 index 0000000000..25b1884bbc --- /dev/null +++ b/.changeset/tough-lies-repair.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +RepoUrlPicker: refetch user credentials when a new host is selected diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.test.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.test.tsx index 002652cfab..fce9d9517c 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.test.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.test.tsx @@ -33,6 +33,7 @@ import { ScaffolderRJSFField, } from '@backstage/plugin-scaffolder-react'; import { act, fireEvent } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; describe('RepoUrlPicker', () => { const mockScaffolderApi: Partial<ScaffolderApi> = { @@ -323,14 +324,29 @@ describe('RepoUrlPicker', () => { }); }); - it('should not call the scmAuthApi if secret is available in the state', async () => { + it('should call the scmAuthApi with the new host when the host is changed', async () => { const SecretsComponent = () => { const { secrets } = useTemplateSecrets(); return ( <div data-testid="current-secrets">{JSON.stringify({ secrets })}</div> ); }; - const { getByTestId } = await renderInTestApp( + const allowedHosts = ['github.com', 'gitlab.example.com']; + + (mockScmAuthApi.getCredentials as jest.Mock).mockImplementation( + ({ url }) => { + let token = ''; + if (url === `https://${allowedHosts[0]}`) { + token = 'abc123'; + } else if (url === `https://${allowedHosts[1]}`) { + token = 'def456'; + } + return Promise.resolve({ token }); + }, + ); + const secondHost = allowedHosts[1]; + + const { getAllByRole, getByTestId } = await renderInTestApp( <TestApiProvider apis={[ [scmIntegrationsApiRef, mockIntegrationsApi], @@ -338,16 +354,16 @@ describe('RepoUrlPicker', () => { [scaffolderApiRef, mockScaffolderApi], ]} > - <SecretsContextProvider initialSecrets={{ testKey: 'abc123' }}> + <SecretsContextProvider> <Form validator={validator} schema={{ type: 'string' }} uiSchema={{ 'ui:field': 'RepoUrlPicker', 'ui:options': { + allowedHosts, requestUserCredentials: { secretsKey: 'testKey', - additionalScopes: { github: ['workflow'] }, }, }, }} @@ -361,19 +377,35 @@ describe('RepoUrlPicker', () => { ); await act(async () => { + // need to wait for the debounce to finish to fetch credentials for the first selected host + await new Promise(resolve => setTimeout(resolve, 600)); + }); + const firstHostSecrets = JSON.parse( + getByTestId('current-secrets').textContent!, + ); + expect(firstHostSecrets).toEqual({ + secrets: { testKey: 'abc123' }, + }); + + await act(async () => { + // Select the second host + const hostInput = getAllByRole('combobox')[0]; + await userEvent.selectOptions(hostInput, secondHost); + // need to wait for the debounce to finish await new Promise(resolve => setTimeout(resolve, 600)); }); - - // as we already have a secret in the state, getCredentials should not be called again. - expect(mockScmAuthApi.getCredentials).toHaveBeenCalledTimes(0); - - const currentSecrets = JSON.parse( + const secondHostSecrets = JSON.parse( getByTestId('current-secrets').textContent!, ); - - expect(currentSecrets).toEqual({ - secrets: { testKey: 'abc123' }, + expect(secondHostSecrets).toEqual({ + secrets: { testKey: 'def456' }, + }); + expect(mockScmAuthApi.getCredentials).toHaveBeenCalledWith({ + url: `https://${secondHost}`, + additionalScope: { + repoWrite: true, + }, }); }); }); diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx index e0d714ffda..e653be9178 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx @@ -49,6 +49,9 @@ export const RepoUrlPicker = (props: RepoUrlPickerProps) => { const [state, setState] = useState<RepoUrlPickerState>( parseRepoPickerUrl(formData), ); + const [credentialsHost, setCredentialsHost] = useState<string | undefined>( + undefined, + ); const integrationApi = useApi(scmIntegrationsApiRef); const scmAuthApi = useApi(scmAuthApiRef); const { secrets, setSecrets } = useTemplateSecrets(); @@ -128,8 +131,11 @@ export const RepoUrlPicker = (props: RepoUrlPickerProps) => { return; } - // don't show login prompt if secret value is already in state - if (secrets[requestUserCredentials.secretsKey]) { + // don't show login prompt if secret value is already in state for selected host + if ( + secrets[requestUserCredentials.secretsKey] && + credentialsHost === state.host + ) { return; } @@ -147,6 +153,7 @@ export const RepoUrlPicker = (props: RepoUrlPickerProps) => { // set the secret using the key provided in the ui:options for use // in the templating the manifest with ${{ secrets[secretsKey] }} setSecrets({ [requestUserCredentials.secretsKey]: token }); + setCredentialsHost(state.host); }, 500, [state, uiSchema], From 274428fd9d32fd0df19e95f96139c3845fcfb045 Mon Sep 17 00:00:00 2001 From: Tim Klever <tim.v.klever@aexp.com> Date: Tue, 18 Jun 2024 16:12:52 -0700 Subject: [PATCH 341/510] feat: add parsing configuration option for `ConfigSource`s FileConfigSource and RemoteConfigSource can now be optionally configured to operate on more than yaml files Signed-off-by: Tim Klever <tim.v.klever@aexp.com> --- .changeset/young-peaches-shake.md | 5 +++ packages/config-loader/api-report.md | 7 ++++ .../src/sources/FileConfigSource.test.ts | 13 +++++++ .../src/sources/FileConfigSource.ts | 18 ++++++--- .../src/sources/RemoteConfigSource.test.ts | 39 +++++++++++++++++++ .../src/sources/RemoteConfigSource.ts | 28 ++++++++++--- packages/config-loader/src/sources/index.ts | 1 + packages/config-loader/src/sources/types.ts | 16 ++++++++ packages/config-loader/src/sources/utils.ts | 9 +++++ 9 files changed, 126 insertions(+), 10 deletions(-) create mode 100644 .changeset/young-peaches-shake.md diff --git a/.changeset/young-peaches-shake.md b/.changeset/young-peaches-shake.md new file mode 100644 index 0000000000..75c93f8f3b --- /dev/null +++ b/.changeset/young-peaches-shake.md @@ -0,0 +1,5 @@ +--- +'@backstage/config-loader': minor +--- + +Add configuration key to File and Remote `ConfigSource`s that enables configuration of parsing logic. Previously limited to yaml, these `ConfigSource`s now allow for a multitude of parsing options (e.g. JSON). diff --git a/packages/config-loader/api-report.md b/packages/config-loader/api-report.md index bc8f217bbb..7b7ab5a36d 100644 --- a/packages/config-loader/api-report.md +++ b/packages/config-loader/api-report.md @@ -141,6 +141,7 @@ export class FileConfigSource implements ConfigSource { // @public export interface FileConfigSourceOptions { + parser?: Parser; path: string; substitutionFunc?: EnvFunc; watch?: boolean; @@ -218,6 +219,11 @@ export interface MutableConfigSourceOptions { data?: JsonObject; } +// @public +export type Parser = ({ contents }: { contents: string }) => Promise<{ + result?: JsonObject; +}>; + // @public export interface ReadConfigDataOptions { // (undocumented) @@ -242,6 +248,7 @@ export class RemoteConfigSource implements ConfigSource { // @public export interface RemoteConfigSourceOptions { + parser?: Parser; reloadInterval?: HumanDuration; substitutionFunc?: EnvFunc; url: string; diff --git a/packages/config-loader/src/sources/FileConfigSource.test.ts b/packages/config-loader/src/sources/FileConfigSource.test.ts index 61cdeed272..4ed31ccee0 100644 --- a/packages/config-loader/src/sources/FileConfigSource.test.ts +++ b/packages/config-loader/src/sources/FileConfigSource.test.ts @@ -59,6 +59,19 @@ describe('FileConfigSource', () => { ]); }); + it('should read a config file with optional parser', async () => { + const tmp = await tmpFiles({ 'a.json': JSON.stringify({ a: 1 }) }); + + const source = FileConfigSource.create({ + path: tmp.resolve('a.json'), + parser: async ({ contents }) => ({ result: JSON.parse(contents) }), + }); + + await expect(readN(source, 1)).resolves.toEqual([ + [{ data: { a: 1 }, context: 'a.json', path: tmp.resolve('a.json') }], + ]); + }); + it('should watch config files', async () => { const tmp = await tmpFiles({ 'a.yaml': 'a: 1' }); diff --git a/packages/config-loader/src/sources/FileConfigSource.ts b/packages/config-loader/src/sources/FileConfigSource.ts index 74266de227..c0697c1180 100644 --- a/packages/config-loader/src/sources/FileConfigSource.ts +++ b/packages/config-loader/src/sources/FileConfigSource.ts @@ -17,16 +17,17 @@ import chokidar, { FSWatcher } from 'chokidar'; import fs from 'fs-extra'; import { basename, dirname, isAbsolute, resolve as resolvePath } from 'path'; -import yaml from 'yaml'; import { AsyncConfigSourceGenerator, ConfigSource, ConfigSourceData, SubstitutionFunc, + Parser, ReadConfigDataOptions, } from './types'; import { createConfigTransformer } from './transform'; import { NotFoundError } from '@backstage/errors'; +import { parseYamlContent } from './utils'; /** * Options for {@link FileConfigSource.create}. @@ -48,6 +49,11 @@ export interface FileConfigSourceOptions { * A substitution function to use instead of the default environment substitution. */ substitutionFunc?: SubstitutionFunc; + + /** + * A content parsing function to transform string content to configuration values. + */ + parser?: Parser; } async function readFile(path: string): Promise<string | undefined> { @@ -95,11 +101,13 @@ export class FileConfigSource implements ConfigSource { readonly #path: string; readonly #substitutionFunc?: SubstitutionFunc; readonly #watch?: boolean; + readonly #parser: Parser; private constructor(options: FileConfigSourceOptions) { this.#path = options.path; this.#substitutionFunc = options.substitutionFunc; this.#watch = options.watch ?? true; + this.#parser = options.parser ?? parseYamlContent; } // Work is duplicated across each read, in practice that should not @@ -154,12 +162,12 @@ export class FileConfigSource implements ConfigSource { watchedPaths.push(this.#path); } - const content = await readFile(this.#path); - if (content === undefined) { + const contents = await readFile(this.#path); + if (contents === undefined) { throw new NotFoundError(`Config file "${this.#path}" does not exist`); } - const parsed = yaml.parse(content); - if (parsed === null) { + const { result: parsed } = await this.#parser({ contents }); + if (parsed === undefined) { return []; } try { diff --git a/packages/config-loader/src/sources/RemoteConfigSource.test.ts b/packages/config-loader/src/sources/RemoteConfigSource.test.ts index e825bf3434..372dc91823 100644 --- a/packages/config-loader/src/sources/RemoteConfigSource.test.ts +++ b/packages/config-loader/src/sources/RemoteConfigSource.test.ts @@ -59,6 +59,45 @@ app: ]); }); + it('should load and parse config from a remote URL', async () => { + worker.use( + rest.get('http://localhost/config.json', (_req, res, ctx) => + res( + ctx.body( + JSON.stringify({ + app: { + title: 'Example App', + substituted: 'x', + escaped: '$${VALUE}', + }, + }), + ), + ), + ), + ); + + const source = RemoteConfigSource.create({ + url: 'http://localhost/config.json', + substitutionFunc: async () => 'x', + parser: async ({ contents }) => ({ result: JSON.parse(contents) }), + }); + + await expect(readN(source, 1)).resolves.toEqual([ + [ + { + context: 'http://localhost/config.json', + data: { + app: { + title: 'Example App', + substituted: 'x', + escaped: '${VALUE}', + }, + }, + }, + ], + ]); + }); + it('should reload config from a remote URL', async () => { let fetched = false; diff --git a/packages/config-loader/src/sources/RemoteConfigSource.ts b/packages/config-loader/src/sources/RemoteConfigSource.ts index 10a64ee635..1492cd4d28 100644 --- a/packages/config-loader/src/sources/RemoteConfigSource.ts +++ b/packages/config-loader/src/sources/RemoteConfigSource.ts @@ -22,14 +22,15 @@ import { } from '@backstage/types'; import isEqual from 'lodash/isEqual'; import fetch from 'node-fetch'; -import yaml from 'yaml'; import { ConfigTransformer, createConfigTransformer } from './transform'; import { AsyncConfigSourceGenerator, ConfigSource, SubstitutionFunc, ReadConfigDataOptions, + Parser, } from './types'; +import { parseYamlContent } from './utils'; const DEFAULT_RELOAD_INTERVAL = { seconds: 60 }; @@ -55,6 +56,11 @@ export interface RemoteConfigSourceOptions { * A substitution function to use instead of the default environment substitution. */ substitutionFunc?: SubstitutionFunc; + + /** + * A content parsing function to transform string content to configuration values. + */ + parser?: Parser; } /** @@ -84,6 +90,7 @@ export class RemoteConfigSource implements ConfigSource { readonly #url: string; readonly #reloadIntervalMs: number; readonly #transformer: ConfigTransformer; + readonly #parser: Parser; private constructor(options: RemoteConfigSourceOptions) { this.#url = options.url; @@ -93,6 +100,7 @@ export class RemoteConfigSource implements ConfigSource { this.#transformer = createConfigTransformer({ substitutionFunc: options.substitutionFunc, }); + this.#parser = options.parser ?? parseYamlContent; } async *readConfigData( @@ -135,11 +143,21 @@ export class RemoteConfigSource implements ConfigSource { throw await ResponseError.fromResponse(res); } - const content = await res.text(); - const data = await this.#transformer(yaml.parse(content)); - if (data === null) { + const contents = await res.text(); + const { result: rawData } = await this.#parser({ contents }); + if (rawData === undefined) { + /** + * This error message is/was coupled to the implementation and with refactoring it is no longer truly accurate + * This behavior is also inconsistent with {@link FileConfigSource}, which doesn't error on unparseable or empty + * content + * + * Preserving to not make a breaking change + */ throw new Error('configuration data is null'); - } else if (typeof data !== 'object') { + } + + const data = await this.#transformer(rawData); + if (typeof data !== 'object') { throw new Error('configuration data is not an object'); } else if (Array.isArray(data)) { throw new Error( diff --git a/packages/config-loader/src/sources/index.ts b/packages/config-loader/src/sources/index.ts index a25f689b40..3bf8e71990 100644 --- a/packages/config-loader/src/sources/index.ts +++ b/packages/config-loader/src/sources/index.ts @@ -38,4 +38,5 @@ export type { ConfigSourceData, ReadConfigDataOptions, AsyncConfigSourceGenerator, + Parser, } from './types'; diff --git a/packages/config-loader/src/sources/types.ts b/packages/config-loader/src/sources/types.ts index dec6f415f2..abdf2f5c8e 100644 --- a/packages/config-loader/src/sources/types.ts +++ b/packages/config-loader/src/sources/types.ts @@ -15,6 +15,7 @@ */ import { AppConfig } from '@backstage/config'; +import { JsonObject } from '@backstage/types'; /** * The data returned by {@link ConfigSource.readConfigData}. @@ -89,3 +90,18 @@ export interface ConfigSource { * @public */ export type SubstitutionFunc = (name: string) => Promise<string | undefined>; + +/** + * A custom function to be used for parsing configuration content. + * + * @remarks + * + * The default parsing function will parse configuration content as yaml. + * + * @public + */ +export type Parser = ({ + contents, +}: { + contents: string; +}) => Promise<{ result?: JsonObject }>; diff --git a/packages/config-loader/src/sources/utils.ts b/packages/config-loader/src/sources/utils.ts index 9978234195..b948cc47b4 100644 --- a/packages/config-loader/src/sources/utils.ts +++ b/packages/config-loader/src/sources/utils.ts @@ -14,6 +14,9 @@ * limitations under the License. */ +import { Parser } from './types'; +import yaml from 'yaml'; + /** @internal */ export interface SimpleDeferred<T> { promise: Promise<T>; @@ -55,3 +58,9 @@ export async function waitOrAbort<T>( signals.forEach(s => s.addEventListener('abort', onAbort)); }); } + +/** @internal */ +export const parseYamlContent: Parser = async ({ contents }) => { + const parsed = yaml.parse(contents); + return { result: parsed === null ? undefined : parsed }; +}; From 924c0a6379fa9a2c521622259126125b0bc2ddc0 Mon Sep 17 00:00:00 2001 From: rghara <ramin.g01@infosys.com> Date: Fri, 19 Jul 2024 12:53:18 -0400 Subject: [PATCH 342/510] Updated document getting-started/logging-in with missing login screen screenshot Signed-off-by: rghara <ramin.g01@infosys.com> --- docs/assets/getting-started/login-screen.png | Bin 0 -> 108521 bytes docs/getting-started/logging-in.md | 2 ++ 2 files changed, 2 insertions(+) create mode 100755 docs/assets/getting-started/login-screen.png diff --git a/docs/assets/getting-started/login-screen.png b/docs/assets/getting-started/login-screen.png new file mode 100755 index 0000000000000000000000000000000000000000..70b56f399a22d19ad863f77db22739f67a352501 GIT binary patch literal 108521 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�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 literal 0 HcmV?d00001 diff --git a/docs/getting-started/logging-in.md b/docs/getting-started/logging-in.md index fef8907e07..5386e98798 100644 --- a/docs/getting-started/logging-in.md +++ b/docs/getting-started/logging-in.md @@ -20,6 +20,8 @@ Run your Backstage app with `yarn dev`. Navigate to `http://localhost:3000`. If you're not already logged in, you should see a login screen like this, +![Screenshot of the the login screen](../assets/getting-started/login-screen.png) + To login, you should choose the "Github" provider and click the "Sign in" button. This will redirect you to a Github OAuth page. Verify that the scopes mentioned on that page match the setup you did in [the authentication tutorial](./config/authentication.md). Once you click "Confirm", you will be brought back to the Backstage interface and signed in! If you are already logged in, you will be automatically brought to your Backstage instance. From 708294012180f435dd61c87a827b752b6f3fb974 Mon Sep 17 00:00:00 2001 From: MT Lewis <mtlewis@users.noreply.github.com> Date: Wed, 17 Jul 2024 18:01:01 +0100 Subject: [PATCH 343/510] cli: add support for frontend-dynamic-container role in yarn start Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com> --- .../cli/src/commands/build/buildFrontend.ts | 27 +----------- packages/cli/src/commands/start/command.ts | 8 ++++ .../cli/src/commands/start/startFrontend.ts | 11 ++++- packages/cli/src/lib/bundler/index.ts | 1 + .../cli/src/lib/bundler/moduleFederation.ts | 44 +++++++++++++++++++ packages/cli/src/lib/bundler/types.ts | 1 + 6 files changed, 65 insertions(+), 27 deletions(-) create mode 100644 packages/cli/src/lib/bundler/moduleFederation.ts diff --git a/packages/cli/src/commands/build/buildFrontend.ts b/packages/cli/src/commands/build/buildFrontend.ts index 62da74e6d3..f29e0bdd38 100644 --- a/packages/cli/src/commands/build/buildFrontend.ts +++ b/packages/cli/src/commands/build/buildFrontend.ts @@ -16,11 +16,9 @@ import fs from 'fs-extra'; import { resolve as resolvePath } from 'path'; -import { buildBundle } from '../../lib/bundler'; +import { buildBundle, getModuleFederationOptions } from '../../lib/bundler'; import { getEnvironmentParallelism } from '../../lib/parallel'; import { loadCliConfig } from '../../lib/config'; -import chalk from 'chalk'; -import { BuildOptions } from '../../lib/bundler/types'; interface BuildAppOptions { targetDir: string; @@ -29,29 +27,6 @@ interface BuildAppOptions { isModuleFederationRemote?: true; } -function getModuleFederationOptions( - name: string, - isRemote?: boolean, -): BuildOptions['moduleFederation'] { - if (!isRemote && !process.env.EXPERIMENTAL_MODULE_FEDERATION) { - return undefined; - } - - console.log( - chalk.yellow( - `⚠️ WARNING: Module federation is experimental and will receive immediate breaking changes in the future.`, - ), - ); - - return { - mode: isRemote ? 'remote' : 'host', - // The default output mode requires the name to be a usable as a code - // symbol, there might be better options here but for now we need to - // sanitize the name. - name: name.replaceAll('@', '').replaceAll('/', '__').replaceAll('-', '_'), - }; -} - export async function buildFrontend(options: BuildAppOptions) { const { targetDir, writeStats, configPaths } = options; const { name } = await fs.readJson(resolvePath(targetDir, 'package.json')); diff --git a/packages/cli/src/commands/start/command.ts b/packages/cli/src/commands/start/command.ts index 2f2af95d85..aa46b717bb 100644 --- a/packages/cli/src/commands/start/command.ts +++ b/packages/cli/src/commands/start/command.ts @@ -15,6 +15,7 @@ */ import { OptionValues } from 'commander'; +import { PackageRole } from '@backstage/cli-node'; import { findRoleFromCommand } from '../../lib/role'; import { startBackend, startBackendPlugin } from './startBackend'; import { startFrontend } from './startFrontend'; @@ -47,6 +48,13 @@ export async function command(opts: OptionValues): Promise<void> { case 'frontend-plugin': case 'frontend-plugin-module': return startFrontend({ entry: 'dev/index', ...options }); + case 'frontend-dynamic-container' as PackageRole: // experimental + return startFrontend({ + entry: 'src/index', + ...options, + skipOpenBrowser: true, + isModuleFederationRemote: true, + }); default: throw new Error( `Start command is not supported for package role '${role}'`, diff --git a/packages/cli/src/commands/start/startFrontend.ts b/packages/cli/src/commands/start/startFrontend.ts index a809473788..627da1bd1a 100644 --- a/packages/cli/src/commands/start/startFrontend.ts +++ b/packages/cli/src/commands/start/startFrontend.ts @@ -14,7 +14,9 @@ * limitations under the License. */ -import { serveBundle } from '../../lib/bundler'; +import { readJson } from 'fs-extra'; +import { getModuleFederationOptions, serveBundle } from '../../lib/bundler'; +import { paths } from '../../lib/paths'; interface StartAppOptions { verifyVersions?: boolean; @@ -22,14 +24,21 @@ interface StartAppOptions { checksEnabled: boolean; configPaths: string[]; + isModuleFederationRemote?: boolean; } export async function startFrontend(options: StartAppOptions) { + const { name } = await readJson(paths.resolveTarget('package.json')); + const waitForExit = await serveBundle({ entry: options.entry, checksEnabled: options.checksEnabled, configPaths: options.configPaths, verifyVersions: options.verifyVersions, + moduleFederation: getModuleFederationOptions( + name, + options.isModuleFederationRemote, + ), }); await waitForExit(); diff --git a/packages/cli/src/lib/bundler/index.ts b/packages/cli/src/lib/bundler/index.ts index a3b584efc4..2219784dc9 100644 --- a/packages/cli/src/lib/bundler/index.ts +++ b/packages/cli/src/lib/bundler/index.ts @@ -16,4 +16,5 @@ export { serveBackend } from './backend'; export { buildBundle } from './bundle'; +export { getModuleFederationOptions } from './moduleFederation'; export { serveBundle } from './server'; diff --git a/packages/cli/src/lib/bundler/moduleFederation.ts b/packages/cli/src/lib/bundler/moduleFederation.ts new file mode 100644 index 0000000000..ae3f9ab048 --- /dev/null +++ b/packages/cli/src/lib/bundler/moduleFederation.ts @@ -0,0 +1,44 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import chalk from 'chalk'; +import { ModuleFederationOptions } from './types'; + +export function getModuleFederationOptions( + name: string, + isModuleFederationRemote?: boolean, +): ModuleFederationOptions | undefined { + if ( + !isModuleFederationRemote && + !process.env.EXPERIMENTAL_MODULE_FEDERATION + ) { + return undefined; + } + + console.log( + chalk.yellow( + `⚠️ WARNING: Module federation is experimental and will receive immediate breaking changes in the future.`, + ), + ); + + return { + mode: isModuleFederationRemote ? 'remote' : 'host', + // The default output mode requires the name to be a usable as a code + // symbol, there might be better options here but for now we need to + // sanitize the name. + name: name.replaceAll('@', '').replaceAll('/', '__').replaceAll('-', '_'), + }; +} diff --git a/packages/cli/src/lib/bundler/types.ts b/packages/cli/src/lib/bundler/types.ts index 7291ac0818..60c59f757b 100644 --- a/packages/cli/src/lib/bundler/types.ts +++ b/packages/cli/src/lib/bundler/types.ts @@ -43,6 +43,7 @@ export type ServeOptions = BundlingPathsOptions & { checksEnabled: boolean; configPaths: string[]; verifyVersions?: boolean; + moduleFederation?: ModuleFederationOptions; }; export type BuildOptions = BundlingPathsOptions & { From 94ab20ebfa48ae8197be8180dfa86b7ee4ea6bfa Mon Sep 17 00:00:00 2001 From: MT Lewis <mtlewis@users.noreply.github.com> Date: Wed, 17 Jul 2024 18:04:36 +0100 Subject: [PATCH 344/510] cli: skip opening browser when serving bundle for packages with frontend-dynamic-container role Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com> --- packages/cli/src/commands/start/startFrontend.ts | 2 ++ packages/cli/src/lib/bundler/server.ts | 5 ++++- packages/cli/src/lib/bundler/types.ts | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/commands/start/startFrontend.ts b/packages/cli/src/commands/start/startFrontend.ts index 627da1bd1a..20faf4a9ff 100644 --- a/packages/cli/src/commands/start/startFrontend.ts +++ b/packages/cli/src/commands/start/startFrontend.ts @@ -24,6 +24,7 @@ interface StartAppOptions { checksEnabled: boolean; configPaths: string[]; + skipOpenBrowser?: boolean; isModuleFederationRemote?: boolean; } @@ -35,6 +36,7 @@ export async function startFrontend(options: StartAppOptions) { checksEnabled: options.checksEnabled, configPaths: options.configPaths, verifyVersions: options.verifyVersions, + skipOpenBrowser: options.skipOpenBrowser, moduleFederation: getModuleFederationOptions( name, options.isModuleFederationRemote, diff --git a/packages/cli/src/lib/bundler/server.ts b/packages/cli/src/lib/bundler/server.ts index 1da15cd37e..cf35f65518 100644 --- a/packages/cli/src/lib/bundler/server.ts +++ b/packages/cli/src/lib/bundler/server.ts @@ -162,6 +162,7 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be const config = await createConfig(paths, { ...commonConfigOptions, additionalEntryPoints: detectedModulesEntryPoint, + moduleFederation: options.moduleFederation, }); if (process.env.EXPERIMENTAL_VITE) { @@ -278,7 +279,9 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be } }); - openBrowser(url.href); + if (!options.skipOpenBrowser) { + openBrowser(url.href); + } const waitForExit = async () => { for (const signal of ['SIGINT', 'SIGTERM'] as const) { diff --git a/packages/cli/src/lib/bundler/types.ts b/packages/cli/src/lib/bundler/types.ts index 60c59f757b..f8e228c5c4 100644 --- a/packages/cli/src/lib/bundler/types.ts +++ b/packages/cli/src/lib/bundler/types.ts @@ -43,6 +43,7 @@ export type ServeOptions = BundlingPathsOptions & { checksEnabled: boolean; configPaths: string[]; verifyVersions?: boolean; + skipOpenBrowser?: boolean; moduleFederation?: ModuleFederationOptions; }; From b7709255e8b3540176b7db675e9ad77e658920cc Mon Sep 17 00:00:00 2001 From: MT Lewis <mtlewis@users.noreply.github.com> Date: Wed, 17 Jul 2024 18:12:16 +0100 Subject: [PATCH 345/510] cli: pass websocket host and port explicitly in configuration When configuring the ReactRefreshPlugin and the WebpackDevServer, we previously inferred the host and port from the browser location. This is no longer sufficient, since dynamic plugin containers may be served from separate dev servers. https://webpack.js.org/configuration/dev-server/#websocketurl https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/main/docs/API.md#sockhost Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com> --- packages/cli/src/lib/bundler/config.ts | 30 ++++++++++++++++++++++ packages/cli/src/lib/bundler/server.ts | 12 +++------ packages/cli/src/lib/bundler/transforms.ts | 11 +------- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index 9a611a5954..1f08f74a85 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -29,6 +29,7 @@ import { ModuleFederationPlugin } from '@module-federation/enhanced/webpack'; import { LinkedPackageResolvePlugin } from './LinkedPackageResolvePlugin'; import ModuleScopePlugin from 'react-dev-utils/ModuleScopePlugin'; import { RunScriptWebpackPlugin } from 'run-script-webpack-plugin'; +import ReactRefreshPlugin from '@pmmmwh/react-refresh-webpack-plugin'; import { paths as cliPaths } from '../../lib/paths'; import fs from 'fs-extra'; import { getPackages } from '@manypkg/get-packages'; @@ -54,6 +55,21 @@ export function resolveBaseUrl(config: Config): URL { } } +export function resolveEndpoint(config: Config): { + host: string; + port: number; +} { + const url = resolveBaseUrl(config); + + return { + host: config.getOptionalString('app.listen.host') ?? url.hostname, + port: + config.getOptionalNumber('app.listen.port') ?? + Number(url.port) ?? + (url.protocol === 'https:' ? 443 : 80), + }; +} + async function readBuildInfo() { const timestamp = Date.now(); @@ -108,6 +124,20 @@ export async function createConfig( publicPath = `${publicPath}${publicSubPath}`.replace('//', '/'); } + if (isDev) { + const { host, port } = resolveEndpoint(options.frontendConfig); + + plugins.push( + new ReactRefreshPlugin({ + overlay: { + sockProtocol: 'ws', + sockHost: host, + sockPort: port, + }, + }), + ); + } + if (checksEnabled) { plugins.push( new ForkTsCheckerWebpackPlugin({ diff --git a/packages/cli/src/lib/bundler/server.ts b/packages/cli/src/lib/bundler/server.ts index cf35f65518..cbd76b4ead 100644 --- a/packages/cli/src/lib/bundler/server.ts +++ b/packages/cli/src/lib/bundler/server.ts @@ -30,7 +30,7 @@ import { import { paths as libPaths } from '../../lib/paths'; import { loadCliConfig } from '../config'; import { Lockfile } from '../versioning'; -import { createConfig, resolveBaseUrl } from './config'; +import { createConfig, resolveBaseUrl, resolveEndpoint } from './config'; import { createDetectedModulesEntryPoint } from './packageDetection'; import { resolveBundlingPaths, resolveOptionalBundlingPaths } from './paths'; import { ServeOptions } from './types'; @@ -131,13 +131,7 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be const { frontendConfig, fullConfig } = cliConfig; const url = resolveBaseUrl(frontendConfig); - - const host = - frontendConfig.getOptionalString('app.listen.host') || url.hostname; - const port = - frontendConfig.getOptionalNumber('app.listen.port') || - Number(url.port) || - (url.protocol === 'https:' ? 443 : 80); + const { host, port } = resolveEndpoint(frontendConfig); const detectedModulesEntryPoint = await createDetectedModulesEntryPoint({ config: fullConfig, @@ -257,7 +251,7 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be // When the dev server is behind a proxy, the host and public hostname differ allowedHosts: [url.hostname], client: { - webSocketURL: 'auto://0.0.0.0:0/ws', + webSocketURL: { hostname: host, port }, }, }, compiler, diff --git a/packages/cli/src/lib/bundler/transforms.ts b/packages/cli/src/lib/bundler/transforms.ts index da1eec4e11..0900b8e48e 100644 --- a/packages/cli/src/lib/bundler/transforms.ts +++ b/packages/cli/src/lib/bundler/transforms.ts @@ -17,7 +17,6 @@ import { ModuleOptions, WebpackPluginInstance } from 'webpack'; import MiniCssExtractPlugin from 'mini-css-extract-plugin'; import { svgrTemplate } from '../svgrTemplate'; -import ReactRefreshPlugin from '@pmmmwh/react-refresh-webpack-plugin'; type Transforms = { loaders: ModuleOptions['rules']; @@ -193,15 +192,7 @@ export const transforms = (options: TransformOptions): Transforms => { const plugins = new Array<WebpackPluginInstance>(); - if (isDev) { - if (!isBackend) { - plugins.push( - new ReactRefreshPlugin({ - overlay: { sockProtocol: 'ws' }, - }), - ); - } - } else { + if (!isDev) { plugins.push( new MiniCssExtractPlugin({ filename: 'static/[name].[contenthash:8].css', From be1ee471cf2b09d455256ad6edfa84031ca16489 Mon Sep 17 00:00:00 2001 From: MT Lewis <mtlewis@users.noreply.github.com> Date: Wed, 17 Jul 2024 18:18:20 +0100 Subject: [PATCH 346/510] cli: disable historyApiFallback for module federation remotes Module federation remotes only serve static assets, and aren't intended to be loaded directly in a browser. As such, the historyApiFallback isn't useful and should be disabled in this context. Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com> --- packages/cli/src/lib/bundler/server.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/cli/src/lib/bundler/server.ts b/packages/cli/src/lib/bundler/server.ts index cbd76b4ead..a3cbaeacc7 100644 --- a/packages/cli/src/lib/bundler/server.ts +++ b/packages/cli/src/lib/bundler/server.ts @@ -227,14 +227,17 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be directory: paths.targetPublic, } : undefined, - historyApiFallback: { - // Paths with dots should still use the history fallback. - // See https://github.com/facebookincubator/create-react-app/issues/387. - disableDotRule: true, + historyApiFallback: + options.moduleFederation?.mode === 'remote' + ? false + : { + // Paths with dots should still use the history fallback. + // See https://github.com/facebookincubator/create-react-app/issues/387. + disableDotRule: true, - // The index needs to be rewritten relative to the new public path, including subroutes. - index: `${config.output?.publicPath}index.html`, - }, + // The index needs to be rewritten relative to the new public path, including subroutes. + index: `${config.output?.publicPath}index.html`, + }, server: url.protocol === 'https:' ? { From f93ae496ce956598c56254d5420438be92faf0c0 Mon Sep 17 00:00:00 2001 From: MT Lewis <mtlewis@users.noreply.github.com> Date: Wed, 17 Jul 2024 18:19:32 +0100 Subject: [PATCH 347/510] cli: add CORS headers for webpack-dev-server content This allows loading static assets from dev-servers for dynamic plugin containers. Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com> --- packages/cli/src/lib/bundler/server.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/cli/src/lib/bundler/server.ts b/packages/cli/src/lib/bundler/server.ts index a3cbaeacc7..0421f4d019 100644 --- a/packages/cli/src/lib/bundler/server.ts +++ b/packages/cli/src/lib/bundler/server.ts @@ -256,6 +256,12 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be client: { webSocketURL: { hostname: host, port }, }, + headers: { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, OPTIONS', + 'Access-Control-Allow-Headers': + 'X-Requested-With, content-type, Authorization', + }, }, compiler, ); From e20fe546952f78e8f82faed76c03daf930d821ec Mon Sep 17 00:00:00 2001 From: Ramin G <rghara@outlook.com> Date: Fri, 19 Jul 2024 15:56:09 -0400 Subject: [PATCH 348/510] Corrected typo in logging-in.md Corrected typo in the description of the image Signed-off-by: Ramin G <rghara@outlook.com> --- docs/getting-started/logging-in.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/logging-in.md b/docs/getting-started/logging-in.md index 5386e98798..7d6fb5d55b 100644 --- a/docs/getting-started/logging-in.md +++ b/docs/getting-started/logging-in.md @@ -20,7 +20,7 @@ Run your Backstage app with `yarn dev`. Navigate to `http://localhost:3000`. If you're not already logged in, you should see a login screen like this, -![Screenshot of the the login screen](../assets/getting-started/login-screen.png) +![Screenshot of the login screen](../assets/getting-started/login-screen.png) To login, you should choose the "Github" provider and click the "Sign in" button. This will redirect you to a Github OAuth page. Verify that the scopes mentioned on that page match the setup you did in [the authentication tutorial](./config/authentication.md). Once you click "Confirm", you will be brought back to the Backstage interface and signed in! From c761199ce774a272e303f4493ba4a9c505ee5131 Mon Sep 17 00:00:00 2001 From: rghara <ramin.g01@infosys.com> Date: Fri, 19 Jul 2024 18:51:44 -0400 Subject: [PATCH 349/510] Replaced login screen image Signed-off-by: rghara <ramin.g01@infosys.com> --- docs/assets/getting-started/login-screen.png | Bin 108521 -> 53116 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/assets/getting-started/login-screen.png b/docs/assets/getting-started/login-screen.png index 70b56f399a22d19ad863f77db22739f67a352501..1af52cb2c9b0b95cac2b6e715077bf9095ec038c 100755 GIT binary patch literal 53116 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 literal 108521 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�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 From 24de0058e667c4512d9722f37f34a9df9df937e8 Mon Sep 17 00:00:00 2001 From: parmar-abhinav <abhinav.parmar@infosys.com> Date: Sat, 20 Jul 2024 12:56:27 +0530 Subject: [PATCH 350/510] Added test cases for publish:gitea examples Signed-off-by: parmar-abhinav <abhinav.parmar@infosys.com> --- .changeset/good-steaks-report.md | 5 + .../src/actions/gitea.examples.test.ts | 806 ++++++++++++++++++ .../src/actions/gitea.examples.ts | 2 +- 3 files changed, 812 insertions(+), 1 deletion(-) create mode 100644 .changeset/good-steaks-report.md create mode 100644 plugins/scaffolder-backend-module-gitea/src/actions/gitea.examples.test.ts diff --git a/.changeset/good-steaks-report.md b/.changeset/good-steaks-report.md new file mode 100644 index 0000000000..5f9ce25470 --- /dev/null +++ b/.changeset/good-steaks-report.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gitea': patch +--- + +Added test cases for publish:gitea examples diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.examples.test.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.examples.test.ts new file mode 100644 index 0000000000..5575921c34 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.examples.test.ts @@ -0,0 +1,806 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { ScmIntegrations } from '@backstage/integration'; +import { ConfigReader } from '@backstage/config'; +import { createPublishGiteaAction } from './gitea'; +import { + getRepoSourceDirectory, + initRepoAndPush, +} from '@backstage/plugin-scaffolder-node'; +import { rest } from 'msw'; +import { registerMswTestHooks } from '@backstage/backend-test-utils'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { setupServer } from 'msw/node'; +import { examples } from './gitea.examples'; +import yaml from 'yaml'; + +jest.mock('@backstage/plugin-scaffolder-node', () => { + return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), + initRepoAndPush: jest.fn().mockResolvedValue({ + commitHash: '431f19cc36b551763d157f1b5e4a4b446165dbn2', + }), + }; +}); + +describe('publish:gitea', () => { + const config = new ConfigReader({ + integrations: { + gitea: [ + { + host: 'gitea.com', + username: 'sample_user', + password: 'password_token', + }, + ], + }, + }); + + const description = 'gitea description'; + const integrations = ScmIntegrations.fromConfig(config); + const action = createPublishGiteaAction({ integrations, config }); + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitea.com?repo=repo&owner=owner', + description, + }, + }); + + const server = setupServer(); + registerMswTestHooks(server); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + it(`should ${examples[0].description}`, async () => { + server.use( + rest.get('https://gitea.com/api/v1/orgs/org1', (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + id: 1, + name: 'org1', + visibility: 'public', + repo_admin_change_team_access: false, + username: 'org1', + }), + ); + }), + rest.get( + 'https://gitea.com/org1/repo/src/branch/main', + (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }, + ), + rest.post('https://gitea.com/api/v1/orgs/org1/repos', (req, res, ctx) => { + // Basic auth must match the user and password defined part of the config + expect(req.headers.get('Authorization')).toBe( + 'basic c2FtcGxlX3VzZXI6cGFzc3dvcmRfdG9rZW4=', + ); + expect(req.body).toEqual({ + name: 'repo', + private: false, + description, + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }), + ); + + let input; + try { + input = yaml.parse(examples[0].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + repoUrl: 'gitea.com?repo=repo&owner=org1', + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + remoteUrl: 'https://gitea.com/org1/repo.git', + defaultBranch: 'main', + auth: { username: 'sample_user', password: 'password_token' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('initial commit\n\nChange-Id:'), + gitAuthorInfo: { + email: undefined, + name: undefined, + }, + }); + }); + + it(`should ${examples[1].description}`, async () => { + server.use( + rest.get('https://gitea.com/api/v1/orgs/org1', (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + id: 1, + name: 'org1', + visibility: 'public', + repo_admin_change_team_access: false, + username: 'org1', + }), + ); + }), + rest.get( + 'https://gitea.com/org1/repo/src/branch/main', + (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }, + ), + rest.post('https://gitea.com/api/v1/orgs/org1/repos', (req, res, ctx) => { + // Basic auth must match the user and password defined part of the config + expect(req.headers.get('Authorization')).toBe( + 'basic c2FtcGxlX3VzZXI6cGFzc3dvcmRfdG9rZW4=', + ); + expect(req.body).toEqual({ + name: 'repo', + private: false, + description: 'Initialize a gitea repository', + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }), + ); + + let input; + try { + input = yaml.parse(examples[1].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + repoUrl: 'gitea.com?repo=repo&owner=org1', + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + remoteUrl: 'https://gitea.com/org1/repo.git', + defaultBranch: 'main', + auth: { username: 'sample_user', password: 'password_token' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('initial commit\n\nChange-Id:'), + gitAuthorInfo: { + email: undefined, + name: undefined, + }, + }); + }); + + it(`should ${examples[2].description}`, async () => { + server.use( + rest.get('https://gitea.com/api/v1/orgs/org1', (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + id: 1, + name: 'org1', + visibility: 'public', + repo_admin_change_team_access: false, + username: 'org1', + }), + ); + }), + rest.get( + 'https://gitea.com/org1/repo/src/branch/main', + (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }, + ), + rest.post('https://gitea.com/api/v1/orgs/org1/repos', (req, res, ctx) => { + // Basic auth must match the user and password defined part of the config + expect(req.headers.get('Authorization')).toBe( + 'basic c2FtcGxlX3VzZXI6cGFzc3dvcmRfdG9rZW4=', + ); + expect(req.body).toEqual({ + name: 'repo', + private: true, + description, + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }), + ); + + let input; + try { + input = yaml.parse(examples[2].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + repoUrl: 'gitea.com?repo=repo&owner=org1', + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + remoteUrl: 'https://gitea.com/org1/repo.git', + defaultBranch: 'main', + auth: { username: 'sample_user', password: 'password_token' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('initial commit\n\nChange-Id:'), + gitAuthorInfo: { + email: undefined, + name: undefined, + }, + }); + }); + + it(`should ${examples[3].description}`, async () => { + server.use( + rest.get('https://gitea.com/api/v1/orgs/org1', (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + id: 1, + name: 'org1', + visibility: 'public', + repo_admin_change_team_access: false, + username: 'org1', + }), + ); + }), + rest.get( + 'https://gitea.com/org1/repo/src/branch/staging', + (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }, + ), + rest.post('https://gitea.com/api/v1/orgs/org1/repos', (req, res, ctx) => { + // Basic auth must match the user and password defined part of the config + expect(req.headers.get('Authorization')).toBe( + 'basic c2FtcGxlX3VzZXI6cGFzc3dvcmRfdG9rZW4=', + ); + expect(req.body).toEqual({ + name: 'repo', + private: false, + description, + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }), + ); + + let input; + try { + input = yaml.parse(examples[3].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + repoUrl: 'gitea.com?repo=repo&owner=org1', + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + remoteUrl: 'https://gitea.com/org1/repo.git', + defaultBranch: 'staging', + auth: { username: 'sample_user', password: 'password_token' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('initial commit\n\nChange-Id:'), + gitAuthorInfo: { + email: undefined, + name: undefined, + }, + }); + }); + + it(`should ${examples[4].description}`, async () => { + server.use( + rest.get('https://gitea.com/api/v1/orgs/org1', (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + id: 1, + name: 'org1', + visibility: 'public', + repo_admin_change_team_access: false, + username: 'org1', + }), + ); + }), + rest.get( + 'https://gitea.com/org1/repo/src/branch/main', + (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }, + ), + rest.post('https://gitea.com/api/v1/orgs/org1/repos', (req, res, ctx) => { + // Basic auth must match the user and password defined part of the config + expect(req.headers.get('Authorization')).toBe( + 'basic c2FtcGxlX3VzZXI6cGFzc3dvcmRfdG9rZW4=', + ); + expect(req.body).toEqual({ + name: 'repo', + private: false, + description, + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }), + ); + + let input; + try { + input = yaml.parse(examples[4].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + repoUrl: 'gitea.com?repo=repo&owner=org1', + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + remoteUrl: 'https://gitea.com/org1/repo.git', + defaultBranch: 'main', + auth: { username: 'sample_user', password: 'password_token' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining( + 'Initial Commit Message\n\nChange-Id:', + ), + gitAuthorInfo: { + email: undefined, + name: undefined, + }, + }); + }); + + it(`should ${examples[5].description}`, async () => { + server.use( + rest.get('https://gitea.com/api/v1/orgs/org1', (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + id: 1, + name: 'org1', + visibility: 'public', + repo_admin_change_team_access: false, + username: 'org1', + }), + ); + }), + rest.get( + 'https://gitea.com/org1/repo/src/branch/main', + (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }, + ), + rest.post('https://gitea.com/api/v1/orgs/org1/repos', (req, res, ctx) => { + // Basic auth must match the user and password defined part of the config + expect(req.headers.get('Authorization')).toBe( + 'basic c2FtcGxlX3VzZXI6cGFzc3dvcmRfdG9rZW4=', + ); + expect(req.body).toEqual({ + name: 'repo', + private: false, + description, + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }), + ); + + let input; + try { + input = yaml.parse(examples[5].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + repoUrl: 'gitea.com?repo=repo&owner=org1', + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + remoteUrl: 'https://gitea.com/org1/repo.git', + defaultBranch: 'main', + auth: { username: 'sample_user', password: 'password_token' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('initial commit\n\nChange-Id:'), + gitAuthorInfo: { + email: undefined, + name: 'John Doe', + }, + }); + }); + + it(`should ${examples[6].description}`, async () => { + server.use( + rest.get('https://gitea.com/api/v1/orgs/org1', (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + id: 1, + name: 'org1', + visibility: 'public', + repo_admin_change_team_access: false, + username: 'org1', + }), + ); + }), + rest.get( + 'https://gitea.com/org1/repo/src/branch/main', + (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }, + ), + rest.post('https://gitea.com/api/v1/orgs/org1/repos', (req, res, ctx) => { + // Basic auth must match the user and password defined part of the config + expect(req.headers.get('Authorization')).toBe( + 'basic c2FtcGxlX3VzZXI6cGFzc3dvcmRfdG9rZW4=', + ); + expect(req.body).toEqual({ + name: 'repo', + private: false, + description, + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }), + ); + + let input; + try { + input = yaml.parse(examples[6].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + repoUrl: 'gitea.com?repo=repo&owner=org1', + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + remoteUrl: 'https://gitea.com/org1/repo.git', + defaultBranch: 'main', + auth: { username: 'sample_user', password: 'password_token' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('initial commit\n\nChange-Id:'), + gitAuthorInfo: { + email: 'johndoe@email.com', + name: undefined, + }, + }); + }); + + it(`should ${examples[7].description}`, async () => { + server.use( + rest.get('https://gitea.com/api/v1/orgs/org1', (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + id: 1, + name: 'org1', + visibility: 'public', + repo_admin_change_team_access: false, + username: 'org1', + }), + ); + }), + rest.get( + 'https://gitea.com/org1/repo/src/branch/main', + (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }, + ), + rest.post('https://gitea.com/api/v1/orgs/org1/repos', (req, res, ctx) => { + // Basic auth must match the user and password defined part of the config + expect(req.headers.get('Authorization')).toBe( + 'basic c2FtcGxlX3VzZXI6cGFzc3dvcmRfdG9rZW4=', + ); + expect(req.body).toEqual({ + name: 'repo', + private: false, + description, + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }), + ); + + let input; + try { + input = yaml.parse(examples[7].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + repoUrl: 'gitea.com?repo=repo&owner=org1', + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: getRepoSourceDirectory(mockContext.workspacePath, 'repository/'), + remoteUrl: 'https://gitea.com/org1/repo.git', + defaultBranch: 'main', + auth: { username: 'sample_user', password: 'password_token' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('initial commit\n\nChange-Id:'), + gitAuthorInfo: { + email: undefined, + name: undefined, + }, + }); + }); + + it(`should ${examples[8].description}`, async () => { + server.use( + rest.get('https://gitea.com/api/v1/orgs/org1', (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + id: 1, + name: 'org1', + visibility: 'public', + repo_admin_change_team_access: false, + username: 'org1', + }), + ); + }), + rest.get( + 'https://gitea.com/org1/repo/src/branch/staging', + (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }, + ), + rest.post('https://gitea.com/api/v1/orgs/org1/repos', (req, res, ctx) => { + // Basic auth must match the user and password defined part of the config + expect(req.headers.get('Authorization')).toBe( + 'basic c2FtcGxlX3VzZXI6cGFzc3dvcmRfdG9rZW4=', + ); + expect(req.body).toEqual({ + name: 'repo', + private: false, + description: 'Initialize a gitea repository', + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }), + ); + + let input; + try { + input = yaml.parse(examples[8].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + repoUrl: 'gitea.com?repo=repo&owner=org1', + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: getRepoSourceDirectory(mockContext.workspacePath, 'repository/'), + remoteUrl: 'https://gitea.com/org1/repo.git', + defaultBranch: 'staging', + auth: { username: 'sample_user', password: 'password_token' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining( + 'Initial Commit Message\n\nChange-Id:', + ), + gitAuthorInfo: { + email: 'johndoe@email.com', + name: 'John Doe', + }, + }); + }); + + it(`should ${examples[0].description}`, async () => { + server.use( + rest.get('https://gitea.com/api/v1/orgs/org1', (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + id: 1, + name: 'org1', + visibility: 'public', + repo_admin_change_team_access: false, + username: 'org1', + }), + ); + }), + rest.get( + 'https://gitea.com/org1/repo/src/branch/main', + (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }, + ), + rest.post('https://gitea.com/api/v1/orgs/org1/repos', (req, res, ctx) => { + // Basic auth must match the user and password defined part of the config + expect(req.headers.get('Authorization')).toBe( + 'basic c2FtcGxlX3VzZXI6cGFzc3dvcmRfdG9rZW4=', + ); + expect(req.body).toEqual({ + name: 'repo', + private: false, + description, + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }), + ); + + let input; + try { + input = yaml.parse(examples[0].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + repoUrl: 'gitea.com?repo=repo&owner=org1', + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + remoteUrl: 'https://gitea.com/org1/repo.git', + defaultBranch: 'main', + auth: { username: 'sample_user', password: 'password_token' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('initial commit\n\nChange-Id:'), + gitAuthorInfo: { + email: undefined, + name: undefined, + }, + }); + }); + + afterEach(() => { + jest.resetAllMocks(); + }); +}); diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.examples.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.examples.ts index dd4d038ead..5cf640de87 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.examples.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.examples.ts @@ -78,7 +78,7 @@ export const examples: TemplateExample[] = [ name: 'Publish to Gitea', input: { repoUrl: 'gitea.com?repo=repo&owner=owner', - defaultBranch: 'main', + defaultBranch: 'staging', }, }, ], From aab708eb27b0a3809685d7d3e1057ac0f9ea8b54 Mon Sep 17 00:00:00 2001 From: parmar-abhinav <abhinav.parmar@infosys.com> Date: Sun, 21 Jul 2024 10:14:29 +0530 Subject: [PATCH 351/510] Added test cases for gitlab:issue:edit examples Signed-off-by: parmar-abhinav <abhinav.parmar@infosys.com> --- .changeset/plenty-tools-exist.md | 5 + .../actions/gitlabIssueEdit.examples.test.ts | 817 ++++++++++++++++++ .../src/actions/gitlabIssueEdit.examples.ts | 177 +++- 3 files changed, 997 insertions(+), 2 deletions(-) create mode 100644 .changeset/plenty-tools-exist.md create mode 100644 plugins/scaffolder-backend-module-gitlab/src/actions/gitlabIssueEdit.examples.test.ts diff --git a/.changeset/plenty-tools-exist.md b/.changeset/plenty-tools-exist.md new file mode 100644 index 0000000000..0ce22a74f2 --- /dev/null +++ b/.changeset/plenty-tools-exist.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gitlab': patch +--- + +Added test cases for gitlab:issue:edit examples diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabIssueEdit.examples.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabIssueEdit.examples.test.ts new file mode 100644 index 0000000000..7e50eac66c --- /dev/null +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabIssueEdit.examples.test.ts @@ -0,0 +1,817 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { ConfigReader } from '@backstage/core-app-api'; +import { ScmIntegrations } from '@backstage/integration'; +import { editGitlabIssueAction } from './gitlabIssueEdit'; +import { examples } from './gitlabIssueEdit.examples'; +import yaml from 'yaml'; + +const mockGitlabClient = { + Issues: { + edit: jest.fn(), + }, +}; +jest.mock('@gitbeaker/rest', () => ({ + Gitlab: class { + constructor() { + return mockGitlabClient; + } + }, +})); + +describe('gitlab:issue:edit', () => { + beforeEach(() => { + jest.clearAllMocks(); + jest.useFakeTimers({ + now: new Date(1999, 6, 14, 12, 0, 0), + }); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + const config = new ConfigReader({ + integrations: { + gitlab: [ + { + host: 'gitlab.com', + token: 'myIntegrationsToken', + apiBaseUrl: 'https://gitlab.com/api/v4', + }, + ], + }, + }); + const integrations = ScmIntegrations.fromConfig(config); + + const action = editGitlabIssueAction({ integrations }); + + it(`Should ${examples[0].description}`, async () => { + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 123, + issueIid: 42, + title: 'Computer banks to rule the world', + }, + workspacePath: 'seen2much', + }); + + mockGitlabClient.Issues.edit.mockResolvedValue({ + id: 123, + iid: 42, + web_url: 'https://gitlab.com/hangar18-/issues/42', + }); + + let input; + try { + input = yaml.parse(examples[0].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(mockGitlabClient.Issues.edit).toHaveBeenCalledWith(12, 42, { + title: input.title, + issueType: undefined, + addLabels: undefined, + removeLabels: undefined, + description: input.description, + assigneeIds: [], + confidential: false, + discussionLocked: false, + epicId: undefined, + labels: undefined, + updatedAt: new Date().toISOString(), + dueDate: undefined, + milestoneId: undefined, + weight: undefined, + stateEvent: undefined, + }); + + expect(mockContext.output).toHaveBeenCalledWith('issueId', 123); + expect(mockContext.output).toHaveBeenCalledWith('issueIid', 42); + expect(mockContext.output).toHaveBeenCalledWith( + 'issueUrl', + 'https://gitlab.com/hangar18-/issues/42', + ); + }); + + it(`Should ${examples[1].description}`, async () => { + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 123, + issueIid: 42, + title: 'Computer banks to rule the world', + }, + workspacePath: 'seen2much', + }); + + mockGitlabClient.Issues.edit.mockResolvedValue({ + id: 123, + iid: 42, + web_url: 'https://gitlab.com/hangar18-/issues/42', + }); + + let input; + try { + input = yaml.parse(examples[1].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(mockGitlabClient.Issues.edit).toHaveBeenCalledWith(12, 42, { + title: input.title, + issueType: undefined, + addLabels: undefined, + removeLabels: undefined, + description: input.description, + assigneeIds: [18], + confidential: false, + discussionLocked: false, + epicId: undefined, + labels: undefined, + updatedAt: '2024-05-10T18:00:00.000Z', + dueDate: '2024-09-28', + milestoneId: undefined, + weight: undefined, + stateEvent: undefined, + }); + + expect(mockContext.output).toHaveBeenCalledWith('issueId', 123); + expect(mockContext.output).toHaveBeenCalledWith('issueIid', 42); + expect(mockContext.output).toHaveBeenCalledWith( + 'issueUrl', + 'https://gitlab.com/hangar18-/issues/42', + ); + }); + + it(`Should ${examples[2].description}`, async () => { + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 123, + issueIid: 42, + title: 'Computer banks to rule the world', + }, + workspacePath: 'seen2much', + }); + + mockGitlabClient.Issues.edit.mockResolvedValue({ + id: 123, + iid: 42, + web_url: 'https://gitlab.com/hangar18-/issues/42', + }); + + let input; + try { + input = yaml.parse(examples[2].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + epicId: undefined, + }, + }); + + expect(mockGitlabClient.Issues.edit).toHaveBeenCalledWith(12, 42, { + title: input.title, + issueType: undefined, + addLabels: undefined, + removeLabels: undefined, + description: input.description, + assigneeIds: [18, 15], + confidential: false, + discussionLocked: true, + epicId: undefined, + labels: 'phase1:label1,phase2:label2', + updatedAt: '2024-05-10T18:00:00.000Z', + dueDate: '2024-09-28', + milestoneId: undefined, + weight: undefined, + stateEvent: undefined, + }); + + expect(mockContext.output).toHaveBeenCalledWith('issueId', 123); + expect(mockContext.output).toHaveBeenCalledWith('issueIid', 42); + expect(mockContext.output).toHaveBeenCalledWith( + 'issueUrl', + 'https://gitlab.com/hangar18-/issues/42', + ); + }); + + it(`Should ${examples[2].description}`, async () => { + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 123, + issueIid: 42, + title: 'Computer banks to rule the world', + }, + workspacePath: 'seen2much', + }); + + mockGitlabClient.Issues.edit.mockResolvedValue({ + id: 123, + iid: 42, + web_url: 'https://gitlab.com/hangar18-/issues/42', + }); + + let input; + try { + input = yaml.parse(examples[2].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + epicId: undefined, + }, + }); + + expect(mockGitlabClient.Issues.edit).toHaveBeenCalledWith(12, 42, { + title: input.title, + issueType: undefined, + addLabels: undefined, + removeLabels: undefined, + description: input.description, + assigneeIds: [18, 15], + confidential: false, + discussionLocked: true, + epicId: undefined, + labels: 'phase1:label1,phase2:label2', + updatedAt: '2024-05-10T18:00:00.000Z', + dueDate: '2024-09-28', + milestoneId: undefined, + weight: undefined, + stateEvent: undefined, + }); + + expect(mockContext.output).toHaveBeenCalledWith('issueId', 123); + expect(mockContext.output).toHaveBeenCalledWith('issueIid', 42); + expect(mockContext.output).toHaveBeenCalledWith( + 'issueUrl', + 'https://gitlab.com/hangar18-/issues/42', + ); + }); + + it(`Should ${examples[3].description}`, async () => { + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 123, + issueIid: 42, + title: 'Computer banks to rule the world', + }, + workspacePath: 'seen2much', + }); + + mockGitlabClient.Issues.edit.mockResolvedValue({ + id: 123, + iid: 42, + web_url: 'https://gitlab.com/hangar18-/issues/42', + }); + + let input; + try { + input = yaml.parse(examples[3].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(mockGitlabClient.Issues.edit).toHaveBeenCalledWith(12, 42, { + title: 'Computer banks to rule the world', + issueType: undefined, + addLabels: undefined, + removeLabels: undefined, + description: input.description, + assigneeIds: [], + confidential: false, + discussionLocked: false, + epicId: undefined, + labels: undefined, + updatedAt: new Date().toISOString(), + dueDate: undefined, + milestoneId: undefined, + weight: undefined, + stateEvent: 'close', + }); + + expect(mockContext.output).toHaveBeenCalledWith('issueId', 123); + expect(mockContext.output).toHaveBeenCalledWith('issueIid', 42); + expect(mockContext.output).toHaveBeenCalledWith( + 'issueUrl', + 'https://gitlab.com/hangar18-/issues/42', + ); + }); + + it(`Should ${examples[4].description}`, async () => { + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 123, + issueIid: 42, + title: 'Computer banks to rule the world', + }, + workspacePath: 'seen2much', + }); + + mockGitlabClient.Issues.edit.mockResolvedValue({ + id: 123, + iid: 42, + web_url: 'https://gitlab.com/hangar18-/issues/42', + }); + + let input; + try { + input = yaml.parse(examples[4].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(mockGitlabClient.Issues.edit).toHaveBeenCalledWith(12, 42, { + title: 'Computer banks to rule the world', + issueType: undefined, + addLabels: undefined, + removeLabels: undefined, + description: input.description, + assigneeIds: [], + confidential: false, + discussionLocked: false, + epicId: undefined, + labels: undefined, + updatedAt: new Date().toISOString(), + dueDate: undefined, + milestoneId: undefined, + weight: undefined, + stateEvent: 'reopen', + }); + + expect(mockContext.output).toHaveBeenCalledWith('issueId', 123); + expect(mockContext.output).toHaveBeenCalledWith('issueIid', 42); + expect(mockContext.output).toHaveBeenCalledWith( + 'issueUrl', + 'https://gitlab.com/hangar18-/issues/42', + ); + }); + + it(`Should ${examples[5].description}`, async () => { + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 123, + issueIid: 42, + title: 'Computer banks to rule the world', + }, + workspacePath: 'seen2much', + }); + + mockGitlabClient.Issues.edit.mockResolvedValue({ + id: 123, + iid: 42, + web_url: 'https://gitlab.com/hangar18-/issues/42', + }); + + let input; + try { + input = yaml.parse(examples[5].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(mockGitlabClient.Issues.edit).toHaveBeenCalledWith(12, 42, { + title: input.title, + issueType: undefined, + addLabels: undefined, + removeLabels: undefined, + description: input.description, + assigneeIds: [18, 20], + confidential: false, + discussionLocked: false, + epicId: undefined, + labels: undefined, + updatedAt: new Date().toISOString(), + dueDate: undefined, + milestoneId: input.milestoneId, + weight: undefined, + stateEvent: undefined, + }); + + expect(mockContext.output).toHaveBeenCalledWith('issueId', 123); + expect(mockContext.output).toHaveBeenCalledWith('issueIid', 42); + expect(mockContext.output).toHaveBeenCalledWith( + 'issueUrl', + 'https://gitlab.com/hangar18-/issues/42', + ); + }); + + it(`Should ${examples[6].description}`, async () => { + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 123, + issueIid: 42, + title: 'Computer banks to rule the world', + }, + workspacePath: 'seen2much', + }); + + mockGitlabClient.Issues.edit.mockResolvedValue({ + id: 123, + iid: 42, + web_url: 'https://gitlab.com/hangar18-/issues/42', + }); + + let input; + try { + input = yaml.parse(examples[6].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(mockGitlabClient.Issues.edit).toHaveBeenCalledWith(12, 42, { + title: input.title, + issueType: undefined, + addLabels: undefined, + removeLabels: undefined, + description: input.description, + assigneeIds: [], + confidential: false, + discussionLocked: false, + epicId: undefined, + labels: input.labels, + updatedAt: new Date().toISOString(), + dueDate: undefined, + milestoneId: input.milestoneId, + weight: input.weight, + stateEvent: undefined, + }); + + expect(mockContext.output).toHaveBeenCalledWith('issueId', 123); + expect(mockContext.output).toHaveBeenCalledWith('issueIid', 42); + expect(mockContext.output).toHaveBeenCalledWith( + 'issueUrl', + 'https://gitlab.com/hangar18-/issues/42', + ); + }); + + it(`Should ${examples[7].description}`, async () => { + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 123, + issueIid: 42, + title: 'Computer banks to rule the world', + }, + workspacePath: 'seen2much', + }); + + mockGitlabClient.Issues.edit.mockResolvedValue({ + id: 123, + iid: 42, + web_url: 'https://gitlab.com/hangar18-/issues/42', + }); + + let input; + try { + input = yaml.parse(examples[7].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(mockGitlabClient.Issues.edit).toHaveBeenCalledWith(12, 42, { + title: input.title, + issueType: undefined, + addLabels: undefined, + removeLabels: undefined, + description: input.description, + assigneeIds: [], + confidential: input.confidential, + discussionLocked: false, + epicId: undefined, + labels: input.labels, + updatedAt: new Date().toISOString(), + dueDate: undefined, + milestoneId: input.milestoneId, + weight: input.weight, + stateEvent: undefined, + }); + + expect(mockContext.output).toHaveBeenCalledWith('issueId', 123); + expect(mockContext.output).toHaveBeenCalledWith('issueIid', 42); + expect(mockContext.output).toHaveBeenCalledWith( + 'issueUrl', + 'https://gitlab.com/hangar18-/issues/42', + ); + }); + + it(`Should ${examples[8].description}`, async () => { + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 123, + issueIid: 42, + title: 'Computer banks to rule the world', + }, + workspacePath: 'seen2much', + }); + + mockGitlabClient.Issues.edit.mockResolvedValue({ + id: 123, + iid: 42, + web_url: 'https://gitlab.com/hangar18-/issues/42', + }); + + let input; + try { + input = yaml.parse(examples[8].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(mockGitlabClient.Issues.edit).toHaveBeenCalledWith(12, 42, { + title: input.title, + issueType: undefined, + addLabels: undefined, + removeLabels: undefined, + description: input.description, + assigneeIds: [], + confidential: false, + discussionLocked: input.discussionLocked, + epicId: undefined, + labels: input.labels, + updatedAt: new Date().toISOString(), + dueDate: undefined, + milestoneId: input.milestoneId, + weight: input.weight, + stateEvent: undefined, + }); + + expect(mockContext.output).toHaveBeenCalledWith('issueId', 123); + expect(mockContext.output).toHaveBeenCalledWith('issueIid', 42); + expect(mockContext.output).toHaveBeenCalledWith( + 'issueUrl', + 'https://gitlab.com/hangar18-/issues/42', + ); + }); + + it(`Should ${examples[9].description}`, async () => { + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 123, + issueIid: 42, + title: 'Computer banks to rule the world', + }, + workspacePath: 'seen2much', + }); + + mockGitlabClient.Issues.edit.mockResolvedValue({ + id: 123, + iid: 42, + web_url: 'https://gitlab.com/hangar18-/issues/42', + }); + + let input; + try { + input = yaml.parse(examples[9].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(mockGitlabClient.Issues.edit).toHaveBeenCalledWith(12, 42, { + title: input.title, + issueType: undefined, + addLabels: undefined, + removeLabels: input.removeLabels, + description: input.description, + assigneeIds: [], + confidential: false, + discussionLocked: false, + epicId: undefined, + labels: input.labels, + updatedAt: new Date().toISOString(), + dueDate: undefined, + milestoneId: input.milestoneId, + weight: input.weight, + stateEvent: undefined, + }); + + expect(mockContext.output).toHaveBeenCalledWith('issueId', 123); + expect(mockContext.output).toHaveBeenCalledWith('issueIid', 42); + expect(mockContext.output).toHaveBeenCalledWith( + 'issueUrl', + 'https://gitlab.com/hangar18-/issues/42', + ); + }); + it(`Should ${examples[10].description}`, async () => { + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 123, + issueIid: 42, + title: 'Computer banks to rule the world', + }, + workspacePath: 'seen2much', + }); + + mockGitlabClient.Issues.edit.mockResolvedValue({ + id: 123, + iid: 42, + web_url: 'https://gitlab.com/hangar18-/issues/42', + }); + + let input; + try { + input = yaml.parse(examples[10].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(mockGitlabClient.Issues.edit).toHaveBeenCalledWith(12, 42, { + title: input.title, + issueType: undefined, + addLabels: undefined, + removeLabels: input.removeLabels, + description: input.description, + assigneeIds: [], + confidential: false, + discussionLocked: false, + epicId: undefined, + labels: input.labels, + updatedAt: new Date().toISOString(), + dueDate: undefined, + milestoneId: input.milestoneId, + weight: input.weight, + stateEvent: undefined, + }); + + expect(mockContext.output).toHaveBeenCalledWith('issueId', 123); + expect(mockContext.output).toHaveBeenCalledWith('issueIid', 42); + expect(mockContext.output).toHaveBeenCalledWith( + 'issueUrl', + 'https://gitlab.com/hangar18-/issues/42', + ); + }); + it(`Should ${examples[11].description}`, async () => { + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 123, + issueIid: 42, + title: 'Computer banks to rule the world', + }, + workspacePath: 'seen2much', + }); + + mockGitlabClient.Issues.edit.mockResolvedValue({ + id: 123, + iid: 42, + web_url: 'https://gitlab.com/hangar18-/issues/42', + }); + + let input; + try { + input = yaml.parse(examples[11].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(mockGitlabClient.Issues.edit).toHaveBeenCalledWith(12, 42, { + title: input.title, + issueType: input.issueType, + addLabels: undefined, + removeLabels: input.removeLabels, + description: input.description, + assigneeIds: [], + confidential: false, + discussionLocked: false, + epicId: undefined, + labels: input.labels, + updatedAt: new Date().toISOString(), + dueDate: undefined, + milestoneId: input.milestoneId, + weight: input.weight, + stateEvent: undefined, + }); + + expect(mockContext.output).toHaveBeenCalledWith('issueId', 123); + expect(mockContext.output).toHaveBeenCalledWith('issueIid', 42); + expect(mockContext.output).toHaveBeenCalledWith( + 'issueUrl', + 'https://gitlab.com/hangar18-/issues/42', + ); + }); +}); diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabIssueEdit.examples.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabIssueEdit.examples.ts index 861c0736f0..8686a66250 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabIssueEdit.examples.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabIssueEdit.examples.ts @@ -50,7 +50,7 @@ export const examples: TemplateExample[] = [ title: 'Test Issue', assignees: [18], description: 'This is the edited description of the issue', - updatedAt: '2024-05-10 18:00:00.000', + updatedAt: '2024-05-10T18:00:00.000Z', dueDate: '2024-09-28', }, }, @@ -72,7 +72,7 @@ export const examples: TemplateExample[] = [ assignees: [18, 15], description: 'This is the description of the issue', confidential: false, - updatedAt: '2024-05-10 18:00:00.000', + updatedAt: '2024-05-10T18:00:00.000Z', dueDate: '2024-09-28', discussionLocked: true, epicId: 1, @@ -82,4 +82,177 @@ export const examples: TemplateExample[] = [ ], }), }, + { + description: 'Edit a gitlab issue to change its state to close', + example: yaml.stringify({ + steps: [ + { + id: 'gitlabIssue', + name: 'EditIssues', + action: 'gitlab:issue:edit', + input: { + ...commonGitlabConfigExample, + projectId: 12, + stateEvent: 'close', + }, + }, + ], + }), + }, + { + description: 'Edit a gitlab issue to change its state to reopened', + example: yaml.stringify({ + steps: [ + { + id: 'gitlabIssue', + name: 'EditIssues', + action: 'gitlab:issue:edit', + input: { + ...commonGitlabConfigExample, + projectId: 12, + stateEvent: 'reopen', + }, + }, + ], + }), + }, + { + description: + 'Edit a gitlab issue to assign it to multiple users and set milestone', + example: yaml.stringify({ + steps: [ + { + id: 'gitlabIssue', + name: 'EditIssues', + action: 'gitlab:issue:edit', + input: { + ...commonGitlabConfigExample, + projectId: 12, + title: 'Test issue with milestone', + assignees: [18, 20], + description: 'This issue has milestone set', + milestoneId: 5, + }, + }, + ], + }), + }, + { + description: 'Edit a gitlab issue to add weight and update labels', + example: yaml.stringify({ + steps: [ + { + id: 'gitlabIssue', + name: 'EditIssues', + action: 'gitlab:issue:edit', + input: { + ...commonGitlabConfigExample, + projectId: 12, + title: 'Issue with weight and labels', + description: 'This issue has weight and new labels', + weight: 3, + labels: 'bug,urgent', + }, + }, + ], + }), + }, + { + description: 'Edit a gitlab issue to make it confidential', + example: yaml.stringify({ + steps: [ + { + id: 'gitlabIssue', + name: 'EditIssues', + action: 'gitlab:issue:edit', + input: { + ...commonGitlabConfigExample, + projectId: 12, + title: 'Confidential Issue', + description: 'This issue is confidential', + confidential: true, + }, + }, + ], + }), + }, + { + description: 'Edit a gitlab issue to lock the discussion', + example: yaml.stringify({ + steps: [ + { + id: 'gitlabIssue', + name: 'EditIssues', + action: 'gitlab:issue:edit', + input: { + ...commonGitlabConfigExample, + projectId: 12, + title: 'Locked Discussion Issue', + description: 'This discussion on this issue is locked', + discussionLocked: true, + }, + }, + ], + }), + }, + { + description: 'Edit a gitlab issue to remove labels and update milestone', + example: yaml.stringify({ + steps: [ + { + id: 'gitlabIssue', + name: 'EditIssues', + action: 'gitlab:issue:edit', + input: { + ...commonGitlabConfigExample, + projectId: 12, + title: 'Issue with labels removed and milestone updated', + description: 'This issue has labels removed and milestone updated', + removeLabels: 'phase1:label1', + milestoneId: 6, + }, + }, + ], + }), + }, + { + description: 'Edit a gitlab issue to remove some labels and new ones', + example: yaml.stringify({ + steps: [ + { + id: 'gitlabIssue', + name: 'EditIssues', + action: 'gitlab:issue:edit', + input: { + ...commonGitlabConfigExample, + projectId: 12, + title: 'Issue with labels updated', + description: 'This issue has labels removed and new ones added', + removeLabels: 'bug,urgent', + labels: 'enhancement:documentation', + }, + }, + ], + }), + }, + { + description: 'Edit a gitlab issue to change issue type and add labels', + example: yaml.stringify({ + steps: [ + { + id: 'gitlabIssue', + name: 'EditIssues', + action: 'gitlab:issue:edit', + input: { + ...commonGitlabConfigExample, + projectId: 12, + title: 'Issue with type and labels', + description: 'This issue has been changes and new labels added', + labels: 'task,high-priority', + issueType: 'task', + }, + }, + ], + }), + }, ]; From 1ba4c2f6da8412660a236fa3588c4fa129cdf92e Mon Sep 17 00:00:00 2001 From: parmar-abhinav <abhinav.parmar@infosys.com> Date: Sun, 21 Jul 2024 10:59:49 +0530 Subject: [PATCH 352/510] Added test cases for gitlab:pipeline:trigger examples Signed-off-by: parmar-abhinav <abhinav.parmar@infosys.com> --- .changeset/strange-papayas-beg.md | 5 + .../gitlabPipelineTrigger.examples.test.ts | 320 ++++++++++++++++++ .../actions/gitlabPipelineTrigger.examples.ts | 63 ++++ 3 files changed, 388 insertions(+) create mode 100644 .changeset/strange-papayas-beg.md create mode 100644 plugins/scaffolder-backend-module-gitlab/src/actions/gitlabPipelineTrigger.examples.test.ts diff --git a/.changeset/strange-papayas-beg.md b/.changeset/strange-papayas-beg.md new file mode 100644 index 0000000000..6ce33fb029 --- /dev/null +++ b/.changeset/strange-papayas-beg.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gitlab': patch +--- + +Added test cases for gitlab:pipeline:trigger examples diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabPipelineTrigger.examples.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabPipelineTrigger.examples.test.ts new file mode 100644 index 0000000000..53cbfb0b87 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabPipelineTrigger.examples.test.ts @@ -0,0 +1,320 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ConfigReader } from '@backstage/core-app-api'; +import { ScmIntegrations } from '@backstage/integration'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { createTriggerGitlabPipelineAction } from './gitlabPipelineTrigger'; +import { examples } from './gitlabPipelineTrigger.examples'; +import yaml from 'yaml'; + +const mockGitlabClient = { + PipelineTriggerTokens: { + create: jest.fn(), + trigger: jest.fn(), + remove: jest.fn(), + }, +}; +jest.mock('@gitbeaker/rest', () => ({ + Gitlab: class { + constructor() { + return mockGitlabClient; + } + }, +})); + +describe('gitlab:pipeline:trigger', () => { + beforeEach(() => { + jest.resetModules(); + jest.clearAllMocks(); + jest.useFakeTimers({ + now: new Date(1988, 5, 3, 12, 0, 0), + }); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + const config = new ConfigReader({ + integrations: { + gitlab: [ + { + host: 'gitlab.com', + token: 'glpat-abcdef', + apiBaseUrl: 'https://gitlab.com/api/v4', + }, + ], + }, + }); + const integrations = ScmIntegrations.fromConfig(config); + + const action = createTriggerGitlabPipelineAction({ integrations }); + + it(`should ${examples[0].description}`, async () => { + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 123, + tokenDescription: 'Gitlab sample pipeline', + branch: 'main', + }, + workspacePath: 'repository', + }); + + mockGitlabClient.PipelineTriggerTokens.create.mockResolvedValue({ + id: 42, + description: 'Gitlab sample pipeline', + createdAt: new Date().toISOString(), + last_used: null, + token: 'abcdd-ghijkl', + updated_at: new Date().toISOString(), + owner: null, + }); + + mockGitlabClient.PipelineTriggerTokens.trigger.mockResolvedValue({ + id: 99, + web_url: 'https://gitlab.com/hangar18-/pipelines/99', + }); + + let input; + try { + input = yaml.parse(examples[0].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(mockGitlabClient.PipelineTriggerTokens.create).toHaveBeenCalledWith( + input.projectId, + input.tokenDescription, + ); + + expect(mockGitlabClient.PipelineTriggerTokens.trigger).toHaveBeenCalledWith( + input.projectId, + 'main', + 'abcdd-ghijkl', + { variables: input.variables }, + ); + + expect(mockGitlabClient.PipelineTriggerTokens.remove).toHaveBeenCalledWith( + input.projectId, + 42, + ); + + expect(mockContext.output).toHaveBeenCalledWith( + 'pipelineUrl', + 'https://gitlab.com/hangar18-/pipelines/99', + ); + }); + + it(`should ${examples[1].description}`, async () => { + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 123, + tokenDescription: 'Gitlab sample pipeline', + branch: 'main', + }, + workspacePath: 'repository', + }); + + mockGitlabClient.PipelineTriggerTokens.create.mockResolvedValue({ + id: 42, + description: 'Gitlab sample pipeline', + createdAt: new Date().toISOString(), + last_used: null, + token: 'abcdd-ghijkl', + updated_at: new Date().toISOString(), + owner: null, + }); + + mockGitlabClient.PipelineTriggerTokens.trigger.mockResolvedValue({ + id: 99, + web_url: 'https://gitlab.com/hangar18-/pipelines/99', + }); + + let input; + try { + input = yaml.parse(examples[1].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(mockGitlabClient.PipelineTriggerTokens.create).toHaveBeenCalledWith( + input.projectId, + input.tokenDescription, + ); + + expect(mockGitlabClient.PipelineTriggerTokens.trigger).toHaveBeenCalledWith( + input.projectId, + 'main', + 'abcdd-ghijkl', + { variables: input.variables }, + ); + + expect(mockGitlabClient.PipelineTriggerTokens.remove).toHaveBeenCalledWith( + input.projectId, + 42, + ); + + expect(mockContext.output).toHaveBeenCalledWith( + 'pipelineUrl', + 'https://gitlab.com/hangar18-/pipelines/99', + ); + }); + it(`should ${examples[2].description}`, async () => { + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 123, + tokenDescription: 'Gitlab sample pipeline', + branch: 'main', + }, + workspacePath: 'repository', + }); + + mockGitlabClient.PipelineTriggerTokens.create.mockResolvedValue({ + id: 42, + description: 'Gitlab sample pipeline', + createdAt: new Date().toISOString(), + last_used: null, + token: 'abcdd-ghijkl', + updated_at: new Date().toISOString(), + owner: null, + }); + + mockGitlabClient.PipelineTriggerTokens.trigger.mockResolvedValue({ + id: 99, + web_url: 'https://gitlab.com/hangar18-/pipelines/99', + }); + + let input; + try { + input = yaml.parse(examples[2].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(mockGitlabClient.PipelineTriggerTokens.create).toHaveBeenCalledWith( + input.projectId, + input.tokenDescription, + ); + + expect(mockGitlabClient.PipelineTriggerTokens.trigger).toHaveBeenCalledWith( + input.projectId, + 'main', + 'abcdd-ghijkl', + { variables: input.variables }, + ); + + expect(mockGitlabClient.PipelineTriggerTokens.remove).toHaveBeenCalledWith( + input.projectId, + 42, + ); + + expect(mockContext.output).toHaveBeenCalledWith( + 'pipelineUrl', + 'https://gitlab.com/hangar18-/pipelines/99', + ); + }); + it(`should ${examples[3].description}`, async () => { + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 123, + tokenDescription: 'Gitlab sample pipeline', + branch: 'main', + }, + workspacePath: 'repository', + }); + + mockGitlabClient.PipelineTriggerTokens.create.mockResolvedValue({ + id: 42, + description: 'Gitlab sample pipeline', + createdAt: new Date().toISOString(), + last_used: null, + token: 'abcdd-ghijkl', + updated_at: new Date().toISOString(), + owner: null, + }); + + mockGitlabClient.PipelineTriggerTokens.trigger.mockResolvedValue({ + id: 99, + web_url: 'https://gitlab.com/hangar18-/pipelines/99', + }); + + let input; + try { + input = yaml.parse(examples[3].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(mockGitlabClient.PipelineTriggerTokens.create).toHaveBeenCalledWith( + input.projectId, + input.tokenDescription, + ); + + expect(mockGitlabClient.PipelineTriggerTokens.trigger).toHaveBeenCalledWith( + input.projectId, + 'main', + 'abcdd-ghijkl', + { variables: input.variables }, + ); + + expect(mockGitlabClient.PipelineTriggerTokens.remove).toHaveBeenCalledWith( + input.projectId, + 42, + ); + + expect(mockContext.output).toHaveBeenCalledWith( + 'pipelineUrl', + 'https://gitlab.com/hangar18-/pipelines/99', + ); + }); +}); diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabPipelineTrigger.examples.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabPipelineTrigger.examples.ts index d0840030df..f213fcd83f 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabPipelineTrigger.examples.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabPipelineTrigger.examples.ts @@ -39,4 +39,67 @@ export const examples: TemplateExample[] = [ ], }), }, + { + description: 'Trigger a GitLab Project Pipeline with No Variables', + example: yaml.stringify({ + steps: [ + { + id: 'triggerPipeline', + name: 'Trigger Project Pipeline', + action: 'gitlab:pipeline:trigger', + input: { + ...commonGitlabConfigExample, + projectId: 12, + tokenDescription: + 'This is the text that will appear in the pipeline token', + token: 'glpt-xxxxxxxxxxxx', + branch: 'main', + variables: {}, + }, + }, + ], + }), + }, + { + description: 'Trigger a GitLab Project Pipeline with Single Variables', + example: yaml.stringify({ + steps: [ + { + id: 'triggerPipeline', + name: 'Trigger Project Pipeline', + action: 'gitlab:pipeline:trigger', + input: { + ...commonGitlabConfigExample, + projectId: 12, + tokenDescription: + 'This is the text that will appear in the pipeline token', + token: 'glpt-xxxxxxxxxxxx', + branch: 'main', + variables: { var_one: 'one' }, + }, + }, + ], + }), + }, + { + description: 'Trigger a GitLab Project Pipeline with Multiple Variables', + example: yaml.stringify({ + steps: [ + { + id: 'triggerPipeline', + name: 'Trigger Project Pipeline', + action: 'gitlab:pipeline:trigger', + input: { + ...commonGitlabConfigExample, + projectId: 12, + tokenDescription: + 'This is the text that will appear in the pipeline token', + token: 'glpt-xxxxxxxxxxxx', + branch: 'main', + variables: { var_one: 'one', var_two: 'two', var_three: 'three' }, + }, + }, + ], + }), + }, ]; From e53074fb0ec07d93025beefa783f52de2ce21b4c Mon Sep 17 00:00:00 2001 From: Stephen Glass <stephen@stephen.glass> Date: Sun, 21 Jul 2024 01:44:13 -0400 Subject: [PATCH 353/510] Update default backend plugin to use RootConfigService Signed-off-by: Stephen Glass <stephen@stephen.glass> --- .changeset/heavy-numbers-love.md | 5 +++++ .../cli/templates/default-backend-plugin/package.json.hbs | 1 - .../templates/default-backend-plugin/src/service/router.ts | 5 ++--- 3 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 .changeset/heavy-numbers-love.md diff --git a/.changeset/heavy-numbers-love.md b/.changeset/heavy-numbers-love.md new file mode 100644 index 0000000000..c18d144636 --- /dev/null +++ b/.changeset/heavy-numbers-love.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Updated default backend plugin to use `RootConfigService` instead of `Config`. This also removes the dependency on `@backstage/config` as it's no longer used. diff --git a/packages/cli/templates/default-backend-plugin/package.json.hbs b/packages/cli/templates/default-backend-plugin/package.json.hbs index 3b808fc5e5..8dd31cbc38 100644 --- a/packages/cli/templates/default-backend-plugin/package.json.hbs +++ b/packages/cli/templates/default-backend-plugin/package.json.hbs @@ -31,7 +31,6 @@ "@backstage/backend-common": "{{versionQuery '@backstage/backend-common'}}", "@backstage/backend-defaults": "{{versionQuery '@backstage/backend-defaults'}}", "@backstage/backend-plugin-api": "{{versionQuery '@backstage/backend-plugin-api'}}", - "@backstage/config": "{{versionQuery '@backstage/config'}}", "express": "{{versionQuery 'express' '4.17.1'}}", "express-promise-router": "{{versionQuery 'express-promise-router' '4.1.0'}}", "node-fetch": "{{versionQuery 'node-fetch' '2.6.7'}}" diff --git a/packages/cli/templates/default-backend-plugin/src/service/router.ts b/packages/cli/templates/default-backend-plugin/src/service/router.ts index 312d7e252e..ced654aa82 100644 --- a/packages/cli/templates/default-backend-plugin/src/service/router.ts +++ b/packages/cli/templates/default-backend-plugin/src/service/router.ts @@ -1,12 +1,11 @@ import { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter'; -import { LoggerService } from '@backstage/backend-plugin-api'; -import { Config } from '@backstage/config'; +import { LoggerService, RootConfigService } from '@backstage/backend-plugin-api'; import express from 'express'; import Router from 'express-promise-router'; export interface RouterOptions { logger: LoggerService; - config: Config; + config: RootConfigService; } export async function createRouter( From ef742dc56e889f254983cd1a0575c0880a104aa0 Mon Sep 17 00:00:00 2001 From: parmar-abhinav <abhinav.parmar@infosys.com> Date: Sun, 21 Jul 2024 12:29:54 +0530 Subject: [PATCH 354/510] Added test cases for gitlab:projectAccessToken:create example Signed-off-by: parmar-abhinav <abhinav.parmar@infosys.com> --- .changeset/six-rats-kick.md | 5 + ...bProjectAccessTokenCreate.examples.test.ts | 256 ++++++++++++++++++ ...gitlabProjectAccessTokenCreate.examples.ts | 158 +++++++++++ .../gitlabProjectAccessTokenCreate.test.ts | 221 +++++++++++++++ 4 files changed, 640 insertions(+) create mode 100644 .changeset/six-rats-kick.md create mode 100644 plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.test.ts diff --git a/.changeset/six-rats-kick.md b/.changeset/six-rats-kick.md new file mode 100644 index 0000000000..23958a2502 --- /dev/null +++ b/.changeset/six-rats-kick.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gitlab': patch +--- + +Added test cases for gitlab:projectAccessToken:create example diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.examples.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.examples.test.ts index 811926cc82..0762212809 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.examples.test.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.examples.test.ts @@ -51,6 +51,10 @@ describe('gitlab:projectAccessToken:create examples', () => { host: 'hosted.gitlab.com', apiBaseUrl: 'https://api.hosted.gitlab.com', }, + { + host: 'gitlab.example.com', + apiBaseUrl: 'https://api.gitlab.example.com', + }, ], }, }); @@ -192,4 +196,256 @@ describe('gitlab:projectAccessToken:create examples', () => { expect(mockContext.output).toHaveBeenCalledWith('access_token', 'TOKEN'); }); + + it(`should ${examples[5].description}`, async () => { + mockGitlabClient.ProjectAccessTokens.create.mockResolvedValue({ + token: 'personal-access-token', + username: 'gitlab-user', + }); + + const input = yaml.parse(examples[5].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(mockGitlabClient.ProjectAccessTokens.create).toHaveBeenCalledWith( + '456', + 'tokenname', + ['read_repository'], + { + accessLevel: 30, + expiresAt: '2025-07-21', + }, + ); + + expect(mockContext.output).toHaveBeenCalledWith( + 'access_token', + 'personal-access-token', + ); + }); + + it(`should ${examples[6].description}`, async () => { + mockGitlabClient.ProjectAccessTokens.create.mockResolvedValue({ + token: 'personal-access-token', + username: 'gitlab-user', + }); + + const input = yaml.parse(examples[6].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(mockGitlabClient.ProjectAccessTokens.create).toHaveBeenCalledWith( + '456', + 'full-access-token', + ['read_repository'], + { + accessLevel: 40, + expiresAt: '2024-12-31', + }, + ); + + expect(mockContext.output).toHaveBeenCalledWith( + 'access_token', + 'personal-access-token', + ); + }); + + it(`should ${examples[7].description}`, async () => { + mockGitlabClient.ProjectAccessTokens.create.mockResolvedValue({ + token: 'personal-access-token', + username: 'gitlab-user', + }); + + const input = yaml.parse(examples[7].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(mockGitlabClient.ProjectAccessTokens.create).toHaveBeenCalledWith( + '101112', + 'tokenname', + ['read_repository'], + { + accessLevel: 40, + expiresAt: '2025-07-21', + }, + ); + + expect(mockContext.output).toHaveBeenCalledWith( + 'access_token', + 'personal-access-token', + ); + }); + + it(`should ${examples[8].description}`, async () => { + mockGitlabClient.ProjectAccessTokens.create.mockResolvedValue({ + token: 'personal-access-token', + username: 'gitlab-user', + }); + + const input = yaml.parse(examples[8].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(mockGitlabClient.ProjectAccessTokens.create).toHaveBeenCalledWith( + '101112', + 'tokenname', + ['read_repository', 'read_api'], + { + accessLevel: 40, + expiresAt: '2025-07-21', + }, + ); + + expect(mockContext.output).toHaveBeenCalledWith( + 'access_token', + 'personal-access-token', + ); + }); + + it(`should ${examples[9].description}`, async () => { + mockGitlabClient.ProjectAccessTokens.create.mockResolvedValue({ + token: 'personal-access-token', + username: 'gitlab-user', + }); + + const input = yaml.parse(examples[9].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(mockGitlabClient.ProjectAccessTokens.create).toHaveBeenCalledWith( + '101112', + 'tokenname', + ['read_repository'], + { + accessLevel: 10, + expiresAt: '2025-07-21', + }, + ); + + expect(mockContext.output).toHaveBeenCalledWith( + 'access_token', + 'personal-access-token', + ); + }); + + it(`should ${examples[10].description}`, async () => { + mockGitlabClient.ProjectAccessTokens.create.mockResolvedValue({ + token: 'personal-access-token', + username: 'gitlab-user', + }); + + const input = yaml.parse(examples[10].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(mockGitlabClient.ProjectAccessTokens.create).toHaveBeenCalledWith( + '101112', + 'tokenname', + ['read_repository'], + { + accessLevel: 40, + expiresAt: '2025-07-21', + }, + ); + + expect(mockContext.output).toHaveBeenCalledWith( + 'access_token', + 'personal-access-token', + ); + }); + + it(`should ${examples[11].description}`, async () => { + mockGitlabClient.ProjectAccessTokens.create.mockResolvedValue({ + token: 'personal-access-token', + username: 'gitlab-user', + }); + + const input = yaml.parse(examples[11].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(mockGitlabClient.ProjectAccessTokens.create).toHaveBeenCalledWith( + '101112', + 'tokenname', + ['read_repository'], + { + accessLevel: 50, + expiresAt: '2025-07-21', + }, + ); + + expect(mockContext.output).toHaveBeenCalledWith( + 'access_token', + 'personal-access-token', + ); + }); + + it(`should ${examples[12].description}`, async () => { + mockGitlabClient.ProjectAccessTokens.create.mockResolvedValue({ + token: 'personal-access-token', + username: 'gitlab-user', + }); + + const input = yaml.parse(examples[12].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(mockGitlabClient.ProjectAccessTokens.create).toHaveBeenCalledWith( + '101112', + 'no-expiry-token', + ['read_repository'], + { + accessLevel: 40, + expiresAt: '2025-07-21', + }, + ); + + expect(mockContext.output).toHaveBeenCalledWith( + 'access_token', + 'personal-access-token', + ); + }); + + it(`should ${examples[13].description}`, async () => { + mockGitlabClient.ProjectAccessTokens.create.mockResolvedValue({ + token: 'personal-access-token', + username: 'gitlab-user', + }); + + const input = yaml.parse(examples[13].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(mockGitlabClient.ProjectAccessTokens.create).toHaveBeenCalledWith( + '101112', + 'tokenname', + ['read_repository'], + { + accessLevel: 40, + expiresAt: '2025-07-21', + }, + ); + + expect(mockContext.output).toHaveBeenCalledWith( + 'access_token', + 'personal-access-token', + ); + }); }); diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.examples.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.examples.ts index 8d4f335a46..89f8ae6269 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.examples.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.examples.ts @@ -102,4 +102,162 @@ export const examples: TemplateExample[] = [ ], }), }, + { + description: 'Create a GitLab project access token with an access level', + example: yaml.stringify({ + steps: [ + { + id: 'createAccessToken', + action: 'gitlab:projectAccessToken:create', + name: 'Create GitLab Project Access Token', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: '456', + accessLevel: 30, + }, + }, + ], + }), + }, + { + description: 'Create a GitLab project access token with multiple options', + example: yaml.stringify({ + steps: [ + { + id: 'createAccessToken', + action: 'gitlab:projectAccessToken:create', + name: 'Create GitLab Project Access Token', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: '456', + accessLevel: 40, + name: 'full-access-token', + expiresAt: '2024-12-31', + }, + }, + ], + }), + }, + { + description: + 'Create a GitLab project access token with a token for authorization', + example: yaml.stringify({ + steps: [ + { + id: 'createAccessToken', + action: 'gitlab:projectAccessToken:create', + name: 'Create GitLab Project Access Token', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: '101112', + token: 'personal-access-token', + }, + }, + ], + }), + }, + { + description: 'Create a GitLab project access token with read-only scopes', + example: yaml.stringify({ + steps: [ + { + id: 'createAccessToken', + action: 'gitlab:projectAccessToken:create', + name: 'Create GitLab Project Access Token', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: '101112', + scopes: ['read_repository', 'read_api'], + }, + }, + ], + }), + }, + { + description: 'Create a GitLab project access token with guest access level', + example: yaml.stringify({ + steps: [ + { + id: 'createAccessToken', + action: 'gitlab:projectAccessToken:create', + name: 'Create GitLab Project Access Token', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: '101112', + accessLevel: 10, + }, + }, + ], + }), + }, + { + description: + 'Create a GitLab project access token with maintainer access level', + example: yaml.stringify({ + steps: [ + { + id: 'createAccessToken', + action: 'gitlab:projectAccessToken:create', + name: 'Create GitLab Project Access Token', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: '101112', + accessLevel: 40, + }, + }, + ], + }), + }, + { + description: 'Create a GitLab project access token with owner access level', + example: yaml.stringify({ + steps: [ + { + id: 'createAccessToken', + action: 'gitlab:projectAccessToken:create', + name: 'Create GitLab Project Access Token', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: '101112', + accessLevel: 50, + }, + }, + ], + }), + }, + { + description: + 'Create a GitLab project access token with a specified name and no expiration date', + example: yaml.stringify({ + steps: [ + { + id: 'createAccessToken', + action: 'gitlab:projectAccessToken:create', + name: 'Create GitLab Project Access Token', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: '101112', + name: 'no-expiry-token', + }, + }, + ], + }), + }, + { + description: + 'Create a GitLab project access token for a specific gitlab instance', + example: yaml.stringify({ + steps: [ + { + id: 'createAccessToken', + action: 'gitlab:projectAccessToken:create', + name: 'Create GitLab Project Access Token', + input: { + repoUrl: 'gitlab.example.com?repo=repo&owner=owner', + projectId: '101112', + }, + }, + ], + }), + }, ]; diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.test.ts new file mode 100644 index 0000000000..34ce8878f2 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.test.ts @@ -0,0 +1,221 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { ConfigReader } from '@backstage/config'; +import { ScmIntegrations } from '@backstage/integration'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { createGitlabProjectAccessTokenAction } from './gitlabProjectAccessTokenCreate'; // Adjust the import based on your project structure + +import { DateTime } from 'luxon'; + +jest.mock('node-fetch'); + +const mockGitlabClient = { + ProjectAccessTokens: { + create: jest.fn(), + }, +}; + +jest.mock('@gitbeaker/rest', () => ({ + Gitlab: class { + constructor() { + return mockGitlabClient; + } + }, +})); + +describe('gitlab:projectAccessToken:create examples', () => { + const config = new ConfigReader({ + integrations: { + gitlab: [ + { + host: 'gitlab.com', + token: 'gitlab-token', + apiBaseUrl: 'https://api.gitlab.com', + }, + { + host: 'hosted.gitlab.com', + apiBaseUrl: 'https://api.hosted.gitlab.com', + }, + ], + }, + }); + + const integrations = ScmIntegrations.fromConfig(config); + const action = createGitlabProjectAccessTokenAction({ integrations }); + + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + }, + }); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + it('should create a GitLab project access token with minimal options.', async () => { + mockGitlabClient.ProjectAccessTokens.create.mockResolvedValue({ + token: 'gitlab-token', + username: 'gitlab-user', + }); + + await action.handler({ + ...mockContext, + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: '987', + }, + }); + + expect(mockGitlabClient.ProjectAccessTokens.create).toHaveBeenCalledWith( + '987', + 'tokenname', + ['read_repository'], + { + accessLevel: 40, + expiresAt: DateTime.now().plus({ days: 365 }).toISODate()!, + }, + ); + + expect(mockContext.output).toHaveBeenCalledWith( + 'access_token', + 'gitlab-token', + ); + }); + + it('should create a GitLab project access token with custom scopes.', async () => { + mockGitlabClient.ProjectAccessTokens.create.mockResolvedValue({ + token: 'gitlab-token', + username: 'gitlab-user', + }); + + await action.handler({ + ...mockContext, + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: '987', + scopes: ['read_registry', 'write_repository'], + }, + }); + + expect(mockGitlabClient.ProjectAccessTokens.create).toHaveBeenCalledWith( + '987', + 'tokenname', + ['read_registry', 'write_repository'], + { + accessLevel: 40, + expiresAt: DateTime.now().plus({ days: 365 }).toISODate()!, + }, + ); + + expect(mockContext.output).toHaveBeenCalledWith( + 'access_token', + 'gitlab-token', + ); + }); + + it('should create a GitLab project access token with a specified name.', async () => { + mockGitlabClient.ProjectAccessTokens.create.mockResolvedValue({ + token: 'gitlab-token', + username: 'gitlab-user', + }); + + await action.handler({ + ...mockContext, + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: '2110', + name: 'token', + }, + }); + + expect(mockGitlabClient.ProjectAccessTokens.create).toHaveBeenCalledWith( + '2110', + 'token', + ['read_repository'], + { + accessLevel: 40, + expiresAt: DateTime.now().plus({ days: 365 }).toISODate()!, + }, + ); + + expect(mockContext.output).toHaveBeenCalledWith( + 'access_token', + 'gitlab-token', + ); + }); + + it('should create a GitLab project access token with a numeric project ID.', async () => { + mockGitlabClient.ProjectAccessTokens.create.mockResolvedValue({ + token: 'gitlab-token', + username: 'gitlab-user', + }); + + await action.handler({ + ...mockContext, + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 23, + }, + }); + + expect(mockGitlabClient.ProjectAccessTokens.create).toHaveBeenCalledWith( + 23, + 'tokenname', + ['read_repository'], + { + accessLevel: 40, + expiresAt: DateTime.now().plus({ days: 365 }).toISODate()!, + }, + ); + + expect(mockContext.output).toHaveBeenCalledWith( + 'access_token', + 'gitlab-token', + ); + }); + + it('should create a GitLab project access token with a specified expired Date.', async () => { + mockGitlabClient.ProjectAccessTokens.create.mockResolvedValue({ + token: 'gitlab-token', + username: 'gitlab-user', + }); + + await action.handler({ + ...mockContext, + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: '123', + expiresAt: '1999-07-14', + }, + }); + + expect(mockGitlabClient.ProjectAccessTokens.create).toHaveBeenCalledWith( + '123', + 'tokenname', + ['read_repository'], + { + accessLevel: 40, + expiresAt: '1999-07-14', + }, + ); + + expect(mockContext.output).toHaveBeenCalledWith( + 'access_token', + 'gitlab-token', + ); + }); +}); From fba7537ad1fd83d9578d71ea546b36b3cf1be9f3 Mon Sep 17 00:00:00 2001 From: Jordan Slott <jordan.slott@twosigma.com> Date: Sun, 21 Jul 2024 15:31:35 -0400 Subject: [PATCH 355/510] Fixes #25709 Memoize filtered entity graph nodes Signed-off-by: Jordan Slott <jordan.slott@twosigma.com> --- .changeset/light-pianos-exercise.md | 5 +++++ .../EntityRelationsGraph/useEntityRelationGraph.ts | 12 ++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 .changeset/light-pianos-exercise.md diff --git a/.changeset/light-pianos-exercise.md b/.changeset/light-pianos-exercise.md new file mode 100644 index 0000000000..4bf161eb06 --- /dev/null +++ b/.changeset/light-pianos-exercise.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-graph': patch +--- + +Memoize entity graph nodes when applying an `entityFilter` to prevent repeated redraws diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/useEntityRelationGraph.ts b/plugins/catalog-graph/src/components/EntityRelationsGraph/useEntityRelationGraph.ts index af2a491ada..07e3085f1f 100644 --- a/plugins/catalog-graph/src/components/EntityRelationsGraph/useEntityRelationGraph.ts +++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/useEntityRelationGraph.ts @@ -14,7 +14,7 @@ * limitations under the License. */ import { Entity } from '@backstage/catalog-model'; -import { useEffect } from 'react'; +import { useEffect, useMemo } from 'react'; import { useEntityStore } from './useEntityStore'; import { pickBy } from 'lodash'; @@ -104,9 +104,13 @@ export function useEntityRelationGraph({ requestEntities, ]); - const filteredEntities = entityFilter - ? pickBy(entities, (value, _key) => entityFilter(value)) - : entities; + const filteredEntities = useMemo( + () => + entityFilter + ? pickBy(entities, (value, _key) => entityFilter(value)) + : entities, + [entities, entityFilter], + ); return { entities: filteredEntities, From 4e79d199ccb03c1b57dd4b889b83c058b13fd399 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Wed, 17 Jul 2024 19:59:42 +0200 Subject: [PATCH 356/510] backend-defaults,test-utils: use, export, and test health service Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/gentle-dryers-smile.md | 5 ++ .changeset/soft-gorillas-refuse.md | 5 ++ .../api-report-rootHttpRouter.md | 8 ++ .../rootHttpRouter/createHealthRouter.ts | 6 +- .../src/entrypoints/rootHttpRouter/index.ts | 1 + .../rootHttpRouterServiceFactory.test.ts | 74 +++++++++++++++++++ .../src/next/wiring/TestBackend.test.ts | 9 +++ .../src/next/wiring/TestBackend.ts | 7 +- 8 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 .changeset/gentle-dryers-smile.md create mode 100644 .changeset/soft-gorillas-refuse.md create mode 100644 packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.test.ts diff --git a/.changeset/gentle-dryers-smile.md b/.changeset/gentle-dryers-smile.md new file mode 100644 index 0000000000..b061461da1 --- /dev/null +++ b/.changeset/gentle-dryers-smile.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': patch +--- + +The `createHealthRouter` utility that allows you to create a health check router is now exported via `@backstage/backend-defaults/rootHttpRouter`. diff --git a/.changeset/soft-gorillas-refuse.md b/.changeset/soft-gorillas-refuse.md new file mode 100644 index 0000000000..323c4d20d2 --- /dev/null +++ b/.changeset/soft-gorillas-refuse.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-test-utils': patch +--- + +The default services for `startTestBackend` and `ServiceFactoryTester` now includes the Root Health Service. diff --git a/packages/backend-defaults/api-report-rootHttpRouter.md b/packages/backend-defaults/api-report-rootHttpRouter.md index 329398a7b8..36f3aa3ab6 100644 --- a/packages/backend-defaults/api-report-rootHttpRouter.md +++ b/packages/backend-defaults/api-report-rootHttpRouter.md @@ -3,6 +3,7 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +/// <reference types="express" /> /// <reference types="node" /> import { Config } from '@backstage/config'; @@ -17,10 +18,17 @@ import { LoggerService } from '@backstage/backend-plugin-api'; import { RequestHandler } from 'express'; import { RequestListener } from 'http'; import { RootConfigService } from '@backstage/backend-plugin-api'; +import { RootHealthService } from '@backstage/backend-plugin-api'; import { RootHttpRouterService } from '@backstage/backend-plugin-api'; +import { Router } from 'express'; import type { Server } from 'node:http'; import { ServiceFactory } from '@backstage/backend-plugin-api'; +// @public (undocumented) +export function createHealthRouter(options: { + health: RootHealthService; +}): Router; + // @public export function createHttpServer( listener: RequestListener, diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/createHealthRouter.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/createHealthRouter.ts index 007d1dd9cd..3772ab0fab 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/createHealthRouter.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/createHealthRouter.ts @@ -1,5 +1,3 @@ -import { RootHealthService } from '@backstage/backend-plugin-api'; - /* * Copyright 2024 The Backstage Authors * @@ -16,9 +14,13 @@ import { RootHealthService } from '@backstage/backend-plugin-api'; * limitations under the License. */ +import { RootHealthService } from '@backstage/backend-plugin-api'; import Router from 'express-promise-router'; import { Request, Response } from 'express'; +/** + * @public + */ export function createHealthRouter(options: { health: RootHealthService }) { const router = Router(); diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/index.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/index.ts index 9c2d96dab2..e9aee8a0e0 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/index.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/index.ts @@ -18,6 +18,7 @@ export { DefaultRootHttpRouter, type DefaultRootHttpRouterOptions, } from './DefaultRootHttpRouter'; +export { createHealthRouter } from './createHealthRouter'; export * from './http'; export { rootHttpRouterServiceFactory, diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.test.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.test.ts new file mode 100644 index 0000000000..dea0159dff --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.test.ts @@ -0,0 +1,74 @@ +/* + * 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 { + ServiceFactoryTester, + mockServices, +} from '@backstage/backend-test-utils'; +import { Express } from 'express'; +import request from 'supertest'; +import { rootHttpRouterServiceFactory } from './rootHttpRouterServiceFactory'; +import { coreServices } from '@backstage/backend-plugin-api'; + +describe('rootHttpRouterServiceFactory', () => { + it('should make the health endpoints available', async () => { + let app: Express | undefined = undefined; + + const tester = ServiceFactoryTester.from( + rootHttpRouterServiceFactory({ + configure(options) { + options.applyDefaults(); + app = options.app; + }, + }), + { + dependencies: [ + mockServices.rootConfig.factory({ + data: { + app: { baseUrl: 'http://localhost' }, + backend: { + baseUrl: 'http://localhost', + listen: { host: '', port: 0 }, + }, + }, + }), + ], + }, + ); + + // Trigger creation of the http service, accessing the app instance through the configure callback + await tester.getSubject(); + + await request(app!) + .get('/.backstage/health/v1/liveness') + .expect(200, { status: 'ok' }); + + await request(app!).get('/.backstage/health/v1/readiness').expect(503, { + message: 'Backend has not started yet', + status: 'error', + }); + + const lifecycle = await tester.getService(coreServices.rootLifecycle); + + await (lifecycle as any).startup(); // Trigger startup by calling the private startup method + + await request(app!).get('/.backstage/health/v1/readiness').expect(200, { + status: 'ok', + }); + + expect('test').toBe('test'); + }); +}); diff --git a/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts b/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts index ecba34290d..a01d4bebf5 100644 --- a/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts +++ b/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts @@ -242,6 +242,15 @@ describe('TestBackend', () => { expect(res.body).toEqual({ message: 'pong' }); }); + it('should expose health check endpoints', async () => { + const { server } = await startTestBackend({ features: [] }); + + const res = await request(server).get('/.backstage/health/v1/liveness'); + + expect(res.status).toEqual(200); + expect(res.body).toEqual({ status: 'ok' }); + }); + it('should provide extension point implementations', async () => { expect.assertions(3); diff --git a/packages/backend-test-utils/src/next/wiring/TestBackend.ts b/packages/backend-test-utils/src/next/wiring/TestBackend.ts index 16ee6b78d2..3d662a8c12 100644 --- a/packages/backend-test-utils/src/next/wiring/TestBackend.ts +++ b/packages/backend-test-utils/src/next/wiring/TestBackend.ts @@ -37,6 +37,7 @@ import express from 'express'; // Direct internal import to avoid duplication // eslint-disable-next-line @backstage/no-forbidden-package-imports import { InternalBackendFeature } from '@backstage/backend-plugin-api/src/wiring/types'; +import { createHealthRouter } from '@backstage/backend-defaults/rootHttpRouter'; /** @public */ export interface TestBackendOptions<TExtensionPoints extends any[]> { @@ -73,6 +74,7 @@ export const defaultServiceFactories = [ mockServices.lifecycle.factory(), mockServices.logger.factory(), mockServices.permissions.factory(), + mockServices.rootHealth.factory(), mockServices.rootLifecycle.factory(), mockServices.rootLogger.factory(), mockServices.scheduler.factory(), @@ -251,15 +253,18 @@ export async function startTestBackend<TExtensionPoints extends any[]>( config: coreServices.rootConfig, lifecycle: coreServices.rootLifecycle, rootLogger: coreServices.rootLogger, + health: coreServices.rootHealth, }, - async factory({ config, lifecycle, rootLogger }) { + async factory({ config, lifecycle, rootLogger, health }) { const router = DefaultRootHttpRouter.create(); const logger = rootLogger.child({ service: 'rootHttpRouter' }); const app = express(); const middleware = MiddlewareFactory.create({ config, logger }); + const healthRouter = createHealthRouter({ health }); + app.use(healthRouter); app.use(router.handler()); app.use(middleware.notFound()); app.use(middleware.error()); From 31bfc4417f7a4d04d5899ce1d638505c30f9f627 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Sat, 20 Jul 2024 12:47:09 +0200 Subject: [PATCH 357/510] frontend-plugin-api: update extension data ref declaration to allow embedding of ID in type Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/dull-ghosts-double.md | 7 ++ .changeset/tiny-oranges-pretend.md | 19 ++++++ .../architecture/03-extensions.md | 4 +- .../architecture/08-naming-patterns.md | 20 +++--- .../src/tree/instantiateAppNodeTree.test.ts | 8 ++- packages/frontend-plugin-api/api-report.md | 52 +++++++++++--- .../src/extensions/createApiExtension.ts | 5 +- .../createAppRootWrapperExtension.tsx | 7 +- .../extensions/createComponentExtension.tsx | 2 +- .../src/extensions/createNavItemExtension.tsx | 2 +- .../src/extensions/createNavLogoExtension.tsx | 2 +- .../src/extensions/createRouterExtension.tsx | 7 +- .../extensions/createSignInPageExtension.tsx | 2 +- .../src/extensions/createThemeExtension.ts | 5 +- .../extensions/createTranslationExtension.ts | 2 +- .../src/wiring/coreExtensionData.ts | 8 ++- .../src/wiring/createExtension.test.ts | 2 +- .../src/wiring/createExtension.ts | 2 +- .../src/wiring/createExtensionDataRef.test.ts | 9 +++ .../src/wiring/createExtensionDataRef.ts | 68 +++++++++++++------ .../src/wiring/createPlugin.test.ts | 4 +- plugins/catalog-react/api-report-alpha.md | 13 +++- plugins/catalog-react/src/alpha.tsx | 18 ++--- plugins/home/api-report-alpha.md | 6 +- plugins/home/src/alpha.tsx | 4 +- plugins/search-react/api-report-alpha.md | 1 + plugins/search-react/src/alpha.tsx | 2 +- 27 files changed, 204 insertions(+), 77 deletions(-) create mode 100644 .changeset/dull-ghosts-double.md create mode 100644 .changeset/tiny-oranges-pretend.md diff --git a/.changeset/dull-ghosts-double.md b/.changeset/dull-ghosts-double.md new file mode 100644 index 0000000000..0bc5a09791 --- /dev/null +++ b/.changeset/dull-ghosts-double.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-catalog-react': patch +'@backstage/plugin-search-react': patch +'@backstage/plugin-home': patch +--- + +Updated alpha definitions of extension data references. diff --git a/.changeset/tiny-oranges-pretend.md b/.changeset/tiny-oranges-pretend.md new file mode 100644 index 0000000000..87227fb962 --- /dev/null +++ b/.changeset/tiny-oranges-pretend.md @@ -0,0 +1,19 @@ +--- +'@backstage/frontend-plugin-api': patch +--- + +Extension data references can now be defined in a way that encapsulates the ID string in the type, in addition to the data type itself. The old way of creating extension data references is deprecated and will be removed in a future release. + +For example, the following code: + +```ts +export const myExtension = createExtensionDataRef<MyType>('my-plugin.my-data'); +``` + +Should be updated to the following: + +```ts +export const myExtension = createExtensionDataRef<MyType>().with({ + id: 'my-plugin.my-data', +}); +``` diff --git a/docs/frontend-system/architecture/03-extensions.md b/docs/frontend-system/architecture/03-extensions.md index cdc73a17ec..2f3daba6f8 100644 --- a/docs/frontend-system/architecture/03-extensions.md +++ b/docs/frontend-system/architecture/03-extensions.md @@ -91,7 +91,9 @@ To create a new extension data reference to represent a type of shared extension ```ts export const reactElementExtensionDataRef = - createExtensionDataRef<React.JSX.Element>('my-plugin.reactElement'); + createExtensionDataRef<React.JSX.Element>().with({ + id: 'my-plugin.reactElement', + }); ``` The `ExtensionDataRef` can then be used to describe an output property of the extension. This will enforce typing on the return value of the extension factory: diff --git a/docs/frontend-system/architecture/08-naming-patterns.md b/docs/frontend-system/architecture/08-naming-patterns.md index a17525f3ce..f031b80d84 100644 --- a/docs/frontend-system/architecture/08-naming-patterns.md +++ b/docs/frontend-system/architecture/08-naming-patterns.md @@ -98,9 +98,9 @@ export interface SearchResultItemExtensionData { } export const searchResultItemExtensionDataRef = - createExtensionDataRef<SearchResultItemExtensionData>( - 'search.search-result-item', - ); + createExtensionDataRef<SearchResultItemExtensionData>().with({ + id: 'search.search-result-item', + }); ``` #### Grouped Extension Data @@ -109,8 +109,12 @@ This way of defining extension data is similar to the standalone way, but it use ```ts export const coreExtensionData = { - reactElement: createExtensionDataRef<ReactElement>('core.react-element'), - routePath: createExtensionDataRef<string>('core.route-path'), + reactElement: createExtensionDataRef<ReactElement>().with({ + id: 'core.react-element', + }), + routePath: createExtensionDataRef<string>().with({ + id: 'core.route-path', + }), }; ``` @@ -125,9 +129,9 @@ 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', - ); + export const endpointDataRef = createExtensionDataRef</* ... */>().with({ + id: 'graphiql.graphiql-endpoint.endpoint', + }); } ``` diff --git a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts index 3330b9add8..c5c66e8319 100644 --- a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts +++ b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts @@ -32,9 +32,11 @@ import { resolveAppTree } from './resolveAppTree'; import { resolveExtensionDefinition } from '../../../frontend-plugin-api/src/wiring/resolveExtensionDefinition'; import { withLogCollector } from '@backstage/test-utils'; -const testDataRef = createExtensionDataRef<string>('test'); -const otherDataRef = createExtensionDataRef<number>('other'); -const inputMirrorDataRef = createExtensionDataRef<unknown>('mirror'); +const testDataRef = createExtensionDataRef<string>().with({ id: 'test' }); +const otherDataRef = createExtensionDataRef<number>().with({ id: 'other' }); +const inputMirrorDataRef = createExtensionDataRef<unknown>().with({ + id: 'mirror', +}); const simpleExtension = resolveExtensionDefinition( createExtension({ diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index 29c165aaaa..65445b5c4d 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -151,6 +151,7 @@ export { AnyApiRef }; export type AnyExtensionDataMap = { [name in string]: ExtensionDataRef< unknown, + string, { optional?: true; } @@ -317,13 +318,15 @@ export { configApiRef }; // @public (undocumented) export interface ConfigurableExtensionDataRef< + TId extends string, TData, TConfig extends { optional?: true; } = {}, -> extends ExtensionDataRef<TData, TConfig> { +> extends ExtensionDataRef<TData, TId, TConfig> { // (undocumented) optional(): ConfigurableExtensionDataRef< + TId, TData, TData & { optional: true; @@ -347,9 +350,17 @@ export type CoreErrorBoundaryFallbackProps = { // @public (undocumented) export const coreExtensionData: { - reactElement: ConfigurableExtensionDataRef<JSX_2.Element, {}>; - routePath: ConfigurableExtensionDataRef<string, {}>; - routeRef: ConfigurableExtensionDataRef<RouteRef<AnyRouteRefParams>, {}>; + reactElement: ConfigurableExtensionDataRef< + 'core.reactElement', + JSX_2.Element, + {} + >; + routePath: ConfigurableExtensionDataRef<'core.routing.path', string, {}>; + routeRef: ConfigurableExtensionDataRef< + 'core.routing.ref', + RouteRef<AnyRouteRefParams>, + {} + >; }; // @public (undocumented) @@ -385,7 +396,11 @@ export function createApiExtension< // @public (undocumented) export namespace createApiExtension { const // (undocumented) - factoryDataRef: ConfigurableExtensionDataRef<AnyApiFactory, {}>; + factoryDataRef: ConfigurableExtensionDataRef< + 'core.api.factory', + AnyApiFactory, + {} + >; } export { createApiFactory }; @@ -440,6 +455,7 @@ export function createAppRootWrapperExtension< export namespace createAppRootWrapperExtension { const // (undocumented) componentDataRef: ConfigurableExtensionDataRef< + 'app.root.wrapper', React_2.ComponentType<{ children?: React_2.ReactNode; }>, @@ -477,6 +493,7 @@ export function createComponentExtension< export namespace createComponentExtension { const // (undocumented) componentDataRef: ConfigurableExtensionDataRef< + 'core.component.component', { ref: ComponentRef; impl: ComponentType; @@ -544,10 +561,17 @@ export interface CreateExtensionBlueprintOptions< output: TOutput; } -// @public (undocumented) +// @public @deprecated (undocumented) export function createExtensionDataRef<TData>( id: string, -): ConfigurableExtensionDataRef<TData>; +): ConfigurableExtensionDataRef<string, TData>; + +// @public (undocumented) +export function createExtensionDataRef<TData>(): { + with<TId extends string>(options: { + id: TId; + }): ConfigurableExtensionDataRef<TId, TData>; +}; // @public (undocumented) export function createExtensionInput< @@ -646,6 +670,7 @@ export function createNavItemExtension(options: { export namespace createNavItemExtension { const // (undocumented) targetDataRef: ConfigurableExtensionDataRef< + 'core.nav-item.target', { title: string; icon: IconComponent_2; @@ -667,6 +692,7 @@ export function createNavLogoExtension(options: { export namespace createNavLogoExtension { const // (undocumented) logoElementsDataRef: ConfigurableExtensionDataRef< + 'core.nav-logo.logo-elements', { logoIcon?: JSX.Element | undefined; logoFull?: JSX.Element | undefined; @@ -760,6 +786,7 @@ export function createRouterExtension< export namespace createRouterExtension { const // (undocumented) componentDataRef: ConfigurableExtensionDataRef< + 'app.router.wrapper', React_2.ComponentType<{ children?: React_2.ReactNode; }>, @@ -796,6 +823,7 @@ export function createSignInPageExtension< export namespace createSignInPageExtension { const // (undocumented) componentDataRef: ConfigurableExtensionDataRef< + 'core.sign-in-page.component', React_2.ComponentType<SignInPageProps>, {} >; @@ -818,7 +846,11 @@ export function createThemeExtension( // @public (undocumented) export namespace createThemeExtension { const // (undocumented) - themeDataRef: ConfigurableExtensionDataRef<AppTheme, {}>; + themeDataRef: ConfigurableExtensionDataRef< + 'core.theme.theme', + AppTheme, + {} + >; } // @public (undocumented) @@ -831,6 +863,7 @@ export function createTranslationExtension(options: { export namespace createTranslationExtension { const // (undocumented) translationDataRef: ConfigurableExtensionDataRef< + 'core.translation.translation', | TranslationResource<string> | TranslationMessages< string, @@ -934,11 +967,12 @@ export interface ExtensionBoundaryProps { // @public (undocumented) export type ExtensionDataRef< TData, + TId extends string = string, TConfig extends { optional?: true; } = {}, > = { - id: string; + id: TId; T: TData; config: TConfig; $$type: '@backstage/ExtensionDataRef'; diff --git a/packages/frontend-plugin-api/src/extensions/createApiExtension.ts b/packages/frontend-plugin-api/src/extensions/createApiExtension.ts index 1680332960..93346f1ec9 100644 --- a/packages/frontend-plugin-api/src/extensions/createApiExtension.ts +++ b/packages/frontend-plugin-api/src/extensions/createApiExtension.ts @@ -72,6 +72,7 @@ export function createApiExtension< /** @public */ export namespace createApiExtension { - export const factoryDataRef = - createExtensionDataRef<AnyApiFactory>('core.api.factory'); + export const factoryDataRef = createExtensionDataRef<AnyApiFactory>().with({ + id: 'core.api.factory', + }); } diff --git a/packages/frontend-plugin-api/src/extensions/createAppRootWrapperExtension.tsx b/packages/frontend-plugin-api/src/extensions/createAppRootWrapperExtension.tsx index bbc51806af..ce2eb89f25 100644 --- a/packages/frontend-plugin-api/src/extensions/createAppRootWrapperExtension.tsx +++ b/packages/frontend-plugin-api/src/extensions/createAppRootWrapperExtension.tsx @@ -77,8 +77,7 @@ export function createAppRootWrapperExtension< /** @public */ export namespace createAppRootWrapperExtension { - export const componentDataRef = - createExtensionDataRef<ComponentType<PropsWithChildren<{}>>>( - 'app.root.wrapper', - ); + export const componentDataRef = createExtensionDataRef< + ComponentType<PropsWithChildren<{}>> + >().with({ id: 'app.root.wrapper' }); } diff --git a/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx b/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx index a1231d8353..a40ee3b069 100644 --- a/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx +++ b/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx @@ -92,5 +92,5 @@ export namespace createComponentExtension { export const componentDataRef = createExtensionDataRef<{ ref: ComponentRef; impl: ComponentType; - }>('core.component.component'); + }>().with({ id: 'core.component.component' }); } diff --git a/packages/frontend-plugin-api/src/extensions/createNavItemExtension.tsx b/packages/frontend-plugin-api/src/extensions/createNavItemExtension.tsx index 4b92d4dace..2a2c47835a 100644 --- a/packages/frontend-plugin-api/src/extensions/createNavItemExtension.tsx +++ b/packages/frontend-plugin-api/src/extensions/createNavItemExtension.tsx @@ -61,5 +61,5 @@ export namespace createNavItemExtension { title: string; icon: IconComponent; routeRef: RouteRef<undefined>; - }>('core.nav-item.target'); + }>().with({ id: 'core.nav-item.target' }); } diff --git a/packages/frontend-plugin-api/src/extensions/createNavLogoExtension.tsx b/packages/frontend-plugin-api/src/extensions/createNavLogoExtension.tsx index 3d66b26d6b..1f2419bd02 100644 --- a/packages/frontend-plugin-api/src/extensions/createNavLogoExtension.tsx +++ b/packages/frontend-plugin-api/src/extensions/createNavLogoExtension.tsx @@ -51,5 +51,5 @@ export namespace createNavLogoExtension { export const logoElementsDataRef = createExtensionDataRef<{ logoIcon?: JSX.Element; logoFull?: JSX.Element; - }>('core.nav-logo.logo-elements'); + }>().with({ id: 'core.nav-logo.logo-elements' }); } diff --git a/packages/frontend-plugin-api/src/extensions/createRouterExtension.tsx b/packages/frontend-plugin-api/src/extensions/createRouterExtension.tsx index 32d61f7e60..12f946e8a7 100644 --- a/packages/frontend-plugin-api/src/extensions/createRouterExtension.tsx +++ b/packages/frontend-plugin-api/src/extensions/createRouterExtension.tsx @@ -77,8 +77,7 @@ export function createRouterExtension< /** @public */ export namespace createRouterExtension { - export const componentDataRef = - createExtensionDataRef<ComponentType<PropsWithChildren<{}>>>( - 'app.router.wrapper', - ); + export const componentDataRef = createExtensionDataRef< + ComponentType<PropsWithChildren<{}>> + >().with({ id: 'app.router.wrapper' }); } diff --git a/packages/frontend-plugin-api/src/extensions/createSignInPageExtension.tsx b/packages/frontend-plugin-api/src/extensions/createSignInPageExtension.tsx index b525cc3a7b..312d30c78c 100644 --- a/packages/frontend-plugin-api/src/extensions/createSignInPageExtension.tsx +++ b/packages/frontend-plugin-api/src/extensions/createSignInPageExtension.tsx @@ -79,5 +79,5 @@ export function createSignInPageExtension< export namespace createSignInPageExtension { export const componentDataRef = createExtensionDataRef< ComponentType<SignInPageProps> - >('core.sign-in-page.component'); + >().with({ id: 'core.sign-in-page.component' }); } diff --git a/packages/frontend-plugin-api/src/extensions/createThemeExtension.ts b/packages/frontend-plugin-api/src/extensions/createThemeExtension.ts index cc6dbdabe9..1740f05a5a 100644 --- a/packages/frontend-plugin-api/src/extensions/createThemeExtension.ts +++ b/packages/frontend-plugin-api/src/extensions/createThemeExtension.ts @@ -33,6 +33,7 @@ export function createThemeExtension(theme: AppTheme) { /** @public */ export namespace createThemeExtension { - export const themeDataRef = - createExtensionDataRef<AppTheme>('core.theme.theme'); + export const themeDataRef = createExtensionDataRef<AppTheme>().with({ + id: 'core.theme.theme', + }); } diff --git a/packages/frontend-plugin-api/src/extensions/createTranslationExtension.ts b/packages/frontend-plugin-api/src/extensions/createTranslationExtension.ts index 8497a64b88..9445e32e24 100644 --- a/packages/frontend-plugin-api/src/extensions/createTranslationExtension.ts +++ b/packages/frontend-plugin-api/src/extensions/createTranslationExtension.ts @@ -38,5 +38,5 @@ export function createTranslationExtension(options: { export namespace createTranslationExtension { export const translationDataRef = createExtensionDataRef< TranslationResource | TranslationMessages - >('core.translation.translation'); + >().with({ id: 'core.translation.translation' }); } diff --git a/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts b/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts index a6ff41f6b0..cb48cb8df3 100644 --- a/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts +++ b/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts @@ -20,7 +20,9 @@ import { createExtensionDataRef } from './createExtensionDataRef'; /** @public */ export const coreExtensionData = { - reactElement: createExtensionDataRef<JSX.Element>('core.reactElement'), - routePath: createExtensionDataRef<string>('core.routing.path'), - routeRef: createExtensionDataRef<RouteRef>('core.routing.ref'), + reactElement: createExtensionDataRef<JSX.Element>().with({ + id: 'core.reactElement', + }), + routePath: createExtensionDataRef<string>().with({ id: 'core.routing.path' }), + routeRef: createExtensionDataRef<RouteRef>().with({ id: 'core.routing.ref' }), }; diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts index 42ab21db80..4323737540 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts @@ -18,7 +18,7 @@ import { createExtension } from './createExtension'; import { createExtensionDataRef } from './createExtensionDataRef'; import { createExtensionInput } from './createExtensionInput'; -const stringData = createExtensionDataRef<string>('string'); +const stringData = createExtensionDataRef<string>().with({ id: 'string' }); function unused(..._any: any[]) {} diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index 28dc6a4e29..e87f3a638e 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -22,7 +22,7 @@ import { ExtensionInput } from './createExtensionInput'; /** @public */ export type AnyExtensionDataMap = { - [name in string]: ExtensionDataRef<unknown, { optional?: true }>; + [name in string]: ExtensionDataRef<unknown, string, { optional?: true }>; }; /** @public */ diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.test.ts b/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.test.ts index f7a0dc82d0..f979a7def0 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.test.ts @@ -18,6 +18,15 @@ import { createExtensionDataRef } from './createExtensionDataRef'; describe('createExtensionDataRef', () => { it('can be created and read', () => { + const ref = createExtensionDataRef().with({ id: 'foo' }); + expect(ref.id).toBe('foo'); + expect(String(ref)).toBe('ExtensionDataRef{id=foo,optional=false}'); + const refOptional = ref.optional(); + expect(refOptional.id).toBe('foo'); + expect(String(refOptional)).toBe('ExtensionDataRef{id=foo,optional=true}'); + }); + + it('can be created and read in the deprecated way', () => { const ref = createExtensionDataRef('foo'); expect(ref.id).toBe('foo'); expect(String(ref)).toBe('ExtensionDataRef{id=foo,optional=false}'); diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.ts b/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.ts index a7f4e4374e..a1c7b462f2 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.ts @@ -17,9 +17,10 @@ /** @public */ export type ExtensionDataRef< TData, + TId extends string = string, TConfig extends { optional?: true } = {}, > = { - id: string; + id: TId; T: TData; config: TConfig; $$type: '@backstage/ExtensionDataRef'; @@ -27,30 +28,59 @@ export type ExtensionDataRef< /** @public */ export interface ConfigurableExtensionDataRef< + TId extends string, TData, TConfig extends { optional?: true } = {}, -> extends ExtensionDataRef<TData, TConfig> { - optional(): ConfigurableExtensionDataRef<TData, TData & { optional: true }>; +> extends ExtensionDataRef<TData, TId, TConfig> { + optional(): ConfigurableExtensionDataRef< + TId, + TData, + TData & { optional: true } + >; } -// TODO: change to options object with ID. -/** @public */ +/** + * @public + * @deprecated Use the following form instead: `createExtensionDataRef<Type>().with({ id: 'core.foo' })` + */ export function createExtensionDataRef<TData>( id: string, -): ConfigurableExtensionDataRef<TData> { +): ConfigurableExtensionDataRef<string, TData>; +/** @public */ +export function createExtensionDataRef<TData>(): { + with<TId extends string>(options: { + id: TId; + }): ConfigurableExtensionDataRef<TId, TData>; +}; +export function createExtensionDataRef<TData>(id?: string): + | ConfigurableExtensionDataRef<string, TData> + | { + with<TId extends string>(options: { + id: TId; + }): ConfigurableExtensionDataRef<TId, TData>; + } { + const createRef = <TId extends string>(refId: TId) => + ({ + id: refId, + $$type: '@backstage/ExtensionDataRef', + config: {}, + optional() { + return { + ...this, + config: { ...this.config, optional: true }, + }; + }, + toString() { + const optional = Boolean(this.config.optional); + return `ExtensionDataRef{id=${refId},optional=${optional}}`; + }, + } as ConfigurableExtensionDataRef<TId, TData, { optional?: true }>); + if (id) { + return createRef(id); + } return { - id, - $$type: '@backstage/ExtensionDataRef', - config: {}, - optional() { - return { - ...this, - config: { ...this.config, optional: true }, - }; + with<TId extends string>(options: { id: TId }) { + return createRef(options.id); }, - toString() { - const optional = Boolean(this.config.optional); - return `ExtensionDataRef{id=${id},optional=${optional}}`; - }, - } as ConfigurableExtensionDataRef<TData, { optional?: true }>; + }; } diff --git a/packages/frontend-plugin-api/src/wiring/createPlugin.test.ts b/packages/frontend-plugin-api/src/wiring/createPlugin.test.ts index dab8a9778a..bb9bdc2107 100644 --- a/packages/frontend-plugin-api/src/wiring/createPlugin.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createPlugin.test.ts @@ -27,7 +27,9 @@ import { MockConfigApi, renderWithEffects } from '@backstage/test-utils'; import { createExtensionInput } from './createExtensionInput'; import { BackstagePlugin } from './types'; -const nameExtensionDataRef = createExtensionDataRef<string>('name'); +const nameExtensionDataRef = createExtensionDataRef<string>().with({ + id: 'name', +}); const Extension1 = createExtension({ name: '1', diff --git a/plugins/catalog-react/api-report-alpha.md b/plugins/catalog-react/api-report-alpha.md index b82c7ae3e2..d2bfb29458 100644 --- a/plugins/catalog-react/api-report-alpha.md +++ b/plugins/catalog-react/api-report-alpha.md @@ -17,12 +17,21 @@ import { TranslationRef } from '@backstage/core-plugin-api/alpha'; // @alpha (undocumented) export const catalogExtensionData: { - entityContentTitle: ConfigurableExtensionDataRef<string, {}>; + entityContentTitle: ConfigurableExtensionDataRef< + 'catalog.entity-content-title', + string, + {} + >; entityFilterFunction: ConfigurableExtensionDataRef< + 'catalog.entity-filter-function', (entity: Entity) => boolean, {} >; - entityFilterExpression: ConfigurableExtensionDataRef<string, {}>; + entityFilterExpression: ConfigurableExtensionDataRef< + 'catalog.entity-filter-expression', + string, + {} + >; }; // @alpha (undocumented) diff --git a/plugins/catalog-react/src/alpha.tsx b/plugins/catalog-react/src/alpha.tsx index 85712b358a..e81b8e5ebf 100644 --- a/plugins/catalog-react/src/alpha.tsx +++ b/plugins/catalog-react/src/alpha.tsx @@ -36,15 +36,15 @@ export * from './translation'; /** @alpha */ export const catalogExtensionData = { - entityContentTitle: createExtensionDataRef<string>( - 'catalog.entity-content-title', - ), - entityFilterFunction: createExtensionDataRef<(entity: Entity) => boolean>( - 'catalog.entity-filter-function', - ), - entityFilterExpression: createExtensionDataRef<string>( - 'catalog.entity-filter-expression', - ), + entityContentTitle: createExtensionDataRef<string>().with({ + id: 'catalog.entity-content-title', + }), + entityFilterFunction: createExtensionDataRef< + (entity: Entity) => boolean + >().with({ id: 'catalog.entity-filter-function' }), + entityFilterExpression: createExtensionDataRef<string>().with({ + id: 'catalog.entity-filter-expression', + }), }; // TODO: Figure out how to merge with provided config schema diff --git a/plugins/home/api-report-alpha.md b/plugins/home/api-report-alpha.md index 35ce0bb86c..1dd3da96be 100644 --- a/plugins/home/api-report-alpha.md +++ b/plugins/home/api-report-alpha.md @@ -11,7 +11,11 @@ const _default: BackstagePlugin<{}, {}>; export default _default; // @alpha (undocumented) -export const titleExtensionDataRef: ConfigurableExtensionDataRef<string, {}>; +export const titleExtensionDataRef: ConfigurableExtensionDataRef< + 'title', + string, + {} +>; // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/home/src/alpha.tsx b/plugins/home/src/alpha.tsx index e9ff26c9e1..b13c2a2e0e 100644 --- a/plugins/home/src/alpha.tsx +++ b/plugins/home/src/alpha.tsx @@ -31,7 +31,9 @@ const rootRouteRef = createRouteRef(); /** * @alpha */ -export const titleExtensionDataRef = createExtensionDataRef<string>('title'); +export const titleExtensionDataRef = createExtensionDataRef<string>().with({ + id: 'title', +}); const homePage = createPageExtension({ defaultPath: '/home', diff --git a/plugins/search-react/api-report-alpha.md b/plugins/search-react/api-report-alpha.md index 36f5f049c5..aea85d0f81 100644 --- a/plugins/search-react/api-report-alpha.md +++ b/plugins/search-react/api-report-alpha.md @@ -31,6 +31,7 @@ export function createSearchResultListItemExtension< export namespace createSearchResultListItemExtension { const // (undocumented) itemDataRef: ConfigurableExtensionDataRef< + 'search.search-result-list-item.item', { predicate?: SearchResultItemExtensionPredicate | undefined; component: SearchResultItemExtensionComponent; diff --git a/plugins/search-react/src/alpha.tsx b/plugins/search-react/src/alpha.tsx index db198fa99d..a22eaf4244 100644 --- a/plugins/search-react/src/alpha.tsx +++ b/plugins/search-react/src/alpha.tsx @@ -137,5 +137,5 @@ export namespace createSearchResultListItemExtension { export const itemDataRef = createExtensionDataRef<{ predicate?: SearchResultItemExtensionPredicate; component: SearchResultItemExtensionComponent; - }>('search.search-result-list-item.item'); + }>().with({ id: 'search.search-result-list-item.item' }); } From 0bfe7efa2284b31592c9966278f6d5ad5850c27a Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Thu, 18 Jul 2024 14:54:24 +0200 Subject: [PATCH 358/510] chore: wip Signed-off-by: blam <ben@blam.sh> Signed-off-by: blam <ben@blam.sh> --- .../frontend-app-api/src/wiring/createApp.tsx | 1 + .../src/extensions/IconBundleBlueprint.ts | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createApp.tsx index cf6ea6dab4..ae7283f301 100644 --- a/packages/frontend-app-api/src/wiring/createApp.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.tsx @@ -171,6 +171,7 @@ export interface CreateAppFeatureLoader { /** @public */ export function createApp(options?: { + /** @deprecated - TODO */ icons?: { [key in string]: IconComponent }; features?: (FrontendFeature | CreateAppFeatureLoader)[]; configLoader?: () => Promise<{ config: ConfigApi }>; diff --git a/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts b/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts new file mode 100644 index 0000000000..7008dba5a1 --- /dev/null +++ b/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts @@ -0,0 +1,31 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { IconComponent } from '../icons'; +import { createExtensionBlueprint, createExtensionDataRef } from '../wiring'; + +const iconsDataRef = + createExtensionDataRef<{ [key in string]: IconComponent }>('core.icons'); + +/** @public */ +export const IconBundleBlueprint = createExtensionBlueprint({ + kind: 'icon-bundle', + namespace: 'app', + attachTo: { id: 'app', input: 'icons' }, + output: { + icons: iconsDataRef, + }, + factory: (_, params: { icons: { [key in string]: IconComponent } }) => params, +}); From 39f36a944251d056362702622d82eacd6ff54bb6 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Mon, 22 Jul 2024 14:06:27 +0200 Subject: [PATCH 359/510] auth-backend-module-microsoft-provider: update scope handling to define required scopes in backend Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/new-scissors-try.md | 5 ++ docs/auth/microsoft/provider.md | 4 +- .../src/authenticator.ts | 20 ++++-- .../src/module.test.ts | 65 ++++++++++++++++++- 4 files changed, 83 insertions(+), 11 deletions(-) create mode 100644 .changeset/new-scissors-try.md diff --git a/.changeset/new-scissors-try.md b/.changeset/new-scissors-try.md new file mode 100644 index 0000000000..a9e9a45ce7 --- /dev/null +++ b/.changeset/new-scissors-try.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend-module-microsoft-provider': patch +--- + +Updated the Microsoft authenticator to accurately define required scopes, but to also omit the required and additional scopes when requesting resource scopes. diff --git a/docs/auth/microsoft/provider.md b/docs/auth/microsoft/provider.md index f799eeb627..60104b99b7 100644 --- a/docs/auth/microsoft/provider.md +++ b/docs/auth/microsoft/provider.md @@ -67,8 +67,6 @@ auth: clientSecret: ${AZURE_CLIENT_SECRET} tenantId: ${AZURE_TENANT_ID} domainHint: ${AZURE_TENANT_ID} - additionalScopes: - - Mail.Send signIn: resolvers: # typically you would pick one of these @@ -86,7 +84,7 @@ The Microsoft provider is a structure with three mandatory configuration keys: Leave blank if your app registration is multi tenant. When specified, this reduces login friction for users with accounts in multiple tenants by automatically filtering away accounts from other tenants. For more details, see [Home Realm Discovery](https://learn.microsoft.com/en-us/azure/active-directory/manage-apps/home-realm-discovery-policy) -- `additionalScopes` (optional): List of scopes for the App Registration. The default and mandatory value is ['user.read']. +- `additionalScopes` (optional): List of scopes for the App Registration, to be requested in addition to the required ones. ### Resolvers diff --git a/plugins/auth-backend-module-microsoft-provider/src/authenticator.ts b/plugins/auth-backend-module-microsoft-provider/src/authenticator.ts index 1b6eb87fae..fe7dc8f7e1 100644 --- a/plugins/auth-backend-module-microsoft-provider/src/authenticator.ts +++ b/plugins/auth-backend-module-microsoft-provider/src/authenticator.ts @@ -21,21 +21,30 @@ import { PassportProfile, } from '@backstage/plugin-auth-node'; import { ExtendedMicrosoftStrategy } from './strategy'; -import { union } from 'lodash'; /** @public */ export const microsoftAuthenticator = createOAuthAuthenticator({ defaultProfileTransform: PassportOAuthAuthenticatorHelper.defaultProfileTransform, + scopes: { + required: ['email', 'openid', 'offline_access', 'user.read'], + transform({ requested, granted, required, additional }) { + // Resources scopes are of the form `<resource>/<scope>`, and are handled + // separately from the normal scopes in the client. When request a + // resource scope we should only include forward the request scope along + // with offline_access. + const hasResourceScope = Array.from(requested).some(s => s.includes('/')); + if (hasResourceScope) { + return [...requested, 'offline_access']; + } + return [...requested, ...granted, ...required, ...additional]; + }, + }, initialize({ callbackUrl, config }) { const clientId = config.getString('clientId'); const clientSecret = config.getString('clientSecret'); const tenantId = config.getString('tenantId'); const domainHint = config.getOptionalString('domainHint'); - const scope = union( - ['user.read'], - config.getOptionalStringArray('additionalScopes'), - ); const helper = PassportOAuthAuthenticatorHelper.from( new ExtendedMicrosoftStrategy( @@ -44,7 +53,6 @@ export const microsoftAuthenticator = createOAuthAuthenticator({ clientSecret: clientSecret, callbackURL: callbackUrl, tenant: tenantId, - scope: scope, }, ( accessToken: string, diff --git a/plugins/auth-backend-module-microsoft-provider/src/module.test.ts b/plugins/auth-backend-module-microsoft-provider/src/module.test.ts index b50956b9eb..a072b99bde 100644 --- a/plugins/auth-backend-module-microsoft-provider/src/module.test.ts +++ b/plugins/auth-backend-module-microsoft-provider/src/module.test.ts @@ -67,7 +67,7 @@ describe('authModuleMicrosoftProvider', () => { expect(startUrl.pathname).toBe('/my-tenant-id/oauth2/v2.0/authorize'); expect(Object.fromEntries(startUrl.searchParams)).toEqual({ response_type: 'code', - scope: 'User.Read.All', + scope: 'email openid offline_access user.read User.Read.All', client_id: 'my-client-id', redirect_uri: `http://localhost:${server.port()}/api/auth/microsoft/handler/frame`, state: expect.any(String), @@ -97,6 +97,7 @@ describe('authModuleMicrosoftProvider', () => { clientSecret: 'another-client-secret', tenantId: 'another-tenant-id', domainHint: 'somedomain', + additionalScopes: ['some-extra-scope'], }, }, }, @@ -125,7 +126,7 @@ describe('authModuleMicrosoftProvider', () => { expect(startUrl.pathname).toBe('/another-tenant-id/oauth2/v2.0/authorize'); expect(Object.fromEntries(startUrl.searchParams)).toEqual({ response_type: 'code', - scope: 'user.read', + scope: 'email openid offline_access user.read some-extra-scope', client_id: 'another-client-id', redirect_uri: `http://localhost:${server.port()}/api/auth/microsoft/handler/frame`, state: expect.any(String), @@ -137,4 +138,64 @@ describe('authModuleMicrosoftProvider', () => { nonce: decodeURIComponent(nonceCookie.value), }); }); + + it('should not include required scopes for resources', async () => { + const { server } = await startTestBackend({ + features: [ + authPlugin, + authModuleMicrosoftProvider, + mockServices.rootConfig.factory({ + data: { + app: { + baseUrl: 'http://localhost:3000', + }, + auth: { + providers: { + microsoft: { + development: { + clientId: 'another-client-id', + clientSecret: 'another-client-secret', + tenantId: 'another-tenant-id', + additionalScopes: ['some-extra-scope'], + }, + }, + }, + }, + }, + }), + ], + }); + + const agent = request.agent(server); + + const res = await agent.get( + '/api/auth/microsoft/start?env=development&scope=some-resource/some-scope', + ); + + expect(res.status).toEqual(302); + + const nonceCookie = agent.jar.getCookie('microsoft-nonce', { + domain: 'localhost', + path: '/api/auth/microsoft/handler', + script: false, + secure: false, + }); + expect(nonceCookie).toBeDefined(); + + const startUrl = new URL(res.get('location')); + expect(startUrl.origin).toBe('https://login.microsoftonline.com'); + expect(startUrl.pathname).toBe('/another-tenant-id/oauth2/v2.0/authorize'); + expect(Object.fromEntries(startUrl.searchParams)).toEqual({ + response_type: 'code', + scope: 'some-resource/some-scope offline_access', + client_id: 'another-client-id', + redirect_uri: `http://localhost:${server.port()}/api/auth/microsoft/handler/frame`, + state: expect.any(String), + }); + + expect(decodeOAuthState(startUrl.searchParams.get('state')!)).toEqual({ + env: 'development', + nonce: decodeURIComponent(nonceCookie.value), + }); + }); }); From 09d1370799f92e7043ae0d1d5ebbd0798ab917d3 Mon Sep 17 00:00:00 2001 From: Calvin Lee <calvin.lee@harness.io> Date: Mon, 22 Jul 2024 22:29:47 +0900 Subject: [PATCH 360/510] Update .changeset/witty-bears-behave.md Co-authored-by: Ben Lambert <ben@blam.sh> Signed-off-by: Calvin Lee <calvin.lee@harness.io> --- .changeset/witty-bears-behave.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/witty-bears-behave.md b/.changeset/witty-bears-behave.md index 7514759189..174467b9eb 100644 --- a/.changeset/witty-bears-behave.md +++ b/.changeset/witty-bears-behave.md @@ -2,4 +2,4 @@ '@backstage/integration': patch --- -Updated functions for getHarnessEditContentsUrl, getHarnessFileContentsUrl, getHarnessArchiveUrl, getHarnessLatestCommitUrl and parseHarnessUrl to handle account and org level urls +Updated functions for `getHarnessEditContentsUrl`, `getHarnessFileContentsUrl`, `getHarnessArchiveUrl`, `getHarnessLatestCommitUrl` and `parseHarnessUrl` to handle account and org level urls From dc37210a290aa28ed4e12d4d22a3f4696c693af1 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Mon, 22 Jul 2024 15:38:22 +0200 Subject: [PATCH 361/510] feat: add support for collecting icons using the new extension blueprint Signed-off-by: blam <ben@blam.sh> --- packages/frontend-app-api/src/extensions/App.tsx | 4 ++++ packages/frontend-app-api/src/wiring/createApp.tsx | 10 +++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/frontend-app-api/src/extensions/App.tsx b/packages/frontend-app-api/src/extensions/App.tsx index 82e7600178..7794aceb79 100644 --- a/packages/frontend-app-api/src/extensions/App.tsx +++ b/packages/frontend-app-api/src/extensions/App.tsx @@ -24,6 +24,7 @@ import { createExtensionInput, createThemeExtension, createTranslationExtension, + IconBundleBlueprint, } from '@backstage/frontend-plugin-api'; export const App = createExtension({ @@ -42,6 +43,9 @@ export const App = createExtension({ translations: createExtensionInput({ translation: createTranslationExtension.translationDataRef, }), + icons: createExtensionInput({ + icon: IconBundleBlueprint.dataRefs.icons, + }), root: createExtensionInput( { element: coreExtensionData.reactElement, diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createApp.tsx index ae7283f301..4d929b206f 100644 --- a/packages/frontend-app-api/src/wiring/createApp.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.tsx @@ -25,6 +25,7 @@ import { createThemeExtension, createTranslationExtension, FrontendFeature, + IconBundleBlueprint, iconsApiRef, RouteResolutionApi, routeResolutionApiRef, @@ -247,6 +248,7 @@ export function createApp(options?: { * @public */ export function createSpecializedApp(options?: { + /** @deprecated - TODO */ icons?: { [key in string]: IconComponent }; features?: FrontendFeature[]; config?: ConfigApi; @@ -374,6 +376,11 @@ function createApiHolder( (x): x is typeof createTranslationExtension.translationDataRef.T => !!x, ) ?? []; + const extensionIcons = tree.root.edges.attachments + .get('icons') + ?.map(e => e.instance?.getData(IconBundleBlueprint.dataRefs.icons)) + .reduce((acc, bundle) => ({ ...acc, ...bundle }), {}); + for (const factory of pluginApis) { factoryRegistry.register('default', factory); } @@ -414,7 +421,8 @@ function createApiHolder( factoryRegistry.register('static', { api: iconsApiRef, deps: {}, - factory: () => new DefaultIconsApi({ ...defaultIcons, ...icons }), + factory: () => + new DefaultIconsApi({ ...defaultIcons, ...extensionIcons, ...icons }), }); factoryRegistry.register('static', { From 4a18c942be1d49700540005f9d6a1566d0268f98 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Mon, 22 Jul 2024 15:39:33 +0200 Subject: [PATCH 362/510] feat: support exporting of dataRefs through blueprints Signed-off-by: blam <ben@blam.sh> --- .../src/extensions/IconBundleBlueprint.ts | 10 ++++--- .../src/extensions/index.ts | 1 + .../src/wiring/createExtensionBlueprint.ts | 27 ++++++++++++++++--- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts b/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts index 7008dba5a1..2ad1404102 100644 --- a/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts +++ b/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts @@ -16,8 +16,9 @@ import { IconComponent } from '../icons'; import { createExtensionBlueprint, createExtensionDataRef } from '../wiring'; -const iconsDataRef = - createExtensionDataRef<{ [key in string]: IconComponent }>('core.icons'); +const iconsDataRef = createExtensionDataRef<{ + [key in string]: IconComponent; +}>().with({ id: 'core.icons' }); /** @public */ export const IconBundleBlueprint = createExtensionBlueprint({ @@ -27,5 +28,8 @@ export const IconBundleBlueprint = createExtensionBlueprint({ output: { icons: iconsDataRef, }, - factory: (_, params: { icons: { [key in string]: IconComponent } }) => params, + factory: (params: { icons: { [key in string]: IconComponent } }) => params, + dataRefs: { + icons: iconsDataRef, + }, }); diff --git a/packages/frontend-plugin-api/src/extensions/index.ts b/packages/frontend-plugin-api/src/extensions/index.ts index 562cb728cb..267201db81 100644 --- a/packages/frontend-plugin-api/src/extensions/index.ts +++ b/packages/frontend-plugin-api/src/extensions/index.ts @@ -25,3 +25,4 @@ export { createSignInPageExtension } from './createSignInPageExtension'; export { createThemeExtension } from './createThemeExtension'; export { createComponentExtension } from './createComponentExtension'; export { createTranslationExtension } from './createTranslationExtension'; +export { IconBundleBlueprint } from './IconBundleBlueprint'; diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts index 6c79017a0a..b504db5f03 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts @@ -34,6 +34,7 @@ export interface CreateExtensionBlueprintOptions< TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfig, + TDataRefs extends AnyExtensionDataMap, > { kind: string; namespace?: string; @@ -50,6 +51,8 @@ export interface CreateExtensionBlueprintOptions< inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, ): Expand<ExtensionDataValues<TOutput>>; + + dataRefs?: TDataRefs; } /** @@ -60,7 +63,10 @@ export interface ExtensionBlueprint< TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfig, + TDataRefs extends AnyExtensionDataMap, > { + dataRefs: TDataRefs; + make(args: { namespace?: string; name?: string; @@ -97,15 +103,21 @@ class ExtensionBlueprintImpl< TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfig, + TDataRefs extends AnyExtensionDataMap, > { constructor( private readonly options: CreateExtensionBlueprintOptions< TParams, TInputs, TOutput, - TConfig + TConfig, + TDataRefs >, - ) {} + ) { + this.dataRefs = options.dataRefs!; + } + + dataRefs: TDataRefs; public make(args: { namespace?: string; @@ -184,8 +196,15 @@ export function createExtensionBlueprint< TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfig, + TDataRefs extends AnyExtensionDataMap = never, >( - options: CreateExtensionBlueprintOptions<TParams, TInputs, TOutput, TConfig>, -): ExtensionBlueprint<TParams, TInputs, TOutput, TConfig> { + options: CreateExtensionBlueprintOptions< + TParams, + TInputs, + TOutput, + TConfig, + TDataRefs + >, +): ExtensionBlueprint<TParams, TInputs, TOutput, TConfig, TDataRefs> { return new ExtensionBlueprintImpl(options); } From 7777b5fb40b96fcefe6a418c0d3d657b3ae6b6a1 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Mon, 22 Jul 2024 15:45:01 +0200 Subject: [PATCH 363/510] chore: added changeset Signed-off-by: blam <ben@blam.sh> --- .changeset/forty-ties-agree.md | 18 ++++++++++++++++++ .changeset/forty-ties-disagree.md | 5 +++++ 2 files changed, 23 insertions(+) create mode 100644 .changeset/forty-ties-agree.md create mode 100644 .changeset/forty-ties-disagree.md diff --git a/.changeset/forty-ties-agree.md b/.changeset/forty-ties-agree.md new file mode 100644 index 0000000000..caa45841a2 --- /dev/null +++ b/.changeset/forty-ties-agree.md @@ -0,0 +1,18 @@ +--- +'@backstage/frontend-plugin-api': patch +--- + +Added a new `IconBundleBlueprint` that lets you create icon bundle extensions that can be installed in an App in order to override or add new app icons. + +```tsx +import { IconBundleBlueprint } from '@backstage/frontend-plugin-api'; + +const exampleIconBundle = IconBundleBlueprint.make({ + name: 'example-bundle', + params: { + icons: { + user: MyOwnUserIcon, + }, + }, +}); +``` diff --git a/.changeset/forty-ties-disagree.md b/.changeset/forty-ties-disagree.md new file mode 100644 index 0000000000..214097b35d --- /dev/null +++ b/.changeset/forty-ties-disagree.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-app-api': patch +--- + +Support icon overriding with the new `IconBundleBlueprint` API. From be5cb5ea365f09044cc18788e7b5d9eaa6b3689e Mon Sep 17 00:00:00 2001 From: Devin Lauderdale <devinlauderdale2@gmail.com> Date: Mon, 22 Jul 2024 08:58:25 -0500 Subject: [PATCH 364/510] docs: remove unmaintained dora-metrics plugin Signed-off-by: Devin Lauderdale <devinlauderdale2@gmail.com> --- microsite/data/plugins/dora-metrics.yaml | 10 ---------- microsite/static/img/okay.png | Bin 46181 -> 0 bytes 2 files changed, 10 deletions(-) delete mode 100644 microsite/data/plugins/dora-metrics.yaml delete mode 100644 microsite/static/img/okay.png diff --git a/microsite/data/plugins/dora-metrics.yaml b/microsite/data/plugins/dora-metrics.yaml deleted file mode 100644 index 3f59902f46..0000000000 --- a/microsite/data/plugins/dora-metrics.yaml +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: DORA Metrics -author: Okay -authorUrl: https://www.okayhq.com -category: Metrics -description: Embed dashboards (like DORA metrics) in your team or service pages from any dev tools (including Github, Gitlab, Jira, Argo, CircleCI, Buildkite, Pagerduty, Rollbar, Sentry, etc). -documentation: https://github.com/OkayHQ/backstage-plugin -iconUrl: /img/okay.png -npmPackageName: '@okayhq/backstage-plugin' -addedDate: '2022-06-16' diff --git a/microsite/static/img/okay.png b/microsite/static/img/okay.png deleted file mode 100644 index 357219d9d2c51e1d9a16f3f7a0c4fc476936d685..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46181 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 From cf9da6dafbe6c2fd038d9b8176a2f28816b76e10 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Mon, 22 Jul 2024 16:10:05 +0200 Subject: [PATCH 365/510] chore: added test for dataRef exporting Signed-off-by: blam <ben@blam.sh> --- .../wiring/createExtensionBlueprint.test.tsx | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx index c7b077bdbd..87b3cec152 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx @@ -18,6 +18,7 @@ import React from 'react'; import { coreExtensionData } from './coreExtensionData'; import { createExtensionBlueprint } from './createExtensionBlueprint'; import { createExtensionTester } from '@backstage/frontend-test-utils'; +import { createExtensionDataRef } from './createExtensionDataRef'; describe('createExtensionBlueprint', () => { it('should allow creation of extension blueprints', () => { @@ -102,4 +103,28 @@ describe('createExtensionBlueprint', () => { const { container } = createExtensionTester(extension).render(); expect(container.querySelector('h2')).toHaveTextContent('Hello, world!'); }); + + it('should allow exporting the dataRefs from the extension blueprint', () => { + const dataRef = createExtensionDataRef<string>().with({ id: 'test.data' }); + + const TestExtensionBlueprint = createExtensionBlueprint({ + kind: 'test-extension', + attachTo: { id: 'test', input: 'default' }, + output: { + element: coreExtensionData.reactElement, + }, + dataRefs: { + data: dataRef, + }, + factory(params: { text: string }) { + return { + element: <h1>{params.text}</h1>, + }; + }, + }); + + expect(TestExtensionBlueprint.dataRefs).toEqual({ + data: dataRef, + }); + }); }); From 493feaca4d4af19c4174a531d268f4d6e63c1a9e Mon Sep 17 00:00:00 2001 From: MT Lewis <mtlewis@users.noreply.github.com> Date: Thu, 18 Jul 2024 11:10:18 +0100 Subject: [PATCH 366/510] cli: allow running with no configuration files Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com> Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com> --- .changeset/rich-mugs-dress.md | 7 ++++++ packages/cli/src/lib/bundler/config.ts | 6 ++++- packages/cli/src/lib/config.ts | 8 ++++--- packages/config-loader/api-report.md | 1 + .../src/sources/ConfigSources.test.ts | 13 +++++++++- .../src/sources/ConfigSources.ts | 24 +++++++++++++------ 6 files changed, 47 insertions(+), 12 deletions(-) create mode 100644 .changeset/rich-mugs-dress.md diff --git a/.changeset/rich-mugs-dress.md b/.changeset/rich-mugs-dress.md new file mode 100644 index 0000000000..5008e33a70 --- /dev/null +++ b/.changeset/rich-mugs-dress.md @@ -0,0 +1,7 @@ +--- +'@backstage/config-loader': patch +--- + +Add boolean `allowMissingDefaultConfig` option to `ConfigSources.default` and +`ConfigSources.defaultForTargets`, which results in omission of a ConfigSource +for the default app-config.yaml configuration file if it's not present. diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index 1f08f74a85..042f74d1f3 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -48,8 +48,12 @@ const BUILD_CACHE_ENV_VAR = 'BACKSTAGE_CLI_EXPERIMENTAL_BUILD_CACHE'; export function resolveBaseUrl(config: Config): URL { const baseUrl = config.getOptionalString('app.baseUrl'); + try { - return new URL(baseUrl ?? '/', 'http://localhost:3000'); + return new URL( + baseUrl ?? '/', + `http://localhost:${process.env.PORT ?? '3000'}`, + ); } catch (error) { throw new Error(`Invalid app.baseUrl, ${error}`); } diff --git a/packages/cli/src/lib/config.ts b/packages/cli/src/lib/config.ts index 0c657b640e..0be20b0185 100644 --- a/packages/cli/src/lib/config.ts +++ b/packages/cli/src/lib/config.ts @@ -96,11 +96,13 @@ export async function loadCliConfig(options: Options) { }, }); + const configurationLoadedMessage = appConfigs.length + ? `Loaded config from ${appConfigs.map(c => c.context).join(', ')}` + : `No configuration files found, running without config`; + // printing to stderr to not clobber stdout in case the cli command // outputs structured data (e.g. as config:schema does) - process.stderr.write( - `Loaded config from ${appConfigs.map(c => c.context).join(', ')}\n`, - ); + process.stderr.write(`${configurationLoadedMessage}\n`); try { const frontendAppConfigs = schema.process(appConfigs, { diff --git a/packages/config-loader/api-report.md b/packages/config-loader/api-report.md index bc8f217bbb..835e53351d 100644 --- a/packages/config-loader/api-report.md +++ b/packages/config-loader/api-report.md @@ -21,6 +21,7 @@ export type AsyncConfigSourceGenerator = AsyncGenerator< // @public export interface BaseConfigSourcesOptions { + allowMissingDefaultConfig?: boolean; // (undocumented) remote?: Pick<RemoteConfigSourceOptions, 'reloadInterval'>; // (undocumented) diff --git a/packages/config-loader/src/sources/ConfigSources.test.ts b/packages/config-loader/src/sources/ConfigSources.test.ts index 4b14572666..e19ac1d51f 100644 --- a/packages/config-loader/src/sources/ConfigSources.test.ts +++ b/packages/config-loader/src/sources/ConfigSources.test.ts @@ -69,13 +69,18 @@ describe('ConfigSources', () => { }); it('should create default sources for targets', () => { + const fsSpy = jest.spyOn(fs, 'pathExistsSync').mockImplementation(path => { + return path === `${root}app-config.yaml`; + }); + expect( mergeSources( ConfigSources.defaultForTargets({ rootDir: '/', targets: [] }), ), ).toEqual([{ name: 'FileConfigSource', path: `${root}app-config.yaml` }]); - const fsSpy = jest.spyOn(fs, 'pathExistsSync').mockReturnValue(true); + fsSpy.mockReturnValue(true); + expect( mergeSources( ConfigSources.defaultForTargets({ rootDir: '/', targets: [] }), @@ -159,6 +164,10 @@ describe('ConfigSources', () => { }); it('should create a default source', () => { + const fsSpy = jest.spyOn(fs, 'pathExistsSync').mockImplementation(path => { + return path === `${root}app-config.yaml`; + }); + expect( mergeSources( ConfigSources.default({ @@ -184,6 +193,8 @@ describe('ConfigSources', () => { { name: 'FileConfigSource', path: resolvePath('b.yaml') }, { name: 'EnvConfigSource', env: { HOME: '/' } }, ]); + + fsSpy.mockRestore(); }); it('should merge sources', () => { diff --git a/packages/config-loader/src/sources/ConfigSources.ts b/packages/config-loader/src/sources/ConfigSources.ts index ecff39da2d..be8892f9a9 100644 --- a/packages/config-loader/src/sources/ConfigSources.ts +++ b/packages/config-loader/src/sources/ConfigSources.ts @@ -74,6 +74,11 @@ export interface BaseConfigSourcesOptions { watch?: boolean; rootDir?: string; remote?: Pick<RemoteConfigSourceOptions, 'reloadInterval'>; + /** + * Allow the default app-config.yaml to be missing, in which case the source + * will not be created. + */ + allowMissingDefaultConfig?: boolean; /** * A custom substitution function that overrides the default one. @@ -177,14 +182,19 @@ export class ConfigSources { if (argSources.length === 0) { const defaultPath = resolvePath(rootDir, 'app-config.yaml'); const localPath = resolvePath(rootDir, 'app-config.local.yaml'); + const alwaysIncludeDefaultConfigSource = + !options.allowMissingDefaultConfig; + + if (alwaysIncludeDefaultConfigSource || fs.pathExistsSync(defaultPath)) { + argSources.push( + FileConfigSource.create({ + watch: options.watch, + path: defaultPath, + substitutionFunc: options.substitutionFunc, + }), + ); + } - argSources.push( - FileConfigSource.create({ - watch: options.watch, - path: defaultPath, - substitutionFunc: options.substitutionFunc, - }), - ); if (fs.pathExistsSync(localPath)) { argSources.push( FileConfigSource.create({ From 0eedec304dbe8e4f8b1e982a1e29b081cbed3ddd Mon Sep 17 00:00:00 2001 From: MT Lewis <mtlewis@users.noreply.github.com> Date: Thu, 18 Jul 2024 11:18:07 +0100 Subject: [PATCH 367/510] cli: add changeset for module federation local development changes Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com> --- .changeset/strong-otters-compete.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/strong-otters-compete.md diff --git a/.changeset/strong-otters-compete.md b/.changeset/strong-otters-compete.md new file mode 100644 index 0000000000..fdcb982b88 --- /dev/null +++ b/.changeset/strong-otters-compete.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Add support for dynamic plugins via the EXPERIMENTAL_MODULE_FEDERATION environment variable when running `yarn start`. From 9d661bb3807a534cf023dc84d816cee5d3c81472 Mon Sep 17 00:00:00 2001 From: MT Lewis <mtlewis@users.noreply.github.com> Date: Fri, 19 Jul 2024 14:28:13 +0100 Subject: [PATCH 368/510] cli: only consider PORT environment variable for module federation remotes Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com> --- packages/cli/src/lib/bundler/config.ts | 43 +++++++++++++++++++------- packages/cli/src/lib/bundler/server.ts | 7 +++-- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index 042f74d1f3..42cdae24e3 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -14,7 +14,11 @@ * limitations under the License. */ -import { BackendBundlingOptions, BundlingOptions } from './types'; +import { + BackendBundlingOptions, + BundlingOptions, + ModuleFederationOptions, +} from './types'; import { posix as posixPath, resolve as resolvePath, dirname } from 'path'; import chalk from 'chalk'; import webpack, { ProvidePlugin } from 'webpack'; @@ -46,24 +50,32 @@ import { hasReactDomClient } from './hasReactDomClient'; const BUILD_CACHE_ENV_VAR = 'BACKSTAGE_CLI_EXPERIMENTAL_BUILD_CACHE'; -export function resolveBaseUrl(config: Config): URL { +export function resolveBaseUrl( + config: Config, + moduleFederation?: ModuleFederationOptions, +): URL { const baseUrl = config.getOptionalString('app.baseUrl'); + const defaultBaseUrl = + moduleFederation?.mode === 'remote' + ? `http://localhost:${process.env.PORT ?? '3000'}` + : 'http://localhost:3000'; + try { - return new URL( - baseUrl ?? '/', - `http://localhost:${process.env.PORT ?? '3000'}`, - ); + return new URL(baseUrl ?? '/', defaultBaseUrl); } catch (error) { throw new Error(`Invalid app.baseUrl, ${error}`); } } -export function resolveEndpoint(config: Config): { +export function resolveEndpoint( + config: Config, + moduleFederation?: ModuleFederationOptions, +): { host: string; port: number; } { - const url = resolveBaseUrl(config); + const url = resolveBaseUrl(config, moduleFederation); return { host: config.getOptionalString('app.listen.host') ?? url.hostname, @@ -114,7 +126,13 @@ export async function createConfig( paths: BundlingPaths, options: BundlingOptions, ): Promise<webpack.Configuration> { - const { checksEnabled, isDev, frontendConfig, publicSubPath = '' } = options; + const { + checksEnabled, + isDev, + frontendConfig, + moduleFederation, + publicSubPath = '', + } = options; const { plugins, loaders } = transforms(options); // Any package that is part of the monorepo but outside the monorepo root dir need @@ -122,14 +140,17 @@ export async function createConfig( const { packages } = await getPackages(cliPaths.targetDir); const externalPkgs = packages.filter(p => !isChildPath(paths.root, p.dir)); - const validBaseUrl = resolveBaseUrl(frontendConfig); + const validBaseUrl = resolveBaseUrl(frontendConfig, moduleFederation); let publicPath = validBaseUrl.pathname.replace(/\/$/, ''); if (publicSubPath) { publicPath = `${publicPath}${publicSubPath}`.replace('//', '/'); } if (isDev) { - const { host, port } = resolveEndpoint(options.frontendConfig); + const { host, port } = resolveEndpoint( + options.frontendConfig, + options.moduleFederation, + ); plugins.push( new ReactRefreshPlugin({ diff --git a/packages/cli/src/lib/bundler/server.ts b/packages/cli/src/lib/bundler/server.ts index 0421f4d019..6b89847fb6 100644 --- a/packages/cli/src/lib/bundler/server.ts +++ b/packages/cli/src/lib/bundler/server.ts @@ -130,8 +130,11 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be } const { frontendConfig, fullConfig } = cliConfig; - const url = resolveBaseUrl(frontendConfig); - const { host, port } = resolveEndpoint(frontendConfig); + const url = resolveBaseUrl(frontendConfig, options.moduleFederation); + const { host, port } = resolveEndpoint( + frontendConfig, + options.moduleFederation, + ); const detectedModulesEntryPoint = await createDetectedModulesEntryPoint({ config: fullConfig, From 239dffc970b4b040ffdf9aee24f6937c4994f5ba Mon Sep 17 00:00:00 2001 From: MT Lewis <mtlewis@users.noreply.github.com> Date: Mon, 22 Jul 2024 11:06:42 +0100 Subject: [PATCH 369/510] cli: remove usage of deprecated functionality from @backstage/config-loader Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com> Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com> --- .changeset/ninety-icons-smile.md | 5 +++ packages/cli/src/lib/config.ts | 76 +++++++++++++++++++------------- 2 files changed, 51 insertions(+), 30 deletions(-) create mode 100644 .changeset/ninety-icons-smile.md diff --git a/.changeset/ninety-icons-smile.md b/.changeset/ninety-icons-smile.md new file mode 100644 index 0000000000..f137879706 --- /dev/null +++ b/.changeset/ninety-icons-smile.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Remove usage of deprecated functionality from @backstage/config-loader diff --git a/packages/cli/src/lib/config.ts b/packages/cli/src/lib/config.ts index 0be20b0185..49cce1f1ed 100644 --- a/packages/cli/src/lib/config.ts +++ b/packages/cli/src/lib/config.ts @@ -14,14 +14,9 @@ * limitations under the License. */ -import { - ConfigTarget, - loadConfig, - loadConfigSchema, -} from '@backstage/config-loader'; +import { ConfigSources, loadConfigSchema } from '@backstage/config-loader'; import { AppConfig, ConfigReader } from '@backstage/config'; import { paths } from './paths'; -import { isValidUrl } from './urls'; import { getPackages } from '@manypkg/get-packages'; import { PackageGraph } from '@backstage/cli-node'; @@ -37,13 +32,6 @@ type Options = { }; export async function loadCliConfig(options: Options) { - const configTargets: ConfigTarget[] = []; - options.args.forEach(arg => { - if (!isValidUrl(arg)) { - configTargets.push({ path: paths.resolveTarget(arg) }); - } - }); - // Consider all packages in the monorepo when loading in config const { packages } = await getPackages(paths.targetDir); @@ -75,25 +63,53 @@ export async function loadCliConfig(options: Options) { noUndeclaredProperties: options.strict, }); - const { appConfigs } = await loadConfig({ - experimentalEnvFunc: options.mockEnv + const source = ConfigSources.default({ + allowMissingDefaultConfig: true, + substitutionFunc: options.mockEnv ? async name => process.env[name] || 'x' : undefined, - configRoot: paths.targetRoot, - configTargets: configTargets, - watch: options.watch && { - onChange(newAppConfigs) { - const newFrontendAppConfigs = schema.process(newAppConfigs, { - visibility: options.fullVisibility - ? ['frontend', 'backend', 'secret'] - : ['frontend'], - withFilteredKeys: options.withFilteredKeys, - withDeprecatedKeys: options.withDeprecatedKeys, - ignoreSchemaErrors: !options.strict, - }); - options.watch?.(newFrontendAppConfigs); - }, - }, + watch: Boolean(options.watch), + rootDir: paths.targetRoot, + argv: options.args, + }); + + const appConfigs = await new Promise<AppConfig[]>((resolve, reject) => { + async function loadConfigReaderLoop() { + let loaded = false; + + try { + const abortController = new AbortController(); + for await (const { configs } of source.readConfigData({ + signal: abortController.signal, + })) { + if (loaded) { + const newFrontendAppConfigs = schema.process(configs, { + visibility: options.fullVisibility + ? ['frontend', 'backend', 'secret'] + : ['frontend'], + withFilteredKeys: options.withFilteredKeys, + withDeprecatedKeys: options.withDeprecatedKeys, + ignoreSchemaErrors: !options.strict, + }); + options.watch?.(newFrontendAppConfigs); + } else { + resolve(configs); + loaded = true; + + if (!options.watch) { + abortController.abort(); + } + } + } + } catch (error) { + if (loaded) { + console.error(`Failed to reload configuration, ${error}`); + } else { + reject(error); + } + } + } + loadConfigReaderLoop(); }); const configurationLoadedMessage = appConfigs.length From 348087a09636d79e3a2894325b16afef79275ec9 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Mon, 22 Jul 2024 16:22:29 +0200 Subject: [PATCH 370/510] auth-backend-module-microsoft-provider: cleanup deps Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- plugins/auth-backend-module-microsoft-provider/package.json | 2 -- yarn.lock | 2 -- 2 files changed, 4 deletions(-) diff --git a/plugins/auth-backend-module-microsoft-provider/package.json b/plugins/auth-backend-module-microsoft-provider/package.json index 67a898cf80..b67fb8c447 100644 --- a/plugins/auth-backend-module-microsoft-provider/package.json +++ b/plugins/auth-backend-module-microsoft-provider/package.json @@ -38,9 +38,7 @@ "@backstage/plugin-auth-node": "workspace:^", "express": "^4.18.2", "jose": "^5.0.0", - "lodash": "^4.17.21", "node-fetch": "^2.6.7", - "passport": "^0.7.0", "passport-microsoft": "^1.0.0" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index a8ed83a61a..ff5eac7b1f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4861,10 +4861,8 @@ __metadata: "@types/passport-microsoft": ^1.0.0 express: ^4.18.2 jose: ^5.0.0 - lodash: ^4.17.21 msw: ^1.0.0 node-fetch: ^2.6.7 - passport: ^0.7.0 passport-microsoft: ^1.0.0 supertest: ^6.3.3 languageName: unknown From b1f3c44e42a8f880698e2b4e5c59be133c000738 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Mon, 22 Jul 2024 16:31:09 +0200 Subject: [PATCH 371/510] chore: api-reports Signed-off-by: blam <ben@blam.sh> --- packages/frontend-plugin-api/api-report.md | 46 +++++++++++++++++++++- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index 65445b5c4d..3c082a7694 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -522,9 +522,16 @@ export function createExtensionBlueprint< TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfig, + TDataRefs extends AnyExtensionDataMap = never, >( - options: CreateExtensionBlueprintOptions<TParams, TInputs, TOutput, TConfig>, -): ExtensionBlueprint<TParams, TInputs, TOutput, TConfig>; + options: CreateExtensionBlueprintOptions< + TParams, + TInputs, + TOutput, + TConfig, + TDataRefs + >, +): ExtensionBlueprint<TParams, TInputs, TOutput, TConfig, TDataRefs>; // @public (undocumented) export interface CreateExtensionBlueprintOptions< @@ -532,6 +539,7 @@ export interface CreateExtensionBlueprintOptions< TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfig, + TDataRefs extends AnyExtensionDataMap, > { // (undocumented) attachTo: { @@ -541,6 +549,8 @@ export interface CreateExtensionBlueprintOptions< // (undocumented) configSchema?: PortableSchema<TConfig>; // (undocumented) + dataRefs?: TDataRefs; + // (undocumented) disabled?: boolean; // (undocumented) factory( @@ -917,7 +927,10 @@ export interface ExtensionBlueprint< TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfig, + TDataRefs extends AnyExtensionDataMap, > { + // (undocumented) + dataRefs: TDataRefs; // (undocumented) make(args: { namespace?: string; @@ -1085,6 +1098,35 @@ export { gitlabAuthApiRef }; export { googleAuthApiRef }; +// @public (undocumented) +export const IconBundleBlueprint: ExtensionBlueprint< + { + icons: { + [x: string]: IconComponent; + }; + }, + AnyExtensionInputMap, + { + icons: ConfigurableExtensionDataRef< + 'core.icons', + { + [x: string]: IconComponent; + }, + {} + >; + }, + unknown, + { + icons: ConfigurableExtensionDataRef< + 'core.icons', + { + [x: string]: IconComponent; + }, + {} + >; + } +>; + // @public export type IconComponent = ComponentType< | { From 98ea3e2ca9329f6b131e3d3f038ba5101b039beb Mon Sep 17 00:00:00 2001 From: Adam Letizia <43392371+koalaty-code@users.noreply.github.com> Date: Mon, 22 Jul 2024 09:40:18 -0500 Subject: [PATCH 372/510] chore(changeset): new change description Co-authored-by: Ben Lambert <ben@blam.sh> Signed-off-by: Adam Letizia <43392371+koalaty-code@users.noreply.github.com> --- .changeset/tough-lies-repair.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/tough-lies-repair.md b/.changeset/tough-lies-repair.md index 25b1884bbc..b2f848e292 100644 --- a/.changeset/tough-lies-repair.md +++ b/.changeset/tough-lies-repair.md @@ -2,4 +2,4 @@ '@backstage/plugin-scaffolder': patch --- -RepoUrlPicker: refetch user credentials when a new host is selected +Fix issue with `RepoUrlPicker` not refreshing the credentials for a different host From d0e95a70369cb81bf2c74850a5c3b80250388110 Mon Sep 17 00:00:00 2001 From: Rich Barton-Cooper <58304039+richcooper95@users.noreply.github.com> Date: Fri, 3 May 2024 16:01:05 +0100 Subject: [PATCH 373/510] feat: expose uiSchema and formContext in FormProps This commit exposes two extra fields in the FormProps: `uiSchema` and `formContext`. Signed-off-by: Rich Barton-Cooper <rich@syntasso.io> Co-authored-by: Chunyi Lyu <chunyineko@gmail.com> --- .changeset/flat-plums-grow.md | 6 ++++++ plugins/scaffolder-react/api-report.md | 2 +- plugins/scaffolder-react/src/components/types.ts | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 .changeset/flat-plums-grow.md diff --git a/.changeset/flat-plums-grow.md b/.changeset/flat-plums-grow.md new file mode 100644 index 0000000000..b62f3e65a9 --- /dev/null +++ b/.changeset/flat-plums-grow.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-scaffolder-react': patch +--- + +Add ability to customise form fields in the UI by exposing `uiSchema` and `formContext` in +`FormProps` diff --git a/plugins/scaffolder-react/api-report.md b/plugins/scaffolder-react/api-report.md index a14490b80c..a19a656d17 100644 --- a/plugins/scaffolder-react/api-report.md +++ b/plugins/scaffolder-react/api-report.md @@ -128,7 +128,7 @@ export interface FieldExtensionUiSchema<TFieldReturnValue, TUiOptions> // @public export type FormProps = Pick< FormProps_2, - 'transformErrors' | 'noHtml5Validate' + 'transformErrors' | 'noHtml5Validate' | 'uiSchema' | 'formContext' >; // @public diff --git a/plugins/scaffolder-react/src/components/types.ts b/plugins/scaffolder-react/src/components/types.ts index 597998bac4..d5d317015d 100644 --- a/plugins/scaffolder-react/src/components/types.ts +++ b/plugins/scaffolder-react/src/components/types.ts @@ -32,7 +32,7 @@ export type TemplateGroupFilter = { */ export type FormProps = Pick< SchemaFormProps, - 'transformErrors' | 'noHtml5Validate' + 'transformErrors' | 'noHtml5Validate' | 'uiSchema' | 'formContext' >; /** From 8cdd846abc49841100cdaf5273d4793a821b475e Mon Sep 17 00:00:00 2001 From: Rich Barton-Cooper <rich@syntasso.io> Date: Mon, 22 Jul 2024 15:55:23 +0100 Subject: [PATCH 374/510] fix: merge uiSchema and formContext in Stepper component This commit ensures that the uiSchema and formContext are merged in the Stepper component form, with the non-props values taking precedence over the props values. The uiSchemas are deep-merged using `lodash.merge` to ensure that nested values are correctly merged. Signed-off-by: Rich Barton-Cooper <rich@syntasso.io> --- .../next/components/Stepper/Stepper.test.tsx | 60 +++++++++++++++++++ .../src/next/components/Stepper/Stepper.tsx | 15 ++++- 2 files changed, 72 insertions(+), 3 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 df58d971fb..78aef3428f 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx @@ -549,6 +549,66 @@ describe('Stepper', () => { }); }); + it('should allow overrides to the uiSchema and formContext correctly', async () => { + const manifest: TemplateParameterSchema = { + title: 'Custom Fields', + steps: [ + { + title: 'Test', + schema: { + properties: { + name: { + type: 'string', + 'ui:placeholder': 'Enter your name', + }, + age: { + type: 'number', + 'ui:placeholder': 'Enter your age', + }, + }, + }, + }, + ], + }; + + const uiSchema = { + name: { + 'ui:readonly': true, + 'ui:placeholder': 'Should be overwritten', + }, + }; + + const formContext = { + readOnlyAsDisabled: true, + }; + + const { getByRole } = await renderInTestApp( + <SecretsContextProvider> + <Stepper + manifest={manifest} + onCreate={jest.fn()} + extensions={[]} + formProps={{ uiSchema, formContext }} + initialState={{ name: 'Some Name', age: 40 }} + /> + </SecretsContextProvider>, + ); + + expect(getByRole('textbox', { name: 'name' })).toHaveValue('Some Name'); + expect(getByRole('textbox', { name: 'name' })).toBeDisabled(); + expect(getByRole('textbox', { name: 'name' })).toHaveAttribute( + 'placeholder', + 'Enter your name', + ); + + expect(getByRole('spinbutton', { name: 'age' })).toHaveValue(40); + expect(getByRole('spinbutton', { name: 'age' })).toBeEnabled(); + expect(getByRole('spinbutton', { name: 'age' })).toHaveAttribute( + 'placeholder', + 'Enter your age', + ); + }); + describe('Scaffolder Layouts', () => { it('should render the step in the scaffolder layout', async () => { const ScaffolderLayout: LayoutTemplate = ({ properties }) => ( diff --git a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx index 788c7cd715..3a8858144b 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx @@ -51,6 +51,7 @@ import { ErrorListTemplate } from './ErrorListTemplate'; import { makeStyles } from '@material-ui/core/styles'; import { PasswordWidget } from '../PasswordWidget/PasswordWidget'; import ajvErrors from 'ajv-errors'; +import { merge } from 'lodash'; const validator = customizeValidator(); ajvErrors(validator.ajv); @@ -193,6 +194,14 @@ export const Stepper = (stepperProps: StepperProps) => { setFormState(current => ({ ...current, ...formData })); }; + const { + formContext: propFormContext, + uiSchema: propUiSchema, + ...restFormProps + } = props.formProps ?? {}; + + const mergedUiSchema = merge({}, propUiSchema, currentStep?.uiSchema); + return ( <> {isValidating && <LinearProgress variant="indeterminate" />} @@ -229,9 +238,9 @@ export const Stepper = (stepperProps: StepperProps) => { validator={validator} extraErrors={errors as unknown as ErrorSchema} formData={formState} - formContext={{ formData: formState }} + formContext={{ ...propFormContext, formData: formState }} schema={currentStep.schema} - uiSchema={currentStep.uiSchema} + uiSchema={mergedUiSchema} onSubmit={handleNext} fields={fields} showErrorList="top" @@ -241,7 +250,7 @@ export const Stepper = (stepperProps: StepperProps) => { experimental_defaultFormStateBehavior={{ allOf: 'populateDefaults', }} - {...(props.formProps ?? {})} + {...restFormProps} > <div className={styles.footer}> <Button From 3ca333b683d542cee92998256f0a4607f45be452 Mon Sep 17 00:00:00 2001 From: Thomas Cardonne <thomas.cardonne@adevinta.com> Date: Mon, 22 Jul 2024 22:19:06 +0200 Subject: [PATCH 375/510] test(scaffolder-backend-module-gitlab): fix tests for gitlabProjectAccessTokenCreate examples Fixes tests created in #25713 Signed-off-by: Thomas Cardonne <thomas.cardonne@adevinta.com> --- ...tlabProjectAccessTokenCreate.examples.test.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.examples.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.examples.test.ts index 0762212809..bdf14ce1c8 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.examples.test.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.examples.test.ts @@ -215,7 +215,7 @@ describe('gitlab:projectAccessToken:create examples', () => { ['read_repository'], { accessLevel: 30, - expiresAt: '2025-07-21', + expiresAt: DateTime.now().plus({ days: 365 }).toISODate()!, }, ); @@ -271,7 +271,7 @@ describe('gitlab:projectAccessToken:create examples', () => { ['read_repository'], { accessLevel: 40, - expiresAt: '2025-07-21', + expiresAt: DateTime.now().plus({ days: 365 }).toISODate()!, }, ); @@ -299,7 +299,7 @@ describe('gitlab:projectAccessToken:create examples', () => { ['read_repository', 'read_api'], { accessLevel: 40, - expiresAt: '2025-07-21', + expiresAt: DateTime.now().plus({ days: 365 }).toISODate()!, }, ); @@ -327,7 +327,7 @@ describe('gitlab:projectAccessToken:create examples', () => { ['read_repository'], { accessLevel: 10, - expiresAt: '2025-07-21', + expiresAt: DateTime.now().plus({ days: 365 }).toISODate()!, }, ); @@ -355,7 +355,7 @@ describe('gitlab:projectAccessToken:create examples', () => { ['read_repository'], { accessLevel: 40, - expiresAt: '2025-07-21', + expiresAt: DateTime.now().plus({ days: 365 }).toISODate()!, }, ); @@ -383,7 +383,7 @@ describe('gitlab:projectAccessToken:create examples', () => { ['read_repository'], { accessLevel: 50, - expiresAt: '2025-07-21', + expiresAt: DateTime.now().plus({ days: 365 }).toISODate()!, }, ); @@ -411,7 +411,7 @@ describe('gitlab:projectAccessToken:create examples', () => { ['read_repository'], { accessLevel: 40, - expiresAt: '2025-07-21', + expiresAt: DateTime.now().plus({ days: 365 }).toISODate()!, }, ); @@ -439,7 +439,7 @@ describe('gitlab:projectAccessToken:create examples', () => { ['read_repository'], { accessLevel: 40, - expiresAt: '2025-07-21', + expiresAt: DateTime.now().plus({ days: 365 }).toISODate()!, }, ); From 97abfa22b9e98ad3c8b950628e19b4240243cb52 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Tue, 23 Jul 2024 08:01:34 +0200 Subject: [PATCH 376/510] chore: added some docs and cleanup the todos Signed-off-by: blam <ben@blam.sh> --- .../building-apps/03-built-in-extensions.md | 1 + .../building-apps/08-migrating.md | 25 +++++++++++++++++++ .../building-plugins/03-extension-types.md | 4 +++ .../frontend-app-api/src/wiring/createApp.tsx | 4 +-- 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/docs/frontend-system/building-apps/03-built-in-extensions.md b/docs/frontend-system/building-apps/03-built-in-extensions.md index 4f8417f74f..a5e6476eb0 100644 --- a/docs/frontend-system/building-apps/03-built-in-extensions.md +++ b/docs/frontend-system/building-apps/03-built-in-extensions.md @@ -45,6 +45,7 @@ This extension is the first extension attached to the extension tree. It is resp | themes | The app themes list. | [createThemeExtension.themeDataRef](https://backstage.io/docs/reference/frontend-plugin-api.createthemeextension.themedataref) | false | See [default themes](#default-theme-extensions). | [createThemeExtension](https://backstage.io/docs/reference/frontend-plugin-api.createthemeextension) | | components | The app components list. | [createComponentExtension.componentDataRef](https://backstage.io/docs/reference/frontend-plugin-api.createcomponentextension.componentdataref) | false | See [default components](#default-components-extensions). | [createComponentExtension](https://backstage.io/docs/reference/frontend-plugin-api.createcomponentextension) | | translations | The app translations list. | [createTranslationExtension.translationDataRef](https://backstage.io/docs/reference/frontend-plugin-api.createtranslationextension.translationdataref) | false | - | [createTranslationExtension](https://backstage.io/docs/reference/frontend-plugin-api.createtranslationextension) | +| icons | The app icons list. | [IconBundleBlueprint.dataRefs.icons](https://backstage.io/docs/reference/frontend-plugin-api.iconbundleblueprint.dataRefs.icons) | true | - | [IconBundleBlueprint](https://backstage.io/docs/reference/frontend-plugin-api.iconbundleblueprint) | #### Default theme extensions diff --git a/docs/frontend-system/building-apps/08-migrating.md b/docs/frontend-system/building-apps/08-migrating.md index 0abdd2aac3..716e0da772 100644 --- a/docs/frontend-system/building-apps/08-migrating.md +++ b/docs/frontend-system/building-apps/08-migrating.md @@ -314,6 +314,31 @@ const app = createApp({ }); ``` +### `icons` + +Icons are now installed as extensions, using the `IconBundleBlueprint` to make new instances which can be added to the app. + +```ts +import { IconBundleBlueprint } from '@backstage/frontend-plugin-api'; + +const exampleIconBundle = IconBundleBlueprint.make({ + name: 'example-bundle', + params: { + icons: { + user: MyOwnUserIcon, + }, + }, +}); + +const app = createApp({ + features: [ + createExtensionOverrides({ + extensions: [exampleIconBundle], + }), + ], +}); +``` + ### `bindRoutes` Route bindings can still be done using this option, but you now also have the ability to bind routes using static configuration instead. See the section on [binding routes](../architecture/07-routes.md#binding-external-route-references) for more information. diff --git a/docs/frontend-system/building-plugins/03-extension-types.md b/docs/frontend-system/building-plugins/03-extension-types.md index 2bea073ed6..1f3baaa710 100644 --- a/docs/frontend-system/building-plugins/03-extension-types.md +++ b/docs/frontend-system/building-plugins/03-extension-types.md @@ -38,6 +38,10 @@ Sign-in page extension have a single purpose - to implement a custom sign-in pag Theme extensions provide custom themes for the app. They are always attached to the app extension and you can have any number of themes extensions installed in an app at once, letting the user choose which theme to use. +### Icons - [Reference](../../reference/frontend-plugin-api.iconbundleblueprint.md) + +Icon bundle extensions provide the ability to replace or provide new icons to the app. You can use the above blueprint to make new extension instances which can be installed into the app. + ### Translation - [Reference](../../reference/frontend-plugin-api.createtranslationextension.md) Translation extension provide custom translation messages for the app. They can be used both to override the default english messages to custom ones, as well as provide translations for additional languages. diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createApp.tsx index 4d929b206f..8d39cb65aa 100644 --- a/packages/frontend-app-api/src/wiring/createApp.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.tsx @@ -172,7 +172,7 @@ export interface CreateAppFeatureLoader { /** @public */ export function createApp(options?: { - /** @deprecated - TODO */ + /** @deprecated - Please use {@link @backstage/frontend-app-api#IconBundleBlueprint} to make new icon bundles which can be installed in the app seperately */ icons?: { [key in string]: IconComponent }; features?: (FrontendFeature | CreateAppFeatureLoader)[]; configLoader?: () => Promise<{ config: ConfigApi }>; @@ -248,7 +248,7 @@ export function createApp(options?: { * @public */ export function createSpecializedApp(options?: { - /** @deprecated - TODO */ + /** @deprecated - Please use {@link @backstage/frontend-app-api#IconBundleBlueprint} to make new icon bundles which can be installed in the app seperately */ icons?: { [key in string]: IconComponent }; features?: FrontendFeature[]; config?: ConfigApi; From 2b4358b04429c02b6108bc93b285006ebd1a1be3 Mon Sep 17 00:00:00 2001 From: Ben Lambert <blam@spotify.com> Date: Tue, 23 Jul 2024 08:07:57 +0200 Subject: [PATCH 377/510] Update flat-plums-grow.md Signed-off-by: Ben Lambert <blam@spotify.com> --- .changeset/flat-plums-grow.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.changeset/flat-plums-grow.md b/.changeset/flat-plums-grow.md index b62f3e65a9..7057216786 100644 --- a/.changeset/flat-plums-grow.md +++ b/.changeset/flat-plums-grow.md @@ -2,5 +2,4 @@ '@backstage/plugin-scaffolder-react': patch --- -Add ability to customise form fields in the UI by exposing `uiSchema` and `formContext` in -`FormProps` +Add ability to customise form fields in the UI by exposing `uiSchema` and `formContext` in `FormProps` From d4e33aca1adc461063130fa36e255498490785ec Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Tue, 23 Jul 2024 08:19:53 +0200 Subject: [PATCH 378/510] chore: fixing tests Signed-off-by: blam <ben@blam.sh> --- .../src/components/TabbedLayout/RoutedTabs.test.tsx | 5 +++-- .../src/components/TabbedLayout/RoutedTabs.tsx | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/core-components/src/components/TabbedLayout/RoutedTabs.test.tsx b/packages/core-components/src/components/TabbedLayout/RoutedTabs.test.tsx index 991276c5d3..754ac2ec8d 100644 --- a/packages/core-components/src/components/TabbedLayout/RoutedTabs.test.tsx +++ b/packages/core-components/src/components/TabbedLayout/RoutedTabs.test.tsx @@ -162,14 +162,15 @@ describe('RoutedTabs', () => { }); it('should render the tabs as <a> links', async () => { - const routes = [testRoute2, testRoute1, testRoute3]; + const routes = [testRoute1, testRoute2, testRoute3]; + const expectedHrefs = ['/', '/some-other-path', '/some-other-path-similar']; const rendered = await renderInTestApp(<RoutedTabs routes={routes} />); const tabs = rendered.queryAllByRole('tab'); for (const [k, v] of Object.entries(tabs)) { expect(v.tagName).toBe('A'); - expect(v).toHaveAttribute('href', routes[Number(k)].path); + expect(v).toHaveAttribute('href', expectedHrefs[Number(k)]); } }); }); diff --git a/packages/core-components/src/components/TabbedLayout/RoutedTabs.tsx b/packages/core-components/src/components/TabbedLayout/RoutedTabs.tsx index d6f6eab144..b57a3782bb 100644 --- a/packages/core-components/src/components/TabbedLayout/RoutedTabs.tsx +++ b/packages/core-components/src/components/TabbedLayout/RoutedTabs.tsx @@ -79,9 +79,9 @@ export function RoutedTabs(props: { routes: SubRoute[] }) { id: path, label: title, tabProps: { - ...tabProps, component: Link, to, + ...tabProps, }, }; }), From 663568ebb6946f09a16458feca290059cb2ae79a Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Tue, 23 Jul 2024 08:28:46 +0200 Subject: [PATCH 379/510] chore: fixing todo package Signed-off-by: blam <ben@blam.sh> --- packages/frontend-app-api/src/wiring/createApp.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createApp.tsx index 8d39cb65aa..d82d0ca782 100644 --- a/packages/frontend-app-api/src/wiring/createApp.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.tsx @@ -172,7 +172,7 @@ export interface CreateAppFeatureLoader { /** @public */ export function createApp(options?: { - /** @deprecated - Please use {@link @backstage/frontend-app-api#IconBundleBlueprint} to make new icon bundles which can be installed in the app seperately */ + /** @deprecated - Please use {@link @backstage/frontend-plugin-api#IconBundleBlueprint} to make new icon bundles which can be installed in the app seperately */ icons?: { [key in string]: IconComponent }; features?: (FrontendFeature | CreateAppFeatureLoader)[]; configLoader?: () => Promise<{ config: ConfigApi }>; @@ -248,7 +248,7 @@ export function createApp(options?: { * @public */ export function createSpecializedApp(options?: { - /** @deprecated - Please use {@link @backstage/frontend-app-api#IconBundleBlueprint} to make new icon bundles which can be installed in the app seperately */ + /** @deprecated - Please use {@link @backstage/frontend-plugin-api#IconBundleBlueprint} to make new icon bundles which can be installed in the app seperately */ icons?: { [key in string]: IconComponent }; features?: FrontendFeature[]; config?: ConfigApi; From fbc7819133216ada61e2782a91b96a5d7954a0b2 Mon Sep 17 00:00:00 2001 From: Heikki Hellgren <heikki.hellgren@op.fi> Date: Tue, 23 Jul 2024 10:17:41 +0300 Subject: [PATCH 380/510] fix: use es2022 in cli bundler and in storybook fixes #25737 Signed-off-by: Heikki Hellgren <heikki.hellgren@op.fi> --- .changeset/cuddly-zebras-crash.md | 5 +++++ packages/cli/src/lib/bundler/optimization.ts | 4 ++-- packages/cli/src/lib/bundler/transforms.ts | 6 +++--- storybook/.storybook/main.js | 4 ++-- 4 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 .changeset/cuddly-zebras-crash.md diff --git a/.changeset/cuddly-zebras-crash.md b/.changeset/cuddly-zebras-crash.md new file mode 100644 index 0000000000..473ac4053f --- /dev/null +++ b/.changeset/cuddly-zebras-crash.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Use ES2022 in CLI bundler diff --git a/packages/cli/src/lib/bundler/optimization.ts b/packages/cli/src/lib/bundler/optimization.ts index 891e0793fe..cf240b4791 100644 --- a/packages/cli/src/lib/bundler/optimization.ts +++ b/packages/cli/src/lib/bundler/optimization.ts @@ -28,13 +28,13 @@ export const optimization = ( minimize: !isDev, minimizer: [ new EsbuildPlugin({ - target: 'es2019', + target: 'ES2022', format: 'iife', exclude: 'remoteEntry.js', }), // Avoid iife wrapping of module federation remote entry as it breaks the variable assignment new EsbuildPlugin({ - target: 'es2019', + target: 'ES2022', format: undefined, include: 'remoteEntry.js', }), diff --git a/packages/cli/src/lib/bundler/transforms.ts b/packages/cli/src/lib/bundler/transforms.ts index 0900b8e48e..1be54f7a73 100644 --- a/packages/cli/src/lib/bundler/transforms.ts +++ b/packages/cli/src/lib/bundler/transforms.ts @@ -57,7 +57,7 @@ export const transforms = (options: TransformOptions): Transforms => { loader: require.resolve('swc-loader'), options: { jsc: { - target: 'es2019', + target: 'ES2022', externalHelpers: !isBackend, parser: { syntax: 'typescript', @@ -85,7 +85,7 @@ export const transforms = (options: TransformOptions): Transforms => { loader: require.resolve('swc-loader'), options: { jsc: { - target: 'es2019', + target: 'ES2022', externalHelpers: !isBackend, parser: { syntax: 'ecmascript', @@ -118,7 +118,7 @@ export const transforms = (options: TransformOptions): Transforms => { loader: require.resolve('swc-loader'), options: { jsc: { - target: 'es2019', + target: 'es2022', externalHelpers: !isBackend, parser: { syntax: 'ecmascript', diff --git a/storybook/.storybook/main.js b/storybook/.storybook/main.js index cb5f364a32..799c6c7c85 100644 --- a/storybook/.storybook/main.js +++ b/storybook/.storybook/main.js @@ -69,7 +69,7 @@ module.exports = Object.assign(({ args }) => { loader: require.resolve('swc-loader'), options: { jsc: { - target: 'es2019', + target: 'ES2022', parser: { syntax: 'typescript', tsx: true, @@ -89,7 +89,7 @@ module.exports = Object.assign(({ args }) => { loader: require.resolve('swc-loader'), options: { jsc: { - target: 'es2019', + target: 'ES2022', parser: { syntax: 'ecmascript', jsx: true, From faa1b465e9d5fb64110ff3fe121959f4839fbe3e Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Tue, 23 Jul 2024 09:52:28 +0200 Subject: [PATCH 381/510] app-next,docs: add example for public index entry point in new frontend system Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- docs/tutorials/enable-public-entry.md | 43 ++++++++++++++++ packages/app-next/src/App.tsx | 17 ++----- .../src/index-public-experimental.tsx | 49 +++++++++++++++++++ .../app-next/src/overrides/SignInPage.tsx | 31 ++++++++++++ 4 files changed, 126 insertions(+), 14 deletions(-) create mode 100644 packages/app-next/src/index-public-experimental.tsx create mode 100644 packages/app-next/src/overrides/SignInPage.tsx diff --git a/docs/tutorials/enable-public-entry.md b/docs/tutorials/enable-public-entry.md index 6282f66418..d257753413 100644 --- a/docs/tutorials/enable-public-entry.md +++ b/docs/tutorials/enable-public-entry.md @@ -100,3 +100,46 @@ With that, Backstage's cli and backend will detect public entry point and serve 5. Finally, as soon as you log in, you will be redirected to the main app home page (inspect the page and see that the protected bundle was served from the app backend after the redirect). That's it! + +## New Frontend System + +If your app uses the new frontend system, you can still use the public entry point feature. The `index-public-experimental.tsx` file does end up looking a bit different in this case: + +```tsx title="in packages/app/src/index-public-experimental.tsx" +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import { CookieAuthRedirect } from '@backstage/plugin-auth-react'; +import { createApp } from '@backstage/frontend-app-api'; +import { + coreExtensionData, + createExtension, + createExtensionOverrides, +} from '@backstage/frontend-plugin-api'; + +const signInPage = createSignInPageExtension({ + name: 'guest', + loader: async () => props => <SignInPage {...props} providers={['guest']} />, +}); + +const authRedirectExtension = createExtension({ + namespace: 'app', + name: 'layout', + attachTo: { id: 'app/root', input: 'children' }, + output: { + element: coreExtensionData.reactElement, + }, + factory: () => ({ + element: <CookieAuthRedirect />, + }), +}); + +const app = createApp({ + features: [ + createExtensionOverrides({ + extensions: [signInPage, authRedirectExtension], + }), + ], +}); + +ReactDOM.createRoot(document.getElementById('root')!).render(app.createRoot()); +``` diff --git a/packages/app-next/src/App.tsx b/packages/app-next/src/App.tsx index c911a01258..14c4da8467 100644 --- a/packages/app-next/src/App.tsx +++ b/packages/app-next/src/App.tsx @@ -36,18 +36,13 @@ import { convertLegacyApp } from '@backstage/core-compat-api'; import { FlatRoutes } from '@backstage/core-app-api'; import { Route } from 'react-router'; import { CatalogImportPage } from '@backstage/plugin-catalog-import'; -import { - createApiFactory, - configApiRef, - SignInPageProps, -} from '@backstage/core-plugin-api'; +import { createApiFactory, configApiRef } from '@backstage/core-plugin-api'; import { ScmAuth, ScmIntegrationsApi, scmIntegrationsApiRef, } from '@backstage/integration-react'; -import { createSignInPageExtension } from '@backstage/frontend-plugin-api'; -import { SignInPage } from '@backstage/core-components'; +import { signInPageOverrides } from './overrides/SignInPage'; /* @@ -90,12 +85,6 @@ const homePageExtension = createExtension({ }, }); -const signInPage = createSignInPageExtension({ - name: 'guest', - loader: async () => (props: SignInPageProps) => - <SignInPage {...props} providers={['guest']} />, -}); - const scmAuthExtension = createApiExtension({ factory: ScmAuth.createDefaultApiFactory(), }); @@ -121,13 +110,13 @@ const app = createApp({ userSettingsPlugin, homePlugin, appVisualizerPlugin, + signInPageOverrides, ...collectedLegacyPlugins, createExtensionOverrides({ extensions: [ homePageExtension, scmAuthExtension, scmIntegrationApi, - signInPage, notFoundErrorPage, ], }), diff --git a/packages/app-next/src/index-public-experimental.tsx b/packages/app-next/src/index-public-experimental.tsx new file mode 100644 index 0000000000..56bc698ffd --- /dev/null +++ b/packages/app-next/src/index-public-experimental.tsx @@ -0,0 +1,49 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import { CookieAuthRedirect } from '@backstage/plugin-auth-react'; +import { createApp } from '@backstage/frontend-app-api'; +import { signInPageOverrides } from './overrides/SignInPage'; +import { + coreExtensionData, + createExtension, + createExtensionOverrides, +} from '@backstage/frontend-plugin-api'; + +const authRedirectExtension = createExtension({ + namespace: 'app', + name: 'layout', + attachTo: { id: 'app/root', input: 'children' }, + output: { + element: coreExtensionData.reactElement, + }, + factory: () => ({ + element: <CookieAuthRedirect />, + }), +}); + +const app = createApp({ + features: [ + signInPageOverrides, + createExtensionOverrides({ + extensions: [authRedirectExtension], + }), + ], +}); + +ReactDOM.createRoot(document.getElementById('root')!).render(app.createRoot()); diff --git a/packages/app-next/src/overrides/SignInPage.tsx b/packages/app-next/src/overrides/SignInPage.tsx new file mode 100644 index 0000000000..364a749293 --- /dev/null +++ b/packages/app-next/src/overrides/SignInPage.tsx @@ -0,0 +1,31 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { SignInPage } from '@backstage/core-components'; +import { + createExtensionOverrides, + createSignInPageExtension, +} from '@backstage/frontend-plugin-api'; + +const signInPage = createSignInPageExtension({ + name: 'guest', + loader: async () => props => <SignInPage {...props} providers={['guest']} />, +}); + +export const signInPageOverrides = createExtensionOverrides({ + extensions: [signInPage], +}); From c79eac60653eefe154ea0d68ccd0a9a72785bbc4 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Tue, 23 Jul 2024 10:04:38 +0200 Subject: [PATCH 382/510] scaffolder: fix deprecation comment formatting Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .../src/deprecated.ts | 12 +++-- .../src/scaffolder/actions/deprecated.ts | 54 ++++++++++++------- 2 files changed, 44 insertions(+), 22 deletions(-) diff --git a/plugins/scaffolder-backend-module-bitbucket/src/deprecated.ts b/plugins/scaffolder-backend-module-bitbucket/src/deprecated.ts index a17c88c3a4..a9daa771f0 100644 --- a/plugins/scaffolder-backend-module-bitbucket/src/deprecated.ts +++ b/plugins/scaffolder-backend-module-bitbucket/src/deprecated.ts @@ -19,25 +19,29 @@ import * as bitbucketServer from '@backstage/plugin-scaffolder-backend-module-bi export { createPublishBitbucketAction } from './actions/bitbucket'; /** - * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-bitbucket-cloud instead + * @public + * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-bitbucket-cloud` instead */ export const createPublishBitbucketCloudAction = bitbucketCloud.createPublishBitbucketCloudAction; /** - * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-bitbucket-cloud instead + * @public + * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-bitbucket-cloud` instead */ export const createBitbucketPipelinesRunAction = bitbucketCloud.createBitbucketPipelinesRunAction; /** - * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-bitbucket-server instead + * @public + * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-bitbucket-server` instead */ export const createPublishBitbucketServerAction = bitbucketServer.createPublishBitbucketServerAction; /** - * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-bitbucket-server instead + * @public + * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-bitbucket-server` instead */ export const createPublishBitbucketServerPullRequestAction = bitbucketServer.createPublishBitbucketServerPullRequestAction; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/deprecated.ts b/plugins/scaffolder-backend/src/scaffolder/actions/deprecated.ts index fd5fdd49e8..5d037b44b6 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/deprecated.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/deprecated.ts @@ -22,56 +22,66 @@ import * as bitbucketServer from '@backstage/plugin-scaffolder-backend-module-bi import * as gerrit from '@backstage/plugin-scaffolder-backend-module-gerrit'; /** - * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-github instead + * @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 + * @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 + * @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 + * @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 + * @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 + * @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 + * @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 + * @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 + * @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 + * @public + * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-github` instead */ export const createPublishGithubPullRequestAction = github.createPublishGithubPullRequestAction; @@ -83,46 +93,54 @@ export const createPublishBitbucketAction = bitbucket.createPublishBitbucketAction; /** - * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-bitbucket-cloud instead + * @public + * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-bitbucket-cloud` instead */ export const createPublishBitbucketCloudAction = bitbucketCloud.createPublishBitbucketCloudAction; /** - * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-bitbucket-server instead + * @public + * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-bitbucket-server` instead */ export const createPublishBitbucketServerAction = bitbucketServer.createPublishBitbucketServerAction; /** - * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-bitbucket-server instead + * @public + * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-bitbucket-server` instead */ export const createPublishBitbucketServerPullRequestAction = bitbucketServer.createPublishBitbucketServerPullRequestAction; /** - * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-azure instead + * @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 + * @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 + * @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 + * @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 + * @public + * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-gitlab` instead */ export const createPublishGitlabMergeRequestAction = gitlab.createPublishGitlabMergeRequestAction; From a6603e4f34e1b6c2338ebfa3d8034e6744efcb21 Mon Sep 17 00:00:00 2001 From: Yghore <yhgore@gmail.com> Date: Mon, 8 Jul 2024 21:32:28 +0200 Subject: [PATCH 383/510] feat: add automatic commited action for merge-request gitlab Signed-off-by: Yghore <yhgore@gmail.com> --- .changeset/wild-eggs-exist.md | 10 ++++ .../src/actions/gitlabMergeRequest.ts | 53 ++++++++++++++----- 2 files changed, 50 insertions(+), 13 deletions(-) create mode 100644 .changeset/wild-eggs-exist.md diff --git a/.changeset/wild-eggs-exist.md b/.changeset/wild-eggs-exist.md new file mode 100644 index 0000000000..68c49e343b --- /dev/null +++ b/.changeset/wild-eggs-exist.md @@ -0,0 +1,10 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gitlab': patch +--- + +Add custom action for merge request: **auto** + +The **Auto** action selects the committed action between _create_ and _update_. + +The **Auto** action fetches files using the **/projects/repository/tree endpoint**. +After fetching, it checks if the file exists locally and in the repository. If it does, it chooses **update**; otherwise, it chooses **create**. diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts index a549585426..6032b4ac28 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts @@ -17,6 +17,7 @@ import { createTemplateAction, parseRepoUrl, + SerializedFile, serializeDirectoryContents, } from '@backstage/plugin-scaffolder-node'; import { Types } from '@gitbeaker/core'; @@ -27,6 +28,20 @@ import { resolveSafeChildPath } from '@backstage/backend-plugin-api'; import { createGitlabApi } from './helpers'; import { examples } from './gitlabMergeRequest.examples'; +function getFileAction( + file: SerializedFile, + remoteFiles: Types.RepositoryTreeSchema[], + defaultCommitAction: 'create' | 'delete' | 'update' | 'auto' | undefined, +): 'create' | 'delete' | 'update' { + if (defaultCommitAction === 'auto') { + return remoteFiles && + remoteFiles.some(remoteFile => remoteFile.path === file.path) + ? 'update' + : 'create'; + } + return defaultCommitAction ?? 'create'; +} + /** * Create a new action that creates a gitlab merge request. * @@ -46,7 +61,7 @@ export const createPublishGitlabMergeRequestAction = (options: { sourcePath?: string; targetPath?: string; token?: string; - commitAction?: 'create' | 'delete' | 'update'; + commitAction?: 'create' | 'delete' | 'update' | 'auto'; /** @deprecated projectID passed as query parameters in the repoUrl */ projectid?: string; removeSourceBranch?: boolean; @@ -109,9 +124,9 @@ export const createPublishGitlabMergeRequestAction = (options: { commitAction: { title: 'Commit action', type: 'string', - enum: ['create', 'update', 'delete'], + enum: ['create', 'update', 'delete', 'auto'], description: - 'The action to be used for git commit. Defaults to create.', + 'The action to be used for git commit. Defaults to create. "auto" is custom action provide by backstage, (automatic assign create or update action) /!\\ Use more api calls /!\\ *', }, removeSourceBranch: { title: 'Delete source branch', @@ -199,16 +214,7 @@ export const createPublishGitlabMergeRequestAction = (options: { gitignore: true, }); - const actions: Types.CommitAction[] = fileContents.map(file => ({ - action: ctx.input.commitAction ?? 'create', - filePath: targetPath - ? path.posix.join(targetPath, file.path) - : file.path, - encoding: 'base64', - content: file.content.toString('base64'), - execute_filemode: file.executable, - })); - + let remoteFiles: Types.RepositoryTreeSchema[]; let targetBranch = targetBranchName; if (!targetBranch) { const projects = await api.Projects.show(repoID); @@ -216,6 +222,27 @@ export const createPublishGitlabMergeRequestAction = (options: { const { default_branch: defaultBranch } = projects; targetBranch = defaultBranch!; } + try { + remoteFiles = await api.Repositories.tree(repoID, { + ref: targetBranch, + recursive: true, + path: targetPath ?? undefined, + }); + } catch (e) { + ctx.logger.warn( + `Could not retrieve the list of files for ${repoID} (branch: ${targetBranch}) : ${e}`, + ); + } + + const actions: Types.CommitAction[] = fileContents.map(file => ({ + action: getFileAction(file, remoteFiles, ctx.input.commitAction), + filePath: targetPath + ? path.posix.join(targetPath, file.path) + : file.path, + encoding: 'base64', + content: file.content.toString('base64'), + execute_filemode: file.executable, + })); try { await api.Branches.create(repoID, branchName, String(targetBranch)); From 224958e95239ddf67176fbf4695635dfad70d80d Mon Sep 17 00:00:00 2001 From: Yghore <yhgore@gmail.com> Date: Mon, 8 Jul 2024 21:55:46 +0200 Subject: [PATCH 384/510] doc: add api report Signed-off-by: Yghore <yhgore@gmail.com> --- .../scaffolder-backend-module-gitlab/api-report.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitlab/api-report.md b/plugins/scaffolder-backend-module-gitlab/api-report.md index b1f240029e..4b5dc491ca 100644 --- a/plugins/scaffolder-backend-module-gitlab/api-report.md +++ b/plugins/scaffolder-backend-module-gitlab/api-report.md @@ -33,11 +33,11 @@ export const createGitlabIssueAction: (options: { projectId: number; labels?: string | undefined; description?: string | undefined; - weight?: number | undefined; token?: string | undefined; + weight?: number | undefined; assignees?: number[] | undefined; - createdAt?: string | undefined; confidential?: boolean | undefined; + createdAt?: string | undefined; milestoneId?: number | undefined; epicId?: number | undefined; dueDate?: string | undefined; @@ -61,8 +61,8 @@ export const createGitlabProjectAccessTokenAction: (options: { projectId: string | number; name?: string | undefined; token?: string | undefined; - scopes?: string[] | undefined; expiresAt?: string | undefined; + scopes?: string[] | undefined; accessLevel?: number | undefined; }, { @@ -118,7 +118,7 @@ export const createGitlabRepoPushAction: (options: { sourcePath?: string | undefined; targetPath?: string | undefined; token?: string | undefined; - commitAction?: 'update' | 'delete' | 'create' | undefined; + commitAction?: 'update' | 'create' | 'delete' | undefined; }, JsonObject >; @@ -193,7 +193,7 @@ export const createPublishGitlabMergeRequestAction: (options: { sourcePath?: string | undefined; targetPath?: string | undefined; token?: string | undefined; - commitAction?: 'update' | 'delete' | 'create' | undefined; + commitAction?: 'auto' | 'update' | 'create' | 'delete' | undefined; projectid?: string | undefined; removeSourceBranch?: boolean | undefined; assignee?: string | undefined; @@ -206,8 +206,8 @@ export const createTriggerGitlabPipelineAction: (options: { integrations: ScmIntegrationRegistry; }) => TemplateAction< { - branch: string; repoUrl: string; + branch: string; projectId: number; tokenDescription: string; token?: string | undefined; @@ -229,8 +229,8 @@ export const editGitlabIssueAction: (options: { title?: string | undefined; labels?: string | undefined; description?: string | undefined; - weight?: number | undefined; token?: string | undefined; + weight?: number | undefined; assignees?: number[] | undefined; addLabels?: string | undefined; confidential?: boolean | undefined; From ed0bea5d93d4b2e1f52d04469eb6b288fc13abde Mon Sep 17 00:00:00 2001 From: Yghore <yhgore@gmail.com> Date: Sun, 14 Jul 2024 22:56:19 +0200 Subject: [PATCH 385/510] fix(default action) create -> auto Signed-off-by: Yghore <yhgore@gmail.com> --- .../scaffolder-backend-module-gitlab/api-report.md | 14 +++++++------- .../src/actions/gitlabMergeRequest.ts | 6 +++--- plugins/scaffolder-backend/api-report.md | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitlab/api-report.md b/plugins/scaffolder-backend-module-gitlab/api-report.md index 4b5dc491ca..ab89669ede 100644 --- a/plugins/scaffolder-backend-module-gitlab/api-report.md +++ b/plugins/scaffolder-backend-module-gitlab/api-report.md @@ -33,11 +33,11 @@ export const createGitlabIssueAction: (options: { projectId: number; labels?: string | undefined; description?: string | undefined; - token?: string | undefined; weight?: number | undefined; + token?: string | undefined; assignees?: number[] | undefined; - confidential?: boolean | undefined; createdAt?: string | undefined; + confidential?: boolean | undefined; milestoneId?: number | undefined; epicId?: number | undefined; dueDate?: string | undefined; @@ -61,8 +61,8 @@ export const createGitlabProjectAccessTokenAction: (options: { projectId: string | number; name?: string | undefined; token?: string | undefined; - expiresAt?: string | undefined; scopes?: string[] | undefined; + expiresAt?: string | undefined; accessLevel?: number | undefined; }, { @@ -118,7 +118,7 @@ export const createGitlabRepoPushAction: (options: { sourcePath?: string | undefined; targetPath?: string | undefined; token?: string | undefined; - commitAction?: 'update' | 'create' | 'delete' | undefined; + commitAction?: 'update' | 'delete' | 'create' | undefined; }, JsonObject >; @@ -193,7 +193,7 @@ export const createPublishGitlabMergeRequestAction: (options: { sourcePath?: string | undefined; targetPath?: string | undefined; token?: string | undefined; - commitAction?: 'auto' | 'update' | 'create' | 'delete' | undefined; + commitAction?: 'auto' | 'update' | 'delete' | 'create' | undefined; projectid?: string | undefined; removeSourceBranch?: boolean | undefined; assignee?: string | undefined; @@ -206,8 +206,8 @@ export const createTriggerGitlabPipelineAction: (options: { integrations: ScmIntegrationRegistry; }) => TemplateAction< { - repoUrl: string; branch: string; + repoUrl: string; projectId: number; tokenDescription: string; token?: string | undefined; @@ -229,8 +229,8 @@ export const editGitlabIssueAction: (options: { title?: string | undefined; labels?: string | undefined; description?: string | undefined; - token?: string | undefined; weight?: number | undefined; + token?: string | undefined; assignees?: number[] | undefined; addLabels?: string | undefined; confidential?: boolean | undefined; diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts index 6032b4ac28..d256a2166b 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts @@ -33,13 +33,13 @@ function getFileAction( remoteFiles: Types.RepositoryTreeSchema[], defaultCommitAction: 'create' | 'delete' | 'update' | 'auto' | undefined, ): 'create' | 'delete' | 'update' { - if (defaultCommitAction === 'auto') { + if (!defaultCommitAction || defaultCommitAction === 'auto') { return remoteFiles && remoteFiles.some(remoteFile => remoteFile.path === file.path) ? 'update' : 'create'; } - return defaultCommitAction ?? 'create'; + return defaultCommitAction; } /** @@ -126,7 +126,7 @@ export const createPublishGitlabMergeRequestAction = (options: { type: 'string', enum: ['create', 'update', 'delete', 'auto'], description: - 'The action to be used for git commit. Defaults to create. "auto" is custom action provide by backstage, (automatic assign create or update action) /!\\ Use more api calls /!\\ *', + 'The action to be used for git commit. Defaults to auto. "auto" is custom action provide by backstage, (automatic assign create or update action) /!\\ Use more api calls /!\\ *', }, removeSourceBranch: { title: 'Delete source branch', diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index a3beee2b53..907a30b541 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -312,7 +312,7 @@ export const createPublishGitlabMergeRequestAction: (options: { sourcePath?: string | undefined; targetPath?: string | undefined; token?: string | undefined; - commitAction?: 'update' | 'delete' | 'create' | undefined; + commitAction?: 'auto' | 'update' | 'delete' | 'create' | undefined; projectid?: string | undefined; removeSourceBranch?: boolean | undefined; assignee?: string | undefined; From 3afa2966b2e2b2d90196e604fffa939450e145e8 Mon Sep 17 00:00:00 2001 From: Yghore <yhgore@gmail.com> Date: Tue, 9 Jul 2024 13:12:25 +0000 Subject: [PATCH 386/510] fix: remote file was always fetched even without auto commit action Signed-off-by: Yghore <yhgore@gmail.com> --- .../src/actions/gitlabMergeRequest.ts | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts index d256a2166b..0c6a6fad48 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts @@ -214,7 +214,6 @@ export const createPublishGitlabMergeRequestAction = (options: { gitignore: true, }); - let remoteFiles: Types.RepositoryTreeSchema[]; let targetBranch = targetBranchName; if (!targetBranch) { const projects = await api.Projects.show(repoID); @@ -222,16 +221,20 @@ export const createPublishGitlabMergeRequestAction = (options: { const { default_branch: defaultBranch } = projects; targetBranch = defaultBranch!; } - try { - remoteFiles = await api.Repositories.tree(repoID, { - ref: targetBranch, - recursive: true, - path: targetPath ?? undefined, - }); - } catch (e) { - ctx.logger.warn( - `Could not retrieve the list of files for ${repoID} (branch: ${targetBranch}) : ${e}`, - ); + + let remoteFiles: Types.RepositoryTreeSchema[] = []; + if (ctx.input.commitAction && ctx.input.commitAction === 'auto') { + try { + remoteFiles = await api.Repositories.tree(repoID, { + ref: targetBranch, + recursive: true, + path: targetPath ?? undefined, + }); + } catch (e) { + ctx.logger.warn( + `Could not retrieve the list of files for ${repoID} (branch: ${targetBranch}) : ${e}`, + ); + } } const actions: Types.CommitAction[] = fileContents.map(file => ({ From 9281a5e9bd60da001cc413dd58a7043a94232e72 Mon Sep 17 00:00:00 2001 From: Yghore <yhgore@gmail.com> Date: Mon, 15 Jul 2024 12:29:41 +0000 Subject: [PATCH 387/510] fix(filepath if targetPath is set), fix(default commitAction not retrieve repo files) Signed-off-by: Yghore <yhgore@gmail.com> --- .../src/actions/gitlabMergeRequest.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts index 0c6a6fad48..733365c6df 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts @@ -29,13 +29,14 @@ import { createGitlabApi } from './helpers'; import { examples } from './gitlabMergeRequest.examples'; function getFileAction( - file: SerializedFile, + fileInfo: { file: SerializedFile; targetPath: string | undefined }, remoteFiles: Types.RepositoryTreeSchema[], defaultCommitAction: 'create' | 'delete' | 'update' | 'auto' | undefined, ): 'create' | 'delete' | 'update' { if (!defaultCommitAction || defaultCommitAction === 'auto') { + const filePath = path.join(fileInfo.targetPath ?? '', fileInfo.file.path); return remoteFiles && - remoteFiles.some(remoteFile => remoteFile.path === file.path) + remoteFiles.some(remoteFile => remoteFile.path === filePath) ? 'update' : 'create'; } @@ -223,7 +224,7 @@ export const createPublishGitlabMergeRequestAction = (options: { } let remoteFiles: Types.RepositoryTreeSchema[] = []; - if (ctx.input.commitAction && ctx.input.commitAction === 'auto') { + if (!ctx.input.commitAction || ctx.input.commitAction === 'auto') { try { remoteFiles = await api.Repositories.tree(repoID, { ref: targetBranch, @@ -238,7 +239,11 @@ export const createPublishGitlabMergeRequestAction = (options: { } const actions: Types.CommitAction[] = fileContents.map(file => ({ - action: getFileAction(file, remoteFiles, ctx.input.commitAction), + action: getFileAction( + { file, targetPath }, + remoteFiles, + ctx.input.commitAction, + ), filePath: targetPath ? path.posix.join(targetPath, file.path) : file.path, From 422f883e4e8a7b38452ba6f58e0af910d8894ae3 Mon Sep 17 00:00:00 2001 From: Yghore <yhgore@gmail.com> Date: Mon, 15 Jul 2024 12:33:00 +0000 Subject: [PATCH 388/510] add: test for auto commited action Signed-off-by: Yghore <yhgore@gmail.com> --- .../src/actions/gitlabMergeRequest.test.ts | 115 +++++++++++++++++- 1 file changed, 113 insertions(+), 2 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.test.ts index befc2c01c9..3eda50a924 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.test.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.test.ts @@ -61,6 +61,28 @@ const mockGitlabClient = { ]; }), }, + Repositories: { + tree: jest.fn( + async ( + repoID: string | number, + options: { ref: string; recursive: boolean; path: string | undefined }, + ) => { + if (repoID !== 'owner/repo') throw new Error('repo does not exist'); + if (options.recursive === false) throw new Error('malformed options'); + else { + return [ + { + id: 'a1e8f8d745cc87e3a9248358d9352bb7f9a0aeba', + name: 'auto.txt', + type: 'blob', + path: 'source/auto.txt', + mode: '040000', + }, + ]; + } + }, + ), + }, }; jest.mock('@gitbeaker/node', () => ({ @@ -407,7 +429,7 @@ describe('createGitLabMergeRequest', () => { }); describe('createGitLabMergeRequestWithoutCommitAction', () => { - it('default commitAction is create', async () => { + it('default commitAction is auto', async () => { const input = { repoUrl: 'gitlab.com?repo=repo&owner=owner', title: 'Create my new MR', @@ -417,7 +439,7 @@ describe('createGitLabMergeRequest', () => { }; mockDir.setContent({ [workspacePath]: { - source: { 'foo.txt': 'Hello there!' }, + source: { 'foo.txt': 'Hello there!', 'auto.txt': 'File exist' }, irrelevant: { 'bar.txt': 'Nothing to see here' }, }, }); @@ -429,6 +451,13 @@ describe('createGitLabMergeRequest', () => { 'new-mr', 'Create my new MR', [ + { + action: 'update', + filePath: 'source/auto.txt', + content: 'RmlsZSBleGlzdA==', + encoding: 'base64', + execute_filemode: false, + }, { action: 'create', filePath: 'source/foo.txt', @@ -512,6 +541,88 @@ describe('createGitLabMergeRequest', () => { ); }); + it('commitAction is auto when auto is passed in options', async () => { + const input = { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + title: 'Create my new MR', + branchName: 'new-mr', + description: 'MR description', + commitAction: 'auto', + }; + mockDir.setContent({ + [workspacePath]: { + source: { 'foo.txt': 'Hello there!', 'auto.txt': 'File exist' }, + }, + }); + + const ctx = createMockActionContext({ input, workspacePath }); + await instance.handler(ctx); + + expect(mockGitlabClient.Commits.create).toHaveBeenCalledWith( + 'owner/repo', + 'new-mr', + 'Create my new MR', + [ + { + action: 'update', + filePath: 'source/auto.txt', + content: 'RmlsZSBleGlzdA==', + encoding: 'base64', + execute_filemode: false, + }, + { + action: 'create', + filePath: 'source/foo.txt', + content: 'SGVsbG8gdGhlcmUh', + encoding: 'base64', + execute_filemode: false, + }, + ], + ); + }); + + it('commitAction is auto when auto is passed in options with targetPath', async () => { + const input = { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + title: 'Create my new MR', + branchName: 'new-mr', + description: 'MR description', + commitAction: 'auto', + targetPath: 'source', + }; + mockDir.setContent({ + [workspacePath]: { + source: { 'foo.txt': 'Hello there!', 'auto.txt': 'File exist' }, + irrevelant: {}, + }, + }); + + const ctx = createMockActionContext({ input, workspacePath }); + await instance.handler(ctx); + + expect(mockGitlabClient.Commits.create).toHaveBeenCalledWith( + 'owner/repo', + 'new-mr', + 'Create my new MR', + [ + { + action: 'update', + filePath: 'source/auto.txt', + content: 'RmlsZSBleGlzdA==', + encoding: 'base64', + execute_filemode: false, + }, + { + action: 'create', + filePath: 'source/foo.txt', + content: 'SGVsbG8gdGhlcmUh', + encoding: 'base64', + execute_filemode: false, + }, + ], + ); + }); + it('commitAction is delete when delete is passed in options', async () => { const input = { repoUrl: 'gitlab.com?repo=repo&owner=owner', From 9999ce0937e33086ca2c8a601400f2967b4ebfb1 Mon Sep 17 00:00:00 2001 From: Yghore <yhgore@gmail.com> Date: Mon, 15 Jul 2024 12:47:17 +0000 Subject: [PATCH 389/510] fix: add api-report... Signed-off-by: Yghore <yhgore@gmail.com> --- plugins/scaffolder-backend/api-report.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index 907a30b541..ca008c4280 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -312,7 +312,10 @@ export const createPublishGitlabMergeRequestAction: (options: { sourcePath?: string | undefined; targetPath?: string | undefined; token?: string | undefined; - commitAction?: 'auto' | 'update' | 'delete' | 'create' | undefined; + commitAction?: 'auto' | 'update' | 'delete' | 'create' | undefined + /** + * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-github instead + */; projectid?: string | undefined; removeSourceBranch?: boolean | undefined; assignee?: string | undefined; From 6bec6090a8bbfb11691118bf87c416afdd77eacc Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Tue, 23 Jul 2024 10:21:26 +0200 Subject: [PATCH 390/510] chore: fix api-reports Signed-off-by: blam <ben@blam.sh> --- plugins/scaffolder-backend/api-report.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index ca008c4280..907a30b541 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -312,10 +312,7 @@ export const createPublishGitlabMergeRequestAction: (options: { sourcePath?: string | undefined; targetPath?: string | undefined; token?: string | undefined; - commitAction?: 'auto' | 'update' | 'delete' | 'create' | undefined - /** - * @public @deprecated use import from \@backstage/plugin-scaffolder-backend-module-github instead - */; + commitAction?: 'auto' | 'update' | 'delete' | 'create' | undefined; projectid?: string | undefined; removeSourceBranch?: boolean | undefined; assignee?: string | undefined; From c3f56507740906dddeeb6304216db9f77755dec6 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Tue, 23 Jul 2024 10:32:30 +0200 Subject: [PATCH 391/510] chore: migrate the EntityCardExtension to EntityCardBlueprint Signed-off-by: blam <ben@blam.sh> --- plugins/catalog-react/src/alpha.tsx | 39 +++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/plugins/catalog-react/src/alpha.tsx b/plugins/catalog-react/src/alpha.tsx index e81b8e5ebf..7f276b8ea6 100644 --- a/plugins/catalog-react/src/alpha.tsx +++ b/plugins/catalog-react/src/alpha.tsx @@ -22,6 +22,7 @@ import { RouteRef, coreExtensionData, createExtension, + createExtensionBlueprint, createExtensionDataRef, createSchemaFromZod, } from '@backstage/frontend-plugin-api'; @@ -47,6 +48,44 @@ export const catalogExtensionData = { }), }; +/** @alpha */ +export const EntityCardBlueprint = createExtensionBlueprint({ + kind: 'entity-card', + attachTo: { id: 'entity-content:catalog/overview', input: 'cards' }, + configSchema: createSchemaFromZod(z => + z.object({ + filter: z.string().optional(), + }), + ), + output: { + element: coreExtensionData.reactElement, + filterFunction: catalogExtensionData.entityFilterFunction.optional(), + filterExpression: catalogExtensionData.entityFilterExpression.optional(), + }, + factory( + params: { + filter?: + | typeof catalogExtensionData.entityFilterFunction.T + | typeof catalogExtensionData.entityFilterExpression.T; + loader: () => Promise<JSX.Element>; + }, + { node, config }, + ) { + const ExtensionComponent = lazy(() => + params.loader().then(element => ({ default: () => element })), + ); + + return { + element: ( + <ExtensionBoundary node={node}> + <ExtensionComponent /> + </ExtensionBoundary> + ), + ...mergeFilters({ config, options: params }), + }; + }, +}); + // TODO: Figure out how to merge with provided config schema /** @alpha */ export function createEntityCardExtension< From d5bf3b1f4b7dd3f1c2ba76141c3ba972e0dcfd20 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Tue, 23 Jul 2024 11:09:33 +0200 Subject: [PATCH 392/510] chore: rework how to define factory functions and params in blueprints Signed-off-by: blam <ben@blam.sh> --- .../wiring/createExtensionBlueprint.test.tsx | 13 +-- .../src/wiring/createExtensionBlueprint.ts | 110 ++++++++++-------- 2 files changed, 66 insertions(+), 57 deletions(-) diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx index 87b3cec152..d2373518a3 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx @@ -88,20 +88,17 @@ describe('createExtensionBlueprint', () => { const extension = TestExtensionBlueprint.make({ name: 'my-extension', - params: { - text: 'Hello, world!', - }, - factory(params: { text: string }) { - return { - element: <h2>{params.text}</h2>, - }; + factory(origFactory) { + return origFactory({ + text: 'Hello, world!', + }); }, }); expect(extension).toBeDefined(); const { container } = createExtensionTester(extension).render(); - expect(container.querySelector('h2')).toHaveTextContent('Hello, world!'); + expect(container.querySelector('h1')).toHaveTextContent('Hello, world!'); }); it('should allow exporting the dataRefs from the extension blueprint', () => { diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts index b504db5f03..fb9081f7f8 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts @@ -67,32 +67,43 @@ export interface ExtensionBlueprint< > { dataRefs: TDataRefs; - make(args: { - namespace?: string; - name?: string; - attachTo?: { id: string; input: string }; - disabled?: boolean; - inputs?: TInputs; - output?: TOutput; - configSchema?: PortableSchema<TConfig>; - params: TParams; - factory?( - params: TParams, - context: { - node: AppNode; - config: TConfig; - inputs: Expand<ResolvedExtensionInputs<TInputs>>; - orignalFactory( - params?: TParams, - context?: { - node?: AppNode; - config?: TConfig; - inputs?: Expand<ResolvedExtensionInputs<TInputs>>; - }, - ): Expand<ExtensionDataValues<TOutput>>; - }, - ): Expand<ExtensionDataValues<TOutput>>; - }): ExtensionDefinition<TConfig>; + /** + * Creates a new extension from the blueprint. + * + * You must either pass `params` directly, or define a `factory` that can + * optionally call the original factory with the same params. + */ + make( + args: { + namespace?: string; + name?: string; + attachTo?: { id: string; input: string }; + disabled?: boolean; + inputs?: TInputs; + output?: TOutput; + configSchema?: PortableSchema<TConfig>; + } & ( + | { + factory( + originalFactory: ( + params: TParams, + context?: { + config?: TConfig; + inputs?: Expand<ResolvedExtensionInputs<TInputs>>; + }, + ) => Expand<ExtensionDataValues<TOutput>>, + context: { + node: AppNode; + config: TConfig; + inputs: Expand<ResolvedExtensionInputs<TInputs>>; + }, + ): Expand<ExtensionDataValues<TOutput>>; + } + | { + params: TParams; + } + ), + ): ExtensionDefinition<TConfig>; } /** @@ -127,21 +138,19 @@ class ExtensionBlueprintImpl< inputs?: TInputs; output?: TOutput; configSchema?: PortableSchema<TConfig>; - params: TParams; + params?: TParams; factory?( - params: TParams, + originalFactory: ( + params: TParams, + context?: { + config?: TConfig; + inputs?: Expand<ResolvedExtensionInputs<TInputs>>; + }, + ) => Expand<ExtensionDataValues<TOutput>>, context: { node: AppNode; config: TConfig; inputs: Expand<ResolvedExtensionInputs<TInputs>>; - orignalFactory( - params?: TParams, - context?: { - node?: AppNode; - config?: TConfig; - inputs?: Expand<ResolvedExtensionInputs<TInputs>>; - }, - ): Expand<ExtensionDataValues<TOutput>>; }, ): Expand<ExtensionDataValues<TOutput>>; }): ExtensionDefinition<TConfig> { @@ -156,30 +165,33 @@ class ExtensionBlueprintImpl< configSchema: args.configSchema ?? this.options.configSchema, // TODO: some config merging or smth factory: ({ node, config, inputs }) => { if (args.factory) { - return args.factory(args.params, { - node, - config, - inputs, - orignalFactory: ( - innerParams?: TParams, + return args.factory( + ( + innerParams: TParams, innerContext?: { config?: TConfig; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, ) => - this.options.factory(innerParams ?? args.params, { + this.options.factory(innerParams, { node, config: innerContext?.config ?? config, inputs: innerContext?.inputs ?? inputs, }), + { + node, + config, + inputs, + }, + ); + } else if (args.params) { + return this.options.factory(args.params, { + node, + config, + inputs, }); } - - return this.options.factory(args.params, { - node, - config, - inputs, - }); + throw new Error('Either params or factory must be provided'); }, }); } From 32a38e1f37dd02476a17d78cfc3cc18cc7f08b24 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Sun, 21 Jul 2024 13:21:43 +0200 Subject: [PATCH 393/510] cli: remove most lockfile analysis features Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/neat-gifts-join.md | 5 + .changeset/small-spoons-shout.md | 13 ++ .../config/vocabularies/Backstage/accept.txt | 2 + .../keeping-backstage-updated.md | 24 +- docs/tooling/cli/03-commands.md | 21 +- packages/cli/cli-report.md | 11 - packages/cli/src/commands/index.ts | 2 +- .../cli/src/commands/versions/bump.test.ts | 174 +------------- packages/cli/src/commands/versions/bump.ts | 98 +------- packages/cli/src/commands/versions/lint.ts | 114 +-------- packages/cli/src/lib/bundler/server.ts | 39 ---- .../cli/src/lib/versioning/Lockfile.test.ts | 219 ------------------ packages/cli/src/lib/versioning/Lockfile.ts | 211 ----------------- plugins/devtools-backend/src/util/Lockfile.ts | 189 +-------------- 14 files changed, 43 insertions(+), 1079 deletions(-) create mode 100644 .changeset/neat-gifts-join.md create mode 100644 .changeset/small-spoons-shout.md diff --git a/.changeset/neat-gifts-join.md b/.changeset/neat-gifts-join.md new file mode 100644 index 0000000000..cd140c4692 --- /dev/null +++ b/.changeset/neat-gifts-join.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-devtools-backend': patch +--- + +Removed unused code for lockfile analysis. diff --git a/.changeset/small-spoons-shout.md b/.changeset/small-spoons-shout.md new file mode 100644 index 0000000000..76c209edc6 --- /dev/null +++ b/.changeset/small-spoons-shout.md @@ -0,0 +1,13 @@ +--- +'@backstage/cli': minor +--- + +**BREAKING**: The lockfile (`yarn.lock`) dependency analysis and mutations have been removed from several commands. + +The `versions:bump` command will no longer attempt to bump and deduplicate dependencies by modifying the lockfile, it will only update `package.json` files. + +The `versions:check` command has been removed, since its only purpose was verification and mutation of the lockfile. We recommend using the `yarn dedupe` command instead, or the `yarn-deduplicate` package if you're using Yarn classic. + +The check that was built into the `package start` command has been removed, it will no longer warn about lockfile mismatches. + +The packages in the Backstage ecosystem handle package duplications much better now than when these CLI features were first introduced, so the need for these features has diminished. By removing them, we drastically reduce the integration between the Backstage CLI and Yarn, making it much easier to add support for other package managers in the future. diff --git a/.github/vale/config/vocabularies/Backstage/accept.txt b/.github/vale/config/vocabularies/Backstage/accept.txt index 1092947245..42b0e4895c 100644 --- a/.github/vale/config/vocabularies/Backstage/accept.txt +++ b/.github/vale/config/vocabularies/Backstage/accept.txt @@ -85,7 +85,9 @@ debounce Debounce debuggability declaratively +deduplicate deduplicated +deduplication deliverables denormalized dependabot diff --git a/docs/getting-started/keeping-backstage-updated.md b/docs/getting-started/keeping-backstage-updated.md index 1de8874d56..88e4a02ef2 100644 --- a/docs/getting-started/keeping-backstage-updated.md +++ b/docs/getting-started/keeping-backstage-updated.md @@ -63,18 +63,16 @@ When a given dependency version is the _same_ between different packages, the dependency is hoisted to the main `node_modules` folder in the monorepo root to be shared between packages. When _different_ versions of the same dependency are encountered, Yarn creates a `node_modules` folder within a particular package. +This can lead to multiple versions of the same package being installed and used +in the same app. -This can lead to confusing situations with type definitions, or anything with -global state. React [Context](https://reactjs.org/docs/context.html), for -example, depends on global referential equality. This can cause problems in -Backstage with API lookup, or config loading. +All Backstage core packages are implemented in such as way that package +duplication is **not** a problem. For example, duplicate installations of +packages like `@backstage/core-plugin-api`, `@backstage/core-components`, +`@backstage/plugin-catalog-react`, and `@backstage/backend-plugin-api` are all +acceptable. -To help resolve these situations, the Backstage CLI has -[versions:check](https://backstage.io/docs/tooling/cli/03-commands#versionscheck). This -will validate versions of `@backstage` packages in your app to check for -duplicate definitions: - -```bash -# Add --fix to attempt automatic resolution in yarn.lock -yarn backstage-cli versions:check -``` +While package duplication might be acceptable in many cases, you might want to +deduplicate packages for the purpose of optimizing bundle size and installation +speed. We recommend using deduplication utilities such as `yarn dedupe` to trim +down the number of duplicate packages. diff --git a/docs/tooling/cli/03-commands.md b/docs/tooling/cli/03-commands.md index 234d0d04b7..a6652bd036 100644 --- a/docs/tooling/cli/03-commands.md +++ b/docs/tooling/cli/03-commands.md @@ -26,7 +26,6 @@ repo [command] Command that run across an entire package [command] Lifecycle scripts for individual packages migrate [command] Migration utilities versions:bump [options] Bump Backstage packages to the latest versions -versions:check [options] Check Backstage package versioning clean Delete cache directories [DEPRECATED] build-workspace <workspace-dir> [packages...] Builds a temporary dist workspace from the provided packages @@ -327,8 +326,7 @@ Options: ## versions\:bump Bump all `@backstage` packages to the latest versions. This checks for updates -in the package registry, and will update entries both in `yarn.lock` and -`package.json` files when necessary. +in the package registry, and will update entries `package.json` files when necessary. ```text Usage: backstage-cli versions:bump [options] @@ -339,23 +337,6 @@ Options: --release <version|next|main> Bump to a specific Backstage release line or version (default: "main") ``` -## versions\:check - -Validate `@backstage` dependencies within the repo, making sure that there are -no duplicates of packages that might lead to breakages. - -By supplying the `--fix` flag the command will attempt to fix any conflict that -can be resolved by editing `yarn.lock`, but will not attempt to search for -remote updates or modify any `package.json` files. - -```text -Usage: backstage-cli versions:check [options] - -Options: - --fix Fix any auto-fixable versioning problems - -h, --help display help for command -``` - ## build-workspace Builds a mirror of the workspace using the packaged production version of each diff --git a/packages/cli/cli-report.md b/packages/cli/cli-report.md index 01b0f7ddec..907f0298f2 100644 --- a/packages/cli/cli-report.md +++ b/packages/cli/cli-report.md @@ -22,7 +22,6 @@ Commands: package [command] migrate [command] versions:bump [options] - versions:check [options] versions:migrate [options] clean build-workspace [options] <workspace-dir> [packages...] @@ -607,16 +606,6 @@ Options: -h, --help ``` -### `backstage-cli versions:check` - -``` -Usage: backstage-cli versions:check [options] - -Options: - --fix - -h, --help -``` - ### `backstage-cli versions:migrate` ``` diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index 25a3a4e26c..fa4bb05333 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -396,7 +396,7 @@ export function registerCommands(program: Command) { .action(lazy(() => import('./versions/bump').then(m => m.default))); program - .command('versions:check') + .command('versions:check', { hidden: true }) .option('--fix', 'Fix any auto-fixable versioning problems') .description('Check Backstage package versioning') .action(lazy(() => import('./versions/lint').then(m => m.default))); diff --git a/packages/cli/src/commands/versions/bump.test.ts b/packages/cli/src/commands/versions/bump.test.ts index b8677a48c5..cc48b91fd8 100644 --- a/packages/cli/src/commands/versions/bump.test.ts +++ b/packages/cli/src/commands/versions/bump.test.ts @@ -23,7 +23,6 @@ import { YarnInfoInspectData } from '../../lib/versioning/packages'; import { setupServer } from 'msw/node'; import { rest } from 'msw'; import { NotFoundError } from '@backstage/errors'; -import { Lockfile } from '../../lib/versioning/Lockfile'; import { MockDirectory, createMockDirectory, @@ -117,17 +116,6 @@ const lockfileMock = `${HEADER} version "1.0.3" `; -// This is the lockfile that we produce to unlock versions before we run yarn install -const lockfileMockResult = `${HEADER} -"@backstage/core@^1.0.5": - version "1.0.6" - dependencies: - "@backstage/core-api" "^1.0.6" - -"@backstage/theme@^1.0.0": - version "1.0.0" -`; - // Avoid flakes by comparing sorted log lines. File system access is async, which leads to the log line order being indeterministic const expectLogsToMatch = ( recievedLogs: String[], @@ -204,11 +192,7 @@ describe('bump', () => { 'Using default pattern glob @backstage/*', 'Checking for updates of @backstage/core', 'Checking for updates of @backstage/theme', - 'Checking for updates of @backstage/core-api', 'Some packages are outdated, updating', - 'unlocking @backstage/core@^1.0.3 ~> 1.0.6', - 'unlocking @backstage/core-api@^1.0.6 ~> 1.0.7', - 'unlocking @backstage/core-api@^1.0.3 ~> 1.0.7', 'bumping @backstage/core in a to ^1.0.6', 'bumping @backstage/core in b to ^1.0.6', 'bumping @backstage/theme in b to ^2.0.0', @@ -220,9 +204,8 @@ describe('bump', () => { 'Version bump complete!', ]); - expect(mockFetchPackageInfo).toHaveBeenCalledTimes(3); + expect(mockFetchPackageInfo).toHaveBeenCalledTimes(2); expect(mockFetchPackageInfo).toHaveBeenCalledWith('@backstage/core'); - expect(mockFetchPackageInfo).toHaveBeenCalledWith('@backstage/core-api'); expect(mockFetchPackageInfo).toHaveBeenCalledWith('@backstage/theme'); expect(runObj.run).toHaveBeenCalledTimes(1); @@ -232,12 +215,6 @@ describe('bump', () => { expect.any(Object), ); - const lockfileContents = await fs.readFile( - mockDir.resolve('yarn.lock'), - 'utf8', - ); - expect(lockfileContents).toBe(lockfileMockResult); - const packageA = await fs.readJson( mockDir.resolve('packages/a/package.json'), ); @@ -312,11 +289,7 @@ describe('bump', () => { 'Using default pattern glob @backstage/*', 'Checking for updates of @backstage/core', 'Checking for updates of @backstage/theme', - 'Checking for updates of @backstage/core-api', 'Some packages are outdated, updating', - 'unlocking @backstage/core@^1.0.3 ~> 1.0.6', - 'unlocking @backstage/core-api@^1.0.6 ~> 1.0.7', - 'unlocking @backstage/core-api@^1.0.3 ~> 1.0.7', 'bumping @backstage/core in a to ^1.0.6', 'bumping @backstage/core in b to ^1.0.6', 'bumping @backstage/theme in b to ^2.0.0', @@ -328,9 +301,8 @@ describe('bump', () => { 'Version bump complete!', ]); - expect(mockFetchPackageInfo).toHaveBeenCalledTimes(3); + expect(mockFetchPackageInfo).toHaveBeenCalledTimes(2); expect(mockFetchPackageInfo).toHaveBeenCalledWith('@backstage/core'); - expect(mockFetchPackageInfo).toHaveBeenCalledWith('@backstage/core-api'); expect(mockFetchPackageInfo).toHaveBeenCalledWith('@backstage/theme'); expect(runObj.run).not.toHaveBeenCalledWith( @@ -339,12 +311,6 @@ describe('bump', () => { expect.any(Object), ); - const lockfileContents = await fs.readFile( - mockDir.resolve('yarn.lock'), - 'utf8', - ); - expect(lockfileContents).toBe(lockfileMockResult); - const packageA = await fs.readJson( mockDir.resolve('packages/a/package.json'), ); @@ -425,12 +391,7 @@ describe('bump', () => { 'Using default pattern glob @backstage/*', 'Checking for updates of @backstage/core', 'Checking for updates of @backstage/theme', - 'Checking for updates of @backstage/theme', - 'Checking for updates of @backstage/core-api', 'Some packages are outdated, updating', - 'unlocking @backstage/core@^1.0.3 ~> 1.0.6', - 'unlocking @backstage/core-api@^1.0.6 ~> 1.0.7', - 'unlocking @backstage/core-api@^1.0.3 ~> 1.0.7', 'bumping @backstage/theme in b to ^5.0.0', 'bumping @backstage/core in b to ^1.0.6', 'bumping @backstage/core in a to ^1.0.6', @@ -443,9 +404,8 @@ describe('bump', () => { 'Version bump complete!', ]); - expect(mockFetchPackageInfo).toHaveBeenCalledTimes(2); + expect(mockFetchPackageInfo).toHaveBeenCalledTimes(1); expect(mockFetchPackageInfo).toHaveBeenCalledWith('@backstage/core'); - expect(mockFetchPackageInfo).not.toHaveBeenCalledWith('@backstage/theme'); expect(runObj.run).toHaveBeenCalledTimes(1); expect(runObj.run).toHaveBeenCalledWith( @@ -454,12 +414,6 @@ describe('bump', () => { expect.any(Object), ); - const lockfileContents = await fs.readFile( - mockDir.resolve('yarn.lock'), - 'utf8', - ); - expect(lockfileContents).toBe(lockfileMockResult); - const packageA = await fs.readJson( mockDir.resolve('packages/a/package.json'), ); @@ -629,12 +583,7 @@ describe('bump', () => { 'Using default pattern glob @backstage/*', 'Checking for updates of @backstage/core', 'Checking for updates of @backstage/theme', - 'Checking for updates of @backstage/theme', - 'Checking for updates of @backstage/core-api', 'Some packages are outdated, updating', - 'unlocking @backstage/core@^1.0.3 ~> 1.0.6', - 'unlocking @backstage/core-api@^1.0.6 ~> 1.0.7', - 'unlocking @backstage/core-api@^1.0.3 ~> 1.0.7', 'bumping @backstage/theme in b to ^5.0.0', 'bumping @backstage/core in b to ^1.0.6', 'bumping @backstage/core in a to ^1.0.6', @@ -658,21 +607,6 @@ describe('bump', () => { "@backstage-extra/custom-two@^1.0.0": version "1.0.0" -`; - const customLockfileMockResult = `${HEADER} -"@backstage-extra/custom-two@^1.0.0": - version "1.0.0" - -"@backstage-extra/custom@^1.1.0": - version "1.1.0" - -"@backstage/core@^1.0.5": - version "1.0.6" - dependencies: - "@backstage/core-api" "^1.0.6" - -"@backstage/theme@^1.0.0": - version "1.0.0" `; mockDir.setContent({ 'yarn.lock': customLockfileMock, @@ -731,12 +665,7 @@ describe('bump', () => { 'Checking for updates of @backstage-extra/custom', 'Checking for updates of @backstage-extra/custom-two', 'Checking for updates of @backstage/theme', - 'Checking for updates of @backstage/core-api', 'Some packages are outdated, updating', - 'unlocking @backstage/core@^1.0.3 ~> 1.0.6', - 'unlocking @backstage-extra/custom@^1.0.1 ~> 1.1.0', - 'unlocking @backstage/core-api@^1.0.6 ~> 1.0.7', - 'unlocking @backstage/core-api@^1.0.3 ~> 1.0.7', 'bumping @backstage/core in a to ^1.0.6', 'bumping @backstage-extra/custom in a to ^1.1.0', 'bumping @backstage-extra/custom-two in a to ^2.0.0', @@ -754,7 +683,7 @@ describe('bump', () => { 'Version bump complete!', ]); - expect(mockFetchPackageInfo).toHaveBeenCalledTimes(5); + expect(mockFetchPackageInfo).toHaveBeenCalledTimes(4); expect(mockFetchPackageInfo).toHaveBeenCalledWith('@backstage/core'); expect(mockFetchPackageInfo).toHaveBeenCalledWith('@backstage/theme'); @@ -765,12 +694,6 @@ describe('bump', () => { expect.any(Object), ); - const lockfileContents = await fs.readFile( - mockDir.resolve('yarn.lock'), - 'utf8', - ); - expect(lockfileContents).toEqual(customLockfileMockResult); - const packageA = await fs.readJson( mockDir.resolve('packages/a/package.json'), ); @@ -798,7 +721,7 @@ describe('bump', () => { it('should ignore not found packages', async () => { mockDir.setContent({ - 'yarn.lock': lockfileMockResult, + 'yarn.lock': lockfileMock, 'package.json': JSON.stringify({ workspaces: { packages: ['packages/*'], @@ -848,21 +771,11 @@ describe('bump', () => { 'Checking for updates of @backstage/theme', 'Package info not found, ignoring package @backstage/core', 'Package info not found, ignoring package @backstage/theme', - 'Checking for updates of @backstage/core', - 'Checking for updates of @backstage/theme', - 'Package info not found, ignoring package @backstage/core', - 'Package info not found, ignoring package @backstage/theme', 'All Backstage packages are up to date!', ]); expect(runObj.run).toHaveBeenCalledTimes(0); - const lockfileContents = await fs.readFile( - mockDir.resolve('yarn.lock'), - 'utf8', - ); - expect(lockfileContents).toBe(lockfileMockResult); - const packageA = await fs.readJson( mockDir.resolve('packages/a/package.json'), ); @@ -883,83 +796,6 @@ describe('bump', () => { }, }); }); - - // eslint-disable-next-line jest/expect-expect - it('should log duplicates', async () => { - jest.spyOn(Lockfile.prototype, 'analyze').mockReturnValue({ - invalidRanges: [], - newVersions: [], - newRanges: [ - { - name: '@backstage/backend-app-api', - oldRange: '^1.0.0', - newRange: '^2.0.0', - oldVersion: '1.0.0', - newVersion: '2.0.0', - }, - ], - }); - mockDir.setContent({ - 'yarn.lock': `${HEADER} -"@backstage/backend-app-api@^1.0.0": - version "1.0.0" -`, - 'package.json': JSON.stringify({ - workspaces: { - packages: ['packages/*'], - }, - }), - packages: { - a: { - 'package.json': JSON.stringify({ - name: 'a', - dependencies: { - '@backstage/backend-app-api': '^1.0.0', - }, - }), - }, - }, - }); - - jest.spyOn(runObj, 'run').mockResolvedValue(undefined); - worker.use( - rest.get( - 'https://versions.backstage.io/v1/tags/main/manifest.json', - (_, res, ctx) => - res( - ctx.status(200), - ctx.json({ - packages: [ - { - name: '@backstage/backend-app-api', - version: '2.0.0', - }, - ], - }), - ), - ), - ); - const { log: logs } = await withLogCollector(['log', 'warn'], async () => { - await bump({ pattern: null, release: 'main' } as unknown as Command); - }); - expectLogsToMatch(logs, [ - 'Using default pattern glob @backstage/*', - 'Checking for updates of @backstage/backend-app-api', - 'Checking for updates of @backstage/backend-app-api', - 'Some packages are outdated, updating', - 'bumping @backstage/backend-app-api in a to ^2.0.0', - 'Running yarn install to install new versions', - 'Checking for moved packages to the @backstage-community namespace...', - '⚠️ The following packages may have breaking changes:', - ' @backstage/backend-app-api : 1.0.0 ~> 2.0.0', - ' https://github.com/backstage/backstage/blob/master/packages/backend-app-api/CHANGELOG.md', - 'Version bump complete!', - ' ⚠️ Warning! ⚠️', - ' The below package(s) have incompatible duplicate installations, likely due to a bad dependency in a plugin.', - ' You can investigate this by running `yarn why <package-name>`, and report the issue to the plugin maintainers.', - ' @backstage/backend-app-api', - ]); - }); }); describe('bumpBackstageJsonVersion', () => { diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index d6d5f424ba..5b981d3890 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -24,7 +24,6 @@ import fs from 'fs-extra'; import chalk from 'chalk'; import ora from 'ora'; import semver from 'semver'; -import { minimatch } from 'minimatch'; import { OptionValues } from 'commander'; import { isError, NotFoundError } from '@backstage/errors'; import { resolve as resolvePath } from 'path'; @@ -36,7 +35,6 @@ import { Lockfile, YarnInfoInspectData, } from '../../lib/versioning'; -import { forbiddenDuplicatesFilter } from './lint'; import { BACKSTAGE_JSON } from '@backstage/cli-common'; import { runParallelWorkers } from '../../lib/parallel'; import { @@ -44,7 +42,6 @@ import { getManifestByVersion, ReleaseManifest, } from '@backstage/release-manifests'; -import { PackageGraph } from '@backstage/cli-node'; import { migrateMovedPackages } from './migrate'; function shouldUseGlobalAgent(): boolean { @@ -125,8 +122,6 @@ export default async (opts: OptionValues) => { // Next check with the package registry to see which dependency ranges we need to bump const versionBumps = new Map<string, PkgVersionInfo[]>(); - // Track package versions that we want to remove from yarn.lock in order to trigger a bump - const unlocked = Array<{ name: string; range: string; target: string }>(); await runParallelWorkers({ parallelismFactor: 4, @@ -157,72 +152,13 @@ export default async (opts: OptionValues) => { }, }); - const filter = (name: string) => minimatch(name, pattern); - - // Check for updates of transitive backstage dependencies - await runParallelWorkers({ - parallelismFactor: 4, - items: lockfile.keys(), - async worker(name) { - // Only check @backstage packages and friends, we don't want this to do a full update of all deps - if (!filter(name)) { - return; - } - - let target: string; - try { - target = await findTargetVersion(name); - } catch (error) { - if (isError(error) && error.name === 'NotFoundError') { - console.log(`Package info not found, ignoring package ${name}`); - return; - } - throw error; - } - - for (const entry of lockfile.get(name) ?? []) { - // Ignore lockfile entries that don't satisfy the version range, since - // these can't cause the package to be locked to an older version - if (!semver.satisfies(target, entry.range)) { - continue; - } - // Unlock all entries that are within range but on the old version - unlocked.push({ name, range: entry.range, target }); - } - }, - }); - - console.log(); - // Write all discovered version bumps to package.json in this repo - if (versionBumps.size === 0 && unlocked.length === 0) { + if (versionBumps.size === 0) { console.log(chalk.green('All Backstage packages are up to date!')); } else { console.log(chalk.yellow('Some packages are outdated, updating')); console.log(); - if (unlocked.length > 0) { - const removed = new Set<string>(); - for (const { name, range, target } of unlocked) { - // Don't bother removing lockfile entries if they're already on the correct version - const existingEntry = lockfile.get(name)?.find(e => e.range === range); - if (existingEntry?.version === target) { - continue; - } - const key = JSON.stringify({ name, range }); - if (!removed.has(key)) { - removed.add(key); - console.log( - `${chalk.magenta('unlocking')} ${name}@${chalk.yellow( - range, - )} ~> ${chalk.yellow(target)}`, - ); - lockfile.remove(name, range); - } - } - await lockfile.save(lockfilePath); - } - const breakingUpdates = new Map<string, { from: string; to: string }>(); await runParallelWorkers({ parallelismFactor: 4, @@ -334,38 +270,6 @@ export default async (opts: OptionValues) => { } console.log(); - - // Finally we make sure the new lockfile doesn't have any duplicates - const dedupLockfile = await Lockfile.load(lockfilePath); - - const result = dedupLockfile.analyze({ - filter, - localPackages: PackageGraph.fromPackages( - await PackageGraph.listTargetPackages(), - ), - }); - - const forbiddenNewRanges = result.newRanges.filter(({ name }) => - forbiddenDuplicatesFilter(name), - ); - if (forbiddenNewRanges.length > 0) { - console.log(chalk.yellow(' ⚠️ Warning! ⚠️')); - console.log(); - console.log( - chalk.yellow( - ' The below package(s) have incompatible duplicate installations, likely due to a bad dependency in a plugin.', - ), - ); - console.log( - chalk.yellow( - ' You can investigate this by running `yarn why <package-name>`, and report the issue to the plugin maintainers.', - ), - ); - console.log(); - for (const { name } of forbiddenNewRanges) { - console.log(chalk.yellow(` ${name}`)); - } - } }; export function createStrictVersionFinder(options: { diff --git a/packages/cli/src/commands/versions/lint.ts b/packages/cli/src/commands/versions/lint.ts index bfb2a752a0..66b5fc04c4 100644 --- a/packages/cli/src/commands/versions/lint.ts +++ b/packages/cli/src/commands/versions/lint.ts @@ -14,116 +14,8 @@ * limitations under the License. */ -import { OptionValues } from 'commander'; -import { Lockfile } from '../../lib/versioning'; -import { paths } from '../../lib/paths'; -import partition from 'lodash/partition'; -import { PackageGraph } from '@backstage/cli-node'; - -// Packages that we try to avoid duplicates for -const INCLUDED = [/^@backstage\//]; - -export const includedFilter = (name: string) => - INCLUDED.some(pattern => pattern.test(name)); - -// Packages that are not allowed to have any duplicates -const FORBID_DUPLICATES = [/^@backstage\/\w+-app-api$/, /^@backstage\/plugin-/]; - -// There are some packages that ARE explicitly allowed to have duplicates since -// they handle that appropriately. This takes precedence over FORBID_DUPLICATES -// above. -const ALLOW_DUPLICATES = [ - /^@backstage\/core-plugin-api$/, - // Duplicates of libraries are OK - // TODO(Rugvip): Check this using package role instead - /^@backstage\/plugin-.*-react$/, - /^@backstage\/plugin-.*-node$/, - /^@backstage\/plugin-.*-common$/, -]; - -export const forbiddenDuplicatesFilter = (name: string) => - FORBID_DUPLICATES.some(pattern => pattern.test(name)) && - !ALLOW_DUPLICATES.some(pattern => pattern.test(name)); - -export default async (cmd: OptionValues) => { - const fix = Boolean(cmd.fix); - - let success = true; - - const lockfilePath = paths.resolveTargetRoot('yarn.lock'); - const lockfile = await Lockfile.load(lockfilePath); - const result = lockfile.analyze({ - filter: includedFilter, - localPackages: PackageGraph.fromPackages( - await PackageGraph.listTargetPackages(), - ), - }); - - logArray( - result.invalidRanges, - "The following packages versions are invalid and can't be analyzed:", - e => ` ${e.name} @ ${e.range}`, +export default async () => { + throw new Error( + 'This command has been removed, please consider alternatives such as `yarn dedupe` instead.', ); - - if (fix) { - lockfile.replaceVersions(result.newVersions); - await lockfile.save(lockfilePath); - } else { - const [newVersionsForbidden, newVersionsAllowed] = partition( - result.newVersions, - ({ name }) => forbiddenDuplicatesFilter(name), - ); - if (newVersionsForbidden.length && !fix) { - success = false; - } - - logArray( - newVersionsForbidden, - 'The following packages must be deduplicated, this can be done automatically with --fix', - e => - ` ${e.name} @ ${e.range} bumped from ${e.oldVersion} to ${e.newVersion}`, - ); - logArray( - newVersionsAllowed, - 'The following packages can be deduplicated, this can be done automatically with --fix', - e => - ` ${e.name} @ ${e.range} bumped from ${e.oldVersion} to ${e.newVersion}`, - ); - } - - const [newRangesForbidden, newRangesAllowed] = partition( - result.newRanges, - ({ name }) => forbiddenDuplicatesFilter(name), - ); - if (newRangesForbidden.length) { - success = false; - } - - logArray( - newRangesForbidden, - 'The following packages must be deduplicated by updating dependencies in package.json', - e => ` ${e.name} @ ${e.oldRange} should be changed to ${e.newRange}`, - ); - logArray( - newRangesAllowed, - 'The following packages can be deduplicated by updating dependencies in package.json', - e => ` ${e.name} @ ${e.oldRange} should be changed to ${e.newRange}`, - ); - - if (!success) { - throw new Error('Failed versioning check'); - } }; - -function logArray<T>(arr: T[], header: string, each: (item: T) => string) { - if (arr.length === 0) { - return; - } - - console.log(header); - console.log(); - for (const e of arr) { - console.log(each(e)); - } - console.log(); -} diff --git a/packages/cli/src/lib/bundler/server.ts b/packages/cli/src/lib/bundler/server.ts index 6b89847fb6..259f3263eb 100644 --- a/packages/cli/src/lib/bundler/server.ts +++ b/packages/cli/src/lib/bundler/server.ts @@ -14,22 +14,15 @@ * limitations under the License. */ -import { PackageGraph } from '@backstage/cli-node'; import { AppConfig } from '@backstage/config'; import chalk from 'chalk'; import fs from 'fs-extra'; -import uniq from 'lodash/uniq'; import openBrowser from 'react-dev-utils/openBrowser'; import webpack from 'webpack'; import WebpackDevServer from 'webpack-dev-server'; -import { - forbiddenDuplicatesFilter, - includedFilter, -} from '../../commands/versions/lint'; import { paths as libPaths } from '../../lib/paths'; import { loadCliConfig } from '../config'; -import { Lockfile } from '../versioning'; import { createConfig, resolveBaseUrl, resolveEndpoint } from './config'; import { createDetectedModulesEntryPoint } from './packageDetection'; import { resolveBundlingPaths, resolveOptionalBundlingPaths } from './paths'; @@ -41,38 +34,6 @@ export async function serveBundle(options: ServeOptions) { const targetPkg = await fs.readJson(paths.targetPackageJson); if (options.verifyVersions) { - const lockfile = await Lockfile.load( - libPaths.resolveTargetRoot('yarn.lock'), - ); - const result = lockfile.analyze({ - filter: includedFilter, - localPackages: PackageGraph.fromPackages( - await PackageGraph.listTargetPackages(), - ), - }); - const problemPackages = [...result.newVersions, ...result.newRanges] - .map(({ name }) => name) - .filter(forbiddenDuplicatesFilter); - - if (problemPackages.length > 1) { - console.log( - chalk.yellow( - `⚠️ Some of the following packages may be outdated or have duplicate installations: - - ${uniq(problemPackages).join(', ')} - `, - ), - ); - console.log( - chalk.yellow( - `⚠️ This can be resolved using the following command: - - yarn backstage-cli versions:check --fix - `, - ), - ); - } - if ( targetPkg.dependencies?.['react-router']?.includes('beta') || targetPkg.dependencies?.['react-router-dom']?.includes('beta') diff --git a/packages/cli/src/lib/versioning/Lockfile.test.ts b/packages/cli/src/lib/versioning/Lockfile.test.ts index a4267acdb7..d6996b9143 100644 --- a/packages/cli/src/lib/versioning/Lockfile.test.ts +++ b/packages/cli/src/lib/versioning/Lockfile.test.ts @@ -14,8 +14,6 @@ * limitations under the License. */ -import fs from 'fs-extra'; -import { BackstagePackage } from '@backstage/cli-node'; import { Lockfile } from './Lockfile'; import { createMockDirectory } from '@backstage/backend-test-utils'; @@ -47,34 +45,6 @@ b@^2: version "2.0.0" `; -const mockADedup = `${LEGACY_HEADER} -a@^1: - version "1.0.1" - resolved "https://my-registry/a-1.0.01.tgz#abc123" - integrity sha512-xyz - dependencies: - b "^2" - -b@2.0.x, b@^2: - version "2.0.1" -`; - -const mockB = `${LEGACY_HEADER} -"@s/a@*", "@s/a@1 || 2", "@s/a@^1": - version "1.0.1" - -"@s/a@^2.0.x": - version "2.0.0" -`; - -const mockBDedup = `${LEGACY_HEADER} -"@s/a@*", "@s/a@1 || 2", "@s/a@^2.0.x": - version "2.0.0" - -"@s/a@^1": - version "1.0.1" -`; - describe('Lockfile', () => { const mockDir = createMockDirectory(); @@ -93,75 +63,6 @@ describe('Lockfile', () => { ]); expect(lockfile.toString()).toBe(mockA); }); - - it('should deduplicate and save mockA', async () => { - mockDir.setContent({ - 'yarn.lock': mockA, - }); - - const lockfilePath = mockDir.resolve('yarn.lock'); - const lockfile = await Lockfile.load(lockfilePath); - const result = lockfile.analyze({ localPackages: new Map() }); - expect(result).toEqual({ - invalidRanges: [], - newRanges: [], - newVersions: [ - { - name: 'b', - range: '^2', - oldVersion: '2.0.0', - newVersion: '2.0.1', - }, - ], - }); - - expect(lockfile.toString()).toBe(mockA); - lockfile.replaceVersions(result.newVersions); - expect(lockfile.toString()).toBe(mockADedup); - - await expect(fs.readFile(lockfilePath, 'utf8')).resolves.toBe(mockA); - await expect(lockfile.save(lockfilePath)).resolves.toBeUndefined(); - await expect(fs.readFile(lockfilePath, 'utf8')).resolves.toBe(mockADedup); - }); - - it('should deduplicate mockB', async () => { - mockDir.setContent({ - 'yarn.lock': mockB, - }); - - const lockfile = await Lockfile.load(mockDir.resolve('yarn.lock')); - const result = lockfile.analyze({ localPackages: new Map() }); - expect(result).toEqual({ - invalidRanges: [], - newRanges: [ - { - name: '@s/a', - oldRange: '^1', - newRange: '^2.0.x', - oldVersion: '1.0.1', - newVersion: '2.0.0', - }, - ], - newVersions: [ - { - name: '@s/a', - range: '*', - oldVersion: '1.0.1', - newVersion: '2.0.0', - }, - { - name: '@s/a', - range: '1 || 2', - oldVersion: '1.0.1', - newVersion: '2.0.0', - }, - ], - }); - - expect(lockfile.toString()).toBe(mockB); - lockfile.replaceVersions(result.newVersions); - expect(lockfile.toString()).toBe(mockBDedup); - }); }); const mockANew = `${MODERN_HEADER} @@ -179,51 +80,6 @@ b@^2: version: 2.0.0 `; -const mockANewDedup = `${MODERN_HEADER} -a@^1: - version: 1.0.1 - dependencies: - b: ^2 - integrity: sha512-xyz - resolved: "https://my-registry/a-1.0.01.tgz#abc123" - -"b@2.0.x, b@^2.0.1": - version: 2.0.1 - -b@^2: - version: 2.0.1 -`; - -const mockANewLocal = `${MODERN_HEADER} -a@^1: - version: 1.0.1 - dependencies: - b: ^2 - integrity: sha512-xyz - resolved: "https://my-registry/a-1.0.01.tgz#abc123" - -"b@2.0.x, b@^2.0.1": - version: 0.0.0-use.local - -b@^2: - version: 2.0.0 -`; - -const mockANewLocalDedup = `${MODERN_HEADER} -a@^1: - version: 1.0.1 - dependencies: - b: ^2 - integrity: sha512-xyz - resolved: "https://my-registry/a-1.0.01.tgz#abc123" - -"b@2.0.x, b@^2.0.1": - version: 0.0.0-use.local - -b@^2: - version: 0.0.0-use.local -`; - describe('New Lockfile', () => { const mockDir = createMockDirectory(); @@ -243,79 +99,4 @@ describe('New Lockfile', () => { ]); expect(lockfile.toString()).toBe(mockANew); }); - - it('should deduplicate and save mockANew', async () => { - mockDir.setContent({ - 'yarn.lock': mockANew, - }); - - const lockfilePath = mockDir.resolve('yarn.lock'); - const lockfile = await Lockfile.load(lockfilePath); - const result = lockfile.analyze({ localPackages: new Map() }); - expect(result).toEqual({ - invalidRanges: [], - newRanges: [], - newVersions: [ - { - name: 'b', - range: '^2', - oldVersion: '2.0.0', - newVersion: '2.0.1', - }, - ], - }); - - expect(lockfile.toString()).toBe(mockANew); - lockfile.replaceVersions(result.newVersions); - expect(lockfile.toString()).toBe(mockANewDedup); - - await expect(fs.readFile(lockfilePath, 'utf8')).resolves.toBe(mockANew); - await expect(lockfile.save(lockfilePath)).resolves.toBeUndefined(); - await expect(fs.readFile(lockfilePath, 'utf8')).resolves.toBe( - mockANewDedup, - ); - }); - - it('should deduplicate and save mockANewLocal', async () => { - mockDir.setContent({ - 'yarn.lock': mockANewLocal, - }); - - const lockfilePath = mockDir.resolve('yarn.lock'); - const lockfile = await Lockfile.load(lockfilePath); - const result = lockfile.analyze({ - localPackages: new Map([ - [ - 'b', - { - packageJson: { version: '2.0.1' }, - } as BackstagePackage, - ], - ]), - }); - expect(result).toEqual({ - invalidRanges: [], - newRanges: [], - newVersions: [ - { - name: 'b', - range: '^2', - oldVersion: '2.0.0', - newVersion: '0.0.0-use.local', - }, - ], - }); - - expect(lockfile.toString()).toBe(mockANewLocal); - lockfile.replaceVersions(result.newVersions); - expect(lockfile.toString()).toBe(mockANewLocalDedup); - - await expect(fs.readFile(lockfilePath, 'utf8')).resolves.toBe( - mockANewLocal, - ); - await expect(lockfile.save(lockfilePath)).resolves.toBeUndefined(); - await expect(fs.readFile(lockfilePath, 'utf8')).resolves.toBe( - mockANewLocalDedup, - ); - }); }); diff --git a/packages/cli/src/lib/versioning/Lockfile.ts b/packages/cli/src/lib/versioning/Lockfile.ts index 50d0a77cfd..047cf5aefc 100644 --- a/packages/cli/src/lib/versioning/Lockfile.ts +++ b/packages/cli/src/lib/versioning/Lockfile.ts @@ -15,10 +15,8 @@ */ import fs from 'fs-extra'; -import semver from 'semver'; import { parseSyml, stringifySyml } from '@yarnpkg/parsers'; import { stringify as legacyStringifyLockfile } from '@yarnpkg/lockfile'; -import { BackstagePackage } from '@backstage/cli-node'; const ENTRY_PATTERN = /^((?:@[^/]+\/)?[^@/]+)@(.+)$/; @@ -39,35 +37,6 @@ type LockfileQueryEntry = { dataKey: string; }; -/** Entries that have an invalid version range, for example an npm tag */ -type AnalyzeResultInvalidRange = { - name: string; - range: string; -}; - -/** Entries that can be deduplicated by bumping to an existing higher version */ -type AnalyzeResultNewVersion = { - name: string; - range: string; - oldVersion: string; - newVersion: string; -}; - -/** Entries that would need a dependency update in package.json to be deduplicated */ -type AnalyzeResultNewRange = { - name: string; - oldRange: string; - newRange: string; - oldVersion: string; - newVersion: string; -}; - -type AnalyzeResult = { - invalidRanges: AnalyzeResultInvalidRange[]; - newVersions: AnalyzeResultNewVersion[]; - newRanges: AnalyzeResultNewRange[]; -}; - // the new yarn header is handled out of band of the parsing // https://github.com/yarnpkg/berry/blob/0c5974f193a9397630e9aee2b3876cca62611149/packages/yarnpkg-core/sources/Project.ts#L1741-L1746 const NEW_HEADER = `${[ @@ -153,186 +122,6 @@ export class Lockfile { return this.packages.keys(); } - /** Analyzes the lockfile to identify possible actions and warnings for the entries */ - analyze(options: { - filter?: (name: string) => boolean; - localPackages: Map<string, BackstagePackage>; - }): AnalyzeResult { - const { filter, localPackages } = options; - const result: AnalyzeResult = { - invalidRanges: [], - newVersions: [], - newRanges: [], - }; - - for (const [name, allEntries] of this.packages) { - if (filter && !filter(name)) { - continue; - } - - // Get rid of and signal any invalid ranges upfront - const invalid = allEntries.filter( - e => !semver.validRange(e.range) && !e.range.startsWith('workspace:'), - ); - result.invalidRanges.push( - ...invalid.map(({ range }) => ({ name, range })), - ); - - // Grab all valid entries, if there aren't at least 2 different valid ones we're done - const entries = allEntries.filter(e => semver.validRange(e.range)); - if (entries.length < 2) { - continue; - } - - // Find all versions currently in use - const versions = Array.from(new Set(entries.map(e => e.version))) - .map(v => { - // Translate workspace:^ references to the actual version - if (v === '0.0.0-use.local') { - const local = localPackages.get(name); - if (!local) { - throw new Error(`No local package found for ${name}`); - } - if (!local.packageJson.version) { - throw new Error(`No version found for local package ${name}`); - } - return { - entryVersion: v, - actualVersion: local.packageJson.version, - }; - } - return { entryVersion: v, actualVersion: v }; - }) - .sort((v1, v2) => semver.rcompare(v1.actualVersion, v2.actualVersion)); - - // If we're not using at least 2 different versions we're done - if (versions.length < 2) { - continue; - } - - // TODO(Rugvip): Support bumping into workspace ranges too - const acceptedVersions = new Set<string>(); - for (const { version, range } of entries) { - // Finds the highest matching version from the the known versions - // TODO(Rugvip): We may want to select the version that satisfies the most ranges rather than the highest one - const acceptedVersion = versions.find(v => - semver.satisfies(v.actualVersion, range), - ); - if (!acceptedVersion) { - throw new Error( - `No existing version was accepted for range ${range}, searching through ${versions}, for package ${name}`, - ); - } - - if (acceptedVersion.entryVersion !== version) { - result.newVersions.push({ - name, - range, - newVersion: acceptedVersion.entryVersion, - oldVersion: version, - }); - } - - acceptedVersions.add(acceptedVersion.actualVersion); - } - - // If all ranges were able to accept the same version, we're done - if (acceptedVersions.size === 1) { - continue; - } - - // Find the max version that we may want bump older packages to - const maxVersion = Array.from(acceptedVersions).sort(semver.rcompare)[0]; - // Find all existing ranges that satisfy the new max version, and pick the one that - // results in the highest minimum allowed version, usually being the more specific one - const maxEntry = entries - .filter(e => semver.satisfies(maxVersion, e.range)) - .map(e => ({ e, min: semver.minVersion(e.range) })) - .filter(p => p.min) - .sort((a, b) => semver.rcompare(a.min!, b.min!))[0]?.e; - if (!maxEntry) { - throw new Error( - `No entry found that satisfies max version '${maxVersion}'`, - ); - } - - // Find all entries that don't satisfy the max version - for (const { version, range } of entries) { - if (semver.satisfies(maxVersion, range)) { - continue; - } - - result.newRanges.push({ - name, - oldRange: range, - newRange: maxEntry.range, - oldVersion: version, - newVersion: maxVersion, - }); - } - } - - return result; - } - - remove(name: string, range: string): boolean { - const query = `${name}@${range}`; - const existed = Boolean(this.data[query]); - delete this.data[query]; - - const newEntries = this.packages.get(name)?.filter(e => e.range !== range); - if (newEntries) { - this.packages.set(name, newEntries); - } - - return existed; - } - - /** Modifies the lockfile by bumping packages to the suggested versions */ - replaceVersions(results: AnalyzeResultNewVersion[]) { - for (const { name, range, oldVersion, newVersion } of results) { - const query = `${name}@${range}`; - - // Update the backing data - const entryData = this.data[query]; - if (!entryData) { - throw new Error(`No entry data for ${query}`); - } - if (entryData.version !== oldVersion) { - throw new Error( - `Expected existing version data for ${query} to be ${oldVersion}, was ${entryData.version}`, - ); - } - - // Modifying the data in the entry is not enough, we need to reference an existing version object - const matchingEntry = Object.entries(this.data).find( - ([q, e]) => q.startsWith(`${name}@`) && e.version === newVersion, - ); - if (!matchingEntry) { - throw new Error( - `No matching entry found for ${name} at version ${newVersion}`, - ); - } - this.data[query] = matchingEntry[1]; - - // Update our internal data structure - const entry = this.packages.get(name)?.find(e => e.range === range); - if (!entry) { - throw new Error(`No entry data for ${query}`); - } - if (entry.version !== oldVersion) { - throw new Error( - `Expected existing version data for ${query} to be ${oldVersion}, was ${entryData.version}`, - ); - } - entry.version = newVersion; - } - } - - async save(path: string) { - await fs.writeFile(path, this.toString(), 'utf8'); - } - toString() { return this.legacy ? legacyStringifyLockfile(this.data) diff --git a/plugins/devtools-backend/src/util/Lockfile.ts b/plugins/devtools-backend/src/util/Lockfile.ts index 52dbb847bc..7f5497e948 100644 --- a/plugins/devtools-backend/src/util/Lockfile.ts +++ b/plugins/devtools-backend/src/util/Lockfile.ts @@ -15,7 +15,6 @@ */ import fs from 'fs-extra'; -import semver from 'semver'; import { parseSyml, stringifySyml } from '@yarnpkg/parsers'; import { stringify as legacyStringifyLockfile } from '@yarnpkg/lockfile'; @@ -35,35 +34,6 @@ type LockfileQueryEntry = { version: string; }; -/** Entries that have an invalid version range, for example an npm tag */ -type AnalyzeResultInvalidRange = { - name: string; - range: string; -}; - -/** Entries that can be deduplicated by bumping to an existing higher version */ -type AnalyzeResultNewVersion = { - name: string; - range: string; - oldVersion: string; - newVersion: string; -}; - -/** Entries that would need a dependency update in package.json to be deduplicated */ -type AnalyzeResultNewRange = { - name: string; - oldRange: string; - newRange: string; - oldVersion: string; - newVersion: string; -}; - -type AnalyzeResult = { - invalidRanges: AnalyzeResultInvalidRange[]; - newVersions: AnalyzeResultNewVersion[]; - newRanges: AnalyzeResultNewRange[]; -}; - function parseLockfile(lockfileContents: string) { try { return { @@ -135,11 +105,10 @@ export class Lockfile { queries.push({ range, version: value.version }); } - return new Lockfile(path, packages, data, legacy); + return new Lockfile(packages, data, legacy); } private constructor( - private readonly path: string, private readonly packages: Map<string, LockfileQueryEntry[]>, private readonly data: LockfileData, private readonly legacy: boolean = false, @@ -155,162 +124,6 @@ export class Lockfile { return this.packages.keys(); } - /** Analyzes the lockfile to identify possible actions and warnings for the entries */ - analyze(options?: { filter?: (name: string) => boolean }): AnalyzeResult { - const { filter } = options ?? {}; - const result: AnalyzeResult = { - invalidRanges: [], - newVersions: [], - newRanges: [], - }; - - for (const [name, allEntries] of this.packages) { - if (filter && !filter(name)) { - continue; - } - - // Get rid of and signal any invalid ranges upfront - const invalid = allEntries.filter(e => !semver.validRange(e.range)); - result.invalidRanges.push( - ...invalid.map(({ range }) => ({ name, range })), - ); - - // Grab all valid entries, if there aren't at least 2 different valid ones we're done - const entries = allEntries.filter(e => semver.validRange(e.range)); - if (entries.length < 2) { - continue; - } - - // Find all versions currently in use - const versions = Array.from(new Set(entries.map(e => e.version))).sort( - (v1, v2) => semver.rcompare(v1, v2), - ); - - // If we're not using at least 2 different versions we're done - if (versions.length < 2) { - continue; - } - - const acceptedVersions = new Set<string>(); - for (const { version, range } of entries) { - // Finds the highest matching version from the the known versions - // TODO(Rugvip): We may want to select the version that satisfies the most ranges rather than the highest one - const acceptedVersion = versions.find(v => semver.satisfies(v, range)); - if (!acceptedVersion) { - throw new Error( - `No existing version was accepted for range ${range}, searching through ${versions}, for package ${name}`, - ); - } - - if (acceptedVersion !== version) { - result.newVersions.push({ - name, - range, - newVersion: acceptedVersion, - oldVersion: version, - }); - } - - acceptedVersions.add(acceptedVersion); - } - - // If all ranges were able to accept the same version, we're done - if (acceptedVersions.size === 1) { - continue; - } - - // Find the max version that we may want bump older packages to - const maxVersion = Array.from(acceptedVersions).sort(semver.rcompare)[0]; - // Find all existing ranges that satisfy the new max version, and pick the one that - // results in the highest minimum allowed version, usually being the more specific one - const maxEntry = entries - .filter(e => semver.satisfies(maxVersion, e.range)) - .map(e => ({ e, min: semver.minVersion(e.range) })) - .filter(p => p.min) - .sort((a, b) => semver.rcompare(a.min!, b.min!))[0]?.e; - if (!maxEntry) { - throw new Error( - `No entry found that satisfies max version '${maxVersion}'`, - ); - } - - // Find all entries that don't satisfy the max version - for (const { version, range } of entries) { - if (semver.satisfies(maxVersion, range)) { - continue; - } - - result.newRanges.push({ - name, - oldRange: range, - newRange: maxEntry.range, - oldVersion: version, - newVersion: maxVersion, - }); - } - } - - return result; - } - - remove(name: string, range: string): boolean { - const query = `${name}@${range}`; - const existed = Boolean(this.data[query]); - delete this.data[query]; - - const newEntries = this.packages.get(name)?.filter(e => e.range !== range); - if (newEntries) { - this.packages.set(name, newEntries); - } - - return existed; - } - - /** Modifies the lockfile by bumping packages to the suggested versions */ - replaceVersions(results: AnalyzeResultNewVersion[]) { - for (const { name, range, oldVersion, newVersion } of results) { - const query = `${name}@${range}`; - - // Update the backing data - const entryData = this.data[query]; - if (!entryData) { - throw new Error(`No entry data for ${query}`); - } - if (entryData.version !== oldVersion) { - throw new Error( - `Expected existing version data for ${query} to be ${oldVersion}, was ${entryData.version}`, - ); - } - - // Modifying the data in the entry is not enough, we need to reference an existing version object - const matchingEntry = Object.entries(this.data).find( - ([q, e]) => q.startsWith(`${name}@`) && e.version === newVersion, - ); - if (!matchingEntry) { - throw new Error( - `No matching entry found for ${name} at version ${newVersion}`, - ); - } - this.data[query] = matchingEntry[1]; - - // Update our internal data structure - const entry = this.packages.get(name)?.find(e => e.range === range); - if (!entry) { - throw new Error(`No entry data for ${query}`); - } - if (entry.version !== oldVersion) { - throw new Error( - `Expected existing version data for ${query} to be ${oldVersion}, was ${entryData.version}`, - ); - } - entry.version = newVersion; - } - } - - async save() { - await fs.writeFile(this.path, this.toString(), 'utf8'); - } - toString() { return stringifyLockfile(this.data, this.legacy); } From 81ea85028c0551474f390cb32b08d4096ebdc6cf Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Tue, 23 Jul 2024 11:16:05 +0200 Subject: [PATCH 394/510] chore: fix api-reports Signed-off-by: blam <ben@blam.sh> --- packages/frontend-plugin-api/api-report.md | 64 ++++++++++++---------- plugins/catalog-react/src/alpha.tsx | 39 ------------- 2 files changed, 34 insertions(+), 69 deletions(-) diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index 3c082a7694..d6a91c0c99 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -931,36 +931,40 @@ export interface ExtensionBlueprint< > { // (undocumented) dataRefs: TDataRefs; - // (undocumented) - make(args: { - namespace?: string; - name?: string; - attachTo?: { - id: string; - input: string; - }; - disabled?: boolean; - inputs?: TInputs; - output?: TOutput; - configSchema?: PortableSchema<TConfig>; - params: TParams; - factory?( - params: TParams, - context: { - node: AppNode; - config: TConfig; - inputs: Expand<ResolvedExtensionInputs<TInputs>>; - orignalFactory( - params?: TParams, - context?: { - node?: AppNode; - config?: TConfig; - inputs?: Expand<ResolvedExtensionInputs<TInputs>>; - }, - ): Expand<ExtensionDataValues<TOutput>>; - }, - ): Expand<ExtensionDataValues<TOutput>>; - }): ExtensionDefinition<TConfig>; + make( + args: { + namespace?: string; + name?: string; + attachTo?: { + id: string; + input: string; + }; + disabled?: boolean; + inputs?: TInputs; + output?: TOutput; + configSchema?: PortableSchema<TConfig>; + } & ( + | { + factory( + originalFactory: ( + params: TParams, + context?: { + config?: TConfig; + inputs?: Expand<ResolvedExtensionInputs<TInputs>>; + }, + ) => Expand<ExtensionDataValues<TOutput>>, + context: { + node: AppNode; + config: TConfig; + inputs: Expand<ResolvedExtensionInputs<TInputs>>; + }, + ): Expand<ExtensionDataValues<TOutput>>; + } + | { + params: TParams; + } + ), + ): ExtensionDefinition<TConfig>; } // @public (undocumented) diff --git a/plugins/catalog-react/src/alpha.tsx b/plugins/catalog-react/src/alpha.tsx index 7f276b8ea6..e81b8e5ebf 100644 --- a/plugins/catalog-react/src/alpha.tsx +++ b/plugins/catalog-react/src/alpha.tsx @@ -22,7 +22,6 @@ import { RouteRef, coreExtensionData, createExtension, - createExtensionBlueprint, createExtensionDataRef, createSchemaFromZod, } from '@backstage/frontend-plugin-api'; @@ -48,44 +47,6 @@ export const catalogExtensionData = { }), }; -/** @alpha */ -export const EntityCardBlueprint = createExtensionBlueprint({ - kind: 'entity-card', - attachTo: { id: 'entity-content:catalog/overview', input: 'cards' }, - configSchema: createSchemaFromZod(z => - z.object({ - filter: z.string().optional(), - }), - ), - output: { - element: coreExtensionData.reactElement, - filterFunction: catalogExtensionData.entityFilterFunction.optional(), - filterExpression: catalogExtensionData.entityFilterExpression.optional(), - }, - factory( - params: { - filter?: - | typeof catalogExtensionData.entityFilterFunction.T - | typeof catalogExtensionData.entityFilterExpression.T; - loader: () => Promise<JSX.Element>; - }, - { node, config }, - ) { - const ExtensionComponent = lazy(() => - params.loader().then(element => ({ default: () => element })), - ); - - return { - element: ( - <ExtensionBoundary node={node}> - <ExtensionComponent /> - </ExtensionBoundary> - ), - ...mergeFilters({ config, options: params }), - }; - }, -}); - // TODO: Figure out how to merge with provided config schema /** @alpha */ export function createEntityCardExtension< From 9e8371b9e61c248636e29570aad72c4ed91c1429 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Tue, 23 Jul 2024 12:00:24 +0200 Subject: [PATCH 395/510] Update docs/tutorials/enable-public-entry.md Co-authored-by: Jack Palmer <UsainBloot@users.noreply.github.com> Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- docs/tutorials/enable-public-entry.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/tutorials/enable-public-entry.md b/docs/tutorials/enable-public-entry.md index d257753413..0174d43e3f 100644 --- a/docs/tutorials/enable-public-entry.md +++ b/docs/tutorials/enable-public-entry.md @@ -114,6 +114,7 @@ import { coreExtensionData, createExtension, createExtensionOverrides, + createSignInPageExtension } from '@backstage/frontend-plugin-api'; const signInPage = createSignInPageExtension({ From e3644bf16eac1b87ca85a633b029291adb2883a7 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Tue, 23 Jul 2024 12:38:10 +0200 Subject: [PATCH 396/510] chore: fixing prettier Signed-off-by: blam <ben@blam.sh> --- docs/tutorials/enable-public-entry.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/enable-public-entry.md b/docs/tutorials/enable-public-entry.md index 0174d43e3f..25d7382f13 100644 --- a/docs/tutorials/enable-public-entry.md +++ b/docs/tutorials/enable-public-entry.md @@ -114,7 +114,7 @@ import { coreExtensionData, createExtension, createExtensionOverrides, - createSignInPageExtension + createSignInPageExtension, } from '@backstage/frontend-plugin-api'; const signInPage = createSignInPageExtension({ From 9a46a81ece020408ce61f4eccd0aa922b712601d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Tue, 23 Jul 2024 12:40:11 +0200 Subject: [PATCH 397/510] core-app-api: fix immediate sign-in on sign-out Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/thirty-paws-hope.md | 5 ++++ .../IdentityApi/AppIdentityProxy.ts | 3 ++- .../core-app-api/src/app/AppManager.test.tsx | 26 ++++++++++++++----- 3 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 .changeset/thirty-paws-hope.md diff --git a/.changeset/thirty-paws-hope.md b/.changeset/thirty-paws-hope.md new file mode 100644 index 0000000000..0de607f331 --- /dev/null +++ b/.changeset/thirty-paws-hope.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-app-api': patch +--- + +The request to delete the session cookie when running the app in protected mode is now done with a plain `fetch` rather than `FetchApi`. This fixes a bug where the app would immediately try to sign-in again when removing the cookie during logout. diff --git a/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.ts b/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.ts index 92e2abffb7..941ec90d66 100644 --- a/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.ts +++ b/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.ts @@ -153,8 +153,9 @@ export class AppIdentityProxy implements IdentityApi { // It is fine if we do NOT worry yet about deleting cookies for OTHER backends like techdocs const appBaseUrl = await ctx.discoveryApi.getBaseUrl('app'); try { - await ctx.fetchApi.fetch(`${appBaseUrl}/.backstage/auth/v1/cookie`, { + await fetch(`${appBaseUrl}/.backstage/auth/v1/cookie`, { method: 'DELETE', + credentials: 'include', }); } catch { // Ignore the error for those who use static serving of the frontend diff --git a/packages/core-app-api/src/app/AppManager.test.tsx b/packages/core-app-api/src/app/AppManager.test.tsx index 85b6bcd684..01277a09c7 100644 --- a/packages/core-app-api/src/app/AppManager.test.tsx +++ b/packages/core-app-api/src/app/AppManager.test.tsx @@ -19,9 +19,12 @@ import { MockAnalyticsApi, renderWithEffects, withLogCollector, + registerMswTestHooks, } from '@backstage/test-utils'; -import { screen, waitFor, act } from '@testing-library/react'; +import { screen, act } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import { setupServer } from 'msw/node'; +import { rest } from 'msw'; import React, { PropsWithChildren, ReactNode } from 'react'; import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom'; import { @@ -51,6 +54,9 @@ import { } from '@backstage/core-plugin-api/alpha'; describe('Integration Test', () => { + const server = setupServer(); + registerMswTestHooks(server); + const noOpAnalyticsApi = createApiFactory( analyticsApiRef, new NoOpAnalyticsApi(), @@ -847,6 +853,17 @@ describe('Integration Test', () => { }); it('should clear app cookie when the user logs out', async () => { + const logoutSignal = jest.fn(); + server.use( + rest.delete( + 'http://localhost:7007/app/.backstage/auth/v1/cookie', + (_req, res, ctx) => { + logoutSignal(); + return res(ctx.status(200)); + }, + ), + ); + const meta = global.document.createElement('meta'); meta.name = 'backstage-app-mode'; meta.content = 'protected'; @@ -901,12 +918,7 @@ describe('Integration Test', () => { await userEvent.click(screen.getByText('Sign Out')); }); - await waitFor(() => - expect(fetchApiMock.fetch).toHaveBeenCalledWith( - 'http://localhost:7007/app/.backstage/auth/v1/cookie', - { method: 'DELETE' }, - ), - ); + expect(logoutSignal).toHaveBeenCalled(); global.document.head.removeChild(meta); }); From 749b5efd22af01591e4bb8f4e1854dfcc169317c Mon Sep 17 00:00:00 2001 From: Jack Palmer <jackpalmer@spotify.com> Date: Tue, 23 Jul 2024 12:30:01 +0100 Subject: [PATCH 398/510] feat: Add visibility hidden to CookieAuthRedirect Signed-off-by: Jack Palmer <jackpalmer@spotify.com> --- .../src/components/CookieAuthRedirect/CookieAuthRedirect.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/auth-react/src/components/CookieAuthRedirect/CookieAuthRedirect.tsx b/plugins/auth-react/src/components/CookieAuthRedirect/CookieAuthRedirect.tsx index f719aebdae..c89aa6a54d 100644 --- a/plugins/auth-react/src/components/CookieAuthRedirect/CookieAuthRedirect.tsx +++ b/plugins/auth-react/src/components/CookieAuthRedirect/CookieAuthRedirect.tsx @@ -45,6 +45,7 @@ export function CookieAuthRedirect() { ref={form => form?.submit()} action={window.location.href} method="POST" + style={{ visibility: 'hidden' }} > <input type="hidden" name="type" value="sign-in" /> <input type="hidden" name="token" value={state.result} /> From aeac3e9efa0df730facf88617c6bc7882ee6e830 Mon Sep 17 00:00:00 2001 From: Jack Palmer <jackpalmer@spotify.com> Date: Tue, 23 Jul 2024 12:31:58 +0100 Subject: [PATCH 399/510] chore: changeset Signed-off-by: Jack Palmer <jackpalmer@spotify.com> --- .changeset/wicked-bobcats-teach.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/wicked-bobcats-teach.md diff --git a/.changeset/wicked-bobcats-teach.md b/.changeset/wicked-bobcats-teach.md new file mode 100644 index 0000000000..041e336f7d --- /dev/null +++ b/.changeset/wicked-bobcats-teach.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-react': patch +--- + +feat: Hide visibility of CookieAuthRedirect From dc4fb4f6ac64bc53d38ff00e92eec000ac1911eb Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Tue, 23 Jul 2024 15:08:07 +0200 Subject: [PATCH 400/510] cli: fix forwarding of target dir when resolving optional bundling paths Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/violet-jokes-wave.md | 5 +++++ packages/cli/src/lib/bundler/bundle.ts | 1 + 2 files changed, 6 insertions(+) create mode 100644 .changeset/violet-jokes-wave.md diff --git a/.changeset/violet-jokes-wave.md b/.changeset/violet-jokes-wave.md new file mode 100644 index 0000000000..623cff2583 --- /dev/null +++ b/.changeset/violet-jokes-wave.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Fix for `repo build --all` not properly detecting the experimental public entry point. diff --git a/packages/cli/src/lib/bundler/bundle.ts b/packages/cli/src/lib/bundler/bundle.ts index d24d4252f4..0aa91a90a6 100644 --- a/packages/cli/src/lib/bundler/bundle.ts +++ b/packages/cli/src/lib/bundler/bundle.ts @@ -42,6 +42,7 @@ export async function buildBundle(options: BuildOptions) { const paths = resolveBundlingPaths(options); const publicPaths = await resolveOptionalBundlingPaths({ + targetDir: options.targetDir, entry: 'src/index-public-experimental', dist: 'dist/public', }); From bf2984369d30ee9b1b18974b85d8edb9ae373834 Mon Sep 17 00:00:00 2001 From: Chap Ambrose <cambrose@salesforce.com> Date: Tue, 23 Jul 2024 08:34:14 -0500 Subject: [PATCH 401/510] cleanup heroku.md Signed-off-by: Chap Ambrose <cambrose@salesforce.com> --- docs/deployment/heroku.md | 42 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/docs/deployment/heroku.md b/docs/deployment/heroku.md index faf1c2106e..d285e4b397 100644 --- a/docs/deployment/heroku.md +++ b/docs/deployment/heroku.md @@ -7,8 +7,6 @@ description: How to deploy Backstage to Heroku Heroku is a Platform as a Service (PaaS) designed to simplify application deployment. -[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/chap/backstage-button) - ## Create App Starting with an existing Backstage app or follow the [getting started guide](https://backstage.io/docs/getting-started/) to create a new one. @@ -17,8 +15,8 @@ Install the [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli) and create a new Heroku app: ```shell -$ cd your-app/ -$ heroku apps:create <your-app> +cd your-app/ +heroku apps:create <your-app> ``` ## Domain @@ -26,7 +24,7 @@ $ heroku apps:create <your-app> Get Heroku app URL: ```shell -$ heroku domains -a <your-app> +heroku domains -a <your-app> <your-app-123>.herokuapp.com ``` @@ -59,7 +57,7 @@ Add a build script in `package.json` to compile frontend during deployment: Create a [Procfile](https://devcenter.heroku.com/articles/procfile) in the app's root: ```shell -$ echo "web: yarn workspace backend start --config ../../app-config.yaml --config ../../app-config.production.yaml" > Procfile +echo "web: yarn workspace backend start --config ../../app-config.yaml --config ../../app-config.production.yaml" > Procfile ``` ## Database @@ -67,7 +65,7 @@ $ echo "web: yarn workspace backend start --config ../../app-config.yaml --confi Provision a [Heroku Postgres](https://elements.heroku.com/addons/heroku-postgresql) database: ```shell -$ heroku addons:create heroku-postgresql -a <your-app> +heroku addons:create heroku-postgresql -a <your-app> ``` Update `database` in `app-config.production.yaml`: @@ -85,7 +83,7 @@ backend: Allow postgres self-signed certificates: ```shell -$ heroku config:set PGSSLMODE=no-verify -a <your-app> +heroku config:set PGSSLMODE=no-verify -a <your-app> ``` ## Deployment @@ -93,20 +91,20 @@ $ heroku config:set PGSSLMODE=no-verify -a <your-app> Commit changes and push to Heroku to build and deploy: ```shell -$ git add Procfile && git commit -am "configure heroku" -$ git push heroku main +git add Procfile && git commit -am "configure heroku" +git push heroku main ``` View the app in the browser: ```shell -$ heroku open -a <your-app> +heroku open -a <your-app> ``` View logs: ```shell -$ heroku heroku -a <your-app> +heroku heroku -a <your-app> ``` ## Docker @@ -116,27 +114,27 @@ As an alternative to git deploys, Heroku also [supports container images](https: Login to Heroku's container registry: ```shell -$ heroku container:login +heroku container:login ``` Configure the Heroku app to run a container image: ```shell -$ heroku stack:set container -a <your-app> +heroku stack:set container -a <your-app> ``` -Locally run the [host build command](https://backstage.io/docs/deployment/docker/#host-build): +Locally run the [host build commands](https://backstage.io/docs/deployment/docker/#host-build), they must be run whenever you are going to publish a new image: ```shell -$ yarn build:backend --config ../../app-config.yaml --config ../../app-config.production.yaml +yarn install --frozen-lockfile +yarn tsc +yarn build:backend --config ../../app-config.yaml --config ../../app-config.production.yaml ``` -Build, push, and release the container image: +Build, push, and release the container image to the `web` dyno: ```shell -$ docker image build . -f packages/backend/Dockerfile --tag registry.heroku.com/<your-app>/web - -$ docker push registry.heroku.com/<your-app>/web - -$ heroku container:release web -a <your-app> +docker image build . -f packages/backend/Dockerfile --tag registry.heroku.com/<your-app>/web +docker push registry.heroku.com/<your-app>/web +heroku container:release web -a <your-app> ``` From 4a8774820c5fd84262058a1e48361d5656b57601 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 14:02:37 +0000 Subject: [PATCH 402/510] Version Packages (next) --- .changeset/pre.json | 52 +- docs/releases/v1.30.0-next.0-changelog.md | 2214 +++++++++++++++++ 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 | 43 + packages/app-next/package.json | 2 +- packages/app/CHANGELOG.md | 41 + packages/app/package.json | 2 +- packages/backend-app-api/CHANGELOG.md | 17 + packages/backend-app-api/package.json | 2 +- packages/backend-common/CHANGELOG.md | 28 + packages/backend-common/package.json | 2 +- packages/backend-defaults/CHANGELOG.md | 23 + packages/backend-defaults/package.json | 2 +- .../CHANGELOG.md | 26 + .../package.json | 2 +- packages/backend-legacy/CHANGELOG.md | 42 + packages/backend-legacy/package.json | 2 +- packages/backend-openapi-utils/CHANGELOG.md | 8 + packages/backend-openapi-utils/package.json | 2 +- packages/backend-plugin-api/CHANGELOG.md | 12 + packages/backend-plugin-api/package.json | 2 +- packages/backend-tasks/CHANGELOG.md | 11 + packages/backend-tasks/package.json | 2 +- packages/backend-test-utils/CHANGELOG.md | 15 + packages/backend-test-utils/package.json | 2 +- packages/backend/CHANGELOG.md | 37 + packages/backend/package.json | 2 +- packages/cli/CHANGELOG.md | 35 + packages/cli/package.json | 2 +- packages/config-loader/CHANGELOG.md | 13 + packages/config-loader/package.json | 2 +- packages/core-app-api/CHANGELOG.md | 11 + packages/core-app-api/package.json | 2 +- packages/core-compat-api/CHANGELOG.md | 9 + packages/core-compat-api/package.json | 2 +- packages/core-components/CHANGELOG.md | 12 + 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 | 16 + packages/frontend-app-api/package.json | 2 +- packages/frontend-plugin-api/CHANGELOG.md | 71 + packages/frontend-plugin-api/package.json | 2 +- packages/frontend-test-utils/CHANGELOG.md | 10 + packages/frontend-test-utils/package.json | 2 +- packages/integration-react/CHANGELOG.md | 9 + packages/integration-react/package.json | 2 +- packages/integration/CHANGELOG.md | 13 + packages/integration/package.json | 2 +- packages/repo-tools/CHANGELOG.md | 12 + packages/repo-tools/package.json | 2 +- .../techdocs-cli-embedded-app/CHANGELOG.md | 19 + .../techdocs-cli-embedded-app/package.json | 2 +- packages/techdocs-cli/CHANGELOG.md | 11 + packages/techdocs-cli/package.json | 2 +- packages/test-utils/CHANGELOG.md | 13 + packages/test-utils/package.json | 2 +- plugins/api-docs/CHANGELOG.md | 15 + plugins/api-docs/package.json | 2 +- plugins/app-backend/CHANGELOG.md | 14 + plugins/app-backend/package.json | 2 +- plugins/app-node/CHANGELOG.md | 8 + plugins/app-node/package.json | 2 +- plugins/app-visualizer/CHANGELOG.md | 9 + plugins/app-visualizer/package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- plugins/auth-backend/CHANGELOG.md | 30 + plugins/auth-backend/package.json | 2 +- plugins/auth-node/CHANGELOG.md | 13 + plugins/auth-node/package.json | 2 +- plugins/auth-react/CHANGELOG.md | 10 + plugins/auth-react/package.json | 2 +- plugins/bitbucket-cloud-common/CHANGELOG.md | 7 + plugins/bitbucket-cloud-common/package.json | 2 +- .../catalog-backend-module-aws/CHANGELOG.md | 19 + .../catalog-backend-module-aws/package.json | 2 +- .../catalog-backend-module-azure/CHANGELOG.md | 13 + .../catalog-backend-module-azure/package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 17 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../catalog-backend-module-gcp/CHANGELOG.md | 13 + .../catalog-backend-module-gcp/package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 17 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 15 + .../package.json | 2 +- .../CHANGELOG.md | 16 + .../package.json | 2 +- .../catalog-backend-module-ldap/CHANGELOG.md | 14 + .../catalog-backend-module-ldap/package.json | 2 +- .../catalog-backend-module-logs/CHANGELOG.md | 9 + .../catalog-backend-module-logs/package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../CHANGELOG.md | 15 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- plugins/catalog-backend/CHANGELOG.md | 23 + plugins/catalog-backend/package.json | 2 +- plugins/catalog-graph/CHANGELOG.md | 15 + plugins/catalog-graph/package.json | 2 +- plugins/catalog-import/CHANGELOG.md | 18 + plugins/catalog-import/package.json | 2 +- plugins/catalog-node/CHANGELOG.md | 15 + plugins/catalog-node/package.json | 2 +- plugins/catalog-react/CHANGELOG.md | 21 + plugins/catalog-react/package.json | 2 +- .../catalog-unprocessed-entities/CHANGELOG.md | 10 + .../catalog-unprocessed-entities/package.json | 2 +- plugins/catalog/CHANGELOG.md | 21 + plugins/catalog/package.json | 2 +- plugins/config-schema/CHANGELOG.md | 10 + plugins/config-schema/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 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../events-backend-module-azure/CHANGELOG.md | 8 + .../events-backend-module-azure/package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../events-backend-module-gerrit/CHANGELOG.md | 8 + .../events-backend-module-gerrit/package.json | 2 +- .../events-backend-module-github/CHANGELOG.md | 9 + .../events-backend-module-github/package.json | 2 +- .../events-backend-module-gitlab/CHANGELOG.md | 9 + .../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 | 10 + plugins/events-backend/package.json | 2 +- plugins/events-node/CHANGELOG.md | 7 + plugins/events-node/package.json | 2 +- .../example-todo-list-backend/CHANGELOG.md | 10 + .../example-todo-list-backend/package.json | 2 +- plugins/example-todo-list/CHANGELOG.md | 8 + plugins/example-todo-list/package.json | 2 +- plugins/home-react/CHANGELOG.md | 8 + plugins/home-react/package.json | 2 +- plugins/home/CHANGELOG.md | 19 + plugins/home/package.json | 2 +- plugins/kubernetes-backend/CHANGELOG.md | 20 + plugins/kubernetes-backend/package.json | 2 +- plugins/kubernetes-cluster/CHANGELOG.md | 12 + plugins/kubernetes-cluster/package.json | 2 +- plugins/kubernetes-node/CHANGELOG.md | 10 + plugins/kubernetes-node/package.json | 2 +- plugins/kubernetes-react/CHANGELOG.md | 12 + plugins/kubernetes-react/package.json | 2 +- plugins/kubernetes/CHANGELOG.md | 12 + plugins/kubernetes/package.json | 2 +- .../CHANGELOG.md | 15 + .../package.json | 2 +- plugins/notifications-backend/CHANGELOG.md | 17 + plugins/notifications-backend/package.json | 2 +- plugins/notifications-node/CHANGELOG.md | 12 + plugins/notifications-node/package.json | 2 +- plugins/notifications/CHANGELOG.md | 13 + plugins/notifications/package.json | 2 +- plugins/org-react/CHANGELOG.md | 11 + plugins/org-react/package.json | 2 +- plugins/org/CHANGELOG.md | 13 + plugins/org/package.json | 2 +- .../CHANGELOG.md | 10 + .../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/proxy-backend/CHANGELOG.md | 10 + plugins/proxy-backend/package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 23 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- plugins/scaffolder-backend/CHANGELOG.md | 31 + plugins/scaffolder-backend/package.json | 2 +- .../scaffolder-node-test-utils/CHANGELOG.md | 10 + .../scaffolder-node-test-utils/package.json | 2 +- plugins/scaffolder-node/CHANGELOG.md | 13 + plugins/scaffolder-node/package.json | 2 +- plugins/scaffolder-react/CHANGELOG.md | 22 + plugins/scaffolder-react/package.json | 2 +- plugins/scaffolder/CHANGELOG.md | 23 + plugins/scaffolder/package.json | 2 +- .../CHANGELOG.md | 18 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- plugins/search-backend-module-pg/CHANGELOG.md | 12 + plugins/search-backend-module-pg/package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 18 + .../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 | 16 + plugins/search/package.json | 2 +- plugins/signals-backend/CHANGELOG.md | 13 + plugins/signals-backend/package.json | 2 +- plugins/signals-node/CHANGELOG.md | 12 + plugins/signals-node/package.json | 2 +- plugins/signals/CHANGELOG.md | 11 + plugins/signals/package.json | 2 +- .../techdocs-addons-test-utils/CHANGELOG.md | 15 + .../techdocs-addons-test-utils/package.json | 2 +- plugins/techdocs-backend/CHANGELOG.md | 17 + plugins/techdocs-backend/package.json | 2 +- .../CHANGELOG.md | 11 + .../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 | 21 + plugins/techdocs/package.json | 2 +- plugins/user-settings-backend/CHANGELOG.md | 14 + plugins/user-settings-backend/package.json | 2 +- plugins/user-settings/CHANGELOG.md | 17 + plugins/user-settings/package.json | 2 +- yarn.lock | 264 +- 314 files changed, 4828 insertions(+), 219 deletions(-) create mode 100644 docs/releases/v1.30.0-next.0-changelog.md diff --git a/.changeset/pre.json b/.changeset/pre.json index be1b694c9e..7da5b582e1 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -188,5 +188,55 @@ "@backstage/plugin-user-settings-backend": "0.2.21", "@backstage/plugin-user-settings-common": "0.0.1" }, - "changesets": [] + "changesets": [ + "blue-pumas-cheer", + "bright-trainers-brake", + "chilly-trains-sleep", + "cool-insects-remember", + "cuddly-zebras-crash", + "dry-squids-tap", + "dull-ghosts-double", + "early-trees-dance", + "eighty-mirrors-flow", + "flat-plums-grow", + "forty-ties-agree", + "forty-ties-disagree", + "friendly-feet-refuse", + "gentle-dryers-smile", + "grumpy-owls-suffer", + "heavy-numbers-love", + "hip-hairs-exist", + "late-games-protect", + "light-pianos-exercise", + "little-bulldogs-guess", + "little-suns-fly", + "mighty-dolls-retire", + "modern-parrots-protect", + "neat-gifts-join", + "new-scissors-try", + "nice-peas-retire", + "nine-cherries-decide", + "nine-glasses-nail", + "ninety-icons-smile", + "pink-gorillas-brake", + "plenty-tools-exist", + "rich-mugs-dress", + "selfish-bees-think", + "six-rats-kick", + "slow-toes-jog", + "small-spoons-shout", + "soft-gorillas-refuse", + "spotty-planets-accept", + "strange-papayas-beg", + "strong-otters-compete", + "stupid-dots-relate", + "swift-kings-sparkle", + "thirty-paws-hope", + "tiny-oranges-pretend", + "tough-lies-repair", + "violet-jokes-wave", + "wicked-bobcats-teach", + "wild-eggs-exist", + "witty-bears-behave" + ] } diff --git a/docs/releases/v1.30.0-next.0-changelog.md b/docs/releases/v1.30.0-next.0-changelog.md new file mode 100644 index 0000000000..f3b7f2ef45 --- /dev/null +++ b/docs/releases/v1.30.0-next.0-changelog.md @@ -0,0 +1,2214 @@ +# Release v1.30.0-next.0 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.30.0-next.0](https://backstage.github.io/upgrade-helper/?to=1.30.0-next.0) + +## @backstage/cli@0.27.0-next.0 + +### Minor Changes + +- 32a38e1: **BREAKING**: The lockfile (`yarn.lock`) dependency analysis and mutations have been removed from several commands. + + The `versions:bump` command will no longer attempt to bump and deduplicate dependencies by modifying the lockfile, it will only update `package.json` files. + + The `versions:check` command has been removed, since its only purpose was verification and mutation of the lockfile. We recommend using the `yarn dedupe` command instead, or the `yarn-deduplicate` package if you're using Yarn classic. + + The check that was built into the `package start` command has been removed, it will no longer warn about lockfile mismatches. + + The packages in the Backstage ecosystem handle package duplications much better now than when these CLI features were first introduced, so the need for these features has diminished. By removing them, we drastically reduce the integration between the Backstage CLI and Yarn, making it much easier to add support for other package managers in the future. + +### Patch Changes + +- 7eb08a6: Add frontend-dynamic-container role to eslint config factory +- fbc7819: Use ES2022 in CLI bundler +- e53074f: Updated default backend plugin to use `RootConfigService` instead of `Config`. This also removes the dependency on `@backstage/config` as it's no longer used. +- ee2b0e5: The experimental module federation build now has the ability to force the use of development versions of `react` and `react-dom` by setting the `FORCE_REACT_DEVELOPMENT` flag. +- 239dffc: Remove usage of deprecated functionality from @backstage/config-loader +- 0eedec3: Add support for dynamic plugins via the EXPERIMENTAL_MODULE_FEDERATION environment variable when running `yarn start`. +- dc4fb4f: Fix for `repo build --all` not properly detecting the experimental public entry point. +- Updated dependencies + - @backstage/integration@1.14.0-next.0 + - @backstage/config-loader@1.8.2-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/eslint-plugin@0.1.8 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/integration@1.14.0-next.0 + +### Minor Changes + +- 78c1329: Updated `GitlabUrlReader.readUrl` and `GitlabUrlReader.readTree` to accept a user-provided token, supporting both bearer and private tokens. + +### Patch Changes + +- c591670: Updated functions for `getHarnessEditContentsUrl`, `getHarnessFileContentsUrl`, `getHarnessArchiveUrl`, `getHarnessLatestCommitUrl` and `parseHarnessUrl` to handle account and org level urls +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-react@1.11.0-next.0 + +### Minor Changes + +- 8839381: Add scaffolder option to display object items in separate rows on review page + +### Patch Changes + +- d0e95a7: Add ability to customise form fields in the UI by exposing `uiSchema` and `formContext` in `FormProps` +- 4670f06: support `ajv-errors` for scaffolder validation to allow for customizing the error messages +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-scaffolder-common@1.5.4 + +## @backstage/app-defaults@1.5.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-app-api@1.14.1-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-permission-react@0.4.24 + +## @backstage/backend-app-api@0.8.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/config-loader@1.8.2-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + +## @backstage/backend-common@0.23.4-next.0 + +### Patch Changes + +- ba8571e: Setup user agent header for AWS sdk clients, this enables users to better track API calls made from Backstage to AWS APIs through things like CloudTrail. + +- 7e13b7a: The remaining exports in the package have now been deprecated: + + - `cacheToPluginCacheManager` + - `createLegacyAuthAdapters` + - `LegacyCreateRouter` + - `legacyPlugin` + - `loggerToWinstonLogger` + - `makeLegacyPlugin` + + Users of these export should fully [migrate to the new backend system](https://backstage.io/docs/backend-system/building-backends/migrating). + +- Updated dependencies + - @backstage/integration@1.14.0-next.0 + - @backstage/config-loader@1.8.2-next.0 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.0 + +## @backstage/backend-defaults@0.4.2-next.0 + +### Patch Changes + +- 4e79d19: The `createHealthRouter` utility that allows you to create a health check router is now exported via `@backstage/backend-defaults/rootHttpRouter`. +- 78c1329: Updated `GitlabUrlReader.readUrl` and `GitlabUrlReader.readTree` to accept a user-provided token, supporting both bearer and private tokens. +- 8e967da: Fixed the routing of the new health check service, the health endpoints should now properly be available at `/.backstage/health/v1/readiness` and `/.backstage/health/v1/liveness`. +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/config-loader@1.8.2-next.0 + - @backstage/backend-app-api@0.8.1-next.0 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + +## @backstage/backend-dynamic-feature-service@0.2.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-backend@1.24.1-next.0 + - @backstage/config-loader@1.8.2-next.0 + - @backstage/backend-app-api@0.8.1-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.23-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-events-backend@0.3.10-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + - @backstage/plugin-search-backend-node@1.2.28-next.0 + - @backstage/plugin-search-common@1.2.13 + +## @backstage/backend-openapi-utils@0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/errors@1.2.4 + +## @backstage/backend-plugin-api@0.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-permission-common@0.8.0 + +## @backstage/backend-tasks@0.5.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/backend-test-utils@0.4.5-next.0 + +### Patch Changes + +- 4e79d19: The default services for `startTestBackend` and `ServiceFactoryTester` now includes the Root Health Service. +- Updated dependencies + - @backstage/backend-defaults@0.4.2-next.0 + - @backstage/backend-app-api@0.8.1-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + +## @backstage/config-loader@1.8.2-next.0 + +### Patch Changes + +- 493feac: Add boolean `allowMissingDefaultConfig` option to `ConfigSources.default` and + `ConfigSources.defaultForTargets`, which results in omission of a ConfigSource + for the default app-config.yaml configuration file if it's not present. +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/core-app-api@1.14.1-next.0 + +### Patch Changes + +- 9a46a81: The request to delete the session cookie when running the app in protected mode is now done with a plain `fetch` rather than `FetchApi`. This fixes a bug where the app would immediately try to sign-in again when removing the cookie during logout. +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/core-compat-api@0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/version-bridge@1.0.8 + +## @backstage/core-components@0.14.10-next.0 + +### Patch Changes + +- 678971a: Move the `Link` component to the `RoutedTabs` instead of the `HeaderTabs` component +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/version-bridge@1.0.8 + +## @backstage/create-app@0.5.18-next.0 + +### Patch Changes + +- c0a705d: Added the Kubernetes plugin to `create-app` +- Updated dependencies + - @backstage/cli-common@0.1.14 + +## @backstage/dev-utils@1.0.36-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-app-api@1.14.1-next.0 + - @backstage/app-defaults@1.5.9-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + +## @backstage/frontend-app-api@0.7.4-next.0 + +### Patch Changes + +- 7777b5f: Support icon overriding with the new `IconBundleBlueprint` API. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-app-api@1.14.1-next.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/frontend-plugin-api@0.6.8-next.0 + +### Patch Changes + +- 4e53ad6: Introduce a new way to encapsulate extension kinds that replaces the extension creator pattern with `createExtensionBlueprint` + + This allows the creation of extension instances with the following pattern: + + ```tsx + // create the extension blueprint which is used to create instances + const EntityCardBlueprint = createExtensionBlueprint({ + kind: 'entity-card', + attachTo: { id: 'test', input: 'default' }, + output: { + element: coreExtensionData.reactElement, + }, + factory(params: { text: string }) { + return { + element: <h1>{params.text}</h1>, + }; + }, + }); + + // create an instance of the extension blueprint with params + const testExtension = EntityCardBlueprint.make({ + name: 'foo', + params: { + text: 'Hello World', + }, + }); + ``` + +- 9b89b82: The `ExtensionBoundary` now by default infers whether it's routable from whether it outputs a route path. + +- 7777b5f: Added a new `IconBundleBlueprint` that lets you create icon bundle extensions that can be installed in an App in order to override or add new app icons. + + ```tsx + import { IconBundleBlueprint } from '@backstage/frontend-plugin-api'; + + const exampleIconBundle = IconBundleBlueprint.make({ + name: 'example-bundle', + params: { + icons: { + user: MyOwnUserIcon, + }, + }, + }); + ``` + +- 31bfc44: Extension data references can now be defined in a way that encapsulates the ID string in the type, in addition to the data type itself. The old way of creating extension data references is deprecated and will be removed in a future release. + + For example, the following code: + + ```ts + export const myExtension = + createExtensionDataRef<MyType>('my-plugin.my-data'); + ``` + + Should be updated to the following: + + ```ts + export const myExtension = createExtensionDataRef<MyType>().with({ + id: 'my-plugin.my-data', + }); + ``` + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/frontend-test-utils@0.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/frontend-app-api@0.7.4-next.0 + - @backstage/test-utils@1.5.9-next.0 + - @backstage/types@1.1.1 + +## @backstage/integration-react@1.1.30-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/repo-tools@0.9.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.8.2-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/errors@1.2.4 + +## @techdocs/cli@1.8.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.4.2-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.9-next.0 + +## @backstage/test-utils@1.5.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.14.1-next.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-react@0.4.24 + +## @backstage/plugin-api-docs@0.11.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-catalog@1.21.2-next.0 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-permission-react@0.4.24 + +## @backstage/plugin-app-backend@0.3.72-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/config-loader@1.8.2-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.23-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + +## @backstage/plugin-app-node@0.1.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.8.2-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + +## @backstage/plugin-app-visualizer@0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-auth-backend@0.22.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.1.18-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.2.4-next.0 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.15-next.0 + - @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.1.6-next.0 + - @backstage/plugin-auth-backend-module-bitbucket-provider@0.1.6-next.0 + - @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.1.6-next.0 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.18-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.1.20-next.0 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.20-next.0 + - @backstage/plugin-auth-backend-module-google-provider@0.1.20-next.0 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.2.4-next.0 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.16-next.0 + - @backstage/plugin-auth-backend-module-oidc-provider@0.2.4-next.0 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.16-next.0 + - @backstage/plugin-auth-backend-module-onelogin-provider@0.1.4-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-backend@0.22.10-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.0 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.0 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.0 + +## @backstage/plugin-auth-backend-module-github-provider@0.1.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.1.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + +## @backstage/plugin-auth-backend-module-google-provider@0.1.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + +## @backstage/plugin-auth-backend-module-guest-provider@0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.0 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.1.18-next.0 + +### Patch Changes + +- 39f36a9: Updated the Microsoft authenticator to accurately define required scopes, but to also omit the required and additional scopes when requesting resource scopes. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.0 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-auth-backend@0.22.10-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + +## @backstage/plugin-auth-backend-module-okta-provider@0.0.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.1.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + +## @backstage/plugin-auth-node@0.4.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-react@0.1.5-next.0 + +### Patch Changes + +- aeac3e9: feat: Hide visibility of CookieAuthRedirect +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + +## @backstage/plugin-bitbucket-cloud-common@0.2.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.14.0-next.0 + +## @backstage/plugin-catalog@1.21.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/plugin-search-react@1.7.14-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-scaffolder-common@1.5.4 + - @backstage/plugin-search-common@1.2.13 + +## @backstage/plugin-catalog-backend@1.24.1-next.0 + +### Patch Changes + +- a629fb2: Added setAllowedLocationTypes while introducing a new extension point called CatalogLocationsExtensionPoint +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-openapi-utils@0.1.16-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-events-node@0.3.9-next.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.29-next.0 + +## @backstage/plugin-catalog-backend-module-aws@0.3.18-next.0 + +### Patch Changes + +- ba8571e: Setup user agent header for AWS sdk clients, this enables users to better track API calls made from Backstage to AWS APIs through things like CloudTrail. +- 90a7340: `AwsOrganizationCloudAccountProcessor` configuration field `roleArn` is deprecated in favor of new field `accountId` +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-kubernetes-common@0.8.1 + +## @backstage/plugin-catalog-backend-module-azure@0.1.43-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.25 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-openapi-utils@0.1.16-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.2.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.22-next.0 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-events-node@0.3.9-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.37-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-gcp@0.1.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-kubernetes-common@0.8.1 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.40-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-github@0.6.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-backend@1.24.1-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-events-node@0.3.9-next.0 + +## @backstage/plugin-catalog-backend-module-github-org@0.1.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-backend-module-github@0.6.6-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab@0.3.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-events-node@0.3.9-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.0.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-catalog-backend-module-gitlab@0.3.22-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.4.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-backend@1.24.1-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-events-node@0.3.9-next.0 + - @backstage/plugin-permission-common@0.8.0 + +## @backstage/plugin-catalog-backend-module-ldap@0.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.25 + +## @backstage/plugin-catalog-backend-module-logs@0.0.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.24.1-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + +## @backstage/plugin-catalog-backend-module-msgraph@0.5.31-next.0 + +### Patch Changes + +- 58dff4d: Added option to ingest groups based on their group membership in Azure Entra ID +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.25 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.41-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-backend@1.24.1-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.25 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.1.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-scaffolder-common@1.5.4 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.4.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.3 + - @backstage/plugin-permission-common@0.8.0 + +## @backstage/plugin-catalog-graph@0.4.8-next.0 + +### Patch Changes + +- fba7537: Memoize entity graph nodes when applying an `entityFilter` to prevent repeated redraws +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-import@0.12.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/plugin-catalog-common@1.0.25 + +## @backstage/plugin-catalog-node@1.12.5-next.0 + +### Patch Changes + +- a629fb2: Added setAllowedLocationTypes while introducing a new extension point called CatalogLocationsExtensionPoint +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + +## @backstage/plugin-catalog-react@1.12.3-next.0 + +### Patch Changes + +- 31bfc44: Updated alpha definitions of extension data references. +- 9b89b82: Internal refactor to remove unnecessary `routable` prop in the implementation of the `createEntityContentExtension` alpha export. +- bebd569: Fix extra divider displayed on user list picker component +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-react@0.4.24 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + +## @backstage/plugin-config-schema@0.1.58-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-devtools@0.1.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/plugin-devtools-common@0.1.11 + - @backstage/plugin-permission-react@0.4.24 + +## @backstage/plugin-devtools-backend@0.3.9-next.0 + +### Patch Changes + +- 32a38e1: Removed unused code for lockfile analysis. +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/config-loader@1.8.2-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.11 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + +## @backstage/plugin-events-backend@0.3.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.9-next.0 + +## @backstage/plugin-events-backend-module-aws-sqs@0.3.9-next.0 + +### Patch Changes + +- ba8571e: Setup user agent header for AWS sdk clients, this enables users to better track API calls made from Backstage to AWS APIs through things like CloudTrail. +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.9-next.0 + +## @backstage/plugin-events-backend-module-azure@0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + +## @backstage/plugin-events-backend-module-gerrit@0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + +## @backstage/plugin-events-backend-module-github@0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.9-next.0 + +## @backstage/plugin-events-backend-module-gitlab@0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.9-next.0 + +## @backstage/plugin-events-backend-test-utils@0.1.33-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.9-next.0 + +## @backstage/plugin-events-node@0.3.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + +## @backstage/plugin-home@0.7.8-next.0 + +### Patch Changes + +- 31bfc44: Updated alpha definitions of extension data references. +- fdcc059: Fixed a bug on the WelcomeTitle component where the welcome message wasn't correct when the language was set to Spanish +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-app-api@1.14.1-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-home-react@0.1.16-next.0 + +## @backstage/plugin-home-react@0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-kubernetes@0.11.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-kubernetes-common@0.8.1 + - @backstage/plugin-kubernetes-react@0.4.2-next.0 + +## @backstage/plugin-kubernetes-backend@0.18.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-kubernetes-common@0.8.1 + - @backstage/plugin-kubernetes-node@0.1.17-next.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + +## @backstage/plugin-kubernetes-cluster@0.0.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-kubernetes-common@0.8.1 + - @backstage/plugin-kubernetes-react@0.4.2-next.0 + +## @backstage/plugin-kubernetes-node@0.1.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.1 + +## @backstage/plugin-kubernetes-react@0.4.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.1 + +## @backstage/plugin-notifications@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-signals-react@0.0.4 + +## @backstage/plugin-notifications-backend@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.4-next.0 + - @backstage/plugin-signals-node@0.1.9-next.0 + +## @backstage/plugin-notifications-backend-module-email@0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.4-next.0 + +## @backstage/plugin-notifications-node@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-signals-node@0.1.9-next.0 + +## @backstage/plugin-org@0.6.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-catalog-common@1.0.25 + +## @backstage/plugin-org-react@0.1.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-permission-backend@0.5.47-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.1.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + +## @backstage/plugin-permission-node@0.8.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-permission-common@0.8.0 + +## @backstage/plugin-proxy-backend@0.5.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder@1.23.1-next.0 + +### Patch Changes + +- bbd9f56: Cleaned up codebase of RepoUrlPicker +- b8600fe: Fix issue with `RepoUrlPicker` not refreshing the credentials for a different host +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/plugin-scaffolder-react@1.11.0-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-scaffolder-common@1.5.4 + +## @backstage/plugin-scaffolder-backend@1.23.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.4.5-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.22-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.21-next.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.15-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.13-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.13-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.13-next.0 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.15-next.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.13-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.4.1-next.0 + - @backstage/plugin-scaffolder-common@1.5.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + +## @backstage/plugin-scaffolder-backend-module-azure@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.13-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.13-next.0 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-bitbucket-cloud-common@0.2.22-next.0 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.47-next.0 + +### Patch Changes + +- dae85df: Add examples for `fetch:cookiecutter` scaffolder action & improve related tests +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.1.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + +## @backstage/plugin-scaffolder-backend-module-github@0.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.4.5-next.0 + +### Patch Changes + +- fad1b90: Allow the `createGitlabProjectVariableAction` to use oauth tokens + +- aab708e: Added test cases for gitlab:issue:edit examples + +- ef742dc: Added test cases for gitlab:projectAccessToken:create example + +- 1ba4c2f: Added test cases for gitlab:pipeline:trigger examples + +- a6603e4: Add custom action for merge request: **auto** + + The **Auto** action selects the committed action between _create_ and _update_. + + The **Auto** action fetches files using the **/projects/repository/tree endpoint**. + After fetching, it checks if the file exists locally and in the repository. If it does, it chooses **update**; otherwise, it chooses **create**. + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.0.6-next.0 + +### Patch Changes + +- 6fc03c7: Add examples for notification:send scaffolder action & improve related tests +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.40-next.0 + +### Patch Changes + +- 449def7: Add examples for fetch:rails scaffolder action & improve related tests +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.1.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + - @backstage/plugin-scaffolder-node-test-utils@0.1.10-next.0 + +## @backstage/plugin-scaffolder-node@0.4.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.4 + +## @backstage/plugin-scaffolder-node-test-utils@0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-test-utils@0.4.5-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + +## @backstage/plugin-search@1.4.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/plugin-search-react@1.7.14-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-search-common@1.2.13 + +## @backstage/plugin-search-backend@1.5.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-defaults@0.4.2-next.0 + - @backstage/backend-openapi-utils@0.1.16-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + - @backstage/plugin-search-backend-node@1.2.28-next.0 + - @backstage/plugin-search-common@1.2.13 + +## @backstage/plugin-search-backend-module-catalog@0.1.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-search-backend-node@1.2.28-next.0 + - @backstage/plugin-search-common@1.2.13 + +## @backstage/plugin-search-backend-module-elasticsearch@1.5.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-backend-node@1.2.28-next.0 + - @backstage/plugin-search-common@1.2.13 + +## @backstage/plugin-search-backend-module-explore@0.1.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.2.28-next.0 + - @backstage/plugin-search-common@1.2.13 + +## @backstage/plugin-search-backend-module-pg@0.5.33-next.0 + +### Patch Changes + +- 7251567: Removing `@backstage/backend-app-api` dependency +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.2.28-next.0 + - @backstage/plugin-search-common@1.2.13 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.2.28-next.0 + - @backstage/plugin-search-common@1.2.13 + +## @backstage/plugin-search-backend-module-techdocs@0.1.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-search-backend-node@1.2.28-next.0 + - @backstage/plugin-search-common@1.2.13 + - @backstage/plugin-techdocs-node@1.12.9-next.0 + +## @backstage/plugin-search-backend-node@1.2.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-search-common@1.2.13 + +## @backstage/plugin-search-react@1.7.14-next.0 + +### Patch Changes + +- 31bfc44: Updated alpha definitions of extension data references. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-search-common@1.2.13 + +## @backstage/plugin-signals@0.0.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.4 + +## @backstage/plugin-signals-backend@0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + - @backstage/plugin-signals-node@0.1.9-next.0 + +## @backstage/plugin-signals-node@0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + +## @backstage/plugin-techdocs@1.10.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/plugin-search-react@1.7.14-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-search-common@1.2.13 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.36-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/plugin-search-react@1.7.14-next.0 + - @backstage/core-app-api@1.14.1-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/test-utils@1.5.9-next.0 + - @backstage/plugin-catalog@1.21.2-next.0 + - @backstage/plugin-techdocs@1.10.8-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + +## @backstage/plugin-techdocs-backend@1.10.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.28-next.0 + - @backstage/plugin-techdocs-node@1.12.9-next.0 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + +## @backstage/plugin-techdocs-node@1.12.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.13 + +## @backstage/plugin-techdocs-react@1.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/version-bridge@1.0.8 + +## @backstage/plugin-user-settings@0.8.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-app-api@1.14.1-next.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.4 + - @backstage/plugin-user-settings-common@0.0.1 + +## @backstage/plugin-user-settings-backend@0.2.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-signals-node@0.1.9-next.0 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.100-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.27.0-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/plugin-search-react@1.7.14-next.0 + - @backstage/plugin-home@0.7.8-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/plugin-scaffolder-react@1.11.0-next.0 + - @backstage/frontend-app-api@0.7.4-next.0 + - @backstage/plugin-catalog-graph@0.4.8-next.0 + - @backstage/plugin-scaffolder@1.23.1-next.0 + - @backstage/core-app-api@1.14.1-next.0 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/app-defaults@1.5.9-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-api-docs@0.11.8-next.0 + - @backstage/plugin-catalog@1.21.2-next.0 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-catalog-import@0.12.2-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.7-next.0 + - @backstage/plugin-devtools@0.1.17-next.0 + - @backstage/plugin-kubernetes@0.11.13-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.14-next.0 + - @backstage/plugin-notifications@0.2.4-next.0 + - @backstage/plugin-org@0.6.28-next.0 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-search@1.4.15-next.0 + - @backstage/plugin-search-common@1.2.13 + - @backstage/plugin-signals@0.0.9-next.0 + - @backstage/plugin-techdocs@1.10.8-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.13-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + - @backstage/plugin-user-settings@0.8.10-next.0 + +## example-app-next@0.0.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.27.0-next.0 + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/plugin-search-react@1.7.14-next.0 + - @backstage/plugin-home@0.7.8-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/plugin-scaffolder-react@1.11.0-next.0 + - @backstage/frontend-app-api@0.7.4-next.0 + - @backstage/plugin-catalog-graph@0.4.8-next.0 + - @backstage/plugin-scaffolder@1.23.1-next.0 + - @backstage/core-app-api@1.14.1-next.0 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/app-defaults@1.5.9-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-api-docs@0.11.8-next.0 + - @backstage/plugin-app-visualizer@0.1.9-next.0 + - @backstage/plugin-catalog@1.21.2-next.0 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-catalog-import@0.12.2-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.7-next.0 + - @backstage/plugin-kubernetes@0.11.13-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.14-next.0 + - @backstage/plugin-notifications@0.2.4-next.0 + - @backstage/plugin-org@0.6.28-next.0 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-search@1.4.15-next.0 + - @backstage/plugin-search-common@1.2.13 + - @backstage/plugin-signals@0.0.9-next.0 + - @backstage/plugin-techdocs@1.10.8-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.13-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + - @backstage/plugin-user-settings@0.8.10-next.0 + +## app-next-example-plugin@0.0.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/core-components@0.14.10-next.0 + +## example-backend@0.0.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.4.2-next.0 + - @backstage/plugin-catalog-backend@1.24.1-next.0 + - @backstage/plugin-devtools-backend@0.3.9-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-app-backend@0.3.72-next.0 + - @backstage/plugin-auth-backend@0.22.10-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.1.20-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.1.9-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.2.6-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.1.41-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.21-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.10-next.0 + - @backstage/plugin-kubernetes-backend@0.18.4-next.0 + - @backstage/plugin-notifications-backend@0.3.4-next.0 + - @backstage/plugin-permission-backend@0.5.47-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.20-next.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + - @backstage/plugin-proxy-backend@0.5.4-next.0 + - @backstage/plugin-scaffolder-backend@1.23.1-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.4.1-next.0 + - @backstage/plugin-search-backend@1.5.15-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.29-next.0 + - @backstage/plugin-search-backend-module-explore@0.1.29-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.28-next.0 + - @backstage/plugin-search-backend-node@1.2.28-next.0 + - @backstage/plugin-signals-backend@0.1.9-next.0 + - @backstage/plugin-techdocs-backend@1.10.10-next.0 + +## example-backend-legacy@0.2.101-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.40-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.4.5-next.0 + - @backstage/plugin-catalog-backend@1.24.1-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/plugin-devtools-backend@0.3.9-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-search-backend-module-pg@0.5.33-next.0 + - example-app@0.2.100-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-app-backend@0.3.72-next.0 + - @backstage/plugin-auth-backend@0.22.10-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.21-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.10-next.0 + - @backstage/plugin-events-backend@0.3.10-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + - @backstage/plugin-kubernetes-backend@0.18.4-next.0 + - @backstage/plugin-permission-backend@0.5.47-next.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + - @backstage/plugin-proxy-backend@0.5.4-next.0 + - @backstage/plugin-scaffolder-backend@1.23.1-next.0 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.24-next.0 + - @backstage/plugin-search-backend@1.5.15-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.29-next.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.5.4-next.0 + - @backstage/plugin-search-backend-module-explore@0.1.29-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.28-next.0 + - @backstage/plugin-search-backend-node@1.2.28-next.0 + - @backstage/plugin-signals-backend@0.1.9-next.0 + - @backstage/plugin-signals-node@0.1.9-next.0 + - @backstage/plugin-techdocs-backend@1.10.10-next.0 + +## e2e-test@0.2.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.18-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + +## techdocs-cli-embedded-app@0.2.99-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.27.0-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-app-api@1.14.1-next.0 + - @backstage/app-defaults@1.5.9-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/test-utils@1.5.9-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-catalog@1.21.2-next.0 + - @backstage/plugin-techdocs@1.10.8-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + +## @internal/plugin-todo-list@1.0.30-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + +## @internal/plugin-todo-list-backend@1.0.30-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.0 diff --git a/package.json b/package.json index 07c9b2917b..73d0ca5b19 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "root", - "version": "1.29.0", + "version": "1.30.0-next.0", "private": true, "repository": { "type": "git", diff --git a/packages/app-defaults/CHANGELOG.md b/packages/app-defaults/CHANGELOG.md index a03034112c..a045f9a4f9 100644 --- a/packages/app-defaults/CHANGELOG.md +++ b/packages/app-defaults/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/app-defaults +## 1.5.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-app-api@1.14.1-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-permission-react@0.4.24 + ## 1.5.8 ### Patch Changes diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json index 8997ba860f..2389c2cddc 100644 --- a/packages/app-defaults/package.json +++ b/packages/app-defaults/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/app-defaults", - "version": "1.5.8", + "version": "1.5.9-next.0", "description": "Provides the default wiring of a Backstage App", "backstage": { "role": "web-library" diff --git a/packages/app-next-example-plugin/CHANGELOG.md b/packages/app-next-example-plugin/CHANGELOG.md index fb61388f22..f05b81642f 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.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/core-components@0.14.10-next.0 + ## 0.0.13 ### Patch Changes diff --git a/packages/app-next-example-plugin/package.json b/packages/app-next-example-plugin/package.json index c48d5a92be..d397883063 100644 --- a/packages/app-next-example-plugin/package.json +++ b/packages/app-next-example-plugin/package.json @@ -1,6 +1,6 @@ { "name": "app-next-example-plugin", - "version": "0.0.13", + "version": "0.0.14-next.0", "description": "Backstage internal example plugin", "backstage": { "role": "frontend-plugin", diff --git a/packages/app-next/CHANGELOG.md b/packages/app-next/CHANGELOG.md index 3bbf698ebd..794484d2ce 100644 --- a/packages/app-next/CHANGELOG.md +++ b/packages/app-next/CHANGELOG.md @@ -1,5 +1,48 @@ # example-app-next +## 0.0.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.27.0-next.0 + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/plugin-search-react@1.7.14-next.0 + - @backstage/plugin-home@0.7.8-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/plugin-scaffolder-react@1.11.0-next.0 + - @backstage/frontend-app-api@0.7.4-next.0 + - @backstage/plugin-catalog-graph@0.4.8-next.0 + - @backstage/plugin-scaffolder@1.23.1-next.0 + - @backstage/core-app-api@1.14.1-next.0 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/app-defaults@1.5.9-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-api-docs@0.11.8-next.0 + - @backstage/plugin-app-visualizer@0.1.9-next.0 + - @backstage/plugin-catalog@1.21.2-next.0 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-catalog-import@0.12.2-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.7-next.0 + - @backstage/plugin-kubernetes@0.11.13-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.14-next.0 + - @backstage/plugin-notifications@0.2.4-next.0 + - @backstage/plugin-org@0.6.28-next.0 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-search@1.4.15-next.0 + - @backstage/plugin-search-common@1.2.13 + - @backstage/plugin-signals@0.0.9-next.0 + - @backstage/plugin-techdocs@1.10.8-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.13-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + - @backstage/plugin-user-settings@0.8.10-next.0 + ## 0.0.13 ### Patch Changes diff --git a/packages/app-next/package.json b/packages/app-next/package.json index c0c19bc40c..b4b9f69c51 100644 --- a/packages/app-next/package.json +++ b/packages/app-next/package.json @@ -1,6 +1,6 @@ { "name": "example-app-next", - "version": "0.0.13", + "version": "0.0.14-next.0", "private": true, "repository": { "type": "git", diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index a75cf24a07..4ba5430905 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,46 @@ # example-app +## 0.2.100-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.27.0-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/plugin-search-react@1.7.14-next.0 + - @backstage/plugin-home@0.7.8-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/plugin-scaffolder-react@1.11.0-next.0 + - @backstage/frontend-app-api@0.7.4-next.0 + - @backstage/plugin-catalog-graph@0.4.8-next.0 + - @backstage/plugin-scaffolder@1.23.1-next.0 + - @backstage/core-app-api@1.14.1-next.0 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/app-defaults@1.5.9-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-api-docs@0.11.8-next.0 + - @backstage/plugin-catalog@1.21.2-next.0 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-catalog-import@0.12.2-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.7-next.0 + - @backstage/plugin-devtools@0.1.17-next.0 + - @backstage/plugin-kubernetes@0.11.13-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.14-next.0 + - @backstage/plugin-notifications@0.2.4-next.0 + - @backstage/plugin-org@0.6.28-next.0 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-search@1.4.15-next.0 + - @backstage/plugin-search-common@1.2.13 + - @backstage/plugin-signals@0.0.9-next.0 + - @backstage/plugin-techdocs@1.10.8-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.13-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + - @backstage/plugin-user-settings@0.8.10-next.0 + ## 0.2.99 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index 29cfbf0357..0468a2f7a8 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "example-app", - "version": "0.2.99", + "version": "0.2.100-next.0", "backstage": { "role": "frontend" }, diff --git a/packages/backend-app-api/CHANGELOG.md b/packages/backend-app-api/CHANGELOG.md index 70a163ee34..94ab9afb6f 100644 --- a/packages/backend-app-api/CHANGELOG.md +++ b/packages/backend-app-api/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/backend-app-api +## 0.8.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/config-loader@1.8.2-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + ## 0.8.0 ### Minor Changes diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index 8bd156c3a4..9372b837e0 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-app-api", - "version": "0.8.0", + "version": "0.8.1-next.0", "description": "Core API used by Backstage backend apps", "backstage": { "role": "node-library" diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md index 6d3218e0ed..01499c5d92 100644 --- a/packages/backend-common/CHANGELOG.md +++ b/packages/backend-common/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/backend-common +## 0.23.4-next.0 + +### Patch Changes + +- ba8571e: Setup user agent header for AWS sdk clients, this enables users to better track API calls made from Backstage to AWS APIs through things like CloudTrail. +- 7e13b7a: The remaining exports in the package have now been deprecated: + + - `cacheToPluginCacheManager` + - `createLegacyAuthAdapters` + - `LegacyCreateRouter` + - `legacyPlugin` + - `loggerToWinstonLogger` + - `makeLegacyPlugin` + + Users of these export should fully [migrate to the new backend system](https://backstage.io/docs/backend-system/building-backends/migrating). + +- Updated dependencies + - @backstage/integration@1.14.0-next.0 + - @backstage/config-loader@1.8.2-next.0 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.0 + ## 0.23.3 ### Patch Changes diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 553c800ea5..4ace5e950a 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-common", - "version": "0.23.3", + "version": "0.23.4-next.0", "description": "Common functionality library for Backstage backends", "backstage": { "role": "node-library" diff --git a/packages/backend-defaults/CHANGELOG.md b/packages/backend-defaults/CHANGELOG.md index 7d2ad7d6b7..a8cc588f1e 100644 --- a/packages/backend-defaults/CHANGELOG.md +++ b/packages/backend-defaults/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/backend-defaults +## 0.4.2-next.0 + +### Patch Changes + +- 4e79d19: The `createHealthRouter` utility that allows you to create a health check router is now exported via `@backstage/backend-defaults/rootHttpRouter`. +- 78c1329: Updated `GitlabUrlReader.readUrl` and `GitlabUrlReader.readTree` to accept a user-provided token, supporting both bearer and private tokens. +- 8e967da: Fixed the routing of the new health check service, the health endpoints should now properly be available at `/.backstage/health/v1/readiness` and `/.backstage/health/v1/liveness`. +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/config-loader@1.8.2-next.0 + - @backstage/backend-app-api@0.8.1-next.0 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + ## 0.4.0 ### Minor Changes diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index 87da6e0017..9c04507003 100644 --- a/packages/backend-defaults/package.json +++ b/packages/backend-defaults/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-defaults", - "version": "0.4.0", + "version": "0.4.2-next.0", "description": "Backend defaults used by Backstage backend apps", "backstage": { "role": "node-library" diff --git a/packages/backend-dynamic-feature-service/CHANGELOG.md b/packages/backend-dynamic-feature-service/CHANGELOG.md index 3003a8e177..ade7a7c0ec 100644 --- a/packages/backend-dynamic-feature-service/CHANGELOG.md +++ b/packages/backend-dynamic-feature-service/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/backend-dynamic-feature-service +## 0.2.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-backend@1.24.1-next.0 + - @backstage/config-loader@1.8.2-next.0 + - @backstage/backend-app-api@0.8.1-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.23-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-events-backend@0.3.10-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + - @backstage/plugin-search-backend-node@1.2.28-next.0 + - @backstage/plugin-search-common@1.2.13 + ## 0.2.15 ### Patch Changes diff --git a/packages/backend-dynamic-feature-service/package.json b/packages/backend-dynamic-feature-service/package.json index 0d05b97bd9..cc7a8b390b 100644 --- a/packages/backend-dynamic-feature-service/package.json +++ b/packages/backend-dynamic-feature-service/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-dynamic-feature-service", "description": "Backstage dynamic feature service", - "version": "0.2.15", + "version": "0.2.16-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-legacy/CHANGELOG.md b/packages/backend-legacy/CHANGELOG.md index 04538ca02e..5acae66b6a 100644 --- a/packages/backend-legacy/CHANGELOG.md +++ b/packages/backend-legacy/CHANGELOG.md @@ -1,5 +1,47 @@ # example-backend-legacy +## 0.2.101-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.40-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.4.5-next.0 + - @backstage/plugin-catalog-backend@1.24.1-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/plugin-devtools-backend@0.3.9-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-search-backend-module-pg@0.5.33-next.0 + - example-app@0.2.100-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-app-backend@0.3.72-next.0 + - @backstage/plugin-auth-backend@0.22.10-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.21-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.10-next.0 + - @backstage/plugin-events-backend@0.3.10-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + - @backstage/plugin-kubernetes-backend@0.18.4-next.0 + - @backstage/plugin-permission-backend@0.5.47-next.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + - @backstage/plugin-proxy-backend@0.5.4-next.0 + - @backstage/plugin-scaffolder-backend@1.23.1-next.0 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.24-next.0 + - @backstage/plugin-search-backend@1.5.15-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.29-next.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.5.4-next.0 + - @backstage/plugin-search-backend-module-explore@0.1.29-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.28-next.0 + - @backstage/plugin-search-backend-node@1.2.28-next.0 + - @backstage/plugin-signals-backend@0.1.9-next.0 + - @backstage/plugin-signals-node@0.1.9-next.0 + - @backstage/plugin-techdocs-backend@1.10.10-next.0 + ## 0.2.100 ### Patch Changes diff --git a/packages/backend-legacy/package.json b/packages/backend-legacy/package.json index 5861719455..8b07afca38 100644 --- a/packages/backend-legacy/package.json +++ b/packages/backend-legacy/package.json @@ -1,6 +1,6 @@ { "name": "example-backend-legacy", - "version": "0.2.100", + "version": "0.2.101-next.0", "backstage": { "role": "backend" }, diff --git a/packages/backend-openapi-utils/CHANGELOG.md b/packages/backend-openapi-utils/CHANGELOG.md index 540a239ad6..1056cc4cc1 100644 --- a/packages/backend-openapi-utils/CHANGELOG.md +++ b/packages/backend-openapi-utils/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/backend-openapi-utils +## 0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/errors@1.2.4 + ## 0.1.15 ### Patch Changes diff --git a/packages/backend-openapi-utils/package.json b/packages/backend-openapi-utils/package.json index 3059af5ffe..7b7778f9fe 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.15", + "version": "0.1.16-next.0", "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 3f47354561..9dd2e2587c 100644 --- a/packages/backend-plugin-api/CHANGELOG.md +++ b/packages/backend-plugin-api/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/backend-plugin-api +## 0.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-permission-common@0.8.0 + ## 0.7.0 ### Minor Changes diff --git a/packages/backend-plugin-api/package.json b/packages/backend-plugin-api/package.json index 52fbfb5806..4bad9325f1 100644 --- a/packages/backend-plugin-api/package.json +++ b/packages/backend-plugin-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-plugin-api", - "version": "0.7.0", + "version": "0.7.1-next.0", "description": "Core API used by Backstage backend plugins", "backstage": { "role": "node-library" diff --git a/packages/backend-tasks/CHANGELOG.md b/packages/backend-tasks/CHANGELOG.md index fef4fd56a9..929a38084c 100644 --- a/packages/backend-tasks/CHANGELOG.md +++ b/packages/backend-tasks/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/backend-tasks +## 0.5.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.5.27 ### Patch Changes diff --git a/packages/backend-tasks/package.json b/packages/backend-tasks/package.json index 998e1d0650..51e8c4611e 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.27", + "version": "0.5.28-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-test-utils/CHANGELOG.md b/packages/backend-test-utils/CHANGELOG.md index 9bee6fae55..72672bba7f 100644 --- a/packages/backend-test-utils/CHANGELOG.md +++ b/packages/backend-test-utils/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/backend-test-utils +## 0.4.5-next.0 + +### Patch Changes + +- 4e79d19: The default services for `startTestBackend` and `ServiceFactoryTester` now includes the Root Health Service. +- Updated dependencies + - @backstage/backend-defaults@0.4.2-next.0 + - @backstage/backend-app-api@0.8.1-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + ## 0.4.4 ### Patch Changes diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index 875949c0a0..e562b89c84 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-test-utils", - "version": "0.4.4", + "version": "0.4.5-next.0", "description": "Test helpers library for Backstage backends", "backstage": { "role": "node-library" diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index 854993119c..6110ab5f99 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,42 @@ # example-backend +## 0.0.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.4.2-next.0 + - @backstage/plugin-catalog-backend@1.24.1-next.0 + - @backstage/plugin-devtools-backend@0.3.9-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-app-backend@0.3.72-next.0 + - @backstage/plugin-auth-backend@0.22.10-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.1.20-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.1.9-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.2.6-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.1.41-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.21-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.10-next.0 + - @backstage/plugin-kubernetes-backend@0.18.4-next.0 + - @backstage/plugin-notifications-backend@0.3.4-next.0 + - @backstage/plugin-permission-backend@0.5.47-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.20-next.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + - @backstage/plugin-proxy-backend@0.5.4-next.0 + - @backstage/plugin-scaffolder-backend@1.23.1-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.4.1-next.0 + - @backstage/plugin-search-backend@1.5.15-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.29-next.0 + - @backstage/plugin-search-backend-module-explore@0.1.29-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.28-next.0 + - @backstage/plugin-search-backend-node@1.2.28-next.0 + - @backstage/plugin-signals-backend@0.1.9-next.0 + - @backstage/plugin-techdocs-backend@1.10.10-next.0 + ## 0.0.28 ### Patch Changes diff --git a/packages/backend/package.json b/packages/backend/package.json index ae47716326..27c378e339 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.0.28", + "version": "0.0.29-next.0", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index c062324abb..cbeb8493eb 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,40 @@ # @backstage/cli +## 0.27.0-next.0 + +### Minor Changes + +- 32a38e1: **BREAKING**: The lockfile (`yarn.lock`) dependency analysis and mutations have been removed from several commands. + + The `versions:bump` command will no longer attempt to bump and deduplicate dependencies by modifying the lockfile, it will only update `package.json` files. + + The `versions:check` command has been removed, since its only purpose was verification and mutation of the lockfile. We recommend using the `yarn dedupe` command instead, or the `yarn-deduplicate` package if you're using Yarn classic. + + The check that was built into the `package start` command has been removed, it will no longer warn about lockfile mismatches. + + The packages in the Backstage ecosystem handle package duplications much better now than when these CLI features were first introduced, so the need for these features has diminished. By removing them, we drastically reduce the integration between the Backstage CLI and Yarn, making it much easier to add support for other package managers in the future. + +### Patch Changes + +- 7eb08a6: Add frontend-dynamic-container role to eslint config factory +- fbc7819: Use ES2022 in CLI bundler +- e53074f: Updated default backend plugin to use `RootConfigService` instead of `Config`. This also removes the dependency on `@backstage/config` as it's no longer used. +- ee2b0e5: The experimental module federation build now has the ability to force the use of development versions of `react` and `react-dom` by setting the `FORCE_REACT_DEVELOPMENT` flag. +- 239dffc: Remove usage of deprecated functionality from @backstage/config-loader +- 0eedec3: Add support for dynamic plugins via the EXPERIMENTAL_MODULE_FEDERATION environment variable when running `yarn start`. +- dc4fb4f: Fix for `repo build --all` not properly detecting the experimental public entry point. +- Updated dependencies + - @backstage/integration@1.14.0-next.0 + - @backstage/config-loader@1.8.2-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/eslint-plugin@0.1.8 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + ## 0.26.11 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index ccc4818331..0c999b8b9c 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/cli", - "version": "0.26.11", + "version": "0.27.0-next.0", "description": "CLI for developing Backstage plugins and apps", "backstage": { "role": "cli" diff --git a/packages/config-loader/CHANGELOG.md b/packages/config-loader/CHANGELOG.md index fb048e7237..f19fa29e29 100644 --- a/packages/config-loader/CHANGELOG.md +++ b/packages/config-loader/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/config-loader +## 1.8.2-next.0 + +### Patch Changes + +- 493feac: Add boolean `allowMissingDefaultConfig` option to `ConfigSources.default` and + `ConfigSources.defaultForTargets`, which results in omission of a ConfigSource + for the default app-config.yaml configuration file if it's not present. +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 1.8.1 ### Patch Changes diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json index 28718b8290..16ff3e4f0b 100644 --- a/packages/config-loader/package.json +++ b/packages/config-loader/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/config-loader", - "version": "1.8.1", + "version": "1.8.2-next.0", "description": "Config loading functionality used by Backstage backend, and CLI", "backstage": { "role": "node-library" diff --git a/packages/core-app-api/CHANGELOG.md b/packages/core-app-api/CHANGELOG.md index ff09befd63..26b9eb20fe 100644 --- a/packages/core-app-api/CHANGELOG.md +++ b/packages/core-app-api/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/core-app-api +## 1.14.1-next.0 + +### Patch Changes + +- 9a46a81: The request to delete the session cookie when running the app in protected mode is now done with a plain `fetch` rather than `FetchApi`. This fixes a bug where the app would immediately try to sign-in again when removing the cookie during logout. +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 1.14.0 ### Minor Changes diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json index 5f297b16d5..0f78b11f98 100644 --- a/packages/core-app-api/package.json +++ b/packages/core-app-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-app-api", "description": "Core app API used by Backstage apps", - "version": "1.14.0", + "version": "1.14.1-next.0", "publishConfig": { "access": "public" }, diff --git a/packages/core-compat-api/CHANGELOG.md b/packages/core-compat-api/CHANGELOG.md index 829c6f41ff..43acba43f0 100644 --- a/packages/core-compat-api/CHANGELOG.md +++ b/packages/core-compat-api/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/core-compat-api +## 0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/version-bridge@1.0.8 + ## 0.2.7 ### Patch Changes diff --git a/packages/core-compat-api/package.json b/packages/core-compat-api/package.json index bbf131c761..dd954f3318 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.2.7", + "version": "0.2.8-next.0", "backstage": { "role": "web-library" }, diff --git a/packages/core-components/CHANGELOG.md b/packages/core-components/CHANGELOG.md index 3d46390597..a2463f594e 100644 --- a/packages/core-components/CHANGELOG.md +++ b/packages/core-components/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/core-components +## 0.14.10-next.0 + +### Patch Changes + +- 678971a: Move the `Link` component to the `RoutedTabs` instead of the `HeaderTabs` component +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/version-bridge@1.0.8 + ## 0.14.9 ### Patch Changes diff --git a/packages/core-components/package.json b/packages/core-components/package.json index 55faac9dba..a2688a0037 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.14.9", + "version": "0.14.10-next.0", "publishConfig": { "access": "public" }, diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index d7ad8037e6..dea7ecb237 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/create-app +## 0.5.18-next.0 + +### Patch Changes + +- c0a705d: Added the Kubernetes plugin to `create-app` +- Updated dependencies + - @backstage/cli-common@0.1.14 + ## 0.5.17 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 7d33d03a4b..b566cb53b1 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.17", + "version": "0.5.18-next.0", "publishConfig": { "access": "public" }, diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index f46a65827a..e6d6bf3ae4 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/dev-utils +## 1.0.36-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-app-api@1.14.1-next.0 + - @backstage/app-defaults@1.5.9-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + ## 1.0.35 ### Patch Changes diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index 0902d7c322..72d35cd29c 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/dev-utils", - "version": "1.0.35", + "version": "1.0.36-next.0", "description": "Utilities for developing Backstage plugins.", "backstage": { "role": "web-library" diff --git a/packages/e2e-test/CHANGELOG.md b/packages/e2e-test/CHANGELOG.md index ad76bf8b75..3e346fdac8 100644 --- a/packages/e2e-test/CHANGELOG.md +++ b/packages/e2e-test/CHANGELOG.md @@ -1,5 +1,14 @@ # e2e-test +## 0.2.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.18-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + ## 0.2.18 ### Patch Changes diff --git a/packages/e2e-test/package.json b/packages/e2e-test/package.json index 7fa0349a46..47fbd2ef1e 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.18", + "version": "0.2.19-next.0", "private": true, "backstage": { "role": "cli" diff --git a/packages/frontend-app-api/CHANGELOG.md b/packages/frontend-app-api/CHANGELOG.md index 7203efb8d8..0c7526d65e 100644 --- a/packages/frontend-app-api/CHANGELOG.md +++ b/packages/frontend-app-api/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/frontend-app-api +## 0.7.4-next.0 + +### Patch Changes + +- 7777b5f: Support icon overriding with the new `IconBundleBlueprint` API. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-app-api@1.14.1-next.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 0.7.3 ### Patch Changes diff --git a/packages/frontend-app-api/package.json b/packages/frontend-app-api/package.json index a55284ff68..83127290f4 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.7.3", + "version": "0.7.4-next.0", "backstage": { "role": "web-library" }, diff --git a/packages/frontend-plugin-api/CHANGELOG.md b/packages/frontend-plugin-api/CHANGELOG.md index 4c0e6fe9f8..607883d5e0 100644 --- a/packages/frontend-plugin-api/CHANGELOG.md +++ b/packages/frontend-plugin-api/CHANGELOG.md @@ -1,5 +1,76 @@ # @backstage/frontend-plugin-api +## 0.6.8-next.0 + +### Patch Changes + +- 4e53ad6: Introduce a new way to encapsulate extension kinds that replaces the extension creator pattern with `createExtensionBlueprint` + + This allows the creation of extension instances with the following pattern: + + ```tsx + // create the extension blueprint which is used to create instances + const EntityCardBlueprint = createExtensionBlueprint({ + kind: 'entity-card', + attachTo: { id: 'test', input: 'default' }, + output: { + element: coreExtensionData.reactElement, + }, + factory(params: { text: string }) { + return { + element: <h1>{params.text}</h1>, + }; + }, + }); + + // create an instance of the extension blueprint with params + const testExtension = EntityCardBlueprint.make({ + name: 'foo', + params: { + text: 'Hello World', + }, + }); + ``` + +- 9b89b82: The `ExtensionBoundary` now by default infers whether it's routable from whether it outputs a route path. +- 7777b5f: Added a new `IconBundleBlueprint` that lets you create icon bundle extensions that can be installed in an App in order to override or add new app icons. + + ```tsx + import { IconBundleBlueprint } from '@backstage/frontend-plugin-api'; + + const exampleIconBundle = IconBundleBlueprint.make({ + name: 'example-bundle', + params: { + icons: { + user: MyOwnUserIcon, + }, + }, + }); + ``` + +- 31bfc44: Extension data references can now be defined in a way that encapsulates the ID string in the type, in addition to the data type itself. The old way of creating extension data references is deprecated and will be removed in a future release. + + For example, the following code: + + ```ts + export const myExtension = + createExtensionDataRef<MyType>('my-plugin.my-data'); + ``` + + Should be updated to the following: + + ```ts + export const myExtension = createExtensionDataRef<MyType>().with({ + id: 'my-plugin.my-data', + }); + ``` + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 0.6.7 ### Patch Changes diff --git a/packages/frontend-plugin-api/package.json b/packages/frontend-plugin-api/package.json index f02f3fdedf..0206fece7e 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.6.7", + "version": "0.6.8-next.0", "backstage": { "role": "web-library" }, diff --git a/packages/frontend-test-utils/CHANGELOG.md b/packages/frontend-test-utils/CHANGELOG.md index de21194f4e..89deed057e 100644 --- a/packages/frontend-test-utils/CHANGELOG.md +++ b/packages/frontend-test-utils/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/frontend-test-utils +## 0.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/frontend-app-api@0.7.4-next.0 + - @backstage/test-utils@1.5.9-next.0 + - @backstage/types@1.1.1 + ## 0.1.10 ### Patch Changes diff --git a/packages/frontend-test-utils/package.json b/packages/frontend-test-utils/package.json index 0816a25443..1d0b00132b 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.10", + "version": "0.1.11-next.0", "backstage": { "role": "web-library" }, diff --git a/packages/integration-react/CHANGELOG.md b/packages/integration-react/CHANGELOG.md index ed54a92f5c..36ecf6f718 100644 --- a/packages/integration-react/CHANGELOG.md +++ b/packages/integration-react/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/integration-react +## 1.1.30-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + ## 1.1.29 ### Patch Changes diff --git a/packages/integration-react/package.json b/packages/integration-react/package.json index b04b603327..de42eb2798 100644 --- a/packages/integration-react/package.json +++ b/packages/integration-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/integration-react", - "version": "1.1.29", + "version": "1.1.30-next.0", "description": "Frontend package for managing integrations towards external systems", "backstage": { "role": "web-library" diff --git a/packages/integration/CHANGELOG.md b/packages/integration/CHANGELOG.md index 3fb630ccfc..b49c3410ec 100644 --- a/packages/integration/CHANGELOG.md +++ b/packages/integration/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/integration +## 1.14.0-next.0 + +### Minor Changes + +- 78c1329: Updated `GitlabUrlReader.readUrl` and `GitlabUrlReader.readTree` to accept a user-provided token, supporting both bearer and private tokens. + +### Patch Changes + +- c591670: Updated functions for `getHarnessEditContentsUrl`, `getHarnessFileContentsUrl`, `getHarnessArchiveUrl`, `getHarnessLatestCommitUrl` and `parseHarnessUrl` to handle account and org level urls +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 1.13.0 ### Minor Changes diff --git a/packages/integration/package.json b/packages/integration/package.json index 810150cf2d..0d1b733bbf 100644 --- a/packages/integration/package.json +++ b/packages/integration/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/integration", - "version": "1.13.0", + "version": "1.14.0-next.0", "description": "Helpers for managing integrations towards external systems", "backstage": { "role": "common-library" diff --git a/packages/repo-tools/CHANGELOG.md b/packages/repo-tools/CHANGELOG.md index 18c696a51c..7f90cb37e9 100644 --- a/packages/repo-tools/CHANGELOG.md +++ b/packages/repo-tools/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/repo-tools +## 0.9.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.8.2-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/errors@1.2.4 + ## 0.9.4 ### Patch Changes diff --git a/packages/repo-tools/package.json b/packages/repo-tools/package.json index 9f3a177b4f..f314dcc580 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.9.4", + "version": "0.9.5-next.0", "publishConfig": { "access": "public" }, diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md index 6c8cc3f4ac..727cd20533 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.99-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.27.0-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-app-api@1.14.1-next.0 + - @backstage/app-defaults@1.5.9-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/test-utils@1.5.9-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-catalog@1.21.2-next.0 + - @backstage/plugin-techdocs@1.10.8-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + ## 0.2.98 ### Patch Changes diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json index 6c395636b1..13aa5a1855 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.98", + "version": "0.2.99-next.0", "private": true, "backstage": { "role": "frontend" diff --git a/packages/techdocs-cli/CHANGELOG.md b/packages/techdocs-cli/CHANGELOG.md index 34f612932c..74fe37f0b1 100644 --- a/packages/techdocs-cli/CHANGELOG.md +++ b/packages/techdocs-cli/CHANGELOG.md @@ -1,5 +1,16 @@ # @techdocs/cli +## 1.8.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.4.2-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.9-next.0 + ## 1.8.16 ### Patch Changes diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index a44213abb7..98eea44657 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.16", + "version": "1.8.17-next.0", "publishConfig": { "access": "public" }, diff --git a/packages/test-utils/CHANGELOG.md b/packages/test-utils/CHANGELOG.md index 3f40af6299..951efa799d 100644 --- a/packages/test-utils/CHANGELOG.md +++ b/packages/test-utils/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/test-utils +## 1.5.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.14.1-next.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-react@0.4.24 + ## 1.5.8 ### Patch Changes diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 9d36217b46..dac4827938 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/test-utils", - "version": "1.5.8", + "version": "1.5.9-next.0", "description": "Utilities to test Backstage plugins and apps.", "backstage": { "role": "web-library" diff --git a/plugins/api-docs/CHANGELOG.md b/plugins/api-docs/CHANGELOG.md index b6d585c0f0..80b23769a0 100644 --- a/plugins/api-docs/CHANGELOG.md +++ b/plugins/api-docs/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-api-docs +## 0.11.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-catalog@1.21.2-next.0 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-permission-react@0.4.24 + ## 0.11.7 ### Patch Changes diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 7cda749423..c448b1dd9b 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-api-docs", - "version": "0.11.7", + "version": "0.11.8-next.0", "description": "A Backstage plugin that helps represent API entities in the frontend", "backstage": { "role": "frontend-plugin", diff --git a/plugins/app-backend/CHANGELOG.md b/plugins/app-backend/CHANGELOG.md index 63265e33d9..bb73548da8 100644 --- a/plugins/app-backend/CHANGELOG.md +++ b/plugins/app-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-app-backend +## 0.3.72-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/config-loader@1.8.2-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.23-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + ## 0.3.71 ### Patch Changes diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json index e6661f9d73..fcd9cd34b9 100644 --- a/plugins/app-backend/package.json +++ b/plugins/app-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-app-backend", - "version": "0.3.71", + "version": "0.3.72-next.0", "description": "A Backstage backend plugin that serves the Backstage frontend app", "backstage": { "role": "backend-plugin", diff --git a/plugins/app-node/CHANGELOG.md b/plugins/app-node/CHANGELOG.md index 4dce17870a..af94c02d84 100644 --- a/plugins/app-node/CHANGELOG.md +++ b/plugins/app-node/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-app-node +## 0.1.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.8.2-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + ## 0.1.22 ### Patch Changes diff --git a/plugins/app-node/package.json b/plugins/app-node/package.json index a846190f31..c8e4074899 100644 --- a/plugins/app-node/package.json +++ b/plugins/app-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-app-node", - "version": "0.1.22", + "version": "0.1.23-next.0", "description": "Node.js library for the app plugin", "backstage": { "role": "node-library", diff --git a/plugins/app-visualizer/CHANGELOG.md b/plugins/app-visualizer/CHANGELOG.md index ec24e1cc8b..4db02d9234 100644 --- a/plugins/app-visualizer/CHANGELOG.md +++ b/plugins/app-visualizer/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-app-visualizer +## 0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + ## 0.1.8 ### Patch Changes diff --git a/plugins/app-visualizer/package.json b/plugins/app-visualizer/package.json index 6b10ffc220..a156ceef2e 100644 --- a/plugins/app-visualizer/package.json +++ b/plugins/app-visualizer/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-app-visualizer", - "version": "0.1.8", + "version": "0.1.9-next.0", "description": "Visualizes the Backstage app structure", "backstage": { "role": "frontend-plugin", diff --git a/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md b/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md index 55287ebd46..a683d8199b 100644 --- a/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-atlassian-provider +## 0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + ## 0.2.3 ### Patch Changes diff --git a/plugins/auth-backend-module-atlassian-provider/package.json b/plugins/auth-backend-module-atlassian-provider/package.json index 309dff7f50..dc638ba86f 100644 --- a/plugins/auth-backend-module-atlassian-provider/package.json +++ b/plugins/auth-backend-module-atlassian-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-atlassian-provider", - "version": "0.2.3", + "version": "0.2.4-next.0", "description": "The atlassian-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md b/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md index cc2db5e210..45e5d75611 100644 --- a/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-auth-backend-module-aws-alb-provider +## 0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-backend@0.22.10-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + ## 0.1.14 ### Patch Changes diff --git a/plugins/auth-backend-module-aws-alb-provider/package.json b/plugins/auth-backend-module-aws-alb-provider/package.json index 9d15f0ea09..25e43952e4 100644 --- a/plugins/auth-backend-module-aws-alb-provider/package.json +++ b/plugins/auth-backend-module-aws-alb-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-aws-alb-provider", - "version": "0.1.14", + "version": "0.1.15-next.0", "description": "The aws-alb provider module for the Backstage auth backend.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md b/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md index 26eb0d17b4..88898de862 100644 --- a/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-azure-easyauth-provider +## 0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.0 + ## 0.1.5 ### Patch Changes diff --git a/plugins/auth-backend-module-azure-easyauth-provider/package.json b/plugins/auth-backend-module-azure-easyauth-provider/package.json index 52293f2480..5a94dd320a 100644 --- a/plugins/auth-backend-module-azure-easyauth-provider/package.json +++ b/plugins/auth-backend-module-azure-easyauth-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-azure-easyauth-provider", - "version": "0.1.5", + "version": "0.1.6-next.0", "description": "The azure-easyauth-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md b/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md index 86ec768727..60a7ecc458 100644 --- a/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-bitbucket-provider +## 0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + ## 0.1.5 ### Patch Changes diff --git a/plugins/auth-backend-module-bitbucket-provider/package.json b/plugins/auth-backend-module-bitbucket-provider/package.json index 8ddb0f8acd..159069ad4f 100644 --- a/plugins/auth-backend-module-bitbucket-provider/package.json +++ b/plugins/auth-backend-module-bitbucket-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-bitbucket-provider", - "version": "0.1.5", + "version": "0.1.6-next.0", "description": "The bitbucket-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md b/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md index 2910ffccce..8000a1da90 100644 --- a/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-cloudflare-access-provider +## 0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.0 + ## 0.1.5 ### Patch Changes diff --git a/plugins/auth-backend-module-cloudflare-access-provider/package.json b/plugins/auth-backend-module-cloudflare-access-provider/package.json index 30c60ed6a4..bed6fc8094 100644 --- a/plugins/auth-backend-module-cloudflare-access-provider/package.json +++ b/plugins/auth-backend-module-cloudflare-access-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-cloudflare-access-provider", - "version": "0.1.5", + "version": "0.1.6-next.0", "description": "The cloudflare-access-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md b/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md index 19549dc23a..0e3949cfdc 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-gcp-iap-provider +## 0.2.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.0 + ## 0.2.17 ### 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 d0059e7a69..b106675e14 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/package.json +++ b/plugins/auth-backend-module-gcp-iap-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-gcp-iap-provider", - "version": "0.2.17", + "version": "0.2.18-next.0", "description": "A GCP IAP auth provider module for the Backstage auth backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-github-provider/CHANGELOG.md b/plugins/auth-backend-module-github-provider/CHANGELOG.md index 5d9704a86b..8f2d91ce6f 100644 --- a/plugins/auth-backend-module-github-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-github-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-github-provider +## 0.1.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + ## 0.1.19 ### Patch Changes diff --git a/plugins/auth-backend-module-github-provider/package.json b/plugins/auth-backend-module-github-provider/package.json index 42ef2ccd4e..a986d04852 100644 --- a/plugins/auth-backend-module-github-provider/package.json +++ b/plugins/auth-backend-module-github-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-github-provider", - "version": "0.1.19", + "version": "0.1.20-next.0", "description": "The github-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md b/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md index 57a6aa189b..15265dcca3 100644 --- a/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-gitlab-provider +## 0.1.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + ## 0.1.19 ### Patch Changes diff --git a/plugins/auth-backend-module-gitlab-provider/package.json b/plugins/auth-backend-module-gitlab-provider/package.json index b0e0d2e647..be77920597 100644 --- a/plugins/auth-backend-module-gitlab-provider/package.json +++ b/plugins/auth-backend-module-gitlab-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-gitlab-provider", - "version": "0.1.19", + "version": "0.1.20-next.0", "description": "The gitlab-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-google-provider/CHANGELOG.md b/plugins/auth-backend-module-google-provider/CHANGELOG.md index 17efe0d1a5..eaeed7dbca 100644 --- a/plugins/auth-backend-module-google-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-google-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-google-provider +## 0.1.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + ## 0.1.19 ### Patch Changes diff --git a/plugins/auth-backend-module-google-provider/package.json b/plugins/auth-backend-module-google-provider/package.json index 1153cbb37a..524d1f3d90 100644 --- a/plugins/auth-backend-module-google-provider/package.json +++ b/plugins/auth-backend-module-google-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-google-provider", - "version": "0.1.19", + "version": "0.1.20-next.0", "description": "A Google auth provider module for the Backstage auth backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-guest-provider/CHANGELOG.md b/plugins/auth-backend-module-guest-provider/CHANGELOG.md index 7c9e48041d..7382ea2c19 100644 --- a/plugins/auth-backend-module-guest-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-guest-provider/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-auth-backend-module-guest-provider +## 0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.0 + ## 0.1.8 ### Patch Changes diff --git a/plugins/auth-backend-module-guest-provider/package.json b/plugins/auth-backend-module-guest-provider/package.json index 1648ebea6a..db19f2e37b 100644 --- a/plugins/auth-backend-module-guest-provider/package.json +++ b/plugins/auth-backend-module-guest-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-guest-provider", - "version": "0.1.8", + "version": "0.1.9-next.0", "description": "The guest-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md b/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md index c4df7007f3..b2d8d704d5 100644 --- a/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-microsoft-provider +## 0.1.18-next.0 + +### Patch Changes + +- 39f36a9: Updated the Microsoft authenticator to accurately define required scopes, but to also omit the required and additional scopes when requesting resource scopes. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + ## 0.1.17 ### Patch Changes diff --git a/plugins/auth-backend-module-microsoft-provider/package.json b/plugins/auth-backend-module-microsoft-provider/package.json index b67fb8c447..bb2f82dc68 100644 --- a/plugins/auth-backend-module-microsoft-provider/package.json +++ b/plugins/auth-backend-module-microsoft-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-microsoft-provider", - "version": "0.1.17", + "version": "0.1.18-next.0", "description": "The microsoft-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md b/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md index edfcfa0bcb..4090d62d57 100644 --- a/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-oauth2-provider +## 0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + ## 0.2.3 ### Patch Changes diff --git a/plugins/auth-backend-module-oauth2-provider/package.json b/plugins/auth-backend-module-oauth2-provider/package.json index c98a36d104..962362ce87 100644 --- a/plugins/auth-backend-module-oauth2-provider/package.json +++ b/plugins/auth-backend-module-oauth2-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-oauth2-provider", - "version": "0.2.3", + "version": "0.2.4-next.0", "description": "The oauth2-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md b/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md index 554468bcfe..33fd2b18d4 100644 --- a/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-oauth2-proxy-provider +## 0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.0 + ## 0.1.15 ### Patch Changes diff --git a/plugins/auth-backend-module-oauth2-proxy-provider/package.json b/plugins/auth-backend-module-oauth2-proxy-provider/package.json index 16b4126781..e07da7f6d4 100644 --- a/plugins/auth-backend-module-oauth2-proxy-provider/package.json +++ b/plugins/auth-backend-module-oauth2-proxy-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-oauth2-proxy-provider", - "version": "0.1.15", + "version": "0.1.16-next.0", "description": "The oauth2-proxy-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-oidc-provider/CHANGELOG.md b/plugins/auth-backend-module-oidc-provider/CHANGELOG.md index 5e0d6aeb5c..b8702dd3e4 100644 --- a/plugins/auth-backend-module-oidc-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oidc-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-oidc-provider +## 0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-auth-backend@0.22.10-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + ## 0.2.3 ### Patch Changes diff --git a/plugins/auth-backend-module-oidc-provider/package.json b/plugins/auth-backend-module-oidc-provider/package.json index d825bd2986..89ef91181c 100644 --- a/plugins/auth-backend-module-oidc-provider/package.json +++ b/plugins/auth-backend-module-oidc-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-oidc-provider", - "version": "0.2.3", + "version": "0.2.4-next.0", "description": "The oidc-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-okta-provider/CHANGELOG.md b/plugins/auth-backend-module-okta-provider/CHANGELOG.md index 029892a34a..3f3ecdbffa 100644 --- a/plugins/auth-backend-module-okta-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-okta-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-okta-provider +## 0.0.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + ## 0.0.15 ### Patch Changes diff --git a/plugins/auth-backend-module-okta-provider/package.json b/plugins/auth-backend-module-okta-provider/package.json index 4070ffd31f..18cb4ce208 100644 --- a/plugins/auth-backend-module-okta-provider/package.json +++ b/plugins/auth-backend-module-okta-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-okta-provider", - "version": "0.0.15", + "version": "0.0.16-next.0", "description": "The okta-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md b/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md index 896f6b7e0c..cbaa2f2ad6 100644 --- a/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-auth-backend-module-onelogin-provider +## 0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + ## 0.1.3 ### Patch Changes diff --git a/plugins/auth-backend-module-onelogin-provider/package.json b/plugins/auth-backend-module-onelogin-provider/package.json index 045dce0392..750fe96aab 100644 --- a/plugins/auth-backend-module-onelogin-provider/package.json +++ b/plugins/auth-backend-module-onelogin-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-onelogin-provider", - "version": "0.1.3", + "version": "0.1.4-next.0", "description": "The onelogin-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md b/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md index c3ea4665e8..f0c914c43a 100644 --- a/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-pinniped-provider +## 0.1.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + ## 0.1.16 ### Patch Changes diff --git a/plugins/auth-backend-module-pinniped-provider/package.json b/plugins/auth-backend-module-pinniped-provider/package.json index e6f50e4008..73496380af 100644 --- a/plugins/auth-backend-module-pinniped-provider/package.json +++ b/plugins/auth-backend-module-pinniped-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-pinniped-provider", - "version": "0.1.16", + "version": "0.1.17-next.0", "description": "The pinniped-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md b/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md index f652d6135c..aa61e780c5 100644 --- a/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-vmware-cloud-provider +## 0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + ## 0.2.3 ### Patch Changes diff --git a/plugins/auth-backend-module-vmware-cloud-provider/package.json b/plugins/auth-backend-module-vmware-cloud-provider/package.json index 77dafe38e1..f75891634b 100644 --- a/plugins/auth-backend-module-vmware-cloud-provider/package.json +++ b/plugins/auth-backend-module-vmware-cloud-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-vmware-cloud-provider", - "version": "0.2.3", + "version": "0.2.4-next.0", "description": "The vmware-cloud-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md index 393820ec27..2b74787a53 100644 --- a/plugins/auth-backend/CHANGELOG.md +++ b/plugins/auth-backend/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-auth-backend +## 0.22.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.1.18-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.2.4-next.0 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.15-next.0 + - @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.1.6-next.0 + - @backstage/plugin-auth-backend-module-bitbucket-provider@0.1.6-next.0 + - @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.1.6-next.0 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.18-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.1.20-next.0 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.20-next.0 + - @backstage/plugin-auth-backend-module-google-provider@0.1.20-next.0 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.2.4-next.0 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.16-next.0 + - @backstage/plugin-auth-backend-module-oidc-provider@0.2.4-next.0 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.16-next.0 + - @backstage/plugin-auth-backend-module-onelogin-provider@0.1.4-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + ## 0.22.9 ### Patch Changes diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index c9d437ceba..57591313f4 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend", - "version": "0.22.9", + "version": "0.22.10-next.0", "description": "A Backstage backend plugin that handles authentication", "backstage": { "role": "backend-plugin", diff --git a/plugins/auth-node/CHANGELOG.md b/plugins/auth-node/CHANGELOG.md index 298f0e4472..021d89b518 100644 --- a/plugins/auth-node/CHANGELOG.md +++ b/plugins/auth-node/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-auth-node +## 0.4.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.4.17 ### Patch Changes diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index 0f4b0f5a77..114491c06e 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.17", + "version": "0.4.18-next.0", "backstage": { "role": "node-library", "pluginId": "auth", diff --git a/plugins/auth-react/CHANGELOG.md b/plugins/auth-react/CHANGELOG.md index 4651cf7eae..f7d621164c 100644 --- a/plugins/auth-react/CHANGELOG.md +++ b/plugins/auth-react/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-react +## 0.1.5-next.0 + +### Patch Changes + +- aeac3e9: feat: Hide visibility of CookieAuthRedirect +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + ## 0.1.4 ### Patch Changes diff --git a/plugins/auth-react/package.json b/plugins/auth-react/package.json index 44a4ce9fd0..b68e581c74 100644 --- a/plugins/auth-react/package.json +++ b/plugins/auth-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-react", - "version": "0.1.4", + "version": "0.1.5-next.0", "description": "Web library for the auth plugin", "backstage": { "role": "web-library", diff --git a/plugins/bitbucket-cloud-common/CHANGELOG.md b/plugins/bitbucket-cloud-common/CHANGELOG.md index 7b2b8a936b..c4ce7148f4 100644 --- a/plugins/bitbucket-cloud-common/CHANGELOG.md +++ b/plugins/bitbucket-cloud-common/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-bitbucket-cloud-common +## 0.2.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.14.0-next.0 + ## 0.2.21 ### Patch Changes diff --git a/plugins/bitbucket-cloud-common/package.json b/plugins/bitbucket-cloud-common/package.json index d52122f995..06fd4e6f3a 100644 --- a/plugins/bitbucket-cloud-common/package.json +++ b/plugins/bitbucket-cloud-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bitbucket-cloud-common", - "version": "0.2.21", + "version": "0.2.22-next.0", "description": "Common functionalities for bitbucket-cloud plugins", "backstage": { "role": "common-library", diff --git a/plugins/catalog-backend-module-aws/CHANGELOG.md b/plugins/catalog-backend-module-aws/CHANGELOG.md index f2dd32b7f2..22a372051e 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.18-next.0 + +### Patch Changes + +- ba8571e: Setup user agent header for AWS sdk clients, this enables users to better track API calls made from Backstage to AWS APIs through things like CloudTrail. +- 90a7340: `AwsOrganizationCloudAccountProcessor` configuration field `roleArn` is deprecated in favor of new field `accountId` +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-kubernetes-common@0.8.1 + ## 0.3.17 ### Patch Changes diff --git a/plugins/catalog-backend-module-aws/package.json b/plugins/catalog-backend-module-aws/package.json index 91ac7c4eae..eeb26b2e1c 100644 --- a/plugins/catalog-backend-module-aws/package.json +++ b/plugins/catalog-backend-module-aws/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-aws", - "version": "0.3.17", + "version": "0.3.18-next.0", "description": "A Backstage catalog backend module that helps integrate towards AWS", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-azure/CHANGELOG.md b/plugins/catalog-backend-module-azure/CHANGELOG.md index e96ca2d650..1706dc02bf 100644 --- a/plugins/catalog-backend-module-azure/CHANGELOG.md +++ b/plugins/catalog-backend-module-azure/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-azure +## 0.1.43-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.25 + ## 0.1.42 ### Patch Changes diff --git a/plugins/catalog-backend-module-azure/package.json b/plugins/catalog-backend-module-azure/package.json index 05b920bcb0..5fdd95140d 100644 --- a/plugins/catalog-backend-module-azure/package.json +++ b/plugins/catalog-backend-module-azure/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-azure", - "version": "0.1.42", + "version": "0.1.43-next.0", "description": "A Backstage catalog backend module that helps integrate towards Azure", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md b/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md index 620ab36c40..afdd92803f 100644 --- a/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-backstage-openapi +## 0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-openapi-utils@0.1.16-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.2.5 ### Patch Changes diff --git a/plugins/catalog-backend-module-backstage-openapi/package.json b/plugins/catalog-backend-module-backstage-openapi/package.json index de6c2a8410..6da2d92d5f 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.2.5", + "version": "0.2.6-next.0", "backstage": { "role": "backend-plugin-module", "pluginId": "catalog", diff --git a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md index 920d2bc111..2c01eb8857 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-catalog-backend-module-bitbucket-cloud +## 0.2.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.22-next.0 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-events-node@0.3.9-next.0 + ## 0.2.9 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-cloud/package.json b/plugins/catalog-backend-module-bitbucket-cloud/package.json index 9faa941fd6..234bfea5c5 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/package.json +++ b/plugins/catalog-backend-module-bitbucket-cloud/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-cloud", - "version": "0.2.9", + "version": "0.2.10-next.0", "description": "A Backstage catalog backend module that helps integrate towards Bitbucket Cloud", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md index 857d9a33d9..7f47be269c 100644 --- a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-bitbucket-server +## 0.1.37-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.1.36 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-server/package.json b/plugins/catalog-backend-module-bitbucket-server/package.json index 793a4213f2..45d8c5cd33 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.36", + "version": "0.1.37-next.0", "backstage": { "role": "backend-plugin-module", "pluginId": "catalog", diff --git a/plugins/catalog-backend-module-gcp/CHANGELOG.md b/plugins/catalog-backend-module-gcp/CHANGELOG.md index 779039f858..ca2d4412b2 100644 --- a/plugins/catalog-backend-module-gcp/CHANGELOG.md +++ b/plugins/catalog-backend-module-gcp/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-gcp +## 0.1.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-kubernetes-common@0.8.1 + ## 0.1.23 ### Patch Changes diff --git a/plugins/catalog-backend-module-gcp/package.json b/plugins/catalog-backend-module-gcp/package.json index 7ebe7cbefc..442c7540e3 100644 --- a/plugins/catalog-backend-module-gcp/package.json +++ b/plugins/catalog-backend-module-gcp/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gcp", - "version": "0.1.23", + "version": "0.1.24-next.0", "description": "A Backstage catalog backend module that helps integrate towards GCP", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-gerrit/CHANGELOG.md b/plugins/catalog-backend-module-gerrit/CHANGELOG.md index 159c9bb550..63dcfa9562 100644 --- a/plugins/catalog-backend-module-gerrit/CHANGELOG.md +++ b/plugins/catalog-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-gerrit +## 0.1.40-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.1.39 ### Patch Changes diff --git a/plugins/catalog-backend-module-gerrit/package.json b/plugins/catalog-backend-module-gerrit/package.json index 0732db4465..61f2ac8dfd 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.39", + "version": "0.1.40-next.0", "backstage": { "role": "backend-plugin-module", "pluginId": "catalog", diff --git a/plugins/catalog-backend-module-github-org/CHANGELOG.md b/plugins/catalog-backend-module-github-org/CHANGELOG.md index 424465d813..72c80a97cd 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.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-backend-module-github@0.6.6-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + ## 0.1.17 ### Patch Changes diff --git a/plugins/catalog-backend-module-github-org/package.json b/plugins/catalog-backend-module-github-org/package.json index 3fdcc2fedf..9a363613de 100644 --- a/plugins/catalog-backend-module-github-org/package.json +++ b/plugins/catalog-backend-module-github-org/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-github-org", - "version": "0.1.17", + "version": "0.1.18-next.0", "description": "The github-org backend module for the catalog plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-github/CHANGELOG.md b/plugins/catalog-backend-module-github/CHANGELOG.md index 661712456b..12e2d70eb1 100644 --- a/plugins/catalog-backend-module-github/CHANGELOG.md +++ b/plugins/catalog-backend-module-github/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-catalog-backend-module-github +## 0.6.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-backend@1.24.1-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-events-node@0.3.9-next.0 + ## 0.6.5 ### Patch Changes diff --git a/plugins/catalog-backend-module-github/package.json b/plugins/catalog-backend-module-github/package.json index 50b838be1d..aa1f750aef 100644 --- a/plugins/catalog-backend-module-github/package.json +++ b/plugins/catalog-backend-module-github/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-github", - "version": "0.6.5", + "version": "0.6.6-next.0", "description": "A Backstage catalog backend module that helps integrate towards GitHub", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md b/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md index b36bcb4d71..8d1c8871ae 100644 --- a/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md +++ b/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-catalog-backend-module-gitlab-org +## 0.0.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-catalog-backend-module-gitlab@0.3.22-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + ## 0.0.5 ### Patch Changes diff --git a/plugins/catalog-backend-module-gitlab-org/package.json b/plugins/catalog-backend-module-gitlab-org/package.json index 9c4c1f725f..16c492d849 100644 --- a/plugins/catalog-backend-module-gitlab-org/package.json +++ b/plugins/catalog-backend-module-gitlab-org/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gitlab-org", - "version": "0.0.5", + "version": "0.0.6-next.0", "description": "The gitlab-org backend module for the catalog plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-gitlab/CHANGELOG.md b/plugins/catalog-backend-module-gitlab/CHANGELOG.md index 97ed683942..c4e8f25903 100644 --- a/plugins/catalog-backend-module-gitlab/CHANGELOG.md +++ b/plugins/catalog-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-backend-module-gitlab +## 0.3.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-events-node@0.3.9-next.0 + ## 0.3.21 ### Patch Changes diff --git a/plugins/catalog-backend-module-gitlab/package.json b/plugins/catalog-backend-module-gitlab/package.json index fa21798a62..ad5b8e88bd 100644 --- a/plugins/catalog-backend-module-gitlab/package.json +++ b/plugins/catalog-backend-module-gitlab/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gitlab", - "version": "0.3.21", + "version": "0.3.22-next.0", "description": "A Backstage catalog backend module that helps integrate towards GitLab", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md index 0d04145063..c2b3835940 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md +++ b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-catalog-backend-module-incremental-ingestion +## 0.4.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-backend@1.24.1-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-events-node@0.3.9-next.0 + - @backstage/plugin-permission-common@0.8.0 + ## 0.4.27 ### Patch Changes diff --git a/plugins/catalog-backend-module-incremental-ingestion/package.json b/plugins/catalog-backend-module-incremental-ingestion/package.json index 0180f36d03..cabacc7bd6 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/package.json +++ b/plugins/catalog-backend-module-incremental-ingestion/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-incremental-ingestion", - "version": "0.4.27", + "version": "0.4.28-next.0", "description": "An entity provider for streaming large asset sources into the catalog", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-ldap/CHANGELOG.md b/plugins/catalog-backend-module-ldap/CHANGELOG.md index 9168ce0991..1253404d2d 100644 --- a/plugins/catalog-backend-module-ldap/CHANGELOG.md +++ b/plugins/catalog-backend-module-ldap/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-ldap +## 0.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.25 + ## 0.7.0 ### Minor Changes diff --git a/plugins/catalog-backend-module-ldap/package.json b/plugins/catalog-backend-module-ldap/package.json index 62b3328de7..e5f67d59c6 100644 --- a/plugins/catalog-backend-module-ldap/package.json +++ b/plugins/catalog-backend-module-ldap/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-ldap", - "version": "0.7.0", + "version": "0.7.1-next.0", "description": "A Backstage catalog backend module that helps integrate towards LDAP", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-logs/CHANGELOG.md b/plugins/catalog-backend-module-logs/CHANGELOG.md index 2712f4a134..83053dcf6b 100644 --- a/plugins/catalog-backend-module-logs/CHANGELOG.md +++ b/plugins/catalog-backend-module-logs/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-catalog-backend-module-logs +## 0.0.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.24.1-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + ## 0.0.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-logs/package.json b/plugins/catalog-backend-module-logs/package.json index 560b93737e..0c4a78dfa4 100644 --- a/plugins/catalog-backend-module-logs/package.json +++ b/plugins/catalog-backend-module-logs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-logs", - "version": "0.0.1", + "version": "0.0.2-next.0", "description": "A module that subscribes to catalog releated events and logs them.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-msgraph/CHANGELOG.md b/plugins/catalog-backend-module-msgraph/CHANGELOG.md index a33bea94b8..d9b8da87d2 100644 --- a/plugins/catalog-backend-module-msgraph/CHANGELOG.md +++ b/plugins/catalog-backend-module-msgraph/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-msgraph +## 0.5.31-next.0 + +### Patch Changes + +- 58dff4d: Added option to ingest groups based on their group membership in Azure Entra ID +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.25 + ## 0.5.30 ### Patch Changes diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json index 3f5fa722a8..087d4c4a82 100644 --- a/plugins/catalog-backend-module-msgraph/package.json +++ b/plugins/catalog-backend-module-msgraph/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-msgraph", - "version": "0.5.30", + "version": "0.5.31-next.0", "description": "A Backstage catalog backend module that helps integrate towards Microsoft Graph", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-openapi/CHANGELOG.md b/plugins/catalog-backend-module-openapi/CHANGELOG.md index 6cc947ee17..46d8c1319b 100644 --- a/plugins/catalog-backend-module-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-openapi/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-backend-module-openapi +## 0.1.41-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-backend@1.24.1-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.25 + ## 0.1.40 ### Patch Changes diff --git a/plugins/catalog-backend-module-openapi/package.json b/plugins/catalog-backend-module-openapi/package.json index 2dbe6612ac..1cd250d884 100644 --- a/plugins/catalog-backend-module-openapi/package.json +++ b/plugins/catalog-backend-module-openapi/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-openapi", - "version": "0.1.40", + "version": "0.1.41-next.0", "description": "A Backstage catalog backend module that helps with OpenAPI specifications", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-puppetdb/CHANGELOG.md b/plugins/catalog-backend-module-puppetdb/CHANGELOG.md index cb4cd9664b..d85ad0ecf2 100644 --- a/plugins/catalog-backend-module-puppetdb/CHANGELOG.md +++ b/plugins/catalog-backend-module-puppetdb/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-puppetdb +## 0.1.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.1.28 ### Patch Changes diff --git a/plugins/catalog-backend-module-puppetdb/package.json b/plugins/catalog-backend-module-puppetdb/package.json index cf2a739380..dadba558a5 100644 --- a/plugins/catalog-backend-module-puppetdb/package.json +++ b/plugins/catalog-backend-module-puppetdb/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-puppetdb", - "version": "0.1.28", + "version": "0.1.29-next.0", "description": "A Backstage catalog backend module that helps integrate towards PuppetDB", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md b/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md index 87299358b7..1ec7c01c6a 100644 --- a/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md +++ b/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-catalog-backend-module-scaffolder-entity-model +## 0.1.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-scaffolder-common@1.5.4 + ## 0.1.20 ### 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 3aaa768f76..09dfa63a91 100644 --- a/plugins/catalog-backend-module-scaffolder-entity-model/package.json +++ b/plugins/catalog-backend-module-scaffolder-entity-model/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-scaffolder-entity-model", - "version": "0.1.20", + "version": "0.1.21-next.0", "description": "Adds support for the scaffolder specific entity model (e.g. the Template kind) to the catalog backend plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-unprocessed/CHANGELOG.md b/plugins/catalog-backend-module-unprocessed/CHANGELOG.md index a7d74143a1..2abd4e32a3 100644 --- a/plugins/catalog-backend-module-unprocessed/CHANGELOG.md +++ b/plugins/catalog-backend-module-unprocessed/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-unprocessed +## 0.4.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.3 + - @backstage/plugin-permission-common@0.8.0 + ## 0.4.9 ### Patch Changes diff --git a/plugins/catalog-backend-module-unprocessed/package.json b/plugins/catalog-backend-module-unprocessed/package.json index 6f1f4bb6bc..b01fddef04 100644 --- a/plugins/catalog-backend-module-unprocessed/package.json +++ b/plugins/catalog-backend-module-unprocessed/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-unprocessed", - "version": "0.4.9", + "version": "0.4.10-next.0", "description": "Backstage Catalog module to view unprocessed entities", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md index 8f99ab1f4c..796611fa90 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-catalog-backend +## 1.24.1-next.0 + +### Patch Changes + +- a629fb2: Added setAllowedLocationTypes while introducing a new extension point called CatalogLocationsExtensionPoint +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-openapi-utils@0.1.16-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-events-node@0.3.9-next.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.29-next.0 + ## 1.24.0 ### Minor Changes diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 19d40bd34c..0c1983d1e2 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend", - "version": "1.24.0", + "version": "1.24.1-next.0", "description": "The Backstage backend plugin that provides the Backstage catalog", "backstage": { "role": "backend-plugin", diff --git a/plugins/catalog-graph/CHANGELOG.md b/plugins/catalog-graph/CHANGELOG.md index 332ea17dd0..5995074b53 100644 --- a/plugins/catalog-graph/CHANGELOG.md +++ b/plugins/catalog-graph/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-graph +## 0.4.8-next.0 + +### Patch Changes + +- fba7537: Memoize entity graph nodes when applying an `entityFilter` to prevent repeated redraws +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + ## 0.4.7 ### Patch Changes diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json index 1e7c376436..51ed923a01 100644 --- a/plugins/catalog-graph/package.json +++ b/plugins/catalog-graph/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-graph", - "version": "0.4.7", + "version": "0.4.8-next.0", "backstage": { "role": "frontend-plugin", "pluginId": "catalog-graph", diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md index 29ec3631b4..484676f245 100644 --- a/plugins/catalog-import/CHANGELOG.md +++ b/plugins/catalog-import/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-catalog-import +## 0.12.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/plugin-catalog-common@1.0.25 + ## 0.12.1 ### Patch Changes diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index c3babc09a3..dfc07ddb43 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-import", - "version": "0.12.1", + "version": "0.12.2-next.0", "description": "A Backstage plugin the helps you import entities into your catalog", "backstage": { "role": "frontend-plugin", diff --git a/plugins/catalog-node/CHANGELOG.md b/plugins/catalog-node/CHANGELOG.md index 74982e481f..3d1dbe07ba 100644 --- a/plugins/catalog-node/CHANGELOG.md +++ b/plugins/catalog-node/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-node +## 1.12.5-next.0 + +### Patch Changes + +- a629fb2: Added setAllowedLocationTypes while introducing a new extension point called CatalogLocationsExtensionPoint +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + ## 1.12.4 ### Patch Changes diff --git a/plugins/catalog-node/package.json b/plugins/catalog-node/package.json index ccd83cd129..04a942f7b3 100644 --- a/plugins/catalog-node/package.json +++ b/plugins/catalog-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-node", - "version": "1.12.4", + "version": "1.12.5-next.0", "description": "The plugin-catalog-node module for @backstage/plugin-catalog-backend", "backstage": { "role": "node-library", diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md index 38402e8824..982d3db031 100644 --- a/plugins/catalog-react/CHANGELOG.md +++ b/plugins/catalog-react/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-catalog-react +## 1.12.3-next.0 + +### Patch Changes + +- 31bfc44: Updated alpha definitions of extension data references. +- 9b89b82: Internal refactor to remove unnecessary `routable` prop in the implementation of the `createEntityContentExtension` alpha export. +- bebd569: Fix extra divider displayed on user list picker component +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-react@0.4.24 + ## 1.12.2 ### Patch Changes diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index c6a725ecb6..dc5a80d4b7 100644 --- a/plugins/catalog-react/package.json +++ b/plugins/catalog-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-react", - "version": "1.12.2", + "version": "1.12.3-next.0", "description": "A frontend library that helps other Backstage plugins interact with the catalog", "backstage": { "role": "web-library", diff --git a/plugins/catalog-unprocessed-entities/CHANGELOG.md b/plugins/catalog-unprocessed-entities/CHANGELOG.md index e3fd1b6b76..2c2eb03f5e 100644 --- a/plugins/catalog-unprocessed-entities/CHANGELOG.md +++ b/plugins/catalog-unprocessed-entities/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-catalog-unprocessed-entities +## 0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + ## 0.2.6 ### Patch Changes diff --git a/plugins/catalog-unprocessed-entities/package.json b/plugins/catalog-unprocessed-entities/package.json index 872ce7b11b..8ce8c8b0d3 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.2.6", + "version": "0.2.7-next.0", "backstage": { "role": "frontend-plugin", "pluginId": "catalog-unprocessed-entities", diff --git a/plugins/catalog/CHANGELOG.md b/plugins/catalog/CHANGELOG.md index 2667fdf638..e0b947b965 100644 --- a/plugins/catalog/CHANGELOG.md +++ b/plugins/catalog/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-catalog +## 1.21.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/plugin-search-react@1.7.14-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-scaffolder-common@1.5.4 + - @backstage/plugin-search-common@1.2.13 + ## 1.21.1 ### Patch Changes diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index fc49a8c36b..64f6b0d201 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog", - "version": "1.21.1", + "version": "1.21.2-next.0", "description": "The Backstage plugin for browsing the Backstage catalog", "backstage": { "role": "frontend-plugin", diff --git a/plugins/config-schema/CHANGELOG.md b/plugins/config-schema/CHANGELOG.md index 2344473925..c11499f589 100644 --- a/plugins/config-schema/CHANGELOG.md +++ b/plugins/config-schema/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-config-schema +## 0.1.58-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.1.57 ### Patch Changes diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index 6f91094e5f..ad98b78b98 100644 --- a/plugins/config-schema/package.json +++ b/plugins/config-schema/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-config-schema", - "version": "0.1.57", + "version": "0.1.58-next.0", "description": "A Backstage plugin that lets you browse the configuration schema of your app", "backstage": { "role": "frontend-plugin", diff --git a/plugins/devtools-backend/CHANGELOG.md b/plugins/devtools-backend/CHANGELOG.md index f027384637..d415b1bf65 100644 --- a/plugins/devtools-backend/CHANGELOG.md +++ b/plugins/devtools-backend/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-devtools-backend +## 0.3.9-next.0 + +### Patch Changes + +- 32a38e1: Removed unused code for lockfile analysis. +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/config-loader@1.8.2-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.11 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + ## 0.3.8 ### Patch Changes diff --git a/plugins/devtools-backend/package.json b/plugins/devtools-backend/package.json index ce5e143f24..1fe3330698 100644 --- a/plugins/devtools-backend/package.json +++ b/plugins/devtools-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-devtools-backend", - "version": "0.3.8", + "version": "0.3.9-next.0", "backstage": { "role": "backend-plugin", "pluginId": "devtools", diff --git a/plugins/devtools/CHANGELOG.md b/plugins/devtools/CHANGELOG.md index 3403b7f2fa..b7db4a95bc 100644 --- a/plugins/devtools/CHANGELOG.md +++ b/plugins/devtools/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-devtools +## 0.1.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/plugin-devtools-common@0.1.11 + - @backstage/plugin-permission-react@0.4.24 + ## 0.1.16 ### Patch Changes diff --git a/plugins/devtools/package.json b/plugins/devtools/package.json index 83d2a6b352..2827110d4a 100644 --- a/plugins/devtools/package.json +++ b/plugins/devtools/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-devtools", - "version": "0.1.16", + "version": "0.1.17-next.0", "backstage": { "role": "frontend-plugin", "pluginId": "devtools", diff --git a/plugins/events-backend-module-aws-sqs/CHANGELOG.md b/plugins/events-backend-module-aws-sqs/CHANGELOG.md index e27fcefa6e..5e954c38ca 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.3.9-next.0 + +### Patch Changes + +- ba8571e: Setup user agent header for AWS sdk clients, this enables users to better track API calls made from Backstage to AWS APIs through things like CloudTrail. +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.9-next.0 + ## 0.3.8 ### Patch Changes diff --git a/plugins/events-backend-module-aws-sqs/package.json b/plugins/events-backend-module-aws-sqs/package.json index 983e15567b..0135594bd6 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.3.8", + "version": "0.3.9-next.0", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-azure/CHANGELOG.md b/plugins/events-backend-module-azure/CHANGELOG.md index 225ee30beb..27060d63e4 100644 --- a/plugins/events-backend-module-azure/CHANGELOG.md +++ b/plugins/events-backend-module-azure/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-events-backend-module-azure +## 0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + ## 0.2.8 ### Patch Changes diff --git a/plugins/events-backend-module-azure/package.json b/plugins/events-backend-module-azure/package.json index 49c9b9439f..eacae60bc2 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.2.8", + "version": "0.2.9-next.0", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md index 4676feabbd..a411dcecaa 100644 --- a/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-events-backend-module-bitbucket-cloud +## 0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + ## 0.2.8 ### Patch Changes diff --git a/plugins/events-backend-module-bitbucket-cloud/package.json b/plugins/events-backend-module-bitbucket-cloud/package.json index 6fd443a3b1..084b3cb512 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.2.8", + "version": "0.2.9-next.0", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-gerrit/CHANGELOG.md b/plugins/events-backend-module-gerrit/CHANGELOG.md index eddce5d6c5..3cc3f4f3bf 100644 --- a/plugins/events-backend-module-gerrit/CHANGELOG.md +++ b/plugins/events-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-events-backend-module-gerrit +## 0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + ## 0.2.8 ### Patch Changes diff --git a/plugins/events-backend-module-gerrit/package.json b/plugins/events-backend-module-gerrit/package.json index 7d870063df..99a1cba796 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.2.8", + "version": "0.2.9-next.0", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-github/CHANGELOG.md b/plugins/events-backend-module-github/CHANGELOG.md index 4597583ea8..3ba0e5de31 100644 --- a/plugins/events-backend-module-github/CHANGELOG.md +++ b/plugins/events-backend-module-github/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-events-backend-module-github +## 0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.9-next.0 + ## 0.2.8 ### Patch Changes diff --git a/plugins/events-backend-module-github/package.json b/plugins/events-backend-module-github/package.json index 955793ee6d..bad39f8080 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.2.8", + "version": "0.2.9-next.0", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-gitlab/CHANGELOG.md b/plugins/events-backend-module-gitlab/CHANGELOG.md index f22f90405e..39fd274342 100644 --- a/plugins/events-backend-module-gitlab/CHANGELOG.md +++ b/plugins/events-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-events-backend-module-gitlab +## 0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.9-next.0 + ## 0.2.8 ### Patch Changes diff --git a/plugins/events-backend-module-gitlab/package.json b/plugins/events-backend-module-gitlab/package.json index c97a9e2f02..f2d76a5193 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.2.8", + "version": "0.2.9-next.0", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-test-utils/CHANGELOG.md b/plugins/events-backend-test-utils/CHANGELOG.md index 4fcbcfc172..be1e0f023c 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.33-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.9-next.0 + ## 0.1.32 ### Patch Changes diff --git a/plugins/events-backend-test-utils/package.json b/plugins/events-backend-test-utils/package.json index 09a36a7a1f..f6914c81c5 100644 --- a/plugins/events-backend-test-utils/package.json +++ b/plugins/events-backend-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-test-utils", - "version": "0.1.32", + "version": "0.1.33-next.0", "description": "The plugin-events-backend-test-utils for @backstage/plugin-events-node", "backstage": { "role": "node-library", diff --git a/plugins/events-backend/CHANGELOG.md b/plugins/events-backend/CHANGELOG.md index 4840d9a623..6a6a17c13f 100644 --- a/plugins/events-backend/CHANGELOG.md +++ b/plugins/events-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-events-backend +## 0.3.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.9-next.0 + ## 0.3.9 ### Patch Changes diff --git a/plugins/events-backend/package.json b/plugins/events-backend/package.json index f9f2a4b781..accb240c22 100644 --- a/plugins/events-backend/package.json +++ b/plugins/events-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend", - "version": "0.3.9", + "version": "0.3.10-next.0", "backstage": { "role": "backend-plugin", "pluginId": "events", diff --git a/plugins/events-node/CHANGELOG.md b/plugins/events-node/CHANGELOG.md index d5b1c98372..a3dfd8682d 100644 --- a/plugins/events-node/CHANGELOG.md +++ b/plugins/events-node/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-events-node +## 0.3.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + ## 0.3.8 ### Patch Changes diff --git a/plugins/events-node/package.json b/plugins/events-node/package.json index 965f317357..7387294d24 100644 --- a/plugins/events-node/package.json +++ b/plugins/events-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-node", - "version": "0.3.8", + "version": "0.3.9-next.0", "description": "The plugin-events-node module for @backstage/plugin-events-backend", "backstage": { "role": "node-library", diff --git a/plugins/example-todo-list-backend/CHANGELOG.md b/plugins/example-todo-list-backend/CHANGELOG.md index dd1a2087dc..3d3c9fd1bb 100644 --- a/plugins/example-todo-list-backend/CHANGELOG.md +++ b/plugins/example-todo-list-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @internal/plugin-todo-list-backend +## 1.0.30-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.0 + ## 1.0.29 ### Patch Changes diff --git a/plugins/example-todo-list-backend/package.json b/plugins/example-todo-list-backend/package.json index 0ca987d30b..1ea02728de 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.29", + "version": "1.0.30-next.0", "backstage": { "role": "backend-plugin", "pluginId": "todo-list", diff --git a/plugins/example-todo-list/CHANGELOG.md b/plugins/example-todo-list/CHANGELOG.md index e55f882b0a..51e2b93ef9 100644 --- a/plugins/example-todo-list/CHANGELOG.md +++ b/plugins/example-todo-list/CHANGELOG.md @@ -1,5 +1,13 @@ # @internal/plugin-todo-list +## 1.0.30-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + ## 1.0.29 ### Patch Changes diff --git a/plugins/example-todo-list/package.json b/plugins/example-todo-list/package.json index c8c0a90312..d950d8c406 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.29", + "version": "1.0.30-next.0", "backstage": { "role": "frontend-plugin", "pluginId": "todo-list", diff --git a/plugins/home-react/CHANGELOG.md b/plugins/home-react/CHANGELOG.md index c4db30307f..d810195e7f 100644 --- a/plugins/home-react/CHANGELOG.md +++ b/plugins/home-react/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-home-react +## 0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + ## 0.1.15 ### Patch Changes diff --git a/plugins/home-react/package.json b/plugins/home-react/package.json index 433a91b475..00b0f29fca 100644 --- a/plugins/home-react/package.json +++ b/plugins/home-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-home-react", - "version": "0.1.15", + "version": "0.1.16-next.0", "description": "A Backstage plugin that contains react components helps you build a home page", "backstage": { "role": "web-library", diff --git a/plugins/home/CHANGELOG.md b/plugins/home/CHANGELOG.md index eb49e3217b..75c786c4de 100644 --- a/plugins/home/CHANGELOG.md +++ b/plugins/home/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-home +## 0.7.8-next.0 + +### Patch Changes + +- 31bfc44: Updated alpha definitions of extension data references. +- fdcc059: Fixed a bug on the WelcomeTitle component where the welcome message wasn't correct when the language was set to Spanish +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-app-api@1.14.1-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-home-react@0.1.16-next.0 + ## 0.7.7 ### Patch Changes diff --git a/plugins/home/package.json b/plugins/home/package.json index 189aeec2ac..d2f0c43a11 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-home", - "version": "0.7.7", + "version": "0.7.8-next.0", "description": "A Backstage plugin that helps you build a home page", "backstage": { "role": "frontend-plugin", diff --git a/plugins/kubernetes-backend/CHANGELOG.md b/plugins/kubernetes-backend/CHANGELOG.md index 6a41d014f5..d749d8579e 100644 --- a/plugins/kubernetes-backend/CHANGELOG.md +++ b/plugins/kubernetes-backend/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-kubernetes-backend +## 0.18.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-kubernetes-common@0.8.1 + - @backstage/plugin-kubernetes-node@0.1.17-next.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + ## 0.18.3 ### Patch Changes diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index 0e439ecd91..eb135d4f0f 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-backend", - "version": "0.18.3", + "version": "0.18.4-next.0", "description": "A Backstage backend plugin that integrates towards Kubernetes", "backstage": { "role": "backend-plugin", diff --git a/plugins/kubernetes-cluster/CHANGELOG.md b/plugins/kubernetes-cluster/CHANGELOG.md index a4b12a0556..cd5b6772de 100644 --- a/plugins/kubernetes-cluster/CHANGELOG.md +++ b/plugins/kubernetes-cluster/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-kubernetes-cluster +## 0.0.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-kubernetes-common@0.8.1 + - @backstage/plugin-kubernetes-react@0.4.2-next.0 + ## 0.0.13 ### Patch Changes diff --git a/plugins/kubernetes-cluster/package.json b/plugins/kubernetes-cluster/package.json index af63bf4102..5549c8dcc5 100644 --- a/plugins/kubernetes-cluster/package.json +++ b/plugins/kubernetes-cluster/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-cluster", - "version": "0.0.13", + "version": "0.0.14-next.0", "description": "A Backstage plugin that shows details of Kubernetes clusters", "backstage": { "role": "frontend-plugin", diff --git a/plugins/kubernetes-node/CHANGELOG.md b/plugins/kubernetes-node/CHANGELOG.md index 608fe97cd2..58c458da9c 100644 --- a/plugins/kubernetes-node/CHANGELOG.md +++ b/plugins/kubernetes-node/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-kubernetes-node +## 0.1.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.1 + ## 0.1.16 ### Patch Changes diff --git a/plugins/kubernetes-node/package.json b/plugins/kubernetes-node/package.json index 798978b5d2..6d1d6d73f8 100644 --- a/plugins/kubernetes-node/package.json +++ b/plugins/kubernetes-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-node", - "version": "0.1.16", + "version": "0.1.17-next.0", "description": "Node.js library for the kubernetes plugin", "backstage": { "role": "node-library", diff --git a/plugins/kubernetes-react/CHANGELOG.md b/plugins/kubernetes-react/CHANGELOG.md index 0fd0cfd07e..c84b5c01e3 100644 --- a/plugins/kubernetes-react/CHANGELOG.md +++ b/plugins/kubernetes-react/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-kubernetes-react +## 0.4.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.1 + ## 0.4.1 ### Patch Changes diff --git a/plugins/kubernetes-react/package.json b/plugins/kubernetes-react/package.json index 42ef4f7913..2f4ddd7415 100644 --- a/plugins/kubernetes-react/package.json +++ b/plugins/kubernetes-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-react", - "version": "0.4.1", + "version": "0.4.2-next.0", "description": "Web library for the kubernetes-react plugin", "backstage": { "role": "web-library", diff --git a/plugins/kubernetes/CHANGELOG.md b/plugins/kubernetes/CHANGELOG.md index fcb80b7b26..26fbfffbdb 100644 --- a/plugins/kubernetes/CHANGELOG.md +++ b/plugins/kubernetes/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-kubernetes +## 0.11.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-kubernetes-common@0.8.1 + - @backstage/plugin-kubernetes-react@0.4.2-next.0 + ## 0.11.12 ### Patch Changes diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index 1ab92f5b3c..5469ff5724 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes", - "version": "0.11.12", + "version": "0.11.13-next.0", "description": "A Backstage plugin that integrates towards Kubernetes", "backstage": { "role": "frontend-plugin", diff --git a/plugins/notifications-backend-module-email/CHANGELOG.md b/plugins/notifications-backend-module-email/CHANGELOG.md index 4bfbfbd05d..f13ba48616 100644 --- a/plugins/notifications-backend-module-email/CHANGELOG.md +++ b/plugins/notifications-backend-module-email/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-notifications-backend-module-email +## 0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.4-next.0 + ## 0.1.3 ### Patch Changes diff --git a/plugins/notifications-backend-module-email/package.json b/plugins/notifications-backend-module-email/package.json index b7107a4c6b..c024e6ad50 100644 --- a/plugins/notifications-backend-module-email/package.json +++ b/plugins/notifications-backend-module-email/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications-backend-module-email", - "version": "0.1.3", + "version": "0.1.4-next.0", "description": "The email backend module for the notifications plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/notifications-backend/CHANGELOG.md b/plugins/notifications-backend/CHANGELOG.md index b4fe307f15..ef654d213c 100644 --- a/plugins/notifications-backend/CHANGELOG.md +++ b/plugins/notifications-backend/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-notifications-backend +## 0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.4-next.0 + - @backstage/plugin-signals-node@0.1.9-next.0 + ## 0.3.3 ### Patch Changes diff --git a/plugins/notifications-backend/package.json b/plugins/notifications-backend/package.json index abd0a1bbfe..b59ae301f2 100644 --- a/plugins/notifications-backend/package.json +++ b/plugins/notifications-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications-backend", - "version": "0.3.3", + "version": "0.3.4-next.0", "backstage": { "role": "backend-plugin", "pluginId": "notifications", diff --git a/plugins/notifications-node/CHANGELOG.md b/plugins/notifications-node/CHANGELOG.md index 764ee3affb..4344467104 100644 --- a/plugins/notifications-node/CHANGELOG.md +++ b/plugins/notifications-node/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-notifications-node +## 0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-signals-node@0.1.9-next.0 + ## 0.2.3 ### Patch Changes diff --git a/plugins/notifications-node/package.json b/plugins/notifications-node/package.json index 04564da21e..b71e5d954f 100644 --- a/plugins/notifications-node/package.json +++ b/plugins/notifications-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications-node", - "version": "0.2.3", + "version": "0.2.4-next.0", "description": "Node.js library for the notifications plugin", "backstage": { "role": "node-library", diff --git a/plugins/notifications/CHANGELOG.md b/plugins/notifications/CHANGELOG.md index 263bd9ba70..42c55615b2 100644 --- a/plugins/notifications/CHANGELOG.md +++ b/plugins/notifications/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-notifications +## 0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-signals-react@0.0.4 + ## 0.2.3 ### Patch Changes diff --git a/plugins/notifications/package.json b/plugins/notifications/package.json index 1575c48c5e..5dbfd83255 100644 --- a/plugins/notifications/package.json +++ b/plugins/notifications/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications", - "version": "0.2.3", + "version": "0.2.4-next.0", "backstage": { "role": "frontend-plugin", "pluginId": "notifications", diff --git a/plugins/org-react/CHANGELOG.md b/plugins/org-react/CHANGELOG.md index d6e117d579..9d0c722d80 100644 --- a/plugins/org-react/CHANGELOG.md +++ b/plugins/org-react/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-org-react +## 0.1.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + ## 0.1.26 ### Patch Changes diff --git a/plugins/org-react/package.json b/plugins/org-react/package.json index 9405b38b59..65d600b96f 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.26", + "version": "0.1.27-next.0", "backstage": { "role": "web-library", "pluginId": "org", diff --git a/plugins/org/CHANGELOG.md b/plugins/org/CHANGELOG.md index 6d1fb352f8..130a62d56d 100644 --- a/plugins/org/CHANGELOG.md +++ b/plugins/org/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-org +## 0.6.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-catalog-common@1.0.25 + ## 0.6.27 ### Patch Changes diff --git a/plugins/org/package.json b/plugins/org/package.json index 2530ca2ea1..a3ed608aeb 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-org", - "version": "0.6.27", + "version": "0.6.28-next.0", "description": "A Backstage plugin that helps you create entity pages for your organization", "backstage": { "role": "frontend-plugin", diff --git a/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md b/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md index e06db25a91..c2e00cf839 100644 --- a/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md +++ b/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-permission-backend-module-allow-all-policy +## 0.1.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + ## 0.1.19 ### 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 27303483f7..85becb2b60 100644 --- a/plugins/permission-backend-module-policy-allow-all/package.json +++ b/plugins/permission-backend-module-policy-allow-all/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-backend-module-allow-all-policy", - "version": "0.1.19", + "version": "0.1.20-next.0", "description": "Allow all policy backend module for the permission plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/permission-backend/CHANGELOG.md b/plugins/permission-backend/CHANGELOG.md index e5a826f67a..c5e9b7675f 100644 --- a/plugins/permission-backend/CHANGELOG.md +++ b/plugins/permission-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-permission-backend +## 0.5.47-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + ## 0.5.46 ### Patch Changes diff --git a/plugins/permission-backend/package.json b/plugins/permission-backend/package.json index 95647ba82b..11ad9538be 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.46", + "version": "0.5.47-next.0", "backstage": { "role": "backend-plugin", "pluginId": "permission", diff --git a/plugins/permission-node/CHANGELOG.md b/plugins/permission-node/CHANGELOG.md index 326dfb99d3..31d2f9145e 100644 --- a/plugins/permission-node/CHANGELOG.md +++ b/plugins/permission-node/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-permission-node +## 0.8.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-permission-common@0.8.0 + ## 0.8.0 ### Minor Changes diff --git a/plugins/permission-node/package.json b/plugins/permission-node/package.json index 4bbf4d5faf..630391f373 100644 --- a/plugins/permission-node/package.json +++ b/plugins/permission-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-node", - "version": "0.8.0", + "version": "0.8.1-next.0", "description": "Common permission and authorization utilities for backend plugins", "backstage": { "role": "node-library", diff --git a/plugins/proxy-backend/CHANGELOG.md b/plugins/proxy-backend/CHANGELOG.md index 30cacb1d02..d906b17327 100644 --- a/plugins/proxy-backend/CHANGELOG.md +++ b/plugins/proxy-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-proxy-backend +## 0.5.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + ## 0.5.3 ### Patch Changes diff --git a/plugins/proxy-backend/package.json b/plugins/proxy-backend/package.json index 2e7bd08550..ec3594f985 100644 --- a/plugins/proxy-backend/package.json +++ b/plugins/proxy-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-proxy-backend", - "version": "0.5.3", + "version": "0.5.4-next.0", "description": "A Backstage backend plugin that helps you set up proxy endpoints in the backend", "backstage": { "role": "backend-plugin", diff --git a/plugins/scaffolder-backend-module-azure/CHANGELOG.md b/plugins/scaffolder-backend-module-azure/CHANGELOG.md index e386b5d9b8..bb5b2644ae 100644 --- a/plugins/scaffolder-backend-module-azure/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-azure/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-scaffolder-backend-module-azure +## 0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + ## 0.1.14 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-azure/package.json b/plugins/scaffolder-backend-module-azure/package.json index 205beae578..c2b7a39e0c 100644 --- a/plugins/scaffolder-backend-module-azure/package.json +++ b/plugins/scaffolder-backend-module-azure/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-azure", - "version": "0.1.14", + "version": "0.1.15-next.0", "description": "The azure module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md index c8c79a302b..04236c2a4b 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder-backend-module-bitbucket-cloud +## 0.1.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-bitbucket-cloud-common@0.2.22-next.0 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + ## 0.1.12 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/package.json b/plugins/scaffolder-backend-module-bitbucket-cloud/package.json index 67f275462b..39080241a0 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/package.json +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud", - "version": "0.1.12", + "version": "0.1.13-next.0", "description": "The Bitbucket Cloud module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md b/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md index 5d2a0754cd..93801a3012 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-scaffolder-backend-module-bitbucket-server +## 0.1.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + ## 0.1.12 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-bitbucket-server/package.json b/plugins/scaffolder-backend-module-bitbucket-server/package.json index a33bf90040..b995ef57da 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/package.json +++ b/plugins/scaffolder-backend-module-bitbucket-server/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-bitbucket-server", - "version": "0.1.12", + "version": "0.1.13-next.0", "description": "The Bitbucket Server module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md b/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md index 414f8b7bd8..b905cc33e1 100644 --- a/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-backend-module-bitbucket +## 0.2.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.13-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.13-next.0 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + ## 0.2.12 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-bitbucket/package.json b/plugins/scaffolder-backend-module-bitbucket/package.json index 95d92c39b8..a853f795af 100644 --- a/plugins/scaffolder-backend-module-bitbucket/package.json +++ b/plugins/scaffolder-backend-module-bitbucket/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-bitbucket", - "version": "0.2.12", + "version": "0.2.13-next.0", "description": "The bitbucket module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md b/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md index 1613f1881c..29677250a5 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.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + ## 0.2.23 ### 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 9fe6781eff..39fb5f49b9 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/package.json +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown", - "version": "0.2.23", + "version": "0.2.24-next.0", "description": "The confluence-to-markdown module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md index f2dc2a822d..865478ea2b 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-scaffolder-backend-module-cookiecutter +## 0.2.47-next.0 + +### Patch Changes + +- dae85df: Add examples for `fetch:cookiecutter` scaffolder action & improve related tests +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + ## 0.2.46 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-cookiecutter/package.json b/plugins/scaffolder-backend-module-cookiecutter/package.json index b8ab34dbc9..2f21b89244 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/package.json +++ b/plugins/scaffolder-backend-module-cookiecutter/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-cookiecutter", - "version": "0.2.46", + "version": "0.2.47-next.0", "description": "A module for the scaffolder backend that lets you template projects using cookiecutter", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-gcp/CHANGELOG.md b/plugins/scaffolder-backend-module-gcp/CHANGELOG.md index 51dd92b2cf..05843ee288 100644 --- a/plugins/scaffolder-backend-module-gcp/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gcp/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-scaffolder-backend-module-gcp +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + ## 0.1.0 ### Minor Changes diff --git a/plugins/scaffolder-backend-module-gcp/package.json b/plugins/scaffolder-backend-module-gcp/package.json index ae64d1de61..f6355e93f4 100644 --- a/plugins/scaffolder-backend-module-gcp/package.json +++ b/plugins/scaffolder-backend-module-gcp/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gcp", - "version": "0.1.0", + "version": "0.1.1-next.0", "description": "The GCP Bucket module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md b/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md index 7b95a80811..d95047ba64 100644 --- a/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-scaffolder-backend-module-gerrit +## 0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + ## 0.1.14 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gerrit/package.json b/plugins/scaffolder-backend-module-gerrit/package.json index 96c069ea97..4be6e4c56c 100644 --- a/plugins/scaffolder-backend-module-gerrit/package.json +++ b/plugins/scaffolder-backend-module-gerrit/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gerrit", - "version": "0.1.14", + "version": "0.1.15-next.0", "description": "The gerrit module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-gitea/CHANGELOG.md b/plugins/scaffolder-backend-module-gitea/CHANGELOG.md index 4c03220562..6bc250f801 100644 --- a/plugins/scaffolder-backend-module-gitea/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gitea/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-scaffolder-backend-module-gitea +## 0.1.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + ## 0.1.12 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gitea/package.json b/plugins/scaffolder-backend-module-gitea/package.json index 69a84f43e7..22b6ab700f 100644 --- a/plugins/scaffolder-backend-module-gitea/package.json +++ b/plugins/scaffolder-backend-module-gitea/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gitea", - "version": "0.1.12", + "version": "0.1.13-next.0", "description": "The gitea module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-github/CHANGELOG.md b/plugins/scaffolder-backend-module-github/CHANGELOG.md index 680cb0469d..0399be8de3 100644 --- a/plugins/scaffolder-backend-module-github/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-github/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder-backend-module-github +## 0.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + ## 0.4.0 ### Minor Changes diff --git a/plugins/scaffolder-backend-module-github/package.json b/plugins/scaffolder-backend-module-github/package.json index 7732c7c11a..a43469d7e5 100644 --- a/plugins/scaffolder-backend-module-github/package.json +++ b/plugins/scaffolder-backend-module-github/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-github", - "version": "0.4.0", + "version": "0.4.1-next.0", "description": "The github module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md b/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md index 60e7f1bccf..41df7c2a60 100644 --- a/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-scaffolder-backend-module-gitlab +## 0.4.5-next.0 + +### Patch Changes + +- fad1b90: Allow the `createGitlabProjectVariableAction` to use oauth tokens +- aab708e: Added test cases for gitlab:issue:edit examples +- ef742dc: Added test cases for gitlab:projectAccessToken:create example +- 1ba4c2f: Added test cases for gitlab:pipeline:trigger examples +- a6603e4: Add custom action for merge request: **auto** + + The **Auto** action selects the committed action between _create_ and _update_. + + The **Auto** action fetches files using the **/projects/repository/tree endpoint**. + After fetching, it checks if the file exists locally and in the repository. If it does, it chooses **update**; otherwise, it chooses **create**. + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + ## 0.4.4 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gitlab/package.json b/plugins/scaffolder-backend-module-gitlab/package.json index 8228a3ec0f..e4705e6206 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.4.4", + "version": "0.4.5-next.0", "backstage": { "role": "backend-plugin-module", "pluginId": "scaffolder", diff --git a/plugins/scaffolder-backend-module-notifications/CHANGELOG.md b/plugins/scaffolder-backend-module-notifications/CHANGELOG.md index db52ded0c8..f51473dd0c 100644 --- a/plugins/scaffolder-backend-module-notifications/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-notifications/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder-backend-module-notifications +## 0.0.6-next.0 + +### Patch Changes + +- 6fc03c7: Add examples for notification:send scaffolder action & improve related tests +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + ## 0.0.5 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-notifications/package.json b/plugins/scaffolder-backend-module-notifications/package.json index 4754cca488..15fe158651 100644 --- a/plugins/scaffolder-backend-module-notifications/package.json +++ b/plugins/scaffolder-backend-module-notifications/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-notifications", - "version": "0.0.5", + "version": "0.0.6-next.0", "description": "The notifications backend module for the scaffolder plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-rails/CHANGELOG.md b/plugins/scaffolder-backend-module-rails/CHANGELOG.md index cd34152910..f9ce2e1e6b 100644 --- a/plugins/scaffolder-backend-module-rails/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-rails/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-scaffolder-backend-module-rails +## 0.4.40-next.0 + +### Patch Changes + +- 449def7: Add examples for fetch:rails scaffolder action & improve related tests +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + ## 0.4.39 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-rails/package.json b/plugins/scaffolder-backend-module-rails/package.json index 910fb04636..a2e2a215dd 100644 --- a/plugins/scaffolder-backend-module-rails/package.json +++ b/plugins/scaffolder-backend-module-rails/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-rails", - "version": "0.4.39", + "version": "0.4.40-next.0", "description": "A module for the scaffolder backend that lets you template projects using Rails", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-sentry/CHANGELOG.md b/plugins/scaffolder-backend-module-sentry/CHANGELOG.md index 113a63222f..0dd4fb6c5b 100644 --- a/plugins/scaffolder-backend-module-sentry/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-sentry/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-scaffolder-backend-module-sentry +## 0.1.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + ## 0.1.30 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-sentry/package.json b/plugins/scaffolder-backend-module-sentry/package.json index 264736692a..3eb11dc3e9 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.30", + "version": "0.1.31-next.0", "backstage": { "role": "backend-plugin-module", "pluginId": "scaffolder", diff --git a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md index 53d2369d85..3c9fe7db6b 100644 --- a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-scaffolder-backend-module-yeoman +## 0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + - @backstage/plugin-scaffolder-node-test-utils@0.1.10-next.0 + ## 0.3.6 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-yeoman/package.json b/plugins/scaffolder-backend-module-yeoman/package.json index 5c65315e22..29f4d7c1aa 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.3.6", + "version": "0.3.7-next.0", "backstage": { "role": "backend-plugin-module", "pluginId": "scaffolder", diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md index 27e4b4465e..8496dbf17b 100644 --- a/plugins/scaffolder-backend/CHANGELOG.md +++ b/plugins/scaffolder-backend/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/plugin-scaffolder-backend +## 1.23.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.4.5-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.22-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.21-next.0 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.15-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.13-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.13-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.13-next.0 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.15-next.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.13-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.4.1-next.0 + - @backstage/plugin-scaffolder-common@1.5.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + ## 1.23.0 ### Minor Changes diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index c86a048d46..af67447fed 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend", - "version": "1.23.0", + "version": "1.23.1-next.0", "description": "The Backstage backend plugin that helps you create new things", "backstage": { "role": "backend-plugin", diff --git a/plugins/scaffolder-node-test-utils/CHANGELOG.md b/plugins/scaffolder-node-test-utils/CHANGELOG.md index 7d578a2b14..9eb166062e 100644 --- a/plugins/scaffolder-node-test-utils/CHANGELOG.md +++ b/plugins/scaffolder-node-test-utils/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-scaffolder-node-test-utils +## 0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-test-utils@0.4.5-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.0 + ## 0.1.9 ### Patch Changes diff --git a/plugins/scaffolder-node-test-utils/package.json b/plugins/scaffolder-node-test-utils/package.json index 827b654b4e..ef31d541f4 100644 --- a/plugins/scaffolder-node-test-utils/package.json +++ b/plugins/scaffolder-node-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-node-test-utils", - "version": "0.1.9", + "version": "0.1.10-next.0", "backstage": { "role": "node-library", "pluginId": "scaffolder", diff --git a/plugins/scaffolder-node/CHANGELOG.md b/plugins/scaffolder-node/CHANGELOG.md index 59658dcb11..db361e0120 100644 --- a/plugins/scaffolder-node/CHANGELOG.md +++ b/plugins/scaffolder-node/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-node +## 0.4.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.4 + ## 0.4.8 ### Patch Changes diff --git a/plugins/scaffolder-node/package.json b/plugins/scaffolder-node/package.json index 07e468620b..2cb7198631 100644 --- a/plugins/scaffolder-node/package.json +++ b/plugins/scaffolder-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-node", - "version": "0.4.8", + "version": "0.4.9-next.0", "description": "The plugin-scaffolder-node module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "node-library", diff --git a/plugins/scaffolder-react/CHANGELOG.md b/plugins/scaffolder-react/CHANGELOG.md index 68f94ac3fd..f23a0e2425 100644 --- a/plugins/scaffolder-react/CHANGELOG.md +++ b/plugins/scaffolder-react/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-scaffolder-react +## 1.11.0-next.0 + +### Minor Changes + +- 8839381: Add scaffolder option to display object items in separate rows on review page + +### Patch Changes + +- d0e95a7: Add ability to customise form fields in the UI by exposing `uiSchema` and `formContext` in `FormProps` +- 4670f06: support `ajv-errors` for scaffolder validation to allow for customizing the error messages +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-scaffolder-common@1.5.4 + ## 1.10.0 ### Minor Changes diff --git a/plugins/scaffolder-react/package.json b/plugins/scaffolder-react/package.json index 9c50900c05..7c16c11c1a 100644 --- a/plugins/scaffolder-react/package.json +++ b/plugins/scaffolder-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-react", - "version": "1.10.0", + "version": "1.11.0-next.0", "description": "A frontend library that helps other Backstage plugins interact with the Scaffolder", "backstage": { "role": "web-library", diff --git a/plugins/scaffolder/CHANGELOG.md b/plugins/scaffolder/CHANGELOG.md index 2da2802808..e012f99928 100644 --- a/plugins/scaffolder/CHANGELOG.md +++ b/plugins/scaffolder/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-scaffolder +## 1.23.1-next.0 + +### Patch Changes + +- bbd9f56: Cleaned up codebase of RepoUrlPicker +- b8600fe: Fix issue with `RepoUrlPicker` not refreshing the credentials for a different host +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/plugin-scaffolder-react@1.11.0-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-permission-react@0.4.24 + - @backstage/plugin-scaffolder-common@1.5.4 + ## 1.23.0 ### Minor Changes diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 5cc587fe4d..ed1bb10e7a 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder", - "version": "1.23.0", + "version": "1.23.1-next.0", "description": "The Backstage plugin that helps you create new things", "backstage": { "role": "frontend-plugin", diff --git a/plugins/search-backend-module-catalog/CHANGELOG.md b/plugins/search-backend-module-catalog/CHANGELOG.md index 29304c6cfd..1c6f7205f3 100644 --- a/plugins/search-backend-module-catalog/CHANGELOG.md +++ b/plugins/search-backend-module-catalog/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-search-backend-module-catalog +## 0.1.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-search-backend-node@1.2.28-next.0 + - @backstage/plugin-search-common@1.2.13 + ## 0.1.28 ### Patch Changes diff --git a/plugins/search-backend-module-catalog/package.json b/plugins/search-backend-module-catalog/package.json index 6ec054f10d..972a8b66d2 100644 --- a/plugins/search-backend-module-catalog/package.json +++ b/plugins/search-backend-module-catalog/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-catalog", - "version": "0.1.28", + "version": "0.1.29-next.0", "description": "A module for the search backend that exports catalog modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-elasticsearch/CHANGELOG.md b/plugins/search-backend-module-elasticsearch/CHANGELOG.md index d561b1127a..a78362a926 100644 --- a/plugins/search-backend-module-elasticsearch/CHANGELOG.md +++ b/plugins/search-backend-module-elasticsearch/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-search-backend-module-elasticsearch +## 1.5.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-backend-node@1.2.28-next.0 + - @backstage/plugin-search-common@1.2.13 + ## 1.5.3 ### Patch Changes diff --git a/plugins/search-backend-module-elasticsearch/package.json b/plugins/search-backend-module-elasticsearch/package.json index d96b4c924d..4107811cfd 100644 --- a/plugins/search-backend-module-elasticsearch/package.json +++ b/plugins/search-backend-module-elasticsearch/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-elasticsearch", - "version": "1.5.3", + "version": "1.5.4-next.0", "description": "A module for the search backend that implements search using ElasticSearch", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-explore/CHANGELOG.md b/plugins/search-backend-module-explore/CHANGELOG.md index f5b60fa87e..e14dd6c6c0 100644 --- a/plugins/search-backend-module-explore/CHANGELOG.md +++ b/plugins/search-backend-module-explore/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-search-backend-module-explore +## 0.1.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.2.28-next.0 + - @backstage/plugin-search-common@1.2.13 + ## 0.1.28 ### Patch Changes diff --git a/plugins/search-backend-module-explore/package.json b/plugins/search-backend-module-explore/package.json index 9fd252df66..8d531a6a37 100644 --- a/plugins/search-backend-module-explore/package.json +++ b/plugins/search-backend-module-explore/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-explore", - "version": "0.1.28", + "version": "0.1.29-next.0", "description": "A module for the search backend that exports explore modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-pg/CHANGELOG.md b/plugins/search-backend-module-pg/CHANGELOG.md index c19c797bde..b2fa9b818e 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.33-next.0 + +### Patch Changes + +- 7251567: Removing `@backstage/backend-app-api` dependency +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.2.28-next.0 + - @backstage/plugin-search-common@1.2.13 + ## 0.5.32 ### Patch Changes diff --git a/plugins/search-backend-module-pg/package.json b/plugins/search-backend-module-pg/package.json index 1693c14c8a..9679c5ddec 100644 --- a/plugins/search-backend-module-pg/package.json +++ b/plugins/search-backend-module-pg/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-pg", - "version": "0.5.32", + "version": "0.5.33-next.0", "description": "A module for the search backend that implements search using PostgreSQL", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md b/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md index 6c86337062..ba1143e663 100644 --- a/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md +++ b/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-search-backend-module-stack-overflow-collator +## 0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.2.28-next.0 + - @backstage/plugin-search-common@1.2.13 + ## 0.1.15 ### 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 4d06f928a0..0fd6425e45 100644 --- a/plugins/search-backend-module-stack-overflow-collator/package.json +++ b/plugins/search-backend-module-stack-overflow-collator/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-stack-overflow-collator", - "version": "0.1.15", + "version": "0.1.16-next.0", "description": "A module for the search backend that exports stack overflow modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-techdocs/CHANGELOG.md b/plugins/search-backend-module-techdocs/CHANGELOG.md index 2c41ecda1f..26137e8eef 100644 --- a/plugins/search-backend-module-techdocs/CHANGELOG.md +++ b/plugins/search-backend-module-techdocs/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-search-backend-module-techdocs +## 0.1.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-search-backend-node@1.2.28-next.0 + - @backstage/plugin-search-common@1.2.13 + - @backstage/plugin-techdocs-node@1.12.9-next.0 + ## 0.1.27 ### Patch Changes diff --git a/plugins/search-backend-module-techdocs/package.json b/plugins/search-backend-module-techdocs/package.json index a04f64756b..52f5d7252b 100644 --- a/plugins/search-backend-module-techdocs/package.json +++ b/plugins/search-backend-module-techdocs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-techdocs", - "version": "0.1.27", + "version": "0.1.28-next.0", "description": "A module for the search backend that exports techdocs modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-node/CHANGELOG.md b/plugins/search-backend-node/CHANGELOG.md index f43f3c4009..05d6d3dba2 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.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/backend-tasks@0.5.28-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-search-common@1.2.13 + ## 1.2.27 ### Patch Changes diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index a236eff6c0..f00a58b584 100644 --- a/plugins/search-backend-node/package.json +++ b/plugins/search-backend-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-node", - "version": "1.2.27", + "version": "1.2.28-next.0", "description": "A library for Backstage backend plugins that want to interact with the search backend plugin", "backstage": { "role": "node-library", diff --git a/plugins/search-backend/CHANGELOG.md b/plugins/search-backend/CHANGELOG.md index eb391c6bba..018e049523 100644 --- a/plugins/search-backend/CHANGELOG.md +++ b/plugins/search-backend/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-search-backend +## 1.5.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-defaults@0.4.2-next.0 + - @backstage/backend-openapi-utils@0.1.16-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-permission-node@0.8.1-next.0 + - @backstage/plugin-search-backend-node@1.2.28-next.0 + - @backstage/plugin-search-common@1.2.13 + ## 1.5.14 ### Patch Changes diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index a0e7b48f5b..502bfd674e 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend", - "version": "1.5.14", + "version": "1.5.15-next.0", "description": "The Backstage backend plugin that provides your backstage app with search", "backstage": { "role": "backend-plugin", diff --git a/plugins/search-react/CHANGELOG.md b/plugins/search-react/CHANGELOG.md index 04d8bf312a..f90428a139 100644 --- a/plugins/search-react/CHANGELOG.md +++ b/plugins/search-react/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-search-react +## 1.7.14-next.0 + +### Patch Changes + +- 31bfc44: Updated alpha definitions of extension data references. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-search-common@1.2.13 + ## 1.7.13 ### Patch Changes diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index b5c17c369a..4cf1e476e8 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.13", + "version": "1.7.14-next.0", "backstage": { "role": "web-library", "pluginId": "search", diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md index bce322e95a..2c85c5bcf0 100644 --- a/plugins/search/CHANGELOG.md +++ b/plugins/search/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-search +## 1.4.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/plugin-search-react@1.7.14-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-search-common@1.2.13 + ## 1.4.14 ### Patch Changes diff --git a/plugins/search/package.json b/plugins/search/package.json index 56271eca58..d1aa27716a 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search", - "version": "1.4.14", + "version": "1.4.15-next.0", "description": "The Backstage plugin that provides your backstage app with search", "backstage": { "role": "frontend-plugin", diff --git a/plugins/signals-backend/CHANGELOG.md b/plugins/signals-backend/CHANGELOG.md index e0525a0e78..844d2cc185 100644 --- a/plugins/signals-backend/CHANGELOG.md +++ b/plugins/signals-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-signals-backend +## 0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + - @backstage/plugin-signals-node@0.1.9-next.0 + ## 0.1.8 ### Patch Changes diff --git a/plugins/signals-backend/package.json b/plugins/signals-backend/package.json index 1e0ac41fcb..f88e8825cd 100644 --- a/plugins/signals-backend/package.json +++ b/plugins/signals-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals-backend", - "version": "0.1.8", + "version": "0.1.9-next.0", "backstage": { "role": "backend-plugin", "pluginId": "signals", diff --git a/plugins/signals-node/CHANGELOG.md b/plugins/signals-node/CHANGELOG.md index 0353548fe5..769800350a 100644 --- a/plugins/signals-node/CHANGELOG.md +++ b/plugins/signals-node/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-signals-node +## 0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-events-node@0.3.9-next.0 + ## 0.1.8 ### Patch Changes diff --git a/plugins/signals-node/package.json b/plugins/signals-node/package.json index 1cea62c21b..e4a4000120 100644 --- a/plugins/signals-node/package.json +++ b/plugins/signals-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals-node", - "version": "0.1.8", + "version": "0.1.9-next.0", "description": "Node.js library for the signals plugin", "backstage": { "role": "node-library", diff --git a/plugins/signals/CHANGELOG.md b/plugins/signals/CHANGELOG.md index a4a7daec35..1f6c9fccf7 100644 --- a/plugins/signals/CHANGELOG.md +++ b/plugins/signals/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-signals +## 0.0.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.4 + ## 0.0.8 ### Patch Changes diff --git a/plugins/signals/package.json b/plugins/signals/package.json index 88ca252c1f..54af5cb9f6 100644 --- a/plugins/signals/package.json +++ b/plugins/signals/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals", - "version": "0.0.8", + "version": "0.0.9-next.0", "backstage": { "role": "frontend-plugin", "pluginId": "signals", diff --git a/plugins/techdocs-addons-test-utils/CHANGELOG.md b/plugins/techdocs-addons-test-utils/CHANGELOG.md index 3135cc5ffd..844ee41d30 100644 --- a/plugins/techdocs-addons-test-utils/CHANGELOG.md +++ b/plugins/techdocs-addons-test-utils/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-techdocs-addons-test-utils +## 1.0.36-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/plugin-search-react@1.7.14-next.0 + - @backstage/core-app-api@1.14.1-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/test-utils@1.5.9-next.0 + - @backstage/plugin-catalog@1.21.2-next.0 + - @backstage/plugin-techdocs@1.10.8-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + ## 1.0.35 ### Patch Changes diff --git a/plugins/techdocs-addons-test-utils/package.json b/plugins/techdocs-addons-test-utils/package.json index 57cd4d06a6..6310ad03b8 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.35", + "version": "1.0.36-next.0", "backstage": { "role": "web-library", "pluginId": "techdocs-addons", diff --git a/plugins/techdocs-backend/CHANGELOG.md b/plugins/techdocs-backend/CHANGELOG.md index 571b0d68fc..44ab26cb79 100644 --- a/plugins/techdocs-backend/CHANGELOG.md +++ b/plugins/techdocs-backend/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-techdocs-backend +## 1.10.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.25 + - @backstage/plugin-permission-common@0.8.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.28-next.0 + - @backstage/plugin-techdocs-node@1.12.9-next.0 + ## 1.10.9 ### Patch Changes diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index ce0df2ca78..0bf2381a8c 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-backend", - "version": "1.10.9", + "version": "1.10.10-next.0", "description": "The Backstage backend plugin that renders technical documentation for your components", "backstage": { "role": "backend-plugin", diff --git a/plugins/techdocs-module-addons-contrib/CHANGELOG.md b/plugins/techdocs-module-addons-contrib/CHANGELOG.md index 4072d96d9f..8bfa4e9c49 100644 --- a/plugins/techdocs-module-addons-contrib/CHANGELOG.md +++ b/plugins/techdocs-module-addons-contrib/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-techdocs-module-addons-contrib +## 1.1.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + ## 1.1.12 ### Patch Changes diff --git a/plugins/techdocs-module-addons-contrib/package.json b/plugins/techdocs-module-addons-contrib/package.json index 3c226f6a50..8254dceaf5 100644 --- a/plugins/techdocs-module-addons-contrib/package.json +++ b/plugins/techdocs-module-addons-contrib/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-module-addons-contrib", - "version": "1.1.12", + "version": "1.1.13-next.0", "description": "Plugin module for contributed TechDocs Addons", "backstage": { "role": "frontend-plugin-module", diff --git a/plugins/techdocs-node/CHANGELOG.md b/plugins/techdocs-node/CHANGELOG.md index d392e3e662..6fb8d7bd8d 100644 --- a/plugins/techdocs-node/CHANGELOG.md +++ b/plugins/techdocs-node/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-techdocs-node +## 1.12.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.13 + ## 1.12.8 ### Patch Changes diff --git a/plugins/techdocs-node/package.json b/plugins/techdocs-node/package.json index 572b76e052..615a0b7235 100644 --- a/plugins/techdocs-node/package.json +++ b/plugins/techdocs-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-node", - "version": "1.12.8", + "version": "1.12.9-next.0", "description": "Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", "backstage": { "role": "node-library", diff --git a/plugins/techdocs-react/CHANGELOG.md b/plugins/techdocs-react/CHANGELOG.md index 5c9bd0004f..20301266cc 100644 --- a/plugins/techdocs-react/CHANGELOG.md +++ b/plugins/techdocs-react/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-techdocs-react +## 1.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/version-bridge@1.0.8 + ## 1.2.6 ### Patch Changes diff --git a/plugins/techdocs-react/package.json b/plugins/techdocs-react/package.json index e65079b212..2db27e2c60 100644 --- a/plugins/techdocs-react/package.json +++ b/plugins/techdocs-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-react", - "version": "1.2.6", + "version": "1.2.7-next.0", "description": "Shared frontend utilities for TechDocs and Addons", "backstage": { "role": "web-library", diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index 08a841f25c..f2e16e331c 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-techdocs +## 1.10.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/plugin-search-react@1.7.14-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-search-common@1.2.13 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + ## 1.10.7 ### Patch Changes diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 3a90078c72..b1717ce92e 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs", - "version": "1.10.7", + "version": "1.10.8-next.0", "description": "The Backstage plugin that renders technical documentation for your components", "backstage": { "role": "frontend-plugin", diff --git a/plugins/user-settings-backend/CHANGELOG.md b/plugins/user-settings-backend/CHANGELOG.md index 6a945081e8..05f426e57f 100644 --- a/plugins/user-settings-backend/CHANGELOG.md +++ b/plugins/user-settings-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-user-settings-backend +## 0.2.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.0 + - @backstage/plugin-signals-node@0.1.9-next.0 + - @backstage/plugin-user-settings-common@0.0.1 + ## 0.2.21 ### Patch Changes diff --git a/plugins/user-settings-backend/package.json b/plugins/user-settings-backend/package.json index e33bf0bd4b..1c28f1e90c 100644 --- a/plugins/user-settings-backend/package.json +++ b/plugins/user-settings-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-user-settings-backend", - "version": "0.2.21", + "version": "0.2.22-next.0", "description": "The Backstage backend plugin to manage user settings", "backstage": { "role": "backend-plugin", diff --git a/plugins/user-settings/CHANGELOG.md b/plugins/user-settings/CHANGELOG.md index f10a4c0ea3..84598558ee 100644 --- a/plugins/user-settings/CHANGELOG.md +++ b/plugins/user-settings/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-user-settings +## 0.8.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-app-api@1.14.1-next.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.4 + - @backstage/plugin-user-settings-common@0.0.1 + ## 0.8.9 ### Patch Changes diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index 5ae95e0e45..7534c275d1 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-user-settings", - "version": "0.8.9", + "version": "0.8.10-next.0", "description": "A Backstage plugin that provides a settings page", "backstage": { "role": "frontend-plugin", diff --git a/yarn.lock b/yarn.lock index 8755e05c25..2b3baa5b33 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3839,7 +3839,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/catalog-client@workspace:^, @backstage/catalog-client@workspace:packages/catalog-client": +"@backstage/catalog-client@^1.6.5, @backstage/catalog-client@workspace:^, @backstage/catalog-client@workspace:packages/catalog-client": version: 0.0.0-use.local resolution: "@backstage/catalog-client@workspace:packages/catalog-client" dependencies: @@ -3852,7 +3852,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/catalog-model@^1.4.3, @backstage/catalog-model@^1.4.5, @backstage/catalog-model@workspace:^, @backstage/catalog-model@workspace:packages/catalog-model": +"@backstage/catalog-model@^1.4.3, @backstage/catalog-model@^1.4.5, @backstage/catalog-model@^1.5.0, @backstage/catalog-model@workspace:^, @backstage/catalog-model@workspace:packages/catalog-model": version: 0.0.0-use.local resolution: "@backstage/catalog-model@workspace:packages/catalog-model" dependencies: @@ -4105,7 +4105,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/config@^1.1.1, @backstage/config@workspace:^, @backstage/config@workspace:packages/config": +"@backstage/config@^1.1.1, @backstage/config@^1.2.0, @backstage/config@workspace:^, @backstage/config@workspace:packages/config": version: 0.0.0-use.local resolution: "@backstage/config@workspace:packages/config" dependencies: @@ -4177,7 +4177,107 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-components@^0.14.4, @backstage/core-components@workspace:^, @backstage/core-components@workspace:packages/core-components": +"@backstage/core-components@npm:^0.13.10": + version: 0.13.10 + resolution: "@backstage/core-components@npm:0.13.10" + dependencies: + "@backstage/config": ^1.1.1 + "@backstage/core-plugin-api": ^1.8.2 + "@backstage/errors": ^1.2.3 + "@backstage/theme": ^0.5.0 + "@backstage/version-bridge": ^1.0.7 + "@date-io/core": ^1.3.13 + "@material-table/core": ^3.1.0 + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": 4.0.0-alpha.61 + "@react-hookz/web": ^23.0.0 + "@types/react": ^16.13.1 || ^17.0.0 + "@types/react-sparklines": ^1.7.0 + "@types/react-text-truncate": ^0.14.0 + ansi-regex: ^6.0.1 + classnames: ^2.2.6 + d3-selection: ^3.0.0 + d3-shape: ^3.0.0 + d3-zoom: ^3.0.0 + dagre: ^0.8.5 + linkify-react: 4.1.3 + linkifyjs: 4.1.3 + lodash: ^4.17.21 + pluralize: ^8.0.0 + qs: ^6.9.4 + rc-progress: 3.5.1 + react-helmet: 6.1.0 + react-hook-form: ^7.12.2 + react-idle-timer: 5.6.2 + react-markdown: ^8.0.0 + react-sparklines: ^1.7.0 + react-syntax-highlighter: ^15.4.5 + react-text-truncate: ^0.19.0 + react-use: ^17.3.2 + react-virtualized-auto-sizer: ^1.0.11 + react-window: ^1.8.6 + remark-gfm: ^3.0.1 + zen-observable: ^0.10.0 + zod: ^3.22.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 + checksum: ec2a0d0a27bc4d6b9d4da97f0b4df600148529ee51bf2c8e7d3adc45c3950adac662535d3beabc451db346f2c7e3c412ceaa756fc774012b43dff5e2695f2271 + languageName: node + linkType: hard + +"@backstage/core-components@npm:^0.14.4, @backstage/core-components@npm:^0.14.9": + version: 0.14.9 + resolution: "@backstage/core-components@npm:0.14.9" + dependencies: + "@backstage/config": ^1.2.0 + "@backstage/core-plugin-api": ^1.9.3 + "@backstage/errors": ^1.2.4 + "@backstage/theme": ^0.5.6 + "@backstage/version-bridge": ^1.0.8 + "@date-io/core": ^1.3.13 + "@material-table/core": ^3.1.0 + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": 4.0.0-alpha.61 + "@react-hookz/web": ^24.0.0 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react-sparklines": ^1.7.0 + ansi-regex: ^6.0.1 + classnames: ^2.2.6 + d3-selection: ^3.0.0 + d3-shape: ^3.0.0 + d3-zoom: ^3.0.0 + dagre: ^0.8.5 + linkify-react: 4.1.3 + linkifyjs: 4.1.3 + lodash: ^4.17.21 + pluralize: ^8.0.0 + qs: ^6.9.4 + rc-progress: 3.5.1 + react-helmet: 6.1.0 + react-hook-form: ^7.12.2 + react-idle-timer: 5.7.2 + react-markdown: ^8.0.0 + react-sparklines: ^1.7.0 + react-syntax-highlighter: ^15.4.5 + react-use: ^17.3.2 + react-virtualized-auto-sizer: ^1.0.11 + react-window: ^1.8.6 + remark-gfm: ^3.0.1 + zen-observable: ^0.10.0 + zod: ^3.22.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 + checksum: cf89c9e19dd33270bdc2bb9e7d89487c71b78e6645dcef9a6ac0d1df67b52e4eee61f2873abe093ed921d756a75f97e870c294aa5c2a730598e520b06e38b41f + languageName: node + linkType: hard + +"@backstage/core-components@workspace:^, @backstage/core-components@workspace:packages/core-components": version: 0.0.0-use.local resolution: "@backstage/core-components@workspace:packages/core-components" dependencies: @@ -4248,58 +4348,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-components@npm:^0.13.10": - version: 0.13.10 - resolution: "@backstage/core-components@npm:0.13.10" - dependencies: - "@backstage/config": ^1.1.1 - "@backstage/core-plugin-api": ^1.8.2 - "@backstage/errors": ^1.2.3 - "@backstage/theme": ^0.5.0 - "@backstage/version-bridge": ^1.0.7 - "@date-io/core": ^1.3.13 - "@material-table/core": ^3.1.0 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@react-hookz/web": ^23.0.0 - "@types/react": ^16.13.1 || ^17.0.0 - "@types/react-sparklines": ^1.7.0 - "@types/react-text-truncate": ^0.14.0 - ansi-regex: ^6.0.1 - classnames: ^2.2.6 - d3-selection: ^3.0.0 - d3-shape: ^3.0.0 - d3-zoom: ^3.0.0 - dagre: ^0.8.5 - linkify-react: 4.1.3 - linkifyjs: 4.1.3 - lodash: ^4.17.21 - pluralize: ^8.0.0 - qs: ^6.9.4 - rc-progress: 3.5.1 - react-helmet: 6.1.0 - react-hook-form: ^7.12.2 - react-idle-timer: 5.6.2 - react-markdown: ^8.0.0 - react-sparklines: ^1.7.0 - react-syntax-highlighter: ^15.4.5 - react-text-truncate: ^0.19.0 - react-use: ^17.3.2 - react-virtualized-auto-sizer: ^1.0.11 - react-window: ^1.8.6 - remark-gfm: ^3.0.1 - zen-observable: ^0.10.0 - zod: ^3.22.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 - checksum: ec2a0d0a27bc4d6b9d4da97f0b4df600148529ee51bf2c8e7d3adc45c3950adac662535d3beabc451db346f2c7e3c412ceaa756fc774012b43dff5e2695f2271 - languageName: node - linkType: hard - -"@backstage/core-plugin-api@^1.8.2, @backstage/core-plugin-api@^1.9.2, @backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": +"@backstage/core-plugin-api@^1.8.2, @backstage/core-plugin-api@^1.9.2, @backstage/core-plugin-api@^1.9.3, @backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": version: 0.0.0-use.local resolution: "@backstage/core-plugin-api@workspace:packages/core-plugin-api" dependencies: @@ -4446,6 +4495,26 @@ __metadata: languageName: unknown linkType: soft +"@backstage/frontend-plugin-api@npm:^0.6.7": + version: 0.6.7 + resolution: "@backstage/frontend-plugin-api@npm:0.6.7" + dependencies: + "@backstage/core-components": ^0.14.9 + "@backstage/core-plugin-api": ^1.9.3 + "@backstage/types": ^1.1.1 + "@backstage/version-bridge": ^1.0.8 + "@material-ui/core": ^4.12.4 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + lodash: ^4.17.21 + zod: ^3.22.4 + zod-to-json-schema: ^3.21.4 + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + checksum: cf7485aedcae02c5855a62adea6fffcfad256d614731ade38d2bebd5f98e91aa5d1020cd9ac25b74d67d2681c010addff4a89d5be1e2deb2e688bf1915134c32 + languageName: node + linkType: hard + "@backstage/frontend-plugin-api@workspace:^, @backstage/frontend-plugin-api@workspace:packages/frontend-plugin-api": version: 0.0.0-use.local resolution: "@backstage/frontend-plugin-api@workspace:packages/frontend-plugin-api" @@ -4509,6 +4578,24 @@ __metadata: languageName: unknown linkType: soft +"@backstage/integration-react@npm:^1.1.29": + version: 1.1.29 + resolution: "@backstage/integration-react@npm:1.1.29" + dependencies: + "@backstage/config": ^1.2.0 + "@backstage/core-plugin-api": ^1.9.3 + "@backstage/integration": ^1.13.0 + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@types/react": ^16.13.1 || ^17.0.0 + 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 + checksum: add10ad8c108933354037f9d74ec554174d2af53d74a031e12ed01e98bd51481413b93c694460cf045b3bae818dd18b5efa061fc60c210e145e4629e0cb227b7 + languageName: node + linkType: hard + "@backstage/integration-react@workspace:^, @backstage/integration-react@workspace:packages/integration-react": version: 0.0.0-use.local resolution: "@backstage/integration-react@workspace:packages/integration-react" @@ -4533,6 +4620,23 @@ __metadata: languageName: unknown linkType: soft +"@backstage/integration@npm:^1.13.0": + version: 1.13.0 + resolution: "@backstage/integration@npm:1.13.0" + dependencies: + "@azure/identity": ^4.0.0 + "@backstage/config": ^1.2.0 + "@backstage/errors": ^1.2.4 + "@octokit/auth-app": ^4.0.0 + "@octokit/rest": ^19.0.3 + cross-fetch: ^4.0.0 + git-url-parse: ^14.0.0 + lodash: ^4.17.21 + luxon: ^3.0.0 + checksum: 2b824261b0d30771e54515f8571c2af0b4c64f5cd3d1f990c234152b19e81d1e4ddbbbfae2a0b74f44abbfb67f52609c7eee9dc9fbb61d5f0076acaa80b3e670 + languageName: node + linkType: hard + "@backstage/integration@workspace:^, @backstage/integration@workspace:packages/integration": version: 0.0.0-use.local resolution: "@backstage/integration@workspace:packages/integration" @@ -5616,7 +5720,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-common@^1.0.20, @backstage/plugin-catalog-common@workspace:^, @backstage/plugin-catalog-common@workspace:plugins/catalog-common": +"@backstage/plugin-catalog-common@^1.0.20, @backstage/plugin-catalog-common@^1.0.25, @backstage/plugin-catalog-common@workspace:^, @backstage/plugin-catalog-common@workspace:plugins/catalog-common": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-common@workspace:plugins/catalog-common" dependencies: @@ -5725,7 +5829,43 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-react@^1.11.3, @backstage/plugin-catalog-react@^1.9.3, @backstage/plugin-catalog-react@workspace:^, @backstage/plugin-catalog-react@workspace:plugins/catalog-react": +"@backstage/plugin-catalog-react@npm:^1.11.3, @backstage/plugin-catalog-react@npm:^1.9.3": + version: 1.12.2 + resolution: "@backstage/plugin-catalog-react@npm:1.12.2" + dependencies: + "@backstage/catalog-client": ^1.6.5 + "@backstage/catalog-model": ^1.5.0 + "@backstage/core-components": ^0.14.9 + "@backstage/core-plugin-api": ^1.9.3 + "@backstage/errors": ^1.2.4 + "@backstage/frontend-plugin-api": ^0.6.7 + "@backstage/integration-react": ^1.1.29 + "@backstage/plugin-catalog-common": ^1.0.25 + "@backstage/plugin-permission-common": ^0.8.0 + "@backstage/plugin-permission-react": ^0.4.24 + "@backstage/types": ^1.1.1 + "@backstage/version-bridge": ^1.0.8 + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": 4.0.0-alpha.61 + "@react-hookz/web": ^24.0.0 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + classnames: ^2.2.6 + lodash: ^4.17.21 + material-ui-popup-state: ^1.9.3 + qs: ^6.9.4 + react-use: ^17.2.4 + yaml: ^2.0.0 + zen-observable: ^0.10.0 + 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 + checksum: 8570e71e56e89cc8ba890ad9cd1f2ce22147635e9a326703291ee8a75d704086c4a31cd11b2b2c3eb54f3e1dc82822b1bc7b9317e8c6d81f6ab9758c2c01ec5a + languageName: node + linkType: hard + +"@backstage/plugin-catalog-react@workspace:^, @backstage/plugin-catalog-react@workspace:plugins/catalog-react": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-react@workspace:plugins/catalog-react" dependencies: @@ -6569,7 +6709,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-permission-common@workspace:^, @backstage/plugin-permission-common@workspace:plugins/permission-common": +"@backstage/plugin-permission-common@^0.8.0, @backstage/plugin-permission-common@workspace:^, @backstage/plugin-permission-common@workspace:plugins/permission-common": version: 0.0.0-use.local resolution: "@backstage/plugin-permission-common@workspace:plugins/permission-common" dependencies: @@ -6607,7 +6747,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-permission-react@workspace:^, @backstage/plugin-permission-react@workspace:plugins/permission-react": +"@backstage/plugin-permission-react@^0.4.24, @backstage/plugin-permission-react@workspace:^, @backstage/plugin-permission-react@workspace:plugins/permission-react": version: 0.0.0-use.local resolution: "@backstage/plugin-permission-react@workspace:plugins/permission-react" dependencies: @@ -7933,7 +8073,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/theme@^0.5.0, @backstage/theme@workspace:^, @backstage/theme@workspace:packages/theme": +"@backstage/theme@^0.5.0, @backstage/theme@^0.5.6, @backstage/theme@workspace:^, @backstage/theme@workspace:packages/theme": version: 0.0.0-use.local resolution: "@backstage/theme@workspace:packages/theme" dependencies: @@ -7964,7 +8104,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/version-bridge@^1.0.7, @backstage/version-bridge@workspace:^, @backstage/version-bridge@workspace:packages/version-bridge": +"@backstage/version-bridge@^1.0.7, @backstage/version-bridge@^1.0.8, @backstage/version-bridge@workspace:^, @backstage/version-bridge@workspace:packages/version-bridge": version: 0.0.0-use.local resolution: "@backstage/version-bridge@workspace:packages/version-bridge" dependencies: From fc45f68ecc2d7d3bc912a80fc39d64479722b858 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 14:54:20 +0000 Subject: [PATCH 403/510] fix(deps): update dependency octokit to v3.2.1 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 53 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/yarn.lock b/yarn.lock index 8755e05c25..80cea4fceb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12110,6 +12110,13 @@ __metadata: languageName: node linkType: hard +"@octokit/openapi-types@npm:^22.2.0": + version: 22.2.0 + resolution: "@octokit/openapi-types@npm:22.2.0" + checksum: eca41feac2b83298e0d95e253ac1c5b6d65155ac57f65c5fd8d4a485d9728922d85ff4bee0e815a1f3a5421311db092bdb6da9d6104a1b1843d8b274bcad9630 + languageName: node + linkType: hard + "@octokit/plugin-paginate-graphql@npm:^4.0.0": version: 4.0.0 resolution: "@octokit/plugin-paginate-graphql@npm:4.0.0" @@ -12119,6 +12126,17 @@ __metadata: languageName: node linkType: hard +"@octokit/plugin-paginate-rest@npm:11.3.1": + version: 11.3.1 + resolution: "@octokit/plugin-paginate-rest@npm:11.3.1" + dependencies: + "@octokit/types": ^13.5.0 + peerDependencies: + "@octokit/core": 5 + checksum: 42c7c08e7287b4b85d2ae47852d2ffeb238c134ad6bcff18bddc154b15f6bec31778816c0763181401c370198390db7f6b0c3c44750fdfeec459594f7f4b5933 + languageName: node + linkType: hard + "@octokit/plugin-paginate-rest@npm:^6.1.2": version: 6.1.2 resolution: "@octokit/plugin-paginate-rest@npm:6.1.2" @@ -12151,14 +12169,14 @@ __metadata: languageName: node linkType: hard -"@octokit/plugin-rest-endpoint-methods@npm:^10.0.0": - version: 10.2.0 - resolution: "@octokit/plugin-rest-endpoint-methods@npm:10.2.0" +"@octokit/plugin-rest-endpoint-methods@npm:13.2.2": + version: 13.2.2 + resolution: "@octokit/plugin-rest-endpoint-methods@npm:13.2.2" dependencies: - "@octokit/types": ^12.3.0 + "@octokit/types": ^13.5.0 peerDependencies: - "@octokit/core": ">=5" - checksum: 3209688bf508d22a525fe32d632ff928b048688c1859c7e4bbb08bd181aa07f580b375a502e34368628103e5d5cccf7f9fb0ff0c8fd4262470ac8eeffb80ac6b + "@octokit/core": ^5 + checksum: 347b3a891a561ed1dcc307a2dce42ca48c318c465ad91a26225d3d6493aef1b7ff868e6c56a0d7aa4170d028c7429ca1ec52aed6be34615a6ed701c3bcafdb17 languageName: node linkType: hard @@ -12291,7 +12309,7 @@ __metadata: languageName: node linkType: hard -"@octokit/types@npm:^12.0.0, @octokit/types@npm:^12.2.0, @octokit/types@npm:^12.3.0, @octokit/types@npm:^12.4.0": +"@octokit/types@npm:^12.0.0, @octokit/types@npm:^12.2.0, @octokit/types@npm:^12.4.0": version: 12.4.0 resolution: "@octokit/types@npm:12.4.0" dependencies: @@ -12300,6 +12318,15 @@ __metadata: languageName: node linkType: hard +"@octokit/types@npm:^13.0.0, @octokit/types@npm:^13.5.0": + version: 13.5.0 + resolution: "@octokit/types@npm:13.5.0" + dependencies: + "@octokit/openapi-types": ^22.2.0 + checksum: 8e92f2b145b3c28a35312f93714245824a7b6b7353caa88edfdc85fc2ed4108321ed0c3988001ea53449fbb212febe0e8e9582744e85c3574dabe9d0441af5a0 + languageName: node + linkType: hard + "@octokit/types@npm:^6.0.3, @octokit/types@npm:^6.10.0, @octokit/types@npm:^6.12.2, @octokit/types@npm:^6.16.1": version: 6.41.0 resolution: "@octokit/types@npm:6.41.0" @@ -35642,20 +35669,20 @@ __metadata: linkType: hard "octokit@npm:^3.0.0": - version: 3.2.0 - resolution: "octokit@npm:3.2.0" + version: 3.2.1 + resolution: "octokit@npm:3.2.1" dependencies: "@octokit/app": ^14.0.2 "@octokit/core": ^5.0.0 "@octokit/oauth-app": ^6.0.0 "@octokit/plugin-paginate-graphql": ^4.0.0 - "@octokit/plugin-paginate-rest": ^9.0.0 - "@octokit/plugin-rest-endpoint-methods": ^10.0.0 + "@octokit/plugin-paginate-rest": 11.3.1 + "@octokit/plugin-rest-endpoint-methods": 13.2.2 "@octokit/plugin-retry": ^6.0.0 "@octokit/plugin-throttling": ^8.0.0 "@octokit/request-error": ^5.0.0 - "@octokit/types": ^12.0.0 - checksum: 3ec8efe02144aa6210a5c846947245cbe58d31144fa8e6a1726782001d77fcd044b7e1498a56c5e47aba44c1f5726a37c261f474cb46b816579549f7a09db1f6 + "@octokit/types": ^13.0.0 + checksum: e5608f848fb11808d0c977d946c24bffa622179daf8566c4941f6050551d368aa750b362a95aea14647facd0919e4af392c67b2409f8642dc9f27c7b6c0f964e languageName: node linkType: hard From 6a55e52ff3fafeec2a4fe3ca633dc206e0a85a25 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 15:08:53 +0000 Subject: [PATCH 404/510] chore(deps): bump ws from 8.14.2 to 8.18.0 Bumps [ws](https://github.com/websockets/ws) from 8.14.2 to 8.18.0. - [Release notes](https://github.com/websockets/ws/releases) - [Commits](https://github.com/websockets/ws/compare/8.14.2...8.18.0) --- updated-dependencies: - dependency-name: ws dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 2b3baa5b33..82cc4670b4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -44887,8 +44887,8 @@ __metadata: linkType: hard "ws@npm:*, ws@npm:^8.11.0, ws@npm:^8.12.0, ws@npm:^8.13.0, ws@npm:^8.14.2, ws@npm:^8.16.0, ws@npm:^8.17.0, ws@npm:^8.8.0": - version: 8.17.1 - resolution: "ws@npm:8.17.1" + version: 8.18.0 + resolution: "ws@npm:8.18.0" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ">=5.0.2" @@ -44897,7 +44897,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: 442badcce1f1178ec87a0b5372ae2e9771e07c4929a3180321901f226127f252441e8689d765aa5cfba5f50ac60dd830954afc5aeae81609aefa11d3ddf5cecf + checksum: 91d4d35bc99ff6df483bdf029b9ea4bfd7af1f16fc91231a96777a63d263e1eabf486e13a2353970efc534f9faa43bdbf9ee76525af22f4752cbc5ebda333975 languageName: node linkType: hard From e6c15cc3045ca5ea28d2f944018ee857ff6b216d Mon Sep 17 00:00:00 2001 From: Nurit Izrailov <nuriti@spotify.com> Date: Tue, 23 Jul 2024 11:33:26 -0400 Subject: [PATCH 405/510] add support to the new frontend system Signed-off-by: Nurit Izrailov <nuriti@spotify.com> --- .changeset/mean-apricots-perform.md | 5 + packages/app-next/app-config.yaml | 2 + packages/app-next/src/App.tsx | 2 + plugins/kubernetes/README.md | 32 ++++- plugins/kubernetes/api-report-alpha.md | 19 +++ plugins/kubernetes/package.json | 17 +++ plugins/kubernetes/src/alpha.ts | 18 +++ .../src/alpha/KubernetesContentPage.tsx | 24 ++++ plugins/kubernetes/src/alpha/apis.tsx | 119 ++++++++++++++++++ .../kubernetes/src/alpha/entityContents.tsx | 34 +++++ plugins/kubernetes/src/alpha/index.ts | 17 +++ plugins/kubernetes/src/alpha/pages.tsx | 33 +++++ plugins/kubernetes/src/alpha/plugin.tsx | 40 ++++++ yarn.lock | 2 + 14 files changed, 363 insertions(+), 1 deletion(-) create mode 100644 .changeset/mean-apricots-perform.md create mode 100644 plugins/kubernetes/api-report-alpha.md create mode 100644 plugins/kubernetes/src/alpha.ts create mode 100644 plugins/kubernetes/src/alpha/KubernetesContentPage.tsx create mode 100644 plugins/kubernetes/src/alpha/apis.tsx create mode 100644 plugins/kubernetes/src/alpha/entityContents.tsx create mode 100644 plugins/kubernetes/src/alpha/index.ts create mode 100644 plugins/kubernetes/src/alpha/pages.tsx create mode 100644 plugins/kubernetes/src/alpha/plugin.tsx diff --git a/.changeset/mean-apricots-perform.md b/.changeset/mean-apricots-perform.md new file mode 100644 index 0000000000..089a3ea7a4 --- /dev/null +++ b/.changeset/mean-apricots-perform.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kubernetes': minor +--- + +Adds support for Backstage's new frontend system diff --git a/packages/app-next/app-config.yaml b/packages/app-next/app-config.yaml index 271040ecec..f6d0174ca1 100644 --- a/packages/app-next/app-config.yaml +++ b/packages/app-next/app-config.yaml @@ -43,6 +43,8 @@ app: - entity-card:org/ownership - entity-card:org/user-profile + - entity-content:kubernetes/kubernetes + # scmAuthExtension: >- # createScmAuthExtension({ # id: 'apis.scmAuth.addons.ghe', diff --git a/packages/app-next/src/App.tsx b/packages/app-next/src/App.tsx index c911a01258..303d751338 100644 --- a/packages/app-next/src/App.tsx +++ b/packages/app-next/src/App.tsx @@ -48,6 +48,7 @@ import { } from '@backstage/integration-react'; import { createSignInPageExtension } from '@backstage/frontend-plugin-api'; import { SignInPage } from '@backstage/core-components'; +import kubernetesPlugin from '@backstage/plugin-kubernetes/alpha'; /* @@ -121,6 +122,7 @@ const app = createApp({ userSettingsPlugin, homePlugin, appVisualizerPlugin, + kubernetesPlugin, ...collectedLegacyPlugins, createExtensionOverrides({ extensions: [ diff --git a/plugins/kubernetes/README.md b/plugins/kubernetes/README.md index 15dfd16b17..4ffde719f2 100644 --- a/plugins/kubernetes/README.md +++ b/plugins/kubernetes/README.md @@ -26,8 +26,38 @@ For more information, see the [formal documentation about the Kubernetes feature ## Getting started -Your plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn start` in the root directory, and then navigating to [/kubernetes](http://localhost:3000/kubernetes). +Your plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn start` in the root directory, and then navigating to [/kubernetes](http://localhost:3000/catalog/default/component/:component-name/kubernetes). You can also serve the plugin in isolation by running `yarn start` in the plugin directory. This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads. It is only meant for local development, and the setup for it can be found inside the [/dev](./dev) directory. + +### Integrating with `EntityPage` (New Frontend System) + +Follow this section if you are using Backstage's [new frontend system](https://backstage.io/docs/frontend-system/). + +1. Import `kubernetesPlugin` in your `App.tsx` and add it to your app's `features` array: + +```typescript +import kubernetesPlugin from '@backstage/plugin-kubernetes/alpha'; + +// ... + +export const app = createApp({ + features: [ + // ... + kubernetesPlugin, + // ... + ], +}); +``` + +2. Next, enable your desired extensions in `app-config.yaml` + +```yaml +app: + extensions: + - entity-content:kubernetes/kubernetes +``` + +Now, the extension appears on your entity page as one of the tabs, which is called `KUBERNETES` diff --git a/plugins/kubernetes/api-report-alpha.md b/plugins/kubernetes/api-report-alpha.md new file mode 100644 index 0000000000..8bd6e98baa --- /dev/null +++ b/plugins/kubernetes/api-report-alpha.md @@ -0,0 +1,19 @@ +## API Report File for "@backstage/plugin-kubernetes" + +> 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'; +import { RouteRef } from '@backstage/frontend-plugin-api'; + +// @public (undocumented) +const _default: BackstagePlugin< + { + kubernetes: RouteRef<undefined>; + }, + {} +>; +export default _default; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index 1ab92f5b3c..6a66e42a94 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -30,8 +30,23 @@ }, "license": "Apache-2.0", "sideEffects": false, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, "main": "src/index.ts", "types": "src/index.ts", + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } + }, "files": [ "dist" ], @@ -46,8 +61,10 @@ }, "dependencies": { "@backstage/catalog-model": "workspace:^", + "@backstage/core-compat-api": "workspace:^", "@backstage/core-components": "workspace:^", "@backstage/core-plugin-api": "workspace:^", + "@backstage/frontend-plugin-api": "workspace:^", "@backstage/plugin-catalog-react": "workspace:^", "@backstage/plugin-kubernetes-common": "workspace:^", "@backstage/plugin-kubernetes-react": "workspace:^", diff --git a/plugins/kubernetes/src/alpha.ts b/plugins/kubernetes/src/alpha.ts new file mode 100644 index 0000000000..e80f131817 --- /dev/null +++ b/plugins/kubernetes/src/alpha.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './alpha/index'; +export { default } from './alpha/index'; diff --git a/plugins/kubernetes/src/alpha/KubernetesContentPage.tsx b/plugins/kubernetes/src/alpha/KubernetesContentPage.tsx new file mode 100644 index 0000000000..948a492e63 --- /dev/null +++ b/plugins/kubernetes/src/alpha/KubernetesContentPage.tsx @@ -0,0 +1,24 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { useEntity } from '@backstage/plugin-catalog-react'; +import { KubernetesContent } from '../KubernetesContent'; +import React from 'react'; + +export function KubernetesContentPage() { + const { entity } = useEntity(); + return <KubernetesContent entity={entity} />; +} diff --git a/plugins/kubernetes/src/alpha/apis.tsx b/plugins/kubernetes/src/alpha/apis.tsx new file mode 100644 index 0000000000..6c880d2f53 --- /dev/null +++ b/plugins/kubernetes/src/alpha/apis.tsx @@ -0,0 +1,119 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createApiExtension, + createApiFactory, + discoveryApiRef, + fetchApiRef, +} from '@backstage/frontend-plugin-api'; +import { + KubernetesBackendClient, + kubernetesApiRef, + kubernetesProxyApiRef, + kubernetesAuthProvidersApiRef, + KubernetesAuthProviders, + KubernetesProxyClient, + kubernetesClusterLinkFormatterApiRef, + getDefaultFormatters, + KubernetesClusterLinkFormatter, + DEFAULT_FORMATTER_NAME, +} from '@backstage/plugin-kubernetes-react'; +import { + gitlabAuthApiRef, + googleAuthApiRef, + microsoftAuthApiRef, + oktaAuthApiRef, + oneloginAuthApiRef, +} from '@backstage/core-plugin-api'; + +export const kubernetesApiExtension = createApiExtension({ + factory: createApiFactory({ + api: kubernetesApiRef, + deps: { + discoveryApi: discoveryApiRef, + fetchApi: fetchApiRef, + kubernetesAuthProvidersApi: kubernetesAuthProvidersApiRef, + }, + factory: ({ discoveryApi, fetchApi, kubernetesAuthProvidersApi }) => + new KubernetesBackendClient({ + discoveryApi, + fetchApi, + kubernetesAuthProvidersApi, + }), + }), +}); + +export const kubernetesProxyApi = createApiExtension({ + factory: createApiFactory({ + api: kubernetesProxyApiRef, + deps: { + kubernetesApi: kubernetesApiRef, + }, + factory: ({ kubernetesApi }) => + new KubernetesProxyClient({ + kubernetesApi, + }), + }), +}); + +export const kubernetesAuthProvidersApi = createApiExtension({ + factory: createApiFactory({ + api: kubernetesAuthProvidersApiRef, + deps: { + gitlabAuthApi: gitlabAuthApiRef, + googleAuthApi: googleAuthApiRef, + microsoftAuthApi: microsoftAuthApiRef, + oktaAuthApi: oktaAuthApiRef, + oneloginAuthApi: oneloginAuthApiRef, + }, + factory: ({ + gitlabAuthApi, + googleAuthApi, + microsoftAuthApi, + oktaAuthApi, + oneloginAuthApi, + }) => { + const oidcProviders = { + gitlab: gitlabAuthApi, + google: googleAuthApi, + microsoft: microsoftAuthApi, + okta: oktaAuthApi, + onelogin: oneloginAuthApi, + }; + + return new KubernetesAuthProviders({ + microsoftAuthApi, + googleAuthApi, + oidcProviders, + }); + }, + }), +}); + +export const kubernetesClusterLinkFormatterApi = createApiExtension({ + factory: createApiFactory({ + api: kubernetesClusterLinkFormatterApiRef, + deps: { googleAuthApi: googleAuthApiRef }, + factory: deps => { + const formatters = getDefaultFormatters(deps); + return new KubernetesClusterLinkFormatter({ + formatters, + defaultFormatterName: DEFAULT_FORMATTER_NAME, + }); + }, + }), +}); diff --git a/plugins/kubernetes/src/alpha/entityContents.tsx b/plugins/kubernetes/src/alpha/entityContents.tsx new file mode 100644 index 0000000000..9ad0b6843f --- /dev/null +++ b/plugins/kubernetes/src/alpha/entityContents.tsx @@ -0,0 +1,34 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { + compatWrapper, + convertLegacyRouteRef, +} from '@backstage/core-compat-api'; +import { createEntityContentExtension } from '@backstage/plugin-catalog-react/alpha'; +import { rootCatalogKubernetesRouteRef } from '../plugin'; + +export const entityKubernetesContent = createEntityContentExtension({ + defaultPath: 'kubernetes', + defaultTitle: 'Kubernetes', + name: 'kubernetes', + routeRef: convertLegacyRouteRef(rootCatalogKubernetesRouteRef), + loader: () => + import('./KubernetesContentPage').then(m => + compatWrapper(<m.KubernetesContentPage />), + ), +}); diff --git a/plugins/kubernetes/src/alpha/index.ts b/plugins/kubernetes/src/alpha/index.ts new file mode 100644 index 0000000000..2f137f09ee --- /dev/null +++ b/plugins/kubernetes/src/alpha/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { default } from './plugin'; diff --git a/plugins/kubernetes/src/alpha/pages.tsx b/plugins/kubernetes/src/alpha/pages.tsx new file mode 100644 index 0000000000..8b5db150bd --- /dev/null +++ b/plugins/kubernetes/src/alpha/pages.tsx @@ -0,0 +1,33 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; // Add this line to import React + +import { createPageExtension } from '@backstage/frontend-plugin-api'; +import { + compatWrapper, + convertLegacyRouteRef, +} from '@backstage/core-compat-api'; +import { rootCatalogKubernetesRouteRef } from '../plugin'; + +export const kubernetesPage = createPageExtension({ + defaultPath: '/kubernetes', + // you can reuse the existing routeRef + // by wrapping into the convertLegacyRouteRef. + routeRef: convertLegacyRouteRef(rootCatalogKubernetesRouteRef), + // these inputs usually match the props required by the component. + loader: () => import('../Router').then(m => compatWrapper(<m.Router />)), +}); diff --git a/plugins/kubernetes/src/alpha/plugin.tsx b/plugins/kubernetes/src/alpha/plugin.tsx new file mode 100644 index 0000000000..47433bce35 --- /dev/null +++ b/plugins/kubernetes/src/alpha/plugin.tsx @@ -0,0 +1,40 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { convertLegacyRouteRefs } from '@backstage/core-compat-api'; +import { createPlugin } from '@backstage/frontend-plugin-api'; +import { kubernetesPage } from './pages'; +import { entityKubernetesContent } from './entityContents'; +import { rootCatalogKubernetesRouteRef } from '../plugin'; +import { + kubernetesApiExtension as kubernetesApi, + kubernetesAuthProvidersApi, + kubernetesClusterLinkFormatterApi, + kubernetesProxyApi, +} from './apis'; + +export default createPlugin({ + id: 'kubernetes', + extensions: [ + kubernetesPage, + entityKubernetesContent, + kubernetesApi, + kubernetesProxyApi, + kubernetesAuthProvidersApi, + kubernetesClusterLinkFormatterApi, + ], + routes: convertLegacyRouteRefs({ kubernetes: rootCatalogKubernetesRouteRef }), +}); diff --git a/yarn.lock b/yarn.lock index b63d8d7d63..ed5486f498 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6307,9 +6307,11 @@ __metadata: dependencies: "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" + "@backstage/core-compat-api": "workspace:^" "@backstage/core-components": "workspace:^" "@backstage/core-plugin-api": "workspace:^" "@backstage/dev-utils": "workspace:^" + "@backstage/frontend-plugin-api": "workspace:^" "@backstage/plugin-catalog-react": "workspace:^" "@backstage/plugin-kubernetes-common": "workspace:^" "@backstage/plugin-kubernetes-react": "workspace:^" From d31aa860eb6c2474e945b337181422507ceeb970 Mon Sep 17 00:00:00 2001 From: Nurit Izrailov <38442135+nuritizra@users.noreply.github.com> Date: Tue, 23 Jul 2024 13:41:14 -0400 Subject: [PATCH 406/510] Update .changeset/mean-apricots-perform.md Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com> Signed-off-by: Nurit Izrailov <38442135+nuritizra@users.noreply.github.com> --- .changeset/mean-apricots-perform.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/mean-apricots-perform.md b/.changeset/mean-apricots-perform.md index 089a3ea7a4..26e547086e 100644 --- a/.changeset/mean-apricots-perform.md +++ b/.changeset/mean-apricots-perform.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-kubernetes': minor +'@backstage/plugin-kubernetes': patch --- Adds support for Backstage's new frontend system From 9397e8f175a0310d68b3be26c70db2fe137f4fe9 Mon Sep 17 00:00:00 2001 From: Nurit Izrailov <38442135+nuritizra@users.noreply.github.com> Date: Tue, 23 Jul 2024 13:41:22 -0400 Subject: [PATCH 407/510] Update .changeset/mean-apricots-perform.md Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com> Signed-off-by: Nurit Izrailov <38442135+nuritizra@users.noreply.github.com> --- .changeset/mean-apricots-perform.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/mean-apricots-perform.md b/.changeset/mean-apricots-perform.md index 26e547086e..c93514cb7f 100644 --- a/.changeset/mean-apricots-perform.md +++ b/.changeset/mean-apricots-perform.md @@ -2,4 +2,4 @@ '@backstage/plugin-kubernetes': patch --- -Adds support for Backstage's new frontend system +Adds support for Backstage's new frontend system, available via the `/alpha` sub-path export. From 949083ddb41067368bc3638303683e1340614563 Mon Sep 17 00:00:00 2001 From: Isabel Tomb <isabelgtomb@gmail.com> Date: Mon, 8 Jul 2024 13:03:39 -0500 Subject: [PATCH 408/510] Update `patchMkdocsYmlPreBuild` Update the `patchMkdocsYmlPreBuild` function to modify `repo_url` and `edit_uri` independently of each other. Prior to this change both `repo_url` and `edit_uri` would have to be missing for either to be generated which caused an issue in the situation where `repo_url` is provided in the mkdocs.yml and `edit_uri` is not because the default `edit_uri` value from mkdocs would be used instead. This value uses `master` as the branch in the link which breaks the edit link for repos that don't use `master` as the default branch. Signed-off-by: Isabel Tomb <isabelgtomb@gmail.com> --- .changeset/mighty-geckos-kiss.md | 5 +++++ plugins/techdocs-node/src/stages/generate/mkdocsPatchers.ts | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 .changeset/mighty-geckos-kiss.md diff --git a/.changeset/mighty-geckos-kiss.md b/.changeset/mighty-geckos-kiss.md new file mode 100644 index 0000000000..0761d8b257 --- /dev/null +++ b/.changeset/mighty-geckos-kiss.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs-node': patch +--- + +Update `patchMkdocsYmlPrebuild` to modify `repo_url` and `edit_uri` independently. diff --git a/plugins/techdocs-node/src/stages/generate/mkdocsPatchers.ts b/plugins/techdocs-node/src/stages/generate/mkdocsPatchers.ts index 762a1c267a..fb95c19a9c 100644 --- a/plugins/techdocs-node/src/stages/generate/mkdocsPatchers.ts +++ b/plugins/techdocs-node/src/stages/generate/mkdocsPatchers.ts @@ -108,7 +108,7 @@ export const patchMkdocsYmlPreBuild = async ( scmIntegrations: ScmIntegrationRegistry, ) => { await patchMkdocsFile(mkdocsYmlPath, logger, mkdocsYml => { - if (!('repo_url' in mkdocsYml) && !('edit_uri' in mkdocsYml)) { + if (!('repo_url' in mkdocsYml) || !('edit_uri' in mkdocsYml)) { // Add edit_uri and/or repo_url to mkdocs.yml if it is missing. // This will enable the Page edit button generated by MkDocs. // If the either has been set, keep the original value @@ -119,8 +119,8 @@ export const patchMkdocsYmlPreBuild = async ( ); if (result.repo_url || result.edit_uri) { - mkdocsYml.repo_url = result.repo_url; - mkdocsYml.edit_uri = result.edit_uri; + mkdocsYml.repo_url = mkdocsYml.repo_url || result.repo_url; + mkdocsYml.edit_uri = mkdocsYml.edit_uri || result.edit_uri; logger.info( `Set ${JSON.stringify( From 839e888e3a7e348b200cb6eeda68b782a12e782c Mon Sep 17 00:00:00 2001 From: Isabel Tomb <isabelgtomb@gmail.com> Date: Mon, 8 Jul 2024 13:44:01 -0500 Subject: [PATCH 409/510] Add a test for new repo_url edit_uri scenario Add a test that checks that an edit_uri will be generated as expected if the mkdocs.yml contains a `repo_url` value but no `edit_uri` vlaue. Signed-off-by: Isabel Tomb <isabelgtomb@gmail.com> --- .../src/stages/generate/helpers.test.ts | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/plugins/techdocs-node/src/stages/generate/helpers.test.ts b/plugins/techdocs-node/src/stages/generate/helpers.test.ts index 3589b71c60..a40239c595 100644 --- a/plugins/techdocs-node/src/stages/generate/helpers.test.ts +++ b/plugins/techdocs-node/src/stages/generate/helpers.test.ts @@ -299,6 +299,31 @@ describe('helpers', () => { ); }); + it('should add edit_uri to mkdocs.yml with existing repo_url', async () => { + const parsedLocationAnnotation: ParsedLocationAnnotation = { + type: 'url', + target: 'https://github.com/neworg/newrepo/tree/main/', + }; + + await patchMkdocsYmlPreBuild( + mockDir.resolve('mkdocs_with_repo_url.yml'), + mockLogger, + parsedLocationAnnotation, + scmIntegrations, + ); + + const updatedMkdocsYml = await fs.readFile( + mockDir.resolve('mkdocs_with_repo_url.yml'), + ); + + expect(updatedMkdocsYml.toString()).toContain( + 'edit_uri: https://github.com/neworg/newrepo/edit/main/docs', + ); + expect(updatedMkdocsYml.toString()).toContain( + 'repo_url: https://github.com/backstage/backstage', + ); + }); + it('should not update mkdocs.yml if nothing should be changed', async () => { const parsedLocationAnnotation: ParsedLocationAnnotation = { type: 'dir', From 0afa044555655e07f9e31d3eceb32c2177a0c1db Mon Sep 17 00:00:00 2001 From: Isabel Tomb <isabelgtomb@gmail.com> Date: Mon, 8 Jul 2024 13:45:50 -0500 Subject: [PATCH 410/510] Update test Update the test that checks that the existing edit_uri value in a mkdocs.yml won't be overridden by `patchMkdocsYmlPreBuild` so that it checks the value of 'edit_uri' was not updated rather than just checking for the existence of the substring. This change is needed because the substring will exist in the file but as the `repo_url` value which is expected after the changes in the previous commits. Signed-off-by: Isabel Tomb <isabelgtomb@gmail.com> --- plugins/techdocs-node/src/stages/generate/helpers.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/techdocs-node/src/stages/generate/helpers.test.ts b/plugins/techdocs-node/src/stages/generate/helpers.test.ts index a40239c595..6ee3870845 100644 --- a/plugins/techdocs-node/src/stages/generate/helpers.test.ts +++ b/plugins/techdocs-node/src/stages/generate/helpers.test.ts @@ -295,7 +295,7 @@ describe('helpers', () => { 'edit_uri: https://github.com/backstage/backstage/edit/main/docs', ); expect(updatedMkdocsYml.toString()).not.toContain( - 'https://github.com/neworg/newrepo', + 'edit_uri: https://github.com/neworg/newrepo', ); }); From def53a7f9606550b5cd68744b8c11ab3c8a7cba0 Mon Sep 17 00:00:00 2001 From: Mikko Korhonen <mikko.korhonen@op.fi> Date: Wed, 24 Jul 2024 12:30:55 +0300 Subject: [PATCH 411/510] Change NotificationTemplateRenderer methods to return a promise Signed-off-by: Mikko Korhonen <mikko.korhonen@op.fi> --- .changeset/spicy-planets-provide.md | 46 +++++++++++++++++++ .../api-report.md | 6 +-- .../src/extensions.ts | 6 +-- .../processor/NotificationsEmailProcessor.ts | 6 +-- 4 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 .changeset/spicy-planets-provide.md diff --git a/.changeset/spicy-planets-provide.md b/.changeset/spicy-planets-provide.md new file mode 100644 index 0000000000..f2929df850 --- /dev/null +++ b/.changeset/spicy-planets-provide.md @@ -0,0 +1,46 @@ +--- +'@backstage/plugin-notifications-backend-module-email': minor +--- + +**BREAKING** Following `NotificationTemplateRenderer` methods now return a Promise and **must** be awaited: `getSubject`, `getText` and `getHtml`. + +Required changes and example usage: + +```diff +import { notificationsEmailTemplateExtensionPoint } from '@backstage/plugin-notifications-backend-module-email'; +import { Notification } from '@backstage/plugin-notifications-common'; ++import { getNotificationSubject, getNotificationTextContent, getNotificationHtmlContent } from 'my-notification-processing-library` +export const notificationsModuleEmailDecorator = createBackendModule({ + pluginId: 'notifications', + moduleId: 'email.templates', + register(reg) { + reg.registerInit({ + deps: { + emailTemplates: notificationsEmailTemplateExtensionPoint, + }, + async init({ emailTemplates }) { + emailTemplates.setTemplateRenderer({ +- getSubject(notification) { ++ async getSubject(notification) { +- return `New notification from ${notification.source}`; ++ const subject = await getNotificationSubject(notification); ++ return `New notification from ${subject}`; + }, +- getText(notification) { ++ async getText(notification) { +- return notification.content; ++ const text = await getNotificationTextContent(notification); ++ return text; + }, +- getHtml(notification) { ++ async getHtml(notification) { +- return `<p>${notification.content}</p>`; ++ const html = await getNotificationHtmlContent(notification); ++ return html; + }, + }); + }, + }); + }, +}); +``` diff --git a/plugins/notifications-backend-module-email/api-report.md b/plugins/notifications-backend-module-email/api-report.md index 7e8eac6cb7..b105f15cba 100644 --- a/plugins/notifications-backend-module-email/api-report.md +++ b/plugins/notifications-backend-module-email/api-report.md @@ -23,10 +23,10 @@ export default notificationsModuleEmail; // @public (undocumented) export interface NotificationTemplateRenderer { // (undocumented) - getHtml?(notification: Notification_2): string; + getHtml?(notification: Notification_2): Promise<string>; // (undocumented) - getSubject?(notification: Notification_2): string; + getSubject?(notification: Notification_2): Promise<string>; // (undocumented) - getText?(notification: Notification_2): string; + getText?(notification: Notification_2): Promise<string>; } ``` diff --git a/plugins/notifications-backend-module-email/src/extensions.ts b/plugins/notifications-backend-module-email/src/extensions.ts index 454fe9b384..49795eadcf 100644 --- a/plugins/notifications-backend-module-email/src/extensions.ts +++ b/plugins/notifications-backend-module-email/src/extensions.ts @@ -20,9 +20,9 @@ import { Notification } from '@backstage/plugin-notifications-common'; * @public */ export interface NotificationTemplateRenderer { - getSubject?(notification: Notification): string; - getText?(notification: Notification): string; - getHtml?(notification: Notification): string; + getSubject?(notification: Notification): Promise<string>; + getText?(notification: Notification): Promise<string>; + getHtml?(notification: Notification): Promise<string>; } /** diff --git a/plugins/notifications-backend-module-email/src/processor/NotificationsEmailProcessor.ts b/plugins/notifications-backend-module-email/src/processor/NotificationsEmailProcessor.ts index 8689afc065..3bfccfcc90 100644 --- a/plugins/notifications-backend-module-email/src/processor/NotificationsEmailProcessor.ts +++ b/plugins/notifications-backend-module-email/src/processor/NotificationsEmailProcessor.ts @@ -280,10 +280,10 @@ export class NotificationsEmailProcessor implements NotificationProcessor { const mailOptions = { from: this.sender, subject: - this.templateRenderer?.getSubject?.(notification) ?? + (await this.templateRenderer?.getSubject?.(notification)) ?? notification.payload.title, - html: this.templateRenderer?.getHtml?.(notification), - text: this.templateRenderer?.getText?.(notification), + html: await this.templateRenderer?.getHtml?.(notification), + text: await this.templateRenderer?.getText?.(notification), replyTo: this.replyTo, }; From e3b64bebf2487925c8745be60f9cbdcbe6f23cc2 Mon Sep 17 00:00:00 2001 From: parmar-abhinav <abhinav.parmar@infosys.com> Date: Wed, 24 Jul 2024 15:05:39 +0530 Subject: [PATCH 412/510] Added examples for publish:bitbucketServer action and improve its test cases Signed-off-by: parmar-abhinav <abhinav.parmar@infosys.com> --- .changeset/orange-gifts-protect.md | 5 + .../actions/bitbucketServer.examples.test.ts | 1117 ++++++++++++++++- .../src/actions/bitbucketServer.examples.ts | 203 +++ 3 files changed, 1320 insertions(+), 5 deletions(-) create mode 100644 .changeset/orange-gifts-protect.md diff --git a/.changeset/orange-gifts-protect.md b/.changeset/orange-gifts-protect.md new file mode 100644 index 0000000000..1de9e2a6ba --- /dev/null +++ b/.changeset/orange-gifts-protect.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-bitbucket-server': patch +--- + +Added examples for publish:bitbucketServer action and improve its test cases diff --git a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.examples.test.ts b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.examples.test.ts index 101379d1e6..8e222a6876 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.examples.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.examples.test.ts @@ -34,7 +34,10 @@ import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import yaml from 'yaml'; import { examples } from './bitbucketServer.examples'; -import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; +import { + getRepoSourceDirectory, + initRepoAndPush, +} from '@backstage/plugin-scaffolder-node'; import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; describe('publish:bitbucketServer', () => { @@ -266,7 +269,8 @@ describe('publish:bitbucketServer', () => { it(`should ${examples[3].description}`, async () => { expect.assertions(3); - server.use( + + const handlers = [ rest.post( 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos', (req, res, ctx) => { @@ -300,7 +304,35 @@ describe('publish:bitbucketServer', () => { ); }, ), - ); + rest.put( + 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer thing'); + expect(req.body).toEqual(''); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + ]; + + server.use(...handlers); await action.handler({ ...mockContext, @@ -334,7 +366,8 @@ describe('publish:bitbucketServer', () => { it(`should ${examples[4].description}`, async () => { expect.assertions(3); - server.use( + + const handlers = [ rest.post( 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos', (req, res, ctx) => { @@ -368,7 +401,35 @@ describe('publish:bitbucketServer', () => { ); }, ), - ); + rest.put( + 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer thing'); + expect(req.body).toEqual(''); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + ]; + + server.use(...handlers); await action.handler({ ...mockContext, @@ -399,4 +460,1050 @@ describe('publish:bitbucketServer', () => { gitAuthorInfo: { name: 'Test User', email: 'test.user@example.com' }, }); }); + it(`should ${examples[5].description}`, async () => { + expect.assertions(3); + + const handlers = [ + rest.post( + 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe(`Bearer thing`); + expect(req.body).toEqual({ + public: false, + name: 'repo', + defaultBranch: 'master', + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + rest.put( + 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer thing'); + expect(req.body).toEqual(''); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + ]; + + server.use(...handlers); + + let input; + try { + input = yaml.parse(examples[5].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + // Ensure that the initRepoAndPush function was called with the correct remoteUrl and input properties + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + remoteUrl: 'https://bitbucket.mycompany.com/scm/project/repo', + defaultBranch: 'master', + auth: { token: 'thing' }, + logger: mockContext.logger, + commitMessage: 'initial commit', + gitAuthorInfo: { + name: 'Custom Author', + email: 'custom.author@example.com', + }, + }); + }); + + it(`should ${examples[6].description}`, async () => { + expect.assertions(5); + + const handlers = [ + rest.post( + 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer thing'); + expect(req.body).toEqual({ + public: false, + name: 'repo', + defaultBranch: 'master', + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + { + href: 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + rest.put( + 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer thing'); + expect(req.body).toEqual(''); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + ]; + + server.use(...handlers); + + let input; + try { + input = yaml.parse(examples[6].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + remoteUrl: 'https://bitbucket.mycompany.com/scm/project/repo', + defaultBranch: 'master', + auth: { token: 'thing' }, + logger: mockContext.logger, + commitMessage: 'Initial commit with LFS enabled', + gitAuthorInfo: { + email: input.gitAuthorName, + name: input.gitAuthorEmail, + }, + }); + }); + + it(`should ${examples[7].description}`, async () => { + expect.assertions(3); + + const handlers = [ + rest.post( + 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer custom-token'); + expect(req.body).toEqual({ + public: false, + name: 'repo', + defaultBranch: 'master', + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + { + href: 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + rest.put( + 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer thing'); + expect(req.body).toEqual(''); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + ]; + + server.use(...handlers); + + let input; + try { + input = yaml.parse(examples[7].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: getRepoSourceDirectory(mockContext.workspacePath, input.sourcePath), + remoteUrl: 'https://bitbucket.mycompany.com/scm/project/repo', + auth: { token: 'custom-token' }, + defaultBranch: 'master', + logger: mockContext.logger, + commitMessage: 'initial commit', + gitAuthorInfo: { name: undefined, email: undefined }, + }); + }); + + it(`should ${examples[8].description}`, async () => { + expect.assertions(3); + + const handlers = [ + rest.post( + 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer thing'); + expect(req.body).toEqual({ + public: false, + name: 'repo', + defaultBranch: 'master', + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + { + href: 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + rest.put( + 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer thing'); + expect(req.body).toEqual(''); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + ]; + + server.use(...handlers); + + let input; + try { + input = yaml.parse(examples[8].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + remoteUrl: 'https://bitbucket.mycompany.com/scm/project/repo', + auth: { token: 'thing' }, + defaultBranch: 'master', + logger: mockContext.logger, + commitMessage: 'initial commit', + gitAuthorInfo: { name: input.gitAuthorName, email: input.gitAuthorEmail }, + }); + }); + + it(`should ${examples[9].description}`, async () => { + expect.assertions(3); + + const handlers = [ + rest.post( + 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer thing'); + expect(req.body).toEqual({ + public: true, + name: 'repo', + defaultBranch: 'master', + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + { + href: 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + rest.put( + 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer thing'); + expect(req.body).toEqual(''); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + ]; + + server.use(...handlers); + + let input; + try { + input = yaml.parse(examples[9].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + remoteUrl: 'https://bitbucket.mycompany.com/scm/project/repo', + auth: { token: 'thing' }, + defaultBranch: 'master', + logger: mockContext.logger, + commitMessage: 'Public repository initial commit', + gitAuthorInfo: { name: input.gitAuthorName, email: input.gitAuthorEmail }, + }); + }); + + it(`should ${examples[10].description}`, async () => { + expect.assertions(5); + + const handlers = [ + rest.post( + 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer custom-token'); + expect(req.body).toEqual({ + public: false, + name: 'repo', + description: 'A fully customized repository', + defaultBranch: 'development', + }); + + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + { + href: 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + rest.put( + 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer custom-token'); + expect(req.body).toEqual(''); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + ]; + + server.use(...handlers); + + let input; + try { + input = yaml.parse(examples[10].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: getRepoSourceDirectory(mockContext.workspacePath, input.sourcePath), + remoteUrl: 'https://bitbucket.mycompany.com/scm/project/repo', + auth: { token: input.token }, + defaultBranch: input.defaultBranch, + logger: mockContext.logger, + commitMessage: input.gitCommitMessage, + gitAuthorInfo: { name: input.gitAuthorName, email: input.gitAuthorEmail }, + }); + }); + + it(`should ${examples[11].description}`, async () => { + expect.assertions(3); + + const handlers = [ + rest.post( + 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer thing'); + expect(req.body).toEqual({ + public: false, + name: 'repo', + defaultBranch: 'main', + }); + + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + { + href: 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + rest.put( + 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer custom-token'); + expect(req.body).toEqual(''); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + ]; + + server.use(...handlers); + + let input; + try { + input = yaml.parse(examples[11].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: input.sourcePath + ? getRepoSourceDirectory(mockContext.workspacePath, input.sourcePath) + : mockContext.workspacePath, + remoteUrl: 'https://bitbucket.mycompany.com/scm/project/repo', + auth: { token: input.token ?? 'thing' }, + defaultBranch: input.defaultBranch, + logger: mockContext.logger, + commitMessage: input.gitCommitMessage ?? 'initial commit', + gitAuthorInfo: { name: input.gitAuthorName, email: input.gitAuthorEmail }, + }); + }); + + it(`should ${examples[12].description}`, async () => { + expect.assertions(3); + + const handlers = [ + rest.post( + 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer thing'); + expect(req.body).toEqual({ + public: true, + name: 'repo', + defaultBranch: 'master', + description: 'A public repository with a custom description', + }); + + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + { + href: 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + rest.put( + 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer custom-token'); + expect(req.body).toEqual(''); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + ]; + + server.use(...handlers); + + let input; + try { + input = yaml.parse(examples[12].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: input.sourcePath + ? getRepoSourceDirectory(mockContext.workspacePath, input.sourcePath) + : mockContext.workspacePath, + remoteUrl: 'https://bitbucket.mycompany.com/scm/project/repo', + auth: { token: input.token ?? 'thing' }, + defaultBranch: input.defaultBranch ?? 'master', + logger: mockContext.logger, + commitMessage: input.gitCommitMessage ?? 'initial commit', + gitAuthorInfo: { name: input.gitAuthorName, email: input.gitAuthorEmail }, + }); + }); + + it(`should ${examples[13].description}`, async () => { + expect.assertions(3); + + const handlers = [ + rest.post( + 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe( + 'Bearer custom-auth-token', + ); + expect(req.body).toEqual({ + public: false, + name: 'repo', + defaultBranch: 'master', + }); + + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + { + href: 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + rest.put( + 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer custom-token'); + expect(req.body).toEqual(''); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + ]; + + server.use(...handlers); + + let input; + try { + input = yaml.parse(examples[13].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: input.sourcePath + ? getRepoSourceDirectory(mockContext.workspacePath, input.sourcePath) + : mockContext.workspacePath, + remoteUrl: 'https://bitbucket.mycompany.com/scm/project/repo', + auth: { token: input.token ?? 'thing' }, + defaultBranch: input.defaultBranch ?? 'master', + logger: mockContext.logger, + commitMessage: input.gitCommitMessage ?? 'initial commit', + gitAuthorInfo: { name: input.gitAuthorName, email: input.gitAuthorEmail }, + }); + }); + + it(`should ${examples[14].description}`, async () => { + expect.assertions(3); + + const handlers = [ + rest.post( + 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer thing'); + expect(req.body).toEqual({ + public: false, + name: 'repo', + defaultBranch: 'master', + }); + + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + { + href: 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + rest.put( + 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer custom-token'); + expect(req.body).toEqual(''); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + ]; + + server.use(...handlers); + + let input; + try { + input = yaml.parse(examples[14].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: input.sourcePath + ? getRepoSourceDirectory(mockContext.workspacePath, input.sourcePath) + : mockContext.workspacePath, + remoteUrl: 'https://bitbucket.mycompany.com/scm/project/repo', + auth: { token: input.token ?? 'thing' }, + defaultBranch: input.defaultBranch ?? 'master', + logger: mockContext.logger, + commitMessage: input.gitCommitMessage ?? 'initial commit', + gitAuthorInfo: { name: input.gitAuthorName, email: input.gitAuthorEmail }, + }); + }); + + it(`should ${examples[15].description}`, async () => { + expect.assertions(5); + + const handlers = [ + rest.post( + 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer thing'); + expect(req.body).toEqual({ + public: false, + name: 'repo', + defaultBranch: 'master', + }); + + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + { + href: 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + rest.put( + 'https://hosted.bitbucket.com/rest/git-lfs/admin/projects/project/repos/repo/enabled', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer thing'); + expect(req.body).toEqual(''); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + ]; + + server.use(...handlers); + + let input; + try { + input = yaml.parse(examples[15].example).steps[0].input; + } catch (error) { + console.error('Failed to parse YAML:', error); + } + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...input, + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: input.sourcePath + ? getRepoSourceDirectory(mockContext.workspacePath, input.sourcePath) + : mockContext.workspacePath, + remoteUrl: 'https://bitbucket.mycompany.com/scm/project/repo', + auth: { token: input.token ?? 'thing' }, + defaultBranch: input.defaultBranch ?? 'master', + logger: mockContext.logger, + commitMessage: input.gitCommitMessage ?? 'initial commit', + gitAuthorInfo: { name: input.gitAuthorName, email: input.gitAuthorEmail }, + }); + }); }); diff --git a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.examples.ts b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.examples.ts index b3a68eed57..e28f9ca48c 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.examples.ts +++ b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.examples.ts @@ -129,4 +129,207 @@ export const examples: TemplateExample[] = [ ], }), }, + { + description: + 'Initialize git repository with default settings and custom author information', + example: yaml.stringify({ + steps: [ + { + action: 'publish:bitbucketServer', + id: 'publish-bitbucket-server-custom-author', + name: 'Publish To Bitbucket Server', + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + gitAuthorName: 'Custom Author', + gitAuthorEmail: 'custom.author@example.com', + }, + }, + ], + }), + }, + { + description: + 'Initialize git repository with LFS enabled and a specific commit message', + example: yaml.stringify({ + steps: [ + { + action: 'publish:bitbucketServer', + id: 'publish-bitbucket-server-lfs-commit', + name: 'Publish To Bitbucket Server', + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + enableLFS: true, + gitCommitMessage: 'Initial commit with LFS enabled', + }, + }, + ], + }), + }, + { + description: + 'Initialize git repository with a custom source path and token', + example: yaml.stringify({ + steps: [ + { + action: 'publish:bitbucketServer', + id: 'publish-bitbucket-server-custom-source', + name: 'Publish To Bitbucket Server', + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + sourcePath: 'custom/source/path', + token: 'custom-token', + }, + }, + ], + }), + }, + { + description: + 'Initialize git repository with private visibility and custom author details', + example: yaml.stringify({ + steps: [ + { + action: 'publish:bitbucketServer', + id: 'publish-bitbucket-server-private-custom-author', + name: 'Publish To Bitbucket Server', + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + repoVisibility: 'private', + gitAuthorName: 'Private Author', + gitAuthorEmail: 'private.author@example.com', + }, + }, + ], + }), + }, + { + description: + 'Initialize git repository with public visibility and specific commit message', + example: yaml.stringify({ + steps: [ + { + action: 'publish:bitbucketServer', + id: 'publish-bitbucket-server-public-commit', + name: 'Publish To Bitbucket Server', + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + repoVisibility: 'public', + gitCommitMessage: 'Public repository initial commit', + }, + }, + ], + }), + }, + { + description: 'Initialize git repository with all settings customized', + example: yaml.stringify({ + steps: [ + { + action: 'publish:bitbucketServer', + id: 'publish-bitbucket-server-all-custom', + name: 'Publish To Bitbucket Server', + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + description: 'A fully customized repository', + repoVisibility: 'private', + defaultBranch: 'development', + sourcePath: 'src/backend', + enableLFS: true, + token: 'custom-token', + gitCommitMessage: 'Fully customized initial commit', + gitAuthorName: 'Custom Dev', + gitAuthorEmail: 'custom.dev@example.com', + }, + }, + ], + }), + }, + { + description: + 'Initialize git repository with a specific default branch and no LFS', + example: yaml.stringify({ + steps: [ + { + action: 'publish:bitbucketServer', + id: 'publish-bitbucket-server-no-lfs', + name: 'Publish To Bitbucket Server', + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + defaultBranch: 'main', + enableLFS: false, + }, + }, + ], + }), + }, + { + description: + 'Initialize git repository with a custom repository description and public visibility', + example: yaml.stringify({ + steps: [ + { + action: 'publish:bitbucketServer', + id: 'publish-bitbucket-server-custom-description', + name: 'Publish To Bitbucket Server', + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + description: 'A public repository with a custom description', + repoVisibility: 'public', + }, + }, + ], + }), + }, + { + description: + 'Initialize git repository with a custom token for authentication', + example: yaml.stringify({ + steps: [ + { + action: 'publish:bitbucketServer', + id: 'publish-bitbucket-server-custom-token', + name: 'Publish To Bitbucket Server', + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + token: 'custom-auth-token', + }, + }, + ], + }), + }, + { + description: + 'Initialize git repository with a different repository root path', + example: yaml.stringify({ + steps: [ + { + action: 'publish:bitbucketServer', + id: 'publish-bitbucket-server-different-root', + name: 'Publish To Bitbucket Server', + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + sourcePath: 'different/root/path', + }, + }, + ], + }), + }, + { + description: + 'Initialize git repository with private visibility and LFS enabled', + example: yaml.stringify({ + steps: [ + { + action: 'publish:bitbucketServer', + id: 'publish-bitbucket-server-private-lfs', + name: 'Publish To Bitbucket Server', + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + repoVisibility: 'private', + enableLFS: true, + }, + }, + ], + }), + }, ]; From 7ca331cc2b07c4ee221c689493025f3c5881b975 Mon Sep 17 00:00:00 2001 From: Thomas Cardonne <thomas.cardonne@adevinta.com> Date: Wed, 24 Jul 2024 11:45:51 +0200 Subject: [PATCH 413/510] feat(catalog-react): correct alignment of EntityDisplayName's icon Signed-off-by: Thomas Cardonne <thomas.cardonne@adevinta.com> --- .changeset/few-wasps-hug.md | 5 +++++ .../src/components/EntityDisplayName/EntityDisplayName.tsx | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 .changeset/few-wasps-hug.md diff --git a/.changeset/few-wasps-hug.md b/.changeset/few-wasps-hug.md new file mode 100644 index 0000000000..66cf34fc0b --- /dev/null +++ b/.changeset/few-wasps-hug.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Correct `EntityDisplayName`'s icon alignment with the text. diff --git a/plugins/catalog-react/src/components/EntityDisplayName/EntityDisplayName.tsx b/plugins/catalog-react/src/components/EntityDisplayName/EntityDisplayName.tsx index e953f21afb..68d5ecefdb 100644 --- a/plugins/catalog-react/src/components/EntityDisplayName/EntityDisplayName.tsx +++ b/plugins/catalog-react/src/components/EntityDisplayName/EntityDisplayName.tsx @@ -38,7 +38,9 @@ const useStyles = makeStyles( icon: { marginRight: theme.spacing(0.5), color: theme.palette.text.secondary, - lineHeight: 0, + '& svg': { + verticalAlign: 'middle', + }, }, }), { name: 'CatalogReactEntityDisplayName' }, From 21b66b184dc88f744c69ead1744f4b4d5de4ff0a Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Tue, 23 Jul 2024 12:37:43 +0200 Subject: [PATCH 414/510] chore: initial experiments Signed-off-by: blam <ben@blam.sh> wip Signed-off-by: blam <ben@blam.sh> wip2 Signed-off-by: blam <ben@blam.sh> wip3 Signed-off-by: blam <ben@blam.sh> wip3 Signed-off-by: blam <ben@blam.sh> --- packages/frontend-plugin-api/api-report.md | 41 ++++++--- .../src/extensions/IconBundleBlueprint.ts | 36 ++++++++ .../src/wiring/createExtension.ts | 18 +++- .../src/wiring/createExtensionBlueprint.ts | 92 ++++++++++++++----- .../src/app/createExtensionTester.tsx | 4 +- plugins/catalog-graph/api-report-alpha.md | 72 +++++++++++++++ plugins/catalog-graph/src/alpha.tsx | 79 ++++++++++++---- plugins/catalog-react/api-report-alpha.md | 56 +++++++++-- plugins/catalog-react/src/alpha.tsx | 51 ++++++++++ plugins/catalog/api-report-alpha.md | 35 ++++++- plugins/catalog/src/alpha/index.ts | 2 + plugins/search-react/api-report-alpha.md | 3 +- plugins/search/api-report-alpha.md | 26 ++++-- plugins/techdocs/api-report-alpha.md | 18 ++-- plugins/user-settings/api-report-alpha.md | 10 +- 15 files changed, 456 insertions(+), 87 deletions(-) diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index d6a91c0c99..0c7c3b1d92 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -89,6 +89,7 @@ import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; import { vmwareCloudAuthApiRef } from '@backstage/core-plugin-api'; import { withApis } from '@backstage/core-plugin-api'; import { z } from 'zod'; +import { ZodObject } from 'zod'; import { ZodSchema } from 'zod'; import { ZodTypeDef } from 'zod'; @@ -391,7 +392,7 @@ export function createApiExtension< configSchema?: PortableSchema<TConfig>; inputs?: TInputs; }, -): ExtensionDefinition<TConfig>; +): ExtensionDefinition<TConfig, ZodObject<any, any, any, any, any>>; // @public (undocumented) export namespace createApiExtension { @@ -487,7 +488,7 @@ export function createComponentExtension< inputs: Expand<ResolvedExtensionInputs<TInputs>>; }) => ComponentType<TProps>; }; -}): ExtensionDefinition<TConfig>; +}): ExtensionDefinition<TConfig, ZodObject<any, any, any, any, any>>; // @public (undocumented) export namespace createComponentExtension { @@ -511,10 +512,11 @@ export function createComponentRef<T extends {} = {}>(options: { export function createExtension< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, - TConfig = never, + TConfigSchema extends z.ZodObject<any, any, any, any, any>, + TConfig extends z.infer<TConfigSchema>, >( - options: CreateExtensionOptions<TOutput, TInputs, TConfig>, -): ExtensionDefinition<TConfig>; + options: CreateExtensionOptions<TOutput, TInputs, TConfigSchema, TConfig>, +): ExtensionDefinition<TConfig, TConfigSchema>; // @public export function createExtensionBlueprint< @@ -605,7 +607,8 @@ export function createExtensionInput< export interface CreateExtensionOptions< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, - TConfig, + TConfigSchema extends z.ZodObject<any, any, any, any, any>, + TConfig extends z.infer<TConfigSchema>, > { // (undocumented) attachTo: { @@ -613,6 +616,10 @@ export interface CreateExtensionOptions< input: string; }; // (undocumented) + config?: { + schema: (context: { z: typeof z }) => TConfigSchema; + }; + // @deprecated (undocumented) configSchema?: PortableSchema<TConfig>; // (undocumented) disabled?: boolean; @@ -672,9 +679,12 @@ export function createNavItemExtension(options: { routeRef: RouteRef<undefined>; title: string; icon: IconComponent_2; -}): ExtensionDefinition<{ - title: string; -}>; +}): ExtensionDefinition< + { + title: string; + }, + ZodObject<any, any, any, any, any> +>; // @public (undocumented) export namespace createNavItemExtension { @@ -696,7 +706,7 @@ export function createNavLogoExtension(options: { namespace?: string; logoIcon: JSX.Element; logoFull: JSX.Element; -}): ExtensionDefinition<never>; +}): ExtensionDefinition<any, ZodObject<any, any, any, any, any>>; // @public (undocumented) export namespace createNavLogoExtension { @@ -851,7 +861,7 @@ export function createSubRouteRef< // @public (undocumented) export function createThemeExtension( theme: AppTheme, -): ExtensionDefinition<never>; +): ExtensionDefinition<any, ZodObject<any, any, any, any, any>>; // @public (undocumented) export namespace createThemeExtension { @@ -867,7 +877,7 @@ export namespace createThemeExtension { export function createTranslationExtension(options: { name?: string; resource: TranslationResource | TranslationMessages; -}): ExtensionDefinition<never>; +}): ExtensionDefinition<any, ZodObject<any, any, any, any, any>>; // @public (undocumented) export namespace createTranslationExtension { @@ -1011,7 +1021,10 @@ export type ExtensionDataValues<TExtensionData extends AnyExtensionDataMap> = { }; // @public (undocumented) -export interface ExtensionDefinition<TConfig> { +export interface ExtensionDefinition< + TConfig, + TConfigSchema extends z.ZodObject<any, any, any, any, any> = any, +> { // (undocumented) $$type: '@backstage/ExtensionDefinition'; // (undocumented) @@ -1022,6 +1035,8 @@ export interface ExtensionDefinition<TConfig> { // (undocumented) readonly configSchema?: PortableSchema<TConfig>; // (undocumented) + readonly configSchema2?: TConfigSchema; + // (undocumented) readonly disabled: boolean; // (undocumented) readonly kind?: string; diff --git a/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts b/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts index 2ad1404102..aba3303f2f 100644 --- a/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts +++ b/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts @@ -33,3 +33,39 @@ export const IconBundleBlueprint = createExtensionBlueprint({ icons: iconsDataRef, }, }); + +IconBundleBlueprint.make({ + name: 'asd', + params: { + icons: { + 'icon-name': () => null, + }, + }, +}); + +IconBundleBlueprint.make({ + name: 'asd', + params: { + icons: { + 'icon-name': () => null, + }, + }, +}); + +IconBundleBlueprint.make({ + name: 'asd', + factory() { + return { + icons: { + 'icon-name': () => null, + }, + }; + }, +}); + +IconBundleBlueprint.make({ + name: 'asd', + factory(f) { + return f({ icons: { 'icon-name': () => null } }); + }, +}); diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index e87f3a638e..3733e44957 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -19,7 +19,7 @@ import { PortableSchema } from '../schema'; import { Expand } from '../types'; import { ExtensionDataRef } from './createExtensionDataRef'; import { ExtensionInput } from './createExtensionInput'; - +import { z } from 'zod'; /** @public */ export type AnyExtensionDataMap = { [name in string]: ExtensionDataRef<unknown, string, { optional?: true }>; @@ -82,6 +82,7 @@ export interface CreateExtensionOptions< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, TConfig, + TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodTypeAny }, > { kind?: string; namespace?: string; @@ -90,7 +91,11 @@ export interface CreateExtensionOptions< disabled?: boolean; inputs?: TInputs; output: TOutput; + /** @deprecated - use `config.schema` instead */ configSchema?: PortableSchema<TConfig>; + config?: { + schema: TConfigSchema; + }; factory(context: { node: AppNode; config: TConfig; @@ -99,7 +104,7 @@ export interface CreateExtensionOptions< } /** @public */ -export interface ExtensionDefinition<TConfig> { +export interface ExtensionDefinition<TConfig, TConfigSchema = {}> { $$type: '@backstage/ExtensionDefinition'; readonly kind?: string; readonly namespace?: string; @@ -107,6 +112,9 @@ export interface ExtensionDefinition<TConfig> { readonly attachTo: { id: string; input: string }; readonly disabled: boolean; readonly configSchema?: PortableSchema<TConfig>; + readonly config?: { + schema: TConfigSchema; + }; } /** @internal */ @@ -144,9 +152,10 @@ export function toInternalExtensionDefinition<TConfig>( export function createExtension< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, - TConfig = never, + TConfig, + TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodTypeAny }, >( - options: CreateExtensionOptions<TOutput, TInputs, TConfig>, + options: CreateExtensionOptions<TOutput, TInputs, TConfig, TConfigSchema>, ): ExtensionDefinition<TConfig> { return { $$type: '@backstage/ExtensionDefinition', @@ -159,6 +168,7 @@ export function createExtension< inputs: options.inputs ?? {}, output: options.output, configSchema: options.configSchema, + config: options.config, factory({ inputs, ...rest }) { // TODO: Simplify this, but TS wouldn't infer the input type for some reason return options.factory({ diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts index fb9081f7f8..61227c7dc1 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts @@ -15,7 +15,6 @@ */ import { AppNode } from '../apis'; -import { PortableSchema } from '../schema'; import { Expand } from '../types'; import { AnyExtensionDataMap, @@ -25,6 +24,7 @@ import { ResolvedExtensionInputs, createExtension, } from './createExtension'; +import { z } from 'zod'; /** * @public @@ -33,7 +33,7 @@ export interface CreateExtensionBlueprintOptions< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfig, + TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodTypeAny }, TDataRefs extends AnyExtensionDataMap, > { kind: string; @@ -42,12 +42,16 @@ export interface CreateExtensionBlueprintOptions< disabled?: boolean; inputs?: TInputs; output: TOutput; - configSchema?: PortableSchema<TConfig>; + config?: { + schema: TConfigSchema; + }; factory( params: TParams, context: { node: AppNode; - config: TConfig; + config: { + [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; + }; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, ): Expand<ExtensionDataValues<TOutput>>; @@ -62,7 +66,7 @@ export interface ExtensionBlueprint< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfig, + TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodTypeAny }, TDataRefs extends AnyExtensionDataMap, > { dataRefs: TDataRefs; @@ -73,7 +77,11 @@ export interface ExtensionBlueprint< * You must either pass `params` directly, or define a `factory` that can * optionally call the original factory with the same params. */ - make( + make< + TExtensionConfigSchema extends { + [key: string]: (zImpl: typeof z) => z.ZodTypeAny; + }, + >( args: { namespace?: string; name?: string; @@ -81,20 +89,30 @@ export interface ExtensionBlueprint< disabled?: boolean; inputs?: TInputs; output?: TOutput; - configSchema?: PortableSchema<TConfig>; + config?: { + schema: TExtensionConfigSchema; + }; } & ( | { factory( originalFactory: ( params: TParams, context?: { - config?: TConfig; + config?: { + [key in keyof TConfigSchema]: z.infer< + ReturnType<TConfigSchema[key]> + >; + }; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, ) => Expand<ExtensionDataValues<TOutput>>, context: { node: AppNode; - config: TConfig; + config: { + [key in keyof TExtensionConfigSchema]: z.infer< + ReturnType<TExtensionConfigSchema[key]> + >; + }; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, ): Expand<ExtensionDataValues<TOutput>>; @@ -103,7 +121,14 @@ export interface ExtensionBlueprint< params: TParams; } ), - ): ExtensionDefinition<TConfig>; + ): ExtensionDefinition< + { + [key in keyof TExtensionConfigSchema]: z.infer< + ReturnType<TExtensionConfigSchema[key]> + >; + }, + TExtensionConfigSchema + >; } /** @@ -113,7 +138,7 @@ class ExtensionBlueprintImpl< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfig, + TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodTypeAny }, TDataRefs extends AnyExtensionDataMap, > { constructor( @@ -121,7 +146,7 @@ class ExtensionBlueprintImpl< TParams, TInputs, TOutput, - TConfig, + TConfigSchema, TDataRefs >, ) { @@ -130,30 +155,49 @@ class ExtensionBlueprintImpl< dataRefs: TDataRefs; - public make(args: { + public make< + TExtensionConfigSchema extends TConfigSchema = TConfigSchema, + >(args: { namespace?: string; name?: string; attachTo?: { id: string; input: string }; disabled?: boolean; inputs?: TInputs; output?: TOutput; - configSchema?: PortableSchema<TConfig>; params?: TParams; + config?: { + schema: TConfigSchema; + }; factory?( originalFactory: ( params: TParams, context?: { - config?: TConfig; + config?: { + [key in keyof TConfigSchema]: z.infer< + ReturnType<TConfigSchema[key]> + >; + }; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, ) => Expand<ExtensionDataValues<TOutput>>, context: { node: AppNode; - config: TConfig; + config: { + [key in keyof TExtensionConfigSchema]: z.infer< + ReturnType<TExtensionConfigSchema[key]> + >; + }; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, ): Expand<ExtensionDataValues<TOutput>>; - }): ExtensionDefinition<TConfig> { + }): ExtensionDefinition< + { + [key in keyof TExtensionConfigSchema]: z.infer< + ReturnType<TExtensionConfigSchema[key]> + >; + }, + TExtensionConfigSchema + > { return createExtension({ kind: this.options.kind, namespace: args.namespace ?? this.options.namespace, @@ -162,14 +206,18 @@ class ExtensionBlueprintImpl< disabled: args.disabled ?? this.options.disabled, inputs: args.inputs ?? this.options.inputs, output: args.output ?? this.options.output, - configSchema: args.configSchema ?? this.options.configSchema, // TODO: some config merging or smth + config: args.config, factory: ({ node, config, inputs }) => { if (args.factory) { return args.factory( ( innerParams: TParams, innerContext?: { - config?: TConfig; + config?: { + [key in keyof TConfigSchema]: z.infer< + ReturnType<TConfigSchema[key]> + >; + }; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, ) => @@ -207,16 +255,16 @@ export function createExtensionBlueprint< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfig, + TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodTypeAny }, TDataRefs extends AnyExtensionDataMap = never, >( options: CreateExtensionBlueprintOptions< TParams, TInputs, TOutput, - TConfig, + TConfigSchema, TDataRefs >, -): ExtensionBlueprint<TParams, TInputs, TOutput, TConfig, TDataRefs> { +): ExtensionBlueprint<TParams, TInputs, TOutput, TConfigSchema, TDataRefs> { return new ExtensionBlueprintImpl(options); } diff --git a/packages/frontend-test-utils/src/app/createExtensionTester.tsx b/packages/frontend-test-utils/src/app/createExtensionTester.tsx index a98879fbba..d6be346002 100644 --- a/packages/frontend-test-utils/src/app/createExtensionTester.tsx +++ b/packages/frontend-test-utils/src/app/createExtensionTester.tsx @@ -102,11 +102,11 @@ export class ExtensionTester { ...output, path: coreExtensionData.routePath, }, - factory: params => ({ + factory: (params: any) => ({ ...factory(params), path: '/', }), - }); + } as any); tester.add(extension, options); return tester; } diff --git a/plugins/catalog-graph/api-report-alpha.md b/plugins/catalog-graph/api-report-alpha.md index 3895f12fcf..afd03965ae 100644 --- a/plugins/catalog-graph/api-report-alpha.md +++ b/plugins/catalog-graph/api-report-alpha.md @@ -4,8 +4,76 @@ ```ts import { BackstagePlugin } from '@backstage/frontend-plugin-api'; +import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { ExternalRouteRef } from '@backstage/frontend-plugin-api'; +import { objectUtil } from 'zod'; import { RouteRef } from '@backstage/frontend-plugin-api'; +import { ZodArray } from 'zod'; +import { ZodBoolean } from 'zod'; +import { ZodEnum } from 'zod'; +import { ZodNativeEnum } from 'zod'; +import { ZodNumber } from 'zod'; +import { ZodOptional } from 'zod'; +import { ZodString } from 'zod'; +import { ZodTuple } from 'zod'; + +// Warning: (ae-missing-release-tag) "CatalogGraphEntityCard" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const CatalogGraphEntityCard: ExtensionDefinition< + { + filter?: string | undefined; + height?: number | undefined; + curve?: 'curveStepBefore' | 'curveMonotoneX' | undefined; + direction?: Direction | undefined; + title?: string | undefined; + zoom?: 'disabled' | 'enabled' | 'enable-on-click' | undefined; + relations?: string[] | undefined; + maxDepth?: number | undefined; + kinds?: string[] | undefined; + unidirectional?: boolean | undefined; + mergeRelations?: boolean | undefined; + relationPairs?: [string, string][] | undefined; + }, + objectUtil.extendShape< + objectUtil.extendShape< + { + filter: ZodOptional<ZodString>; + }, + { + title: ZodOptional<ZodString>; + height: ZodOptional<ZodNumber>; + } + >, + { + kinds: ZodOptional<ZodArray<ZodString, 'many'>>; + relations: ZodOptional<ZodArray<ZodString, 'many'>>; + maxDepth: ZodOptional<ZodNumber>; + unidirectional: ZodOptional<ZodBoolean>; + mergeRelations: ZodOptional<ZodBoolean>; + direction: ZodOptional<ZodNativeEnum<typeof Direction>>; + relationPairs: ZodOptional< + ZodArray<ZodTuple<[ZodString, ZodString], null>, 'many'> + >; + zoom: ZodOptional<ZodEnum<['enabled', 'disabled', 'enable-on-click']>>; + curve: ZodOptional<ZodEnum<['curveStepBefore', 'curveMonotoneX']>>; + } + >, + { + filter?: string | undefined; + height?: number | undefined; + curve?: 'curveStepBefore' | 'curveMonotoneX' | undefined; + direction?: Direction | undefined; + title?: string | undefined; + zoom?: 'disabled' | 'enabled' | 'enable-on-click' | undefined; + relations?: string[] | undefined; + maxDepth?: number | undefined; + kinds?: string[] | undefined; + unidirectional?: boolean | undefined; + mergeRelations?: boolean | undefined; + relationPairs?: [string, string][] | undefined; + } +>; // @public (undocumented) const _default: BackstagePlugin< @@ -25,5 +93,9 @@ const _default: BackstagePlugin< >; export default _default; +// Warnings were encountered during analysis: +// +// src/alpha.d.ts:6:5 - (ae-forgotten-export) The symbol "Direction" needs to be exported by the entry point alpha.d.ts + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/catalog-graph/src/alpha.tsx b/plugins/catalog-graph/src/alpha.tsx index 6d8429332e..cf663406fa 100644 --- a/plugins/catalog-graph/src/alpha.tsx +++ b/plugins/catalog-graph/src/alpha.tsx @@ -24,7 +24,7 @@ import { compatWrapper, convertLegacyRouteRef, } from '@backstage/core-compat-api'; -import { createEntityCardExtension } from '@backstage/plugin-catalog-react/alpha'; +import { EntityCardBlueprint } from '@backstage/plugin-catalog-react/alpha'; import { catalogGraphRouteRef, catalogEntityRouteRef } from './routes'; import { Direction } from './components'; @@ -46,24 +46,67 @@ function getEntityGraphRelationsConfigSchema( }); } -const CatalogGraphEntityCard = createEntityCardExtension({ +export const CatalogGraphEntityCard = EntityCardBlueprint.make({ name: 'relations', - configSchema: createSchemaFromZod(z => - z - .object({ - // Filter is a config required to all entity cards - filter: z.string().optional(), - title: z.string().optional(), - height: z.number().optional(), - // Skipping a "variant" config for now, defaulting to "gridItem" in the component - // For more details, see this comment: https://github.com/backstage/backstage/pull/22619#discussion_r1477333252 - }) - .merge(getEntityGraphRelationsConfigSchema(z)), - ), - loader: async ({ config: { filter, ...props } }) => - import('./components/CatalogGraphCard').then(m => - compatWrapper(<m.CatalogGraphCard {...props} />), - ), + // configSchema: origSchema => + // createSchemaFromZod(z => + // z + // .object({ + // // Filter is a config required to all entity cards + // // filter: z.string().optional(), + // title: z.string().optional(), + // height: z.number().optional(), + // // Skipping a "variant" config for now, defaulting to "gridItem" in the component + // // For more details, see this comment: https://github.com/backstage/backstage/pull/22619#discussion_r1477333252 + // }) + // .merge(getEntityGraphRelationsConfigSchema(z)) + // .merge(origSchema), + // ), + + // config: { + // schema: ({ z, parent }) => + // parent + // .merge({ + // title: z.string().optional(), + // height: z.number().optional(), + // }) + // .merge(getEntityGraphRelationsConfigSchema(z)), + // }, + + // config: { + // schema: ({ z, parent }) => + // parent + // .extend({ + // title: z.string().optional(), + // height: z.number().optional(), + // }) + // .merge(getEntityGraphRelationsConfigSchema(z)), + // // .merge(parent) + // }, + + // TODO: implement this and check the types. 👋 zod types. + config: { + schema: { + title: z => z.string().optional(), + height: z => z.number().optional(), + }, + }, + + // config: { + // schema: z => ({ + // title: z.string().optional(), + // height: z.number().optional(), + // }), + // }, + + factory(origFactory, { config: { filter: _, ...props } }) { + return origFactory({ + loader: async () => + import('./components/CatalogGraphCard').then(m => + compatWrapper(<m.CatalogGraphCard {...props} />), + ), + }); + }, }); const CatalogGraphPage = createPageExtension({ diff --git a/plugins/catalog-react/api-report-alpha.md b/plugins/catalog-react/api-report-alpha.md index d2bfb29458..ccf8205f59 100644 --- a/plugins/catalog-react/api-report-alpha.md +++ b/plugins/catalog-react/api-report-alpha.md @@ -3,17 +3,20 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -/// <reference types="react" /> - import { AnyExtensionInputMap } from '@backstage/frontend-plugin-api'; import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { Entity } from '@backstage/catalog-model'; +import { ExtensionBlueprint } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { PortableSchema } from '@backstage/frontend-plugin-api'; +import { default as React_2 } from 'react'; import { ResolvedExtensionInputs } from '@backstage/frontend-plugin-api'; import { ResourcePermission } from '@backstage/plugin-permission-common'; import { RouteRef } from '@backstage/frontend-plugin-api'; import { TranslationRef } from '@backstage/core-plugin-api/alpha'; +import { ZodOptional } from 'zod'; +import { ZodRawShape } from 'zod'; +import { ZodString } from 'zod'; // @alpha (undocumented) export const catalogExtensionData: { @@ -115,7 +118,7 @@ export function createEntityCardExtension< config: TConfig; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }) => Promise<JSX.Element>; -}): ExtensionDefinition<TConfig>; +}): ExtensionDefinition<TConfig, ZodRawShape>; // @alpha (undocumented) export function createEntityContentExtension< @@ -138,11 +141,48 @@ export function createEntityContentExtension< loader: (options: { inputs: Expand<ResolvedExtensionInputs<TInputs>>; }) => Promise<JSX.Element>; -}): ExtensionDefinition<{ - title: string; - path: string; - filter?: string | undefined; -}>; +}): ExtensionDefinition< + { + title: string; + path: string; + filter?: string | undefined; + }, + ZodRawShape +>; + +// @alpha (undocumented) +export const EntityCardBlueprint: ExtensionBlueprint< + { + filter?: string | ((entity: Entity) => boolean) | undefined; + loader: () => Promise<JSX.Element>; + }, + AnyExtensionInputMap, + { + element: ConfigurableExtensionDataRef< + 'core.reactElement', + React_2.JSX.Element, + {} + >; + filterFunction: ConfigurableExtensionDataRef< + 'catalog.entity-filter-function', + (entity: Entity) => boolean, + ((entity: Entity) => boolean) & { + optional: true; + } + >; + filterExpression: ConfigurableExtensionDataRef< + 'catalog.entity-filter-expression', + string, + string & { + optional: true; + } + >; + }, + { + filter: ZodOptional<ZodString>; + }, + never +>; // @alpha export function isOwnerOf(owner: Entity, entity: Entity): boolean; diff --git a/plugins/catalog-react/src/alpha.tsx b/plugins/catalog-react/src/alpha.tsx index e81b8e5ebf..f397c76ce0 100644 --- a/plugins/catalog-react/src/alpha.tsx +++ b/plugins/catalog-react/src/alpha.tsx @@ -22,6 +22,7 @@ import { RouteRef, coreExtensionData, createExtension, + createExtensionBlueprint, createExtensionDataRef, createSchemaFromZod, } from '@backstage/frontend-plugin-api'; @@ -47,6 +48,49 @@ export const catalogExtensionData = { }), }; +/** @alpha */ +export const EntityCardBlueprint = createExtensionBlueprint({ + kind: 'entity-card', + attachTo: { id: 'entity-content:catalog/overview', input: 'cards' }, + // configSchema: createSchemaFromZod(z => + // z.object({ + // filter: z.string().optional(), + // }), + // ), + config: { + schema: { + filter: z => z.string().optional(), + }, + }, + output: { + element: coreExtensionData.reactElement, + filterFunction: catalogExtensionData.entityFilterFunction.optional(), + filterExpression: catalogExtensionData.entityFilterExpression.optional(), + }, + factory( + params: { + filter?: + | typeof catalogExtensionData.entityFilterFunction.T + | typeof catalogExtensionData.entityFilterExpression.T; + loader: () => Promise<JSX.Element>; + }, + { node, config }, + ) { + const ExtensionComponent = lazy(() => + params.loader().then(element => ({ default: () => element })), + ); + + return { + element: ( + <ExtensionBoundary node={node}> + <ExtensionComponent /> + </ExtensionBoundary> + ), + ...mergeFilters({ config, options: params }), + }; + }, +}); + // TODO: Figure out how to merge with provided config schema /** @alpha */ export function createEntityCardExtension< @@ -154,6 +198,13 @@ export function createEntityContentExtension< filter: z.string().optional(), }), ), + // config: { + // schema: ({ z }) => ({ + // path: z.string().default(options.defaultPath), + // title: z.string().default(options.defaultTitle), + // filter: z.string().optional(), + // }), + // }, factory({ config, inputs, node }) { const ExtensionComponent = lazy(() => options diff --git a/plugins/catalog/api-report-alpha.md b/plugins/catalog/api-report-alpha.md index 102e2a7aa3..03711b7d3d 100644 --- a/plugins/catalog/api-report-alpha.md +++ b/plugins/catalog/api-report-alpha.md @@ -12,6 +12,39 @@ import { ExternalRouteRef } from '@backstage/frontend-plugin-api'; import { PortableSchema } from '@backstage/frontend-plugin-api'; import { RouteRef } from '@backstage/frontend-plugin-api'; import { TranslationRef } from '@backstage/core-plugin-api/alpha'; +import { ZodObject } from 'zod'; + +// Warning: (ae-missing-release-tag) "catalogAboutEntityCard" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const catalogAboutEntityCard: ExtensionDefinition< + { + filter?: string | undefined; + }, + ZodObject<any, any, any, any, any> +>; + +// Warning: (ae-missing-release-tag) "catalogLinksEntityCard" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const catalogLinksEntityCard: ExtensionDefinition< + { + filter?: string | undefined; + }, + ZodObject<any, any, any, any, any> +>; + +// Warning: (ae-missing-release-tag) "catalogOverviewEntityContent" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const catalogOverviewEntityContent: ExtensionDefinition< + { + title: string; + path: string; + filter?: string | undefined; + }, + ZodObject<any, any, any, any, any> +>; // @alpha (undocumented) export const catalogTranslationRef: TranslationRef< @@ -106,7 +139,7 @@ export function createCatalogFilterExtension< inputs?: TInputs; configSchema?: PortableSchema<TConfig>; loader: (options: { config: TConfig }) => Promise<JSX.Element>; -}): ExtensionDefinition<TConfig>; +}): ExtensionDefinition<TConfig, ZodObject<any, any, any, any, any>>; // @alpha (undocumented) const _default: BackstagePlugin< diff --git a/plugins/catalog/src/alpha/index.ts b/plugins/catalog/src/alpha/index.ts index 06a78ec6ea..acf61865ba 100644 --- a/plugins/catalog/src/alpha/index.ts +++ b/plugins/catalog/src/alpha/index.ts @@ -16,3 +16,5 @@ export { default } from './plugin'; export { createCatalogFilterExtension } from './createCatalogFilterExtension'; +export { catalogAboutEntityCard, catalogLinksEntityCard } from './entityCards'; +export { catalogOverviewEntityContent } from './entityContents'; diff --git a/plugins/search-react/api-report-alpha.md b/plugins/search-react/api-report-alpha.md index aea85d0f81..6160759042 100644 --- a/plugins/search-react/api-report-alpha.md +++ b/plugins/search-react/api-report-alpha.md @@ -11,6 +11,7 @@ import { ListItemProps } from '@material-ui/core/ListItem'; import { PortableSchema } from '@backstage/frontend-plugin-api'; import { SearchDocument } from '@backstage/plugin-search-common'; import { SearchResult } from '@backstage/plugin-search-common'; +import { ZodObject } from 'zod'; // @alpha (undocumented) export type BaseSearchResultListItemProps<T = {}> = T & { @@ -25,7 +26,7 @@ export function createSearchResultListItemExtension< }, >( options: SearchResultItemExtensionOptions<TConfig>, -): ExtensionDefinition<TConfig>; +): ExtensionDefinition<TConfig, ZodObject<any, any, any, any, any>>; // @alpha (undocumented) export namespace createSearchResultListItemExtension { diff --git a/plugins/search/api-report-alpha.md b/plugins/search/api-report-alpha.md index db2999ba25..ade5f530ef 100644 --- a/plugins/search/api-report-alpha.md +++ b/plugins/search/api-report-alpha.md @@ -6,6 +6,7 @@ import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { RouteRef } from '@backstage/frontend-plugin-api'; +import { ZodObject } from 'zod'; // @alpha (undocumented) const _default: BackstagePlugin< @@ -17,18 +18,27 @@ const _default: BackstagePlugin< export default _default; // @alpha (undocumented) -export const searchApi: ExtensionDefinition<{}>; +export const searchApi: ExtensionDefinition< + {}, + ZodObject<any, any, any, any, any> +>; // @alpha (undocumented) -export const searchNavItem: ExtensionDefinition<{ - title: string; -}>; +export const searchNavItem: ExtensionDefinition< + { + title: string; + }, + ZodObject<any, any, any, any, any> +>; // @alpha (undocumented) -export const searchPage: ExtensionDefinition<{ - path: string; - noTrack: boolean; -}>; +export const searchPage: ExtensionDefinition< + { + path: string; + noTrack: boolean; + }, + any +>; // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/techdocs/api-report-alpha.md b/plugins/techdocs/api-report-alpha.md index cf9f5fa9a3..fc57370a53 100644 --- a/plugins/techdocs/api-report-alpha.md +++ b/plugins/techdocs/api-report-alpha.md @@ -6,6 +6,7 @@ import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { RouteRef } from '@backstage/frontend-plugin-api'; +import { ZodObject } from 'zod'; // @alpha (undocumented) const _default: BackstagePlugin< @@ -23,13 +24,16 @@ const _default: BackstagePlugin< export default _default; // @alpha (undocumented) -export const techDocsSearchResultListItemExtension: ExtensionDefinition<{ - lineClamp: number; - noTrack: boolean; - asListItem: boolean; - asLink: boolean; - title?: string | undefined; -}>; +export const techDocsSearchResultListItemExtension: ExtensionDefinition< + { + lineClamp: number; + noTrack: boolean; + asListItem: boolean; + asLink: boolean; + title?: string | undefined; + }, + ZodObject<any, any, any, any, any> +>; // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/user-settings/api-report-alpha.md b/plugins/user-settings/api-report-alpha.md index b06fd1e583..db4373fd43 100644 --- a/plugins/user-settings/api-report-alpha.md +++ b/plugins/user-settings/api-report-alpha.md @@ -7,6 +7,7 @@ import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { RouteRef } from '@backstage/frontend-plugin-api'; import { TranslationRef } from '@backstage/core-plugin-api/alpha'; +import { ZodObject } from 'zod'; // @alpha (undocumented) const _default: BackstagePlugin< @@ -18,9 +19,12 @@ const _default: BackstagePlugin< export default _default; // @alpha (undocumented) -export const settingsNavItem: ExtensionDefinition<{ - title: string; -}>; +export const settingsNavItem: ExtensionDefinition< + { + title: string; + }, + ZodObject<any, any, any, any, any> +>; // @alpha (undocumented) export const userSettingsTranslationRef: TranslationRef< From 8e387301a4f27c17aa631005a8ec6634f495965b Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Wed, 24 Jul 2024 10:56:12 +0200 Subject: [PATCH 415/510] chore: moving things around Signed-off-by: blam <ben@blam.sh> --- .../src/wiring/createExtension.ts | 13 +- .../src/wiring/createExtensionBlueprint.ts | 125 +++++++++++------- 2 files changed, 84 insertions(+), 54 deletions(-) diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index 3733e44957..61223ca8e8 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -82,7 +82,7 @@ export interface CreateExtensionOptions< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, TConfig, - TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodTypeAny }, + TConfigSchema extends { [key: string]: z.ZodTypeAny }, > { kind?: string; namespace?: string; @@ -94,7 +94,9 @@ export interface CreateExtensionOptions< /** @deprecated - use `config.schema` instead */ configSchema?: PortableSchema<TConfig>; config?: { - schema: TConfigSchema; + schema: { + [key in keyof TConfigSchema]: (zImpl: typeof z) => TConfigSchema[key]; + }; }; factory(context: { node: AppNode; @@ -104,7 +106,10 @@ export interface CreateExtensionOptions< } /** @public */ -export interface ExtensionDefinition<TConfig, TConfigSchema = {}> { +export interface ExtensionDefinition< + TConfig, + TConfigSchema = never /* TODO -> refactor */, +> { $$type: '@backstage/ExtensionDefinition'; readonly kind?: string; readonly namespace?: string; @@ -153,7 +158,7 @@ export function createExtension< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, TConfig, - TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodTypeAny }, + TConfigSchema extends { [key: string]: z.ZodTypeAny }, >( options: CreateExtensionOptions<TOutput, TInputs, TConfig, TConfigSchema>, ): ExtensionDefinition<TConfig> { diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts index 61227c7dc1..9cd5689a95 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts @@ -33,7 +33,7 @@ export interface CreateExtensionBlueprintOptions< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodTypeAny }, + TConfigSchema extends { [key: string]: z.ZodTypeAny }, TDataRefs extends AnyExtensionDataMap, > { kind: string; @@ -43,15 +43,17 @@ export interface CreateExtensionBlueprintOptions< inputs?: TInputs; output: TOutput; config?: { - schema: TConfigSchema; + schema: { + [key in keyof TConfigSchema]: (zImpl: typeof z) => TConfigSchema[key]; + }; }; factory( params: TParams, context: { node: AppNode; - config: { - [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; - }; + config: Expand<{ + [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + }>; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, ): Expand<ExtensionDataValues<TOutput>>; @@ -66,7 +68,7 @@ export interface ExtensionBlueprint< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodTypeAny }, + TConfigSchema extends { [key: string]: z.ZodTypeAny }, TDataRefs extends AnyExtensionDataMap, > { dataRefs: TDataRefs; @@ -77,11 +79,7 @@ export interface ExtensionBlueprint< * You must either pass `params` directly, or define a `factory` that can * optionally call the original factory with the same params. */ - make< - TExtensionConfigSchema extends { - [key: string]: (zImpl: typeof z) => z.ZodTypeAny; - }, - >( + make<TExtensionConfigSchema extends { [key: string]: z.ZodTypeAny }>( args: { namespace?: string; name?: string; @@ -90,7 +88,11 @@ export interface ExtensionBlueprint< inputs?: TInputs; output?: TOutput; config?: { - schema: TExtensionConfigSchema; + schema: { + [key in keyof TExtensionConfigSchema]: ( + zImpl: typeof z, + ) => TExtensionConfigSchema[key]; + }; }; } & ( | { @@ -98,21 +100,23 @@ export interface ExtensionBlueprint< originalFactory: ( params: TParams, context?: { - config?: { - [key in keyof TConfigSchema]: z.infer< - ReturnType<TConfigSchema[key]> - >; - }; + config?: Expand<{ + [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + }>; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, ) => Expand<ExtensionDataValues<TOutput>>, context: { node: AppNode; - config: { - [key in keyof TExtensionConfigSchema]: z.infer< - ReturnType<TExtensionConfigSchema[key]> - >; - }; + config: Expand< + { + [key in keyof TExtensionConfigSchema]: z.infer< + TExtensionConfigSchema[key] + >; + } & { + [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + } + >; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, ): Expand<ExtensionDataValues<TOutput>>; @@ -124,7 +128,7 @@ export interface ExtensionBlueprint< ): ExtensionDefinition< { [key in keyof TExtensionConfigSchema]: z.infer< - ReturnType<TExtensionConfigSchema[key]> + TExtensionConfigSchema[key] >; }, TExtensionConfigSchema @@ -138,7 +142,7 @@ class ExtensionBlueprintImpl< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodTypeAny }, + TConfigSchema extends { [key: string]: z.ZodTypeAny }, TDataRefs extends AnyExtensionDataMap, > { constructor( @@ -156,7 +160,7 @@ class ExtensionBlueprintImpl< dataRefs: TDataRefs; public make< - TExtensionConfigSchema extends TConfigSchema = TConfigSchema, + TExtensionConfigSchema extends { [key: string]: z.ZodTypeAny }, >(args: { namespace?: string; name?: string; @@ -166,37 +170,45 @@ class ExtensionBlueprintImpl< output?: TOutput; params?: TParams; config?: { - schema: TConfigSchema; + schema: { + [key in keyof TConfigSchema]: (zImpl: typeof z) => TConfigSchema[key]; + }; }; factory?( originalFactory: ( params: TParams, context?: { - config?: { - [key in keyof TConfigSchema]: z.infer< - ReturnType<TConfigSchema[key]> - >; - }; + config?: Expand<{ + [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + }>; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, ) => Expand<ExtensionDataValues<TOutput>>, context: { node: AppNode; - config: { - [key in keyof TExtensionConfigSchema]: z.infer< - ReturnType<TExtensionConfigSchema[key]> - >; - }; + config: Expand< + { + [key in keyof TExtensionConfigSchema]: z.infer< + TExtensionConfigSchema[key] + >; + } & { + [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + } + >; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, ): Expand<ExtensionDataValues<TOutput>>; }): ExtensionDefinition< - { - [key in keyof TExtensionConfigSchema]: z.infer< - ReturnType<TExtensionConfigSchema[key]> - >; - }, - TExtensionConfigSchema + Expand< + { + [key in keyof TExtensionConfigSchema]: z.infer< + TExtensionConfigSchema[key] + >; + } & { + [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + } + >, + Expand<TConfigSchema & TExtensionConfigSchema> > { return createExtension({ kind: this.options.kind, @@ -206,18 +218,31 @@ class ExtensionBlueprintImpl< disabled: args.disabled ?? this.options.disabled, inputs: args.inputs ?? this.options.inputs, output: args.output ?? this.options.output, - config: args.config, + config: { + schema: { + ...this.options.config?.schema, + ...args.config, + } as Expand< + { + [key in keyof TConfigSchema]: ( + zImpl: typeof z, + ) => TConfigSchema[key]; + } & { + [key in keyof TExtensionConfigSchema]: ( + zImpl: typeof z, + ) => TExtensionConfigSchema[key]; + } + >, + }, factory: ({ node, config, inputs }) => { if (args.factory) { return args.factory( ( innerParams: TParams, innerContext?: { - config?: { - [key in keyof TConfigSchema]: z.infer< - ReturnType<TConfigSchema[key]> - >; - }; + config?: Expand<{ + [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + }>; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, ) => @@ -255,7 +280,7 @@ export function createExtensionBlueprint< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodTypeAny }, + TConfigSchema extends { [key: string]: z.ZodTypeAny }, TDataRefs extends AnyExtensionDataMap = never, >( options: CreateExtensionBlueprintOptions< @@ -266,5 +291,5 @@ export function createExtensionBlueprint< TDataRefs >, ): ExtensionBlueprint<TParams, TInputs, TOutput, TConfigSchema, TDataRefs> { - return new ExtensionBlueprintImpl(options); + return new ExtensionBlueprintImpl(options) as any; } From d22f1316c50da7ea5d767fd23d9c6acf9be9ba07 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Wed, 24 Jul 2024 11:25:11 +0200 Subject: [PATCH 416/510] chore: getting somewhere with portable schemas and zod types Signed-off-by: blam <ben@blam.sh> --- .../src/wiring/createExtension.ts | 25 ++-- .../src/wiring/createExtensionBlueprint.ts | 120 ++++++++---------- plugins/catalog-graph/api-report-alpha.md | 67 +--------- 3 files changed, 75 insertions(+), 137 deletions(-) diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index 61223ca8e8..6fa3a50634 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -15,7 +15,7 @@ */ import { AppNode } from '../apis'; -import { PortableSchema } from '../schema'; +import { PortableSchema, createSchemaFromZod } from '../schema'; import { Expand } from '../types'; import { ExtensionDataRef } from './createExtensionDataRef'; import { ExtensionInput } from './createExtensionInput'; @@ -106,10 +106,7 @@ export interface CreateExtensionOptions< } /** @public */ -export interface ExtensionDefinition< - TConfig, - TConfigSchema = never /* TODO -> refactor */, -> { +export interface ExtensionDefinition<TConfig> { $$type: '@backstage/ExtensionDefinition'; readonly kind?: string; readonly namespace?: string; @@ -117,9 +114,6 @@ export interface ExtensionDefinition< readonly attachTo: { id: string; input: string }; readonly disabled: boolean; readonly configSchema?: PortableSchema<TConfig>; - readonly config?: { - schema: TConfigSchema; - }; } /** @internal */ @@ -162,6 +156,18 @@ export function createExtension< >( options: CreateExtensionOptions<TOutput, TInputs, TConfig, TConfigSchema>, ): ExtensionDefinition<TConfig> { + // TODO: resovle configSchema from either configSchema or config.schema + const newConfigSchema = options.config?.schema; + const configSchema = newConfigSchema + ? createSchemaFromZod(innerZ => + innerZ.object( + Object.fromEntries( + Object.entries(newConfigSchema).map(([k, v]) => [k, v(innerZ)]), + ), + ), + ) + : options.configSchema; + return { $$type: '@backstage/ExtensionDefinition', version: 'v1', @@ -172,8 +178,7 @@ export function createExtension< disabled: options.disabled ?? false, inputs: options.inputs ?? {}, output: options.output, - configSchema: options.configSchema, - config: options.config, + configSchema, factory({ inputs, ...rest }) { // TODO: Simplify this, but TS wouldn't infer the input type for some reason return options.factory({ diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts index 9cd5689a95..c54131622f 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts @@ -33,7 +33,7 @@ export interface CreateExtensionBlueprintOptions< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfigSchema extends { [key: string]: z.ZodTypeAny }, + TConfigSchema extends { [key in string]: z.ZodTypeAny }, TDataRefs extends AnyExtensionDataMap, > { kind: string; @@ -51,9 +51,9 @@ export interface CreateExtensionBlueprintOptions< params: TParams, context: { node: AppNode; - config: Expand<{ + config: { [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; - }>; + }; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, ): Expand<ExtensionDataValues<TOutput>>; @@ -68,7 +68,7 @@ export interface ExtensionBlueprint< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfigSchema extends { [key: string]: z.ZodTypeAny }, + TConfig extends { [key in string]: unknown }, TDataRefs extends AnyExtensionDataMap, > { dataRefs: TDataRefs; @@ -79,7 +79,7 @@ export interface ExtensionBlueprint< * You must either pass `params` directly, or define a `factory` that can * optionally call the original factory with the same params. */ - make<TExtensionConfigSchema extends { [key: string]: z.ZodTypeAny }>( + make<TExtensionConfigSchema extends { [key in string]: z.ZodTypeAny }>( args: { namespace?: string; name?: string; @@ -100,23 +100,17 @@ export interface ExtensionBlueprint< originalFactory: ( params: TParams, context?: { - config?: Expand<{ - [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; - }>; + config?: TConfig; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, ) => Expand<ExtensionDataValues<TOutput>>, context: { node: AppNode; - config: Expand< - { - [key in keyof TExtensionConfigSchema]: z.infer< - TExtensionConfigSchema[key] - >; - } & { - [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; - } - >; + config: { + [key in keyof TExtensionConfigSchema]: z.infer< + TExtensionConfigSchema[key] + >; + } & TConfig; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, ): Expand<ExtensionDataValues<TOutput>>; @@ -130,8 +124,7 @@ export interface ExtensionBlueprint< [key in keyof TExtensionConfigSchema]: z.infer< TExtensionConfigSchema[key] >; - }, - TExtensionConfigSchema + } & TConfig >; } @@ -142,7 +135,7 @@ class ExtensionBlueprintImpl< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfigSchema extends { [key: string]: z.ZodTypeAny }, + TConfigSchema extends { [key in string]: z.ZodTypeAny }, TDataRefs extends AnyExtensionDataMap, > { constructor( @@ -160,7 +153,7 @@ class ExtensionBlueprintImpl< dataRefs: TDataRefs; public make< - TExtensionConfigSchema extends { [key: string]: z.ZodTypeAny }, + TExtensionConfigSchema extends { [key in string]: z.ZodTypeAny }, >(args: { namespace?: string; name?: string; @@ -171,45 +164,53 @@ class ExtensionBlueprintImpl< params?: TParams; config?: { schema: { - [key in keyof TConfigSchema]: (zImpl: typeof z) => TConfigSchema[key]; + [key in keyof TExtensionConfigSchema]: ( + zImpl: typeof z, + ) => TExtensionConfigSchema[key]; }; }; factory?( originalFactory: ( params: TParams, context?: { - config?: Expand<{ + config?: { [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; - }>; + }; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, ) => Expand<ExtensionDataValues<TOutput>>, context: { node: AppNode; - config: Expand< - { - [key in keyof TExtensionConfigSchema]: z.infer< - TExtensionConfigSchema[key] - >; - } & { - [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; - } - >; + config: { + [key in keyof TExtensionConfigSchema]: z.infer< + TExtensionConfigSchema[key] + >; + } & { + [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + }; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, ): Expand<ExtensionDataValues<TOutput>>; }): ExtensionDefinition< - Expand< - { - [key in keyof TExtensionConfigSchema]: z.infer< - TExtensionConfigSchema[key] - >; - } & { - [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; - } - >, - Expand<TConfigSchema & TExtensionConfigSchema> + { + [key in keyof TExtensionConfigSchema]: z.infer< + TExtensionConfigSchema[key] + >; + } & { + [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + } > { + const schema = { + ...this.options.config?.schema, + ...args.config, + } as { + [key in keyof TConfigSchema]: (zImpl: typeof z) => TConfigSchema[key]; + } & { + [key in keyof TExtensionConfigSchema]: ( + zImpl: typeof z, + ) => TExtensionConfigSchema[key]; + }; + return createExtension({ kind: this.options.kind, namespace: args.namespace ?? this.options.namespace, @@ -218,31 +219,16 @@ class ExtensionBlueprintImpl< disabled: args.disabled ?? this.options.disabled, inputs: args.inputs ?? this.options.inputs, output: args.output ?? this.options.output, - config: { - schema: { - ...this.options.config?.schema, - ...args.config, - } as Expand< - { - [key in keyof TConfigSchema]: ( - zImpl: typeof z, - ) => TConfigSchema[key]; - } & { - [key in keyof TExtensionConfigSchema]: ( - zImpl: typeof z, - ) => TExtensionConfigSchema[key]; - } - >, - }, + config: Object.keys(schema).length === 0 ? undefined : { schema }, factory: ({ node, config, inputs }) => { if (args.factory) { return args.factory( ( innerParams: TParams, innerContext?: { - config?: Expand<{ + config?: { [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; - }>; + }; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, ) => @@ -280,7 +266,7 @@ export function createExtensionBlueprint< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfigSchema extends { [key: string]: z.ZodTypeAny }, + TConfigSchema extends { [key in string]: z.ZodTypeAny }, TDataRefs extends AnyExtensionDataMap = never, >( options: CreateExtensionBlueprintOptions< @@ -290,6 +276,12 @@ export function createExtensionBlueprint< TConfigSchema, TDataRefs >, -): ExtensionBlueprint<TParams, TInputs, TOutput, TConfigSchema, TDataRefs> { - return new ExtensionBlueprintImpl(options) as any; +): ExtensionBlueprint< + TParams, + TInputs, + TOutput, + { [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]> }, + TDataRefs +> { + return new ExtensionBlueprintImpl(options); } diff --git a/plugins/catalog-graph/api-report-alpha.md b/plugins/catalog-graph/api-report-alpha.md index afd03965ae..59a387adf0 100644 --- a/plugins/catalog-graph/api-report-alpha.md +++ b/plugins/catalog-graph/api-report-alpha.md @@ -6,72 +6,17 @@ import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { ExternalRouteRef } from '@backstage/frontend-plugin-api'; -import { objectUtil } from 'zod'; import { RouteRef } from '@backstage/frontend-plugin-api'; -import { ZodArray } from 'zod'; -import { ZodBoolean } from 'zod'; -import { ZodEnum } from 'zod'; -import { ZodNativeEnum } from 'zod'; -import { ZodNumber } from 'zod'; -import { ZodOptional } from 'zod'; -import { ZodString } from 'zod'; -import { ZodTuple } from 'zod'; // Warning: (ae-missing-release-tag) "CatalogGraphEntityCard" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const CatalogGraphEntityCard: ExtensionDefinition< { - filter?: string | undefined; - height?: number | undefined; - curve?: 'curveStepBefore' | 'curveMonotoneX' | undefined; - direction?: Direction | undefined; - title?: string | undefined; - zoom?: 'disabled' | 'enabled' | 'enable-on-click' | undefined; - relations?: string[] | undefined; - maxDepth?: number | undefined; - kinds?: string[] | undefined; - unidirectional?: boolean | undefined; - mergeRelations?: boolean | undefined; - relationPairs?: [string, string][] | undefined; - }, - objectUtil.extendShape< - objectUtil.extendShape< - { - filter: ZodOptional<ZodString>; - }, - { - title: ZodOptional<ZodString>; - height: ZodOptional<ZodNumber>; - } - >, - { - kinds: ZodOptional<ZodArray<ZodString, 'many'>>; - relations: ZodOptional<ZodArray<ZodString, 'many'>>; - maxDepth: ZodOptional<ZodNumber>; - unidirectional: ZodOptional<ZodBoolean>; - mergeRelations: ZodOptional<ZodBoolean>; - direction: ZodOptional<ZodNativeEnum<typeof Direction>>; - relationPairs: ZodOptional< - ZodArray<ZodTuple<[ZodString, ZodString], null>, 'many'> - >; - zoom: ZodOptional<ZodEnum<['enabled', 'disabled', 'enable-on-click']>>; - curve: ZodOptional<ZodEnum<['curveStepBefore', 'curveMonotoneX']>>; - } - >, - { - filter?: string | undefined; - height?: number | undefined; - curve?: 'curveStepBefore' | 'curveMonotoneX' | undefined; - direction?: Direction | undefined; - title?: string | undefined; - zoom?: 'disabled' | 'enabled' | 'enable-on-click' | undefined; - relations?: string[] | undefined; - maxDepth?: number | undefined; - kinds?: string[] | undefined; - unidirectional?: boolean | undefined; - mergeRelations?: boolean | undefined; - relationPairs?: [string, string][] | undefined; + title: string | undefined; + height: number | undefined; + } & { + filter: string | undefined; } >; @@ -93,9 +38,5 @@ const _default: BackstagePlugin< >; export default _default; -// Warnings were encountered during analysis: -// -// src/alpha.d.ts:6:5 - (ae-forgotten-export) The symbol "Direction" needs to be exported by the entry point alpha.d.ts - // (No @packageDocumentation comment for this package) ``` From cac9c3f851221bebef7ae9a3a0b6cc3b816eb9a3 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Wed, 24 Jul 2024 11:48:07 +0200 Subject: [PATCH 417/510] chore: added some tests Signed-off-by: blam <ben@blam.sh> --- .../src/schema/createSchemaFromZod.ts | 5 +- .../src/wiring/createExtension.test.ts | 62 ++++++++++++++++++ .../src/wiring/createExtension.ts | 17 +++-- .../wiring/createExtensionBlueprint.test.tsx | 65 +++++++++++++++++++ .../src/wiring/createExtensionBlueprint.ts | 12 ++-- 5 files changed, 149 insertions(+), 12 deletions(-) diff --git a/packages/frontend-plugin-api/src/schema/createSchemaFromZod.ts b/packages/frontend-plugin-api/src/schema/createSchemaFromZod.ts index bfaf57f522..c69ef5dc60 100644 --- a/packages/frontend-plugin-api/src/schema/createSchemaFromZod.ts +++ b/packages/frontend-plugin-api/src/schema/createSchemaFromZod.ts @@ -19,7 +19,10 @@ import { z, ZodSchema, ZodTypeDef } from 'zod'; import zodToJsonSchema from 'zod-to-json-schema'; import { PortableSchema } from './types'; -/** @public */ +/** + * @public + * @deprecated Use the `config.schema` option of `createExtension` instead, or use `createExtensionBlueprint`. + */ export function createSchemaFromZod<TOutput, TInput>( schemaCreator: (zImpl: typeof z) => ZodSchema<TOutput, ZodTypeDef, TInput>, ): PortableSchema<TOutput> { diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts index 4323737540..468da21eb7 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts @@ -291,4 +291,66 @@ describe('createExtension', () => { 'ExtensionDefinition{namespace=test,attachTo=root@default}', ); }); + + it('should create an extension with config', () => { + const extension = createExtension({ + namespace: 'test', + attachTo: { id: 'root', input: 'default' }, + config: { + schema: { + foo: z => z.string(), + bar: z => z.string().default('bar'), + baz: z => z.string().optional(), + }, + }, + output: { + foo: stringData, + }, + factory({ config }) { + const a1: string = config.foo; + const a2: string = config.bar; + // @ts-expect-error + const a3: string = config.baz; + // @ts-expect-error + const c1: number = config.foo; + // @ts-expect-error + const c2: number = config.bar; + // @ts-expect-error + const c3: number = config.baz; + unused(a1, a2, a3, c1, c2, c3); + + return { + foo: 'bar', + }; + }, + }); + expect(extension.namespace).toBe('test'); + expect(String(extension)).toBe( + 'ExtensionDefinition{namespace=test,attachTo=root@default}', + ); + + expect( + extension.configSchema?.parse({ + foo: 'x', + bar: 'y', + baz: 'z', + qux: 'w', + }), + ).toEqual({ + foo: 'x', + bar: 'y', + baz: 'z', + }); + expect( + extension.configSchema?.parse({ + foo: 'x', + }), + ).toEqual({ + foo: 'x', + bar: 'bar', + }); + expect(() => extension.configSchema?.parse({})).toThrow( + "Missing required value at 'foo'", + ); + }); }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index 6fa3a50634..7783f8e14d 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -82,7 +82,7 @@ export interface CreateExtensionOptions< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, TConfig, - TConfigSchema extends { [key: string]: z.ZodTypeAny }, + TConfigSchema extends { [key: string]: z.ZodType }, > { kind?: string; namespace?: string; @@ -100,7 +100,9 @@ export interface CreateExtensionOptions< }; factory(context: { node: AppNode; - config: TConfig; + config: TConfig & { + [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + }; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }): Expand<ExtensionDataValues<TOutput>>; } @@ -152,12 +154,14 @@ export function createExtension< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, TConfig, - TConfigSchema extends { [key: string]: z.ZodTypeAny }, + TConfigSchema extends { [key: string]: z.ZodType }, >( options: CreateExtensionOptions<TOutput, TInputs, TConfig, TConfigSchema>, ): ExtensionDefinition<TConfig> { - // TODO: resovle configSchema from either configSchema or config.schema const newConfigSchema = options.config?.schema; + if (newConfigSchema && options.configSchema) { + throw new Error(`Cannot provide both configSchema and config.schema`); + } const configSchema = newConfigSchema ? createSchemaFromZod(innerZ => innerZ.object( @@ -179,10 +183,13 @@ export function createExtension< inputs: options.inputs ?? {}, output: options.output, configSchema, - factory({ inputs, ...rest }) { + factory({ inputs, config, ...rest }) { // TODO: Simplify this, but TS wouldn't infer the input type for some reason return options.factory({ inputs: inputs as Expand<ResolvedExtensionInputs<TInputs>>, + config: config as TConfig & { + [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + }, ...rest, }); }, diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx index d2373518a3..cf7de0fed3 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx @@ -20,6 +20,8 @@ import { createExtensionBlueprint } from './createExtensionBlueprint'; import { createExtensionTester } from '@backstage/frontend-test-utils'; import { createExtensionDataRef } from './createExtensionDataRef'; +function unused(..._any: any[]) {} + describe('createExtensionBlueprint', () => { it('should allow creation of extension blueprints', () => { const TestExtensionBlueprint = createExtensionBlueprint({ @@ -124,4 +126,67 @@ describe('createExtensionBlueprint', () => { data: dataRef, }); }); + + it('should allow defining a config schema with additional properties in the instance', () => { + const TestExtensionBlueprint = createExtensionBlueprint({ + kind: 'test-extension', + attachTo: { id: 'test', input: 'default' }, + output: { + element: coreExtensionData.reactElement, + }, + config: { + schema: { + text: z => z.string(), + }, + }, + factory(_, { config }) { + // @ts-expect-error + const b = config.something; + + const a: string = config.text; + unused(a); + + expect(config.text).toBe('Hello, world!'); + + return { + element: <h1>{config.text}</h1>, + }; + }, + }); + + const extension = TestExtensionBlueprint.make({ + name: 'my-extension', + params: { + text: 'Hello, world!', + }, + config: { + schema: { + something: z => z.string(), + defaulted: z => z.string().optional().default('default'), + }, + }, + factory(origFactory, { config }) { + const b: string = config.something; + const c: string = config.text; + const d: string = config.defaulted; + + unused(b, c, d); + + expect(config.text).toBe('Hello, world!'); + expect(config.something).toBe('something new!'); + expect(config.defaulted).toBe('lolz'); + return origFactory({}); + }, + }); + + expect.assertions(4); + + createExtensionTester(extension, { + config: { + something: 'something new!', + text: 'Hello, world!', + defaulted: 'lolz', + }, + }).render(); + }); }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts index c54131622f..56edcd8141 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts @@ -33,7 +33,7 @@ export interface CreateExtensionBlueprintOptions< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfigSchema extends { [key in string]: z.ZodTypeAny }, + TConfigSchema extends { [key in string]: z.ZodType }, TDataRefs extends AnyExtensionDataMap, > { kind: string; @@ -79,7 +79,7 @@ export interface ExtensionBlueprint< * You must either pass `params` directly, or define a `factory` that can * optionally call the original factory with the same params. */ - make<TExtensionConfigSchema extends { [key in string]: z.ZodTypeAny }>( + make<TExtensionConfigSchema extends { [key in string]: z.ZodType }>( args: { namespace?: string; name?: string; @@ -135,7 +135,7 @@ class ExtensionBlueprintImpl< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfigSchema extends { [key in string]: z.ZodTypeAny }, + TConfigSchema extends { [key in string]: z.ZodType }, TDataRefs extends AnyExtensionDataMap, > { constructor( @@ -153,7 +153,7 @@ class ExtensionBlueprintImpl< dataRefs: TDataRefs; public make< - TExtensionConfigSchema extends { [key in string]: z.ZodTypeAny }, + TExtensionConfigSchema extends { [key in string]: z.ZodType }, >(args: { namespace?: string; name?: string; @@ -202,7 +202,7 @@ class ExtensionBlueprintImpl< > { const schema = { ...this.options.config?.schema, - ...args.config, + ...args.config?.schema, } as { [key in keyof TConfigSchema]: (zImpl: typeof z) => TConfigSchema[key]; } & { @@ -266,7 +266,7 @@ export function createExtensionBlueprint< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfigSchema extends { [key in string]: z.ZodTypeAny }, + TConfigSchema extends { [key in string]: z.ZodType }, TDataRefs extends AnyExtensionDataMap = never, >( options: CreateExtensionBlueprintOptions< From 97157c547052fdd46e86c1a28f6c99387a3f89d7 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Wed, 24 Jul 2024 11:51:52 +0200 Subject: [PATCH 418/510] chore: do not allow redefing types from blueprint in make config schema Signed-off-by: blam <ben@blam.sh> --- .../wiring/createExtensionBlueprint.test.tsx | 36 +++++++++++++++++++ .../src/wiring/createExtensionBlueprint.ts | 2 ++ 2 files changed, 38 insertions(+) diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx index cf7de0fed3..209e9759bd 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx @@ -189,4 +189,40 @@ describe('createExtensionBlueprint', () => { }, }).render(); }); + + it('should not allow overlapping config keys', () => { + const TestExtensionBlueprint = createExtensionBlueprint({ + kind: 'test-extension', + attachTo: { id: 'test', input: 'default' }, + output: { + element: coreExtensionData.reactElement, + }, + config: { + schema: { + text: z => z.string(), + }, + }, + factory(params: { text: string }) { + return { + element: <div>{params.text}</div>, + }; + }, + }); + + TestExtensionBlueprint.make({ + name: 'my-extension', + params: { + text: 'Hello, world!', + }, + config: { + schema: { + // @ts-expect-error + text: z => z.number(), + something: z => z.string(), + }, + }, + }); + + expect('test').toBe('test'); + }); }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts index 56edcd8141..21c10f3c0e 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts @@ -92,6 +92,8 @@ export interface ExtensionBlueprint< [key in keyof TExtensionConfigSchema]: ( zImpl: typeof z, ) => TExtensionConfigSchema[key]; + } & { + [key in keyof TConfig]?: never; }; }; } & ( From e59ff0b2bc1b637df7b476dc323aa44d7e92ca37 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Wed, 24 Jul 2024 12:06:53 +0200 Subject: [PATCH 419/510] chore: tidy up Signed-off-by: blam <ben@blam.sh> --- packages/frontend-plugin-api/api-report.md | 121 ++++++++++++------ .../src/extensions/IconBundleBlueprint.ts | 36 ------ .../src/app/createExtensionTester.tsx | 4 +- plugins/catalog-graph/api-report-alpha.md | 13 -- plugins/catalog-graph/src/alpha.tsx | 79 +++--------- plugins/catalog-react/api-report-alpha.md | 56 ++------ plugins/catalog-react/src/alpha.tsx | 51 -------- plugins/catalog/api-report-alpha.md | 35 +---- plugins/catalog/src/alpha/index.ts | 2 - plugins/search-react/api-report-alpha.md | 3 +- plugins/search/api-report-alpha.md | 26 ++-- plugins/techdocs/api-report-alpha.md | 18 +-- plugins/user-settings/api-report-alpha.md | 10 +- 13 files changed, 130 insertions(+), 324 deletions(-) diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index 0c7c3b1d92..33ac02437c 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -89,7 +89,6 @@ import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; import { vmwareCloudAuthApiRef } from '@backstage/core-plugin-api'; import { withApis } from '@backstage/core-plugin-api'; import { z } from 'zod'; -import { ZodObject } from 'zod'; import { ZodSchema } from 'zod'; import { ZodTypeDef } from 'zod'; @@ -392,7 +391,7 @@ export function createApiExtension< configSchema?: PortableSchema<TConfig>; inputs?: TInputs; }, -): ExtensionDefinition<TConfig, ZodObject<any, any, any, any, any>>; +): ExtensionDefinition<TConfig>; // @public (undocumented) export namespace createApiExtension { @@ -488,7 +487,7 @@ export function createComponentExtension< inputs: Expand<ResolvedExtensionInputs<TInputs>>; }) => ComponentType<TProps>; }; -}): ExtensionDefinition<TConfig, ZodObject<any, any, any, any, any>>; +}): ExtensionDefinition<TConfig>; // @public (undocumented) export namespace createComponentExtension { @@ -512,35 +511,49 @@ export function createComponentRef<T extends {} = {}>(options: { export function createExtension< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, - TConfigSchema extends z.ZodObject<any, any, any, any, any>, - TConfig extends z.infer<TConfigSchema>, + TConfig, + TConfigSchema extends { + [key: string]: z.ZodType; + }, >( - options: CreateExtensionOptions<TOutput, TInputs, TConfigSchema, TConfig>, -): ExtensionDefinition<TConfig, TConfigSchema>; + options: CreateExtensionOptions<TOutput, TInputs, TConfig, TConfigSchema>, +): ExtensionDefinition<TConfig>; // @public export function createExtensionBlueprint< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfig, + TConfigSchema extends { + [key in string]: z.ZodType; + }, TDataRefs extends AnyExtensionDataMap = never, >( options: CreateExtensionBlueprintOptions< TParams, TInputs, TOutput, - TConfig, + TConfigSchema, TDataRefs >, -): ExtensionBlueprint<TParams, TInputs, TOutput, TConfig, TDataRefs>; +): ExtensionBlueprint< + TParams, + TInputs, + TOutput, + { + [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + }, + TDataRefs +>; // @public (undocumented) export interface CreateExtensionBlueprintOptions< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfig, + TConfigSchema extends { + [key in string]: z.ZodType; + }, TDataRefs extends AnyExtensionDataMap, > { // (undocumented) @@ -549,7 +562,11 @@ export interface CreateExtensionBlueprintOptions< input: string; }; // (undocumented) - configSchema?: PortableSchema<TConfig>; + config?: { + schema: { + [key in keyof TConfigSchema]: (zImpl: typeof z) => TConfigSchema[key]; + }; + }; // (undocumented) dataRefs?: TDataRefs; // (undocumented) @@ -559,7 +576,9 @@ export interface CreateExtensionBlueprintOptions< params: TParams, context: { node: AppNode; - config: TConfig; + config: { + [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + }; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, ): Expand<ExtensionDataValues<TOutput>>; @@ -607,8 +626,10 @@ export function createExtensionInput< export interface CreateExtensionOptions< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, - TConfigSchema extends z.ZodObject<any, any, any, any, any>, - TConfig extends z.infer<TConfigSchema>, + TConfig, + TConfigSchema extends { + [key: string]: z.ZodType; + }, > { // (undocumented) attachTo: { @@ -617,7 +638,9 @@ export interface CreateExtensionOptions< }; // (undocumented) config?: { - schema: (context: { z: typeof z }) => TConfigSchema; + schema: { + [key in keyof TConfigSchema]: (zImpl: typeof z) => TConfigSchema[key]; + }; }; // @deprecated (undocumented) configSchema?: PortableSchema<TConfig>; @@ -626,7 +649,9 @@ export interface CreateExtensionOptions< // (undocumented) factory(context: { node: AppNode; - config: TConfig; + config: TConfig & { + [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + }; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }): Expand<ExtensionDataValues<TOutput>>; // (undocumented) @@ -679,12 +704,9 @@ export function createNavItemExtension(options: { routeRef: RouteRef<undefined>; title: string; icon: IconComponent_2; -}): ExtensionDefinition< - { - title: string; - }, - ZodObject<any, any, any, any, any> ->; +}): ExtensionDefinition<{ + title: string; +}>; // @public (undocumented) export namespace createNavItemExtension { @@ -706,7 +728,7 @@ export function createNavLogoExtension(options: { namespace?: string; logoIcon: JSX.Element; logoFull: JSX.Element; -}): ExtensionDefinition<any, ZodObject<any, any, any, any, any>>; +}): ExtensionDefinition<unknown>; // @public (undocumented) export namespace createNavLogoExtension { @@ -814,7 +836,7 @@ export namespace createRouterExtension { >; } -// @public (undocumented) +// @public @deprecated (undocumented) export function createSchemaFromZod<TOutput, TInput>( schemaCreator: (zImpl: typeof z) => ZodSchema<TOutput, ZodTypeDef, TInput>, ): PortableSchema<TOutput>; @@ -861,7 +883,7 @@ export function createSubRouteRef< // @public (undocumented) export function createThemeExtension( theme: AppTheme, -): ExtensionDefinition<any, ZodObject<any, any, any, any, any>>; +): ExtensionDefinition<unknown>; // @public (undocumented) export namespace createThemeExtension { @@ -877,7 +899,7 @@ export namespace createThemeExtension { export function createTranslationExtension(options: { name?: string; resource: TranslationResource | TranslationMessages; -}): ExtensionDefinition<any, ZodObject<any, any, any, any, any>>; +}): ExtensionDefinition<unknown>; // @public (undocumented) export namespace createTranslationExtension { @@ -936,12 +958,18 @@ export interface ExtensionBlueprint< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfig, + TConfig extends { + [key in string]: unknown; + }, TDataRefs extends AnyExtensionDataMap, > { // (undocumented) dataRefs: TDataRefs; - make( + make< + TExtensionConfigSchema extends { + [key in string]: z.ZodType; + }, + >( args: { namespace?: string; name?: string; @@ -952,7 +980,15 @@ export interface ExtensionBlueprint< disabled?: boolean; inputs?: TInputs; output?: TOutput; - configSchema?: PortableSchema<TConfig>; + config?: { + schema: { + [key in keyof TExtensionConfigSchema]: ( + zImpl: typeof z, + ) => TExtensionConfigSchema[key]; + } & { + [key in keyof TConfig]?: never; + }; + }; } & ( | { factory( @@ -965,7 +1001,11 @@ export interface ExtensionBlueprint< ) => Expand<ExtensionDataValues<TOutput>>, context: { node: AppNode; - config: TConfig; + config: { + [key in keyof TExtensionConfigSchema]: z.infer< + TExtensionConfigSchema[key] + >; + } & TConfig; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, ): Expand<ExtensionDataValues<TOutput>>; @@ -974,7 +1014,13 @@ export interface ExtensionBlueprint< params: TParams; } ), - ): ExtensionDefinition<TConfig>; + ): ExtensionDefinition< + { + [key in keyof TExtensionConfigSchema]: z.infer< + TExtensionConfigSchema[key] + >; + } & TConfig + >; } // @public (undocumented) @@ -1021,10 +1067,7 @@ export type ExtensionDataValues<TExtensionData extends AnyExtensionDataMap> = { }; // @public (undocumented) -export interface ExtensionDefinition< - TConfig, - TConfigSchema extends z.ZodObject<any, any, any, any, any> = any, -> { +export interface ExtensionDefinition<TConfig> { // (undocumented) $$type: '@backstage/ExtensionDefinition'; // (undocumented) @@ -1035,8 +1078,6 @@ export interface ExtensionDefinition< // (undocumented) readonly configSchema?: PortableSchema<TConfig>; // (undocumented) - readonly configSchema2?: TConfigSchema; - // (undocumented) readonly disabled: boolean; // (undocumented) readonly kind?: string; @@ -1134,7 +1175,9 @@ export const IconBundleBlueprint: ExtensionBlueprint< {} >; }, - unknown, + { + [x: string]: any; + }, { icons: ConfigurableExtensionDataRef< 'core.icons', diff --git a/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts b/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts index aba3303f2f..2ad1404102 100644 --- a/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts +++ b/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts @@ -33,39 +33,3 @@ export const IconBundleBlueprint = createExtensionBlueprint({ icons: iconsDataRef, }, }); - -IconBundleBlueprint.make({ - name: 'asd', - params: { - icons: { - 'icon-name': () => null, - }, - }, -}); - -IconBundleBlueprint.make({ - name: 'asd', - params: { - icons: { - 'icon-name': () => null, - }, - }, -}); - -IconBundleBlueprint.make({ - name: 'asd', - factory() { - return { - icons: { - 'icon-name': () => null, - }, - }; - }, -}); - -IconBundleBlueprint.make({ - name: 'asd', - factory(f) { - return f({ icons: { 'icon-name': () => null } }); - }, -}); diff --git a/packages/frontend-test-utils/src/app/createExtensionTester.tsx b/packages/frontend-test-utils/src/app/createExtensionTester.tsx index d6be346002..a98879fbba 100644 --- a/packages/frontend-test-utils/src/app/createExtensionTester.tsx +++ b/packages/frontend-test-utils/src/app/createExtensionTester.tsx @@ -102,11 +102,11 @@ export class ExtensionTester { ...output, path: coreExtensionData.routePath, }, - factory: (params: any) => ({ + factory: params => ({ ...factory(params), path: '/', }), - } as any); + }); tester.add(extension, options); return tester; } diff --git a/plugins/catalog-graph/api-report-alpha.md b/plugins/catalog-graph/api-report-alpha.md index 59a387adf0..3895f12fcf 100644 --- a/plugins/catalog-graph/api-report-alpha.md +++ b/plugins/catalog-graph/api-report-alpha.md @@ -4,22 +4,9 @@ ```ts import { BackstagePlugin } from '@backstage/frontend-plugin-api'; -import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { ExternalRouteRef } from '@backstage/frontend-plugin-api'; import { RouteRef } from '@backstage/frontend-plugin-api'; -// Warning: (ae-missing-release-tag) "CatalogGraphEntityCard" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const CatalogGraphEntityCard: ExtensionDefinition< - { - title: string | undefined; - height: number | undefined; - } & { - filter: string | undefined; - } ->; - // @public (undocumented) const _default: BackstagePlugin< { diff --git a/plugins/catalog-graph/src/alpha.tsx b/plugins/catalog-graph/src/alpha.tsx index cf663406fa..6d8429332e 100644 --- a/plugins/catalog-graph/src/alpha.tsx +++ b/plugins/catalog-graph/src/alpha.tsx @@ -24,7 +24,7 @@ import { compatWrapper, convertLegacyRouteRef, } from '@backstage/core-compat-api'; -import { EntityCardBlueprint } from '@backstage/plugin-catalog-react/alpha'; +import { createEntityCardExtension } from '@backstage/plugin-catalog-react/alpha'; import { catalogGraphRouteRef, catalogEntityRouteRef } from './routes'; import { Direction } from './components'; @@ -46,67 +46,24 @@ function getEntityGraphRelationsConfigSchema( }); } -export const CatalogGraphEntityCard = EntityCardBlueprint.make({ +const CatalogGraphEntityCard = createEntityCardExtension({ name: 'relations', - // configSchema: origSchema => - // createSchemaFromZod(z => - // z - // .object({ - // // Filter is a config required to all entity cards - // // filter: z.string().optional(), - // title: z.string().optional(), - // height: z.number().optional(), - // // Skipping a "variant" config for now, defaulting to "gridItem" in the component - // // For more details, see this comment: https://github.com/backstage/backstage/pull/22619#discussion_r1477333252 - // }) - // .merge(getEntityGraphRelationsConfigSchema(z)) - // .merge(origSchema), - // ), - - // config: { - // schema: ({ z, parent }) => - // parent - // .merge({ - // title: z.string().optional(), - // height: z.number().optional(), - // }) - // .merge(getEntityGraphRelationsConfigSchema(z)), - // }, - - // config: { - // schema: ({ z, parent }) => - // parent - // .extend({ - // title: z.string().optional(), - // height: z.number().optional(), - // }) - // .merge(getEntityGraphRelationsConfigSchema(z)), - // // .merge(parent) - // }, - - // TODO: implement this and check the types. 👋 zod types. - config: { - schema: { - title: z => z.string().optional(), - height: z => z.number().optional(), - }, - }, - - // config: { - // schema: z => ({ - // title: z.string().optional(), - // height: z.number().optional(), - // }), - // }, - - factory(origFactory, { config: { filter: _, ...props } }) { - return origFactory({ - loader: async () => - import('./components/CatalogGraphCard').then(m => - compatWrapper(<m.CatalogGraphCard {...props} />), - ), - }); - }, + configSchema: createSchemaFromZod(z => + z + .object({ + // Filter is a config required to all entity cards + filter: z.string().optional(), + title: z.string().optional(), + height: z.number().optional(), + // Skipping a "variant" config for now, defaulting to "gridItem" in the component + // For more details, see this comment: https://github.com/backstage/backstage/pull/22619#discussion_r1477333252 + }) + .merge(getEntityGraphRelationsConfigSchema(z)), + ), + loader: async ({ config: { filter, ...props } }) => + import('./components/CatalogGraphCard').then(m => + compatWrapper(<m.CatalogGraphCard {...props} />), + ), }); const CatalogGraphPage = createPageExtension({ diff --git a/plugins/catalog-react/api-report-alpha.md b/plugins/catalog-react/api-report-alpha.md index ccf8205f59..d2bfb29458 100644 --- a/plugins/catalog-react/api-report-alpha.md +++ b/plugins/catalog-react/api-report-alpha.md @@ -3,20 +3,17 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +/// <reference types="react" /> + import { AnyExtensionInputMap } from '@backstage/frontend-plugin-api'; import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { Entity } from '@backstage/catalog-model'; -import { ExtensionBlueprint } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { PortableSchema } from '@backstage/frontend-plugin-api'; -import { default as React_2 } from 'react'; import { ResolvedExtensionInputs } from '@backstage/frontend-plugin-api'; import { ResourcePermission } from '@backstage/plugin-permission-common'; import { RouteRef } from '@backstage/frontend-plugin-api'; import { TranslationRef } from '@backstage/core-plugin-api/alpha'; -import { ZodOptional } from 'zod'; -import { ZodRawShape } from 'zod'; -import { ZodString } from 'zod'; // @alpha (undocumented) export const catalogExtensionData: { @@ -118,7 +115,7 @@ export function createEntityCardExtension< config: TConfig; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }) => Promise<JSX.Element>; -}): ExtensionDefinition<TConfig, ZodRawShape>; +}): ExtensionDefinition<TConfig>; // @alpha (undocumented) export function createEntityContentExtension< @@ -141,48 +138,11 @@ export function createEntityContentExtension< loader: (options: { inputs: Expand<ResolvedExtensionInputs<TInputs>>; }) => Promise<JSX.Element>; -}): ExtensionDefinition< - { - title: string; - path: string; - filter?: string | undefined; - }, - ZodRawShape ->; - -// @alpha (undocumented) -export const EntityCardBlueprint: ExtensionBlueprint< - { - filter?: string | ((entity: Entity) => boolean) | undefined; - loader: () => Promise<JSX.Element>; - }, - AnyExtensionInputMap, - { - element: ConfigurableExtensionDataRef< - 'core.reactElement', - React_2.JSX.Element, - {} - >; - filterFunction: ConfigurableExtensionDataRef< - 'catalog.entity-filter-function', - (entity: Entity) => boolean, - ((entity: Entity) => boolean) & { - optional: true; - } - >; - filterExpression: ConfigurableExtensionDataRef< - 'catalog.entity-filter-expression', - string, - string & { - optional: true; - } - >; - }, - { - filter: ZodOptional<ZodString>; - }, - never ->; +}): ExtensionDefinition<{ + title: string; + path: string; + filter?: string | undefined; +}>; // @alpha export function isOwnerOf(owner: Entity, entity: Entity): boolean; diff --git a/plugins/catalog-react/src/alpha.tsx b/plugins/catalog-react/src/alpha.tsx index f397c76ce0..e81b8e5ebf 100644 --- a/plugins/catalog-react/src/alpha.tsx +++ b/plugins/catalog-react/src/alpha.tsx @@ -22,7 +22,6 @@ import { RouteRef, coreExtensionData, createExtension, - createExtensionBlueprint, createExtensionDataRef, createSchemaFromZod, } from '@backstage/frontend-plugin-api'; @@ -48,49 +47,6 @@ export const catalogExtensionData = { }), }; -/** @alpha */ -export const EntityCardBlueprint = createExtensionBlueprint({ - kind: 'entity-card', - attachTo: { id: 'entity-content:catalog/overview', input: 'cards' }, - // configSchema: createSchemaFromZod(z => - // z.object({ - // filter: z.string().optional(), - // }), - // ), - config: { - schema: { - filter: z => z.string().optional(), - }, - }, - output: { - element: coreExtensionData.reactElement, - filterFunction: catalogExtensionData.entityFilterFunction.optional(), - filterExpression: catalogExtensionData.entityFilterExpression.optional(), - }, - factory( - params: { - filter?: - | typeof catalogExtensionData.entityFilterFunction.T - | typeof catalogExtensionData.entityFilterExpression.T; - loader: () => Promise<JSX.Element>; - }, - { node, config }, - ) { - const ExtensionComponent = lazy(() => - params.loader().then(element => ({ default: () => element })), - ); - - return { - element: ( - <ExtensionBoundary node={node}> - <ExtensionComponent /> - </ExtensionBoundary> - ), - ...mergeFilters({ config, options: params }), - }; - }, -}); - // TODO: Figure out how to merge with provided config schema /** @alpha */ export function createEntityCardExtension< @@ -198,13 +154,6 @@ export function createEntityContentExtension< filter: z.string().optional(), }), ), - // config: { - // schema: ({ z }) => ({ - // path: z.string().default(options.defaultPath), - // title: z.string().default(options.defaultTitle), - // filter: z.string().optional(), - // }), - // }, factory({ config, inputs, node }) { const ExtensionComponent = lazy(() => options diff --git a/plugins/catalog/api-report-alpha.md b/plugins/catalog/api-report-alpha.md index 03711b7d3d..102e2a7aa3 100644 --- a/plugins/catalog/api-report-alpha.md +++ b/plugins/catalog/api-report-alpha.md @@ -12,39 +12,6 @@ import { ExternalRouteRef } from '@backstage/frontend-plugin-api'; import { PortableSchema } from '@backstage/frontend-plugin-api'; import { RouteRef } from '@backstage/frontend-plugin-api'; import { TranslationRef } from '@backstage/core-plugin-api/alpha'; -import { ZodObject } from 'zod'; - -// Warning: (ae-missing-release-tag) "catalogAboutEntityCard" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const catalogAboutEntityCard: ExtensionDefinition< - { - filter?: string | undefined; - }, - ZodObject<any, any, any, any, any> ->; - -// Warning: (ae-missing-release-tag) "catalogLinksEntityCard" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const catalogLinksEntityCard: ExtensionDefinition< - { - filter?: string | undefined; - }, - ZodObject<any, any, any, any, any> ->; - -// Warning: (ae-missing-release-tag) "catalogOverviewEntityContent" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const catalogOverviewEntityContent: ExtensionDefinition< - { - title: string; - path: string; - filter?: string | undefined; - }, - ZodObject<any, any, any, any, any> ->; // @alpha (undocumented) export const catalogTranslationRef: TranslationRef< @@ -139,7 +106,7 @@ export function createCatalogFilterExtension< inputs?: TInputs; configSchema?: PortableSchema<TConfig>; loader: (options: { config: TConfig }) => Promise<JSX.Element>; -}): ExtensionDefinition<TConfig, ZodObject<any, any, any, any, any>>; +}): ExtensionDefinition<TConfig>; // @alpha (undocumented) const _default: BackstagePlugin< diff --git a/plugins/catalog/src/alpha/index.ts b/plugins/catalog/src/alpha/index.ts index acf61865ba..06a78ec6ea 100644 --- a/plugins/catalog/src/alpha/index.ts +++ b/plugins/catalog/src/alpha/index.ts @@ -16,5 +16,3 @@ export { default } from './plugin'; export { createCatalogFilterExtension } from './createCatalogFilterExtension'; -export { catalogAboutEntityCard, catalogLinksEntityCard } from './entityCards'; -export { catalogOverviewEntityContent } from './entityContents'; diff --git a/plugins/search-react/api-report-alpha.md b/plugins/search-react/api-report-alpha.md index 6160759042..aea85d0f81 100644 --- a/plugins/search-react/api-report-alpha.md +++ b/plugins/search-react/api-report-alpha.md @@ -11,7 +11,6 @@ import { ListItemProps } from '@material-ui/core/ListItem'; import { PortableSchema } from '@backstage/frontend-plugin-api'; import { SearchDocument } from '@backstage/plugin-search-common'; import { SearchResult } from '@backstage/plugin-search-common'; -import { ZodObject } from 'zod'; // @alpha (undocumented) export type BaseSearchResultListItemProps<T = {}> = T & { @@ -26,7 +25,7 @@ export function createSearchResultListItemExtension< }, >( options: SearchResultItemExtensionOptions<TConfig>, -): ExtensionDefinition<TConfig, ZodObject<any, any, any, any, any>>; +): ExtensionDefinition<TConfig>; // @alpha (undocumented) export namespace createSearchResultListItemExtension { diff --git a/plugins/search/api-report-alpha.md b/plugins/search/api-report-alpha.md index ade5f530ef..db2999ba25 100644 --- a/plugins/search/api-report-alpha.md +++ b/plugins/search/api-report-alpha.md @@ -6,7 +6,6 @@ import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { RouteRef } from '@backstage/frontend-plugin-api'; -import { ZodObject } from 'zod'; // @alpha (undocumented) const _default: BackstagePlugin< @@ -18,27 +17,18 @@ const _default: BackstagePlugin< export default _default; // @alpha (undocumented) -export const searchApi: ExtensionDefinition< - {}, - ZodObject<any, any, any, any, any> ->; +export const searchApi: ExtensionDefinition<{}>; // @alpha (undocumented) -export const searchNavItem: ExtensionDefinition< - { - title: string; - }, - ZodObject<any, any, any, any, any> ->; +export const searchNavItem: ExtensionDefinition<{ + title: string; +}>; // @alpha (undocumented) -export const searchPage: ExtensionDefinition< - { - path: string; - noTrack: boolean; - }, - any ->; +export const searchPage: ExtensionDefinition<{ + path: string; + noTrack: boolean; +}>; // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/techdocs/api-report-alpha.md b/plugins/techdocs/api-report-alpha.md index fc57370a53..cf9f5fa9a3 100644 --- a/plugins/techdocs/api-report-alpha.md +++ b/plugins/techdocs/api-report-alpha.md @@ -6,7 +6,6 @@ import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { RouteRef } from '@backstage/frontend-plugin-api'; -import { ZodObject } from 'zod'; // @alpha (undocumented) const _default: BackstagePlugin< @@ -24,16 +23,13 @@ const _default: BackstagePlugin< export default _default; // @alpha (undocumented) -export const techDocsSearchResultListItemExtension: ExtensionDefinition< - { - lineClamp: number; - noTrack: boolean; - asListItem: boolean; - asLink: boolean; - title?: string | undefined; - }, - ZodObject<any, any, any, any, any> ->; +export const techDocsSearchResultListItemExtension: ExtensionDefinition<{ + lineClamp: number; + noTrack: boolean; + asListItem: boolean; + asLink: boolean; + title?: string | undefined; +}>; // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/user-settings/api-report-alpha.md b/plugins/user-settings/api-report-alpha.md index db4373fd43..b06fd1e583 100644 --- a/plugins/user-settings/api-report-alpha.md +++ b/plugins/user-settings/api-report-alpha.md @@ -7,7 +7,6 @@ import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { RouteRef } from '@backstage/frontend-plugin-api'; import { TranslationRef } from '@backstage/core-plugin-api/alpha'; -import { ZodObject } from 'zod'; // @alpha (undocumented) const _default: BackstagePlugin< @@ -19,12 +18,9 @@ const _default: BackstagePlugin< export default _default; // @alpha (undocumented) -export const settingsNavItem: ExtensionDefinition< - { - title: string; - }, - ZodObject<any, any, any, any, any> ->; +export const settingsNavItem: ExtensionDefinition<{ + title: string; +}>; // @alpha (undocumented) export const userSettingsTranslationRef: TranslationRef< From 3fb421d1b05281ffdbdfbb42ceb5554931a0aa2f Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Wed, 24 Jul 2024 12:48:49 +0200 Subject: [PATCH 420/510] chore: added changeset Signed-off-by: blam <ben@blam.sh> --- .changeset/sweet-oranges-buy.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/sweet-oranges-buy.md diff --git a/.changeset/sweet-oranges-buy.md b/.changeset/sweet-oranges-buy.md new file mode 100644 index 0000000000..d9f3343e3d --- /dev/null +++ b/.changeset/sweet-oranges-buy.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-plugin-api': patch +--- + +Added support to be able to define `zod` config schema in Blueprints, with built in schema merging from the Blueprint and the extension instances. From e9673327852493d196430c0c4eddf12e2effe8bb Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Wed, 24 Jul 2024 13:40:43 +0200 Subject: [PATCH 421/510] chore: small refactor and fixing some of the types Signed-off-by: blam <ben@blam.sh> --- packages/frontend-plugin-api/api-report.md | 51 +++++------ .../src/wiring/createExtension.ts | 12 ++- .../wiring/createExtensionBlueprint.test.tsx | 49 +++++++++++ .../src/wiring/createExtensionBlueprint.ts | 86 ++++++++++--------- 4 files changed, 122 insertions(+), 76 deletions(-) diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index 33ac02437c..45ed51b415 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -513,7 +513,7 @@ export function createExtension< TInputs extends AnyExtensionInputMap, TConfig, TConfigSchema extends { - [key: string]: z.ZodType; + [key: string]: (zImpl: typeof z) => z.ZodType; }, >( options: CreateExtensionOptions<TOutput, TInputs, TConfig, TConfigSchema>, @@ -525,7 +525,7 @@ export function createExtensionBlueprint< TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfigSchema extends { - [key in string]: z.ZodType; + [key in string]: (zImpl: typeof z) => z.ZodType; }, TDataRefs extends AnyExtensionDataMap = never, >( @@ -540,9 +540,11 @@ export function createExtensionBlueprint< TParams, TInputs, TOutput, - { - [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; - }, + string extends keyof TConfigSchema + ? {} + : { + [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; + }, TDataRefs >; @@ -552,7 +554,7 @@ export interface CreateExtensionBlueprintOptions< TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfigSchema extends { - [key in string]: z.ZodType; + [key in string]: (zImpl: typeof z) => z.ZodType; }, TDataRefs extends AnyExtensionDataMap, > { @@ -563,9 +565,7 @@ export interface CreateExtensionBlueprintOptions< }; // (undocumented) config?: { - schema: { - [key in keyof TConfigSchema]: (zImpl: typeof z) => TConfigSchema[key]; - }; + schema: TConfigSchema; }; // (undocumented) dataRefs?: TDataRefs; @@ -577,7 +577,7 @@ export interface CreateExtensionBlueprintOptions< context: { node: AppNode; config: { - [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; }; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, @@ -628,7 +628,7 @@ export interface CreateExtensionOptions< TInputs extends AnyExtensionInputMap, TConfig, TConfigSchema extends { - [key: string]: z.ZodType; + [key: string]: (zImpl: typeof z) => z.ZodType; }, > { // (undocumented) @@ -638,9 +638,7 @@ export interface CreateExtensionOptions< }; // (undocumented) config?: { - schema: { - [key in keyof TConfigSchema]: (zImpl: typeof z) => TConfigSchema[key]; - }; + schema: TConfigSchema; }; // @deprecated (undocumented) configSchema?: PortableSchema<TConfig>; @@ -650,7 +648,7 @@ export interface CreateExtensionOptions< factory(context: { node: AppNode; config: TConfig & { - [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; }; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }): Expand<ExtensionDataValues<TOutput>>; @@ -967,7 +965,7 @@ export interface ExtensionBlueprint< dataRefs: TDataRefs; make< TExtensionConfigSchema extends { - [key in string]: z.ZodType; + [key in string]: (zImpl: typeof z) => z.ZodType; }, >( args: { @@ -981,12 +979,9 @@ export interface ExtensionBlueprint< inputs?: TInputs; output?: TOutput; config?: { - schema: { - [key in keyof TExtensionConfigSchema]: ( - zImpl: typeof z, - ) => TExtensionConfigSchema[key]; - } & { - [key in keyof TConfig]?: never; + schema: TExtensionConfigSchema & { + [KName in keyof TConfig]?: `Error: Config key '${KName & + string}' is already defined in parent schema`; }; }; } & ( @@ -1001,11 +996,11 @@ export interface ExtensionBlueprint< ) => Expand<ExtensionDataValues<TOutput>>, context: { node: AppNode; - config: { + config: TConfig & { [key in keyof TExtensionConfigSchema]: z.infer< - TExtensionConfigSchema[key] + ReturnType<TExtensionConfigSchema[key]> >; - } & TConfig; + }; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, ): Expand<ExtensionDataValues<TOutput>>; @@ -1017,7 +1012,7 @@ export interface ExtensionBlueprint< ): ExtensionDefinition< { [key in keyof TExtensionConfigSchema]: z.infer< - TExtensionConfigSchema[key] + ReturnType<TExtensionConfigSchema[key]> >; } & TConfig >; @@ -1175,9 +1170,7 @@ export const IconBundleBlueprint: ExtensionBlueprint< {} >; }, - { - [x: string]: any; - }, + {}, { icons: ConfigurableExtensionDataRef< 'core.icons', diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index 7783f8e14d..ac91557906 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -82,7 +82,7 @@ export interface CreateExtensionOptions< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, TConfig, - TConfigSchema extends { [key: string]: z.ZodType }, + TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, > { kind?: string; namespace?: string; @@ -94,14 +94,12 @@ export interface CreateExtensionOptions< /** @deprecated - use `config.schema` instead */ configSchema?: PortableSchema<TConfig>; config?: { - schema: { - [key in keyof TConfigSchema]: (zImpl: typeof z) => TConfigSchema[key]; - }; + schema: TConfigSchema; }; factory(context: { node: AppNode; config: TConfig & { - [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; }; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }): Expand<ExtensionDataValues<TOutput>>; @@ -154,7 +152,7 @@ export function createExtension< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, TConfig, - TConfigSchema extends { [key: string]: z.ZodType }, + TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, >( options: CreateExtensionOptions<TOutput, TInputs, TConfig, TConfigSchema>, ): ExtensionDefinition<TConfig> { @@ -188,7 +186,7 @@ export function createExtension< return options.factory({ inputs: inputs as Expand<ResolvedExtensionInputs<TInputs>>, config: config as TConfig & { - [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; }, ...rest, }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx index 209e9759bd..cb8855d892 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx @@ -225,4 +225,53 @@ describe('createExtensionBlueprint', () => { expect('test').toBe('test'); }); + + it('should allow setting config when one was not already defined in the blueprint', () => { + const TestExtensionBlueprint = createExtensionBlueprint({ + kind: 'test-extension', + attachTo: { id: 'test', input: 'default' }, + output: { + element: coreExtensionData.reactElement, + }, + factory(_, { config }) { + // @ts-expect-error + const b = config.something; + + return { + element: <div />, + }; + }, + }); + + const extension = TestExtensionBlueprint.make({ + name: 'my-extension', + params: { + text: 'Hello, world!', + }, + config: { + schema: { + something: z => z.string(), + defaulted: z => z.string().optional().default('default'), + }, + }, + factory(origFactory, { config }) { + const b: string = config.something; + + unused(b); + + expect(config.something).toBe('something new!'); + expect(config.defaulted).toBe('lolz'); + return origFactory({}); + }, + }); + + expect.assertions(2); + + createExtensionTester(extension, { + config: { + something: 'something new!', + defaulted: 'lolz', + }, + }).render(); + }); }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts index 21c10f3c0e..ce3e650342 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts @@ -33,7 +33,7 @@ export interface CreateExtensionBlueprintOptions< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfigSchema extends { [key in string]: z.ZodType }, + TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType }, TDataRefs extends AnyExtensionDataMap, > { kind: string; @@ -43,16 +43,14 @@ export interface CreateExtensionBlueprintOptions< inputs?: TInputs; output: TOutput; config?: { - schema: { - [key in keyof TConfigSchema]: (zImpl: typeof z) => TConfigSchema[key]; - }; + schema: TConfigSchema; }; factory( params: TParams, context: { node: AppNode; config: { - [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; }; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, @@ -79,7 +77,11 @@ export interface ExtensionBlueprint< * You must either pass `params` directly, or define a `factory` that can * optionally call the original factory with the same params. */ - make<TExtensionConfigSchema extends { [key in string]: z.ZodType }>( + make< + TExtensionConfigSchema extends { + [key in string]: (zImpl: typeof z) => z.ZodType; + }, + >( args: { namespace?: string; name?: string; @@ -88,12 +90,9 @@ export interface ExtensionBlueprint< inputs?: TInputs; output?: TOutput; config?: { - schema: { - [key in keyof TExtensionConfigSchema]: ( - zImpl: typeof z, - ) => TExtensionConfigSchema[key]; - } & { - [key in keyof TConfig]?: never; + schema: TExtensionConfigSchema & { + [KName in keyof TConfig]?: `Error: Config key '${KName & + string}' is already defined in parent schema`; }; }; } & ( @@ -108,11 +107,11 @@ export interface ExtensionBlueprint< ) => Expand<ExtensionDataValues<TOutput>>, context: { node: AppNode; - config: { + config: TConfig & { [key in keyof TExtensionConfigSchema]: z.infer< - TExtensionConfigSchema[key] + ReturnType<TExtensionConfigSchema[key]> >; - } & TConfig; + }; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, ): Expand<ExtensionDataValues<TOutput>>; @@ -124,7 +123,7 @@ export interface ExtensionBlueprint< ): ExtensionDefinition< { [key in keyof TExtensionConfigSchema]: z.infer< - TExtensionConfigSchema[key] + ReturnType<TExtensionConfigSchema[key]> >; } & TConfig >; @@ -137,7 +136,7 @@ class ExtensionBlueprintImpl< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfigSchema extends { [key in string]: z.ZodType }, + TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType }, TDataRefs extends AnyExtensionDataMap, > { constructor( @@ -155,7 +154,9 @@ class ExtensionBlueprintImpl< dataRefs: TDataRefs; public make< - TExtensionConfigSchema extends { [key in string]: z.ZodType }, + TExtensionConfigSchema extends { + [key in string]: (zImpl: typeof z) => z.ZodType; + }, >(args: { namespace?: string; name?: string; @@ -165,18 +166,16 @@ class ExtensionBlueprintImpl< output?: TOutput; params?: TParams; config?: { - schema: { - [key in keyof TExtensionConfigSchema]: ( - zImpl: typeof z, - ) => TExtensionConfigSchema[key]; - }; + schema: TExtensionConfigSchema; }; factory?( originalFactory: ( params: TParams, context?: { config?: { - [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + [key in keyof TConfigSchema]: z.infer< + ReturnType<TConfigSchema[key]> + >; }; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, @@ -185,10 +184,10 @@ class ExtensionBlueprintImpl< node: AppNode; config: { [key in keyof TExtensionConfigSchema]: z.infer< - TExtensionConfigSchema[key] + ReturnType<TExtensionConfigSchema[key]> >; } & { - [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; }; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, @@ -196,23 +195,16 @@ class ExtensionBlueprintImpl< }): ExtensionDefinition< { [key in keyof TExtensionConfigSchema]: z.infer< - TExtensionConfigSchema[key] + ReturnType<TExtensionConfigSchema[key]> >; } & { - [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; } > { const schema = { ...this.options.config?.schema, ...args.config?.schema, - } as { - [key in keyof TConfigSchema]: (zImpl: typeof z) => TConfigSchema[key]; - } & { - [key in keyof TExtensionConfigSchema]: ( - zImpl: typeof z, - ) => TExtensionConfigSchema[key]; - }; - + } as TConfigSchema & TExtensionConfigSchema; return createExtension({ kind: this.options.kind, namespace: args.namespace ?? this.options.namespace, @@ -229,7 +221,9 @@ class ExtensionBlueprintImpl< innerParams: TParams, innerContext?: { config?: { - [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]>; + [key in keyof TConfigSchema]: z.infer< + ReturnType<TConfigSchema[key]> + >; }; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, @@ -268,7 +262,7 @@ export function createExtensionBlueprint< TParams, TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, - TConfigSchema extends { [key in string]: z.ZodType }, + TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType }, TDataRefs extends AnyExtensionDataMap = never, >( options: CreateExtensionBlueprintOptions< @@ -282,8 +276,20 @@ export function createExtensionBlueprint< TParams, TInputs, TOutput, - { [key in keyof TConfigSchema]: z.infer<TConfigSchema[key]> }, + string extends keyof TConfigSchema + ? {} + : { [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>> }, TDataRefs > { - return new ExtensionBlueprintImpl(options); + return new ExtensionBlueprintImpl(options) as ExtensionBlueprint< + TParams, + TInputs, + TOutput, + string extends keyof TConfigSchema + ? {} + : { + [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; + }, + TDataRefs + >; } From 0ad542cbc7e144c45feb4c2b20babebae9a5c60d Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Wed, 24 Jul 2024 14:36:22 +0200 Subject: [PATCH 422/510] feat: added input types for the config to the extensions Signed-off-by: blam <ben@blam.sh> --- .../src/collectLegacyRoutes.tsx | 4 +- .../extractRouteInfoFromAppNode.test.ts | 2 +- .../src/tree/createAppTree.ts | 2 +- .../src/tree/instantiateAppNodeTree.test.ts | 14 +-- .../src/tree/resolveAppTree.test.ts | 4 +- packages/frontend-plugin-api/api-report.md | 102 +++++++++++++----- .../src/apis/definitions/AppTreeApi.ts | 2 +- .../src/extensions/IconBundleBlueprint.ts | 6 ++ .../src/schema/createSchemaFromZod.test.ts | 15 ++- .../src/schema/createSchemaFromZod.ts | 2 +- .../frontend-plugin-api/src/schema/types.ts | 4 +- .../src/wiring/createExtension.test.ts | 8 +- .../src/wiring/createExtension.ts | 78 +++++++++++--- .../src/wiring/createExtensionBlueprint.ts | 38 ++++++- .../src/wiring/createExtensionOverrides.ts | 2 +- .../src/wiring/createPlugin.ts | 2 +- .../src/wiring/resolveExtensionDefinition.ts | 23 ++-- packages/frontend-test-utils/api-report.md | 6 +- .../src/app/createExtensionTester.tsx | 14 +-- plugins/catalog-react/api-report-alpha.md | 19 ++-- plugins/catalog/api-report-alpha.md | 4 +- .../alpha/createCatalogFilterExtension.tsx | 2 +- plugins/search-react/api-report-alpha.md | 2 +- plugins/search/api-report-alpha.md | 27 +++-- plugins/techdocs/api-report-alpha.md | 23 ++-- plugins/user-settings/api-report-alpha.md | 11 +- 26 files changed, 300 insertions(+), 116 deletions(-) diff --git a/packages/core-compat-api/src/collectLegacyRoutes.tsx b/packages/core-compat-api/src/collectLegacyRoutes.tsx index b9f4e5528c..3523b0a40b 100644 --- a/packages/core-compat-api/src/collectLegacyRoutes.tsx +++ b/packages/core-compat-api/src/collectLegacyRoutes.tsx @@ -101,7 +101,7 @@ function visitRouteChildren(options: { parentExtensionId: string; context: { pluginId: string; - extensions: ExtensionDefinition<unknown>[]; + extensions: ExtensionDefinition<any, any>[]; getUniqueName: () => string; discoverPlugin: (plugin: LegacyBackstagePlugin) => void; }; @@ -154,7 +154,7 @@ export function collectLegacyRoutes( ): BackstagePlugin[] { const pluginExtensions = new Map< LegacyBackstagePlugin, - ExtensionDefinition<unknown>[] + ExtensionDefinition<any, any>[] >(); const getUniqueName = (() => { diff --git a/packages/frontend-app-api/src/routing/extractRouteInfoFromAppNode.test.ts b/packages/frontend-app-api/src/routing/extractRouteInfoFromAppNode.test.ts index 1c332b331f..bdab2781e0 100644 --- a/packages/frontend-app-api/src/routing/extractRouteInfoFromAppNode.test.ts +++ b/packages/frontend-app-api/src/routing/extractRouteInfoFromAppNode.test.ts @@ -70,7 +70,7 @@ function createTestExtension(options: { }); } -function routeInfoFromExtensions(extensions: ExtensionDefinition<unknown>[]) { +function routeInfoFromExtensions(extensions: ExtensionDefinition<any, any>[]) { const plugin = createPlugin({ id: 'test', extensions, diff --git a/packages/frontend-app-api/src/tree/createAppTree.ts b/packages/frontend-app-api/src/tree/createAppTree.ts index 12c7f7fc3a..ee9704c3c3 100644 --- a/packages/frontend-app-api/src/tree/createAppTree.ts +++ b/packages/frontend-app-api/src/tree/createAppTree.ts @@ -25,7 +25,7 @@ import { instantiateAppNodeTree } from './instantiateAppNodeTree'; /** @internal */ export interface CreateAppTreeOptions { features: FrontendFeature[]; - builtinExtensions: Extension<unknown>[]; + builtinExtensions: Extension<any, any>[]; config: Config; } diff --git a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts index c5c66e8319..a82c8d99ee 100644 --- a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts +++ b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts @@ -59,22 +59,22 @@ const simpleExtension = resolveExtensionDefinition( }), ); -function makeSpec<TConfig>( - extension: Extension<TConfig>, +function makeSpec<TConfig, TConfigInput>( + extension: Extension<TConfig, TConfigInput>, spec?: Partial<AppNodeSpec>, ): AppNodeSpec { return { id: extension.id, attachTo: extension.attachTo, disabled: extension.disabled, - extension, + extension: extension as Extension<unknown, unknown>, source: undefined, ...spec, }; } -function makeNode<TConfig>( - extension: Extension<TConfig>, +function makeNode<TConfig, TConfigInput>( + extension: Extension<TConfig, TConfigInput>, spec?: Partial<AppNodeSpec>, ): AppNode { return { @@ -85,8 +85,8 @@ function makeNode<TConfig>( }; } -function makeInstanceWithId<TConfig>( - extension: Extension<TConfig>, +function makeInstanceWithId<TConfig, TConfigInput>( + extension: Extension<TConfig, TConfigInput>, config?: TConfig, ): AppNode { const node = makeNode(extension, { config }); diff --git a/packages/frontend-app-api/src/tree/resolveAppTree.test.ts b/packages/frontend-app-api/src/tree/resolveAppTree.test.ts index f964fceb50..d9b65555fe 100644 --- a/packages/frontend-app-api/src/tree/resolveAppTree.test.ts +++ b/packages/frontend-app-api/src/tree/resolveAppTree.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { createExtension } from '@backstage/frontend-plugin-api'; +import { createExtension, Extension } 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'; @@ -26,7 +26,7 @@ const extension = resolveExtensionDefinition( output: {}, factory: () => ({}), }), -); +) as Extension<unknown, unknown>; const baseSpec = { extension, diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index 45ed51b415..c4a96cba59 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -230,7 +230,7 @@ export interface AppNodeSpec { // (undocumented) readonly disabled: boolean; // (undocumented) - readonly extension: Extension<unknown>; + readonly extension: Extension<unknown, unknown>; // (undocumented) readonly id: string; // (undocumented) @@ -391,7 +391,7 @@ export function createApiExtension< configSchema?: PortableSchema<TConfig>; inputs?: TInputs; }, -): ExtensionDefinition<TConfig>; +): ExtensionDefinition<TConfig & {}, TConfig & {}>; // @public (undocumented) export namespace createApiExtension { @@ -487,7 +487,7 @@ export function createComponentExtension< inputs: Expand<ResolvedExtensionInputs<TInputs>>; }) => ComponentType<TProps>; }; -}): ExtensionDefinition<TConfig>; +}): ExtensionDefinition<TConfig & {}, TConfig & {}>; // @public (undocumented) export namespace createComponentExtension { @@ -512,12 +512,34 @@ export function createExtension< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, TConfig, + TConfigInput, TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType; }, >( - options: CreateExtensionOptions<TOutput, TInputs, TConfig, TConfigSchema>, -): ExtensionDefinition<TConfig>; + options: CreateExtensionOptions< + TOutput, + TInputs, + TConfig, + TConfigInput, + TConfigSchema + >, +): ExtensionDefinition< + TConfig & + (string extends keyof TConfigSchema + ? {} + : { + [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; + }), + TConfigInput & + (string extends keyof TConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>; + }> + >) +>; // @public export function createExtensionBlueprint< @@ -545,6 +567,13 @@ export function createExtensionBlueprint< : { [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; }, + string extends keyof TConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>; + }> + >, TDataRefs >; @@ -627,6 +656,7 @@ export interface CreateExtensionOptions< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, TConfig, + TConfigInput, TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType; }, @@ -641,15 +671,20 @@ export interface CreateExtensionOptions< schema: TConfigSchema; }; // @deprecated (undocumented) - configSchema?: PortableSchema<TConfig>; + configSchema?: PortableSchema<TConfig, TConfigInput>; // (undocumented) disabled?: boolean; // (undocumented) factory(context: { node: AppNode; - config: TConfig & { - [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; - }; + config: TConfig & + (string extends keyof TConfigSchema + ? {} + : { + [key in keyof TConfigSchema]: z.infer< + ReturnType<TConfigSchema[key]> + >; + }); inputs: Expand<ResolvedExtensionInputs<TInputs>>; }): Expand<ExtensionDataValues<TOutput>>; // (undocumented) @@ -702,9 +737,14 @@ export function createNavItemExtension(options: { routeRef: RouteRef<undefined>; title: string; icon: IconComponent_2; -}): ExtensionDefinition<{ - title: string; -}>; +}): ExtensionDefinition< + { + title: string; + }, + { + title?: string | undefined; + } +>; // @public (undocumented) export namespace createNavItemExtension { @@ -726,7 +766,7 @@ export function createNavLogoExtension(options: { namespace?: string; logoIcon: JSX.Element; logoFull: JSX.Element; -}): ExtensionDefinition<unknown>; +}): ExtensionDefinition<{}, {}>; // @public (undocumented) export namespace createNavLogoExtension { @@ -837,7 +877,7 @@ export namespace createRouterExtension { // @public @deprecated (undocumented) export function createSchemaFromZod<TOutput, TInput>( schemaCreator: (zImpl: typeof z) => ZodSchema<TOutput, ZodTypeDef, TInput>, -): PortableSchema<TOutput>; +): PortableSchema<TOutput, TInput>; // @public (undocumented) export function createSignInPageExtension< @@ -881,7 +921,7 @@ export function createSubRouteRef< // @public (undocumented) export function createThemeExtension( theme: AppTheme, -): ExtensionDefinition<unknown>; +): ExtensionDefinition<{}, {}>; // @public (undocumented) export namespace createThemeExtension { @@ -897,7 +937,7 @@ export namespace createThemeExtension { export function createTranslationExtension(options: { name?: string; resource: TranslationResource | TranslationMessages; -}): ExtensionDefinition<unknown>; +}): ExtensionDefinition<{}, {}>; // @public (undocumented) export namespace createTranslationExtension { @@ -935,7 +975,7 @@ export { ErrorApiErrorContext }; export { errorApiRef }; // @public (undocumented) -export interface Extension<TConfig> { +export interface Extension<TConfig, TConfigInput = TConfig> { // (undocumented) $$type: '@backstage/Extension'; // (undocumented) @@ -944,7 +984,7 @@ export interface Extension<TConfig> { input: string; }; // (undocumented) - readonly configSchema?: PortableSchema<TConfig>; + readonly configSchema?: PortableSchema<TConfig, TConfigInput>; // (undocumented) readonly disabled: boolean; // (undocumented) @@ -959,6 +999,9 @@ export interface ExtensionBlueprint< TConfig extends { [key in string]: unknown; }, + TConfigInput extends { + [key in string]: unknown; + }, TDataRefs extends AnyExtensionDataMap, > { // (undocumented) @@ -1014,7 +1057,15 @@ export interface ExtensionBlueprint< [key in keyof TExtensionConfigSchema]: z.infer< ReturnType<TExtensionConfigSchema[key]> >; - } & TConfig + } & TConfig, + z.input< + z.ZodObject<{ + [key in keyof TExtensionConfigSchema]: ReturnType< + TExtensionConfigSchema[key] + >; + }> + > & + TConfigInput >; } @@ -1062,7 +1113,7 @@ export type ExtensionDataValues<TExtensionData extends AnyExtensionDataMap> = { }; // @public (undocumented) -export interface ExtensionDefinition<TConfig> { +export interface ExtensionDefinition<TConfig, TConfigInput = TConfig> { // (undocumented) $$type: '@backstage/ExtensionDefinition'; // (undocumented) @@ -1071,7 +1122,7 @@ export interface ExtensionDefinition<TConfig> { input: string; }; // (undocumented) - readonly configSchema?: PortableSchema<TConfig>; + readonly configSchema?: PortableSchema<TConfig, TConfigInput>; // (undocumented) readonly disabled: boolean; // (undocumented) @@ -1107,7 +1158,7 @@ export interface ExtensionOverrides { // @public (undocumented) export interface ExtensionOverridesOptions { // (undocumented) - extensions: ExtensionDefinition<unknown>[]; + extensions: ExtensionDefinition<any, any>[]; // (undocumented) featureFlags?: FeatureFlagConfig[]; } @@ -1171,6 +1222,7 @@ export const IconBundleBlueprint: ExtensionBlueprint< >; }, {}, + {}, { icons: ConfigurableExtensionDataRef< 'core.icons', @@ -1235,7 +1287,7 @@ export interface PluginOptions< ExternalRoutes extends AnyExternalRoutes, > { // (undocumented) - extensions?: ExtensionDefinition<unknown>[]; + extensions?: ExtensionDefinition<any, any>[]; // (undocumented) externalRoutes?: ExternalRoutes; // (undocumented) @@ -1247,8 +1299,8 @@ export interface PluginOptions< } // @public (undocumented) -export type PortableSchema<TOutput> = { - parse: (input: unknown) => TOutput; +export type PortableSchema<TOutput, TInput = TOutput> = { + parse: (input: TInput) => TOutput; schema: JsonObject; }; diff --git a/packages/frontend-plugin-api/src/apis/definitions/AppTreeApi.ts b/packages/frontend-plugin-api/src/apis/definitions/AppTreeApi.ts index 6c79a16964..4b5672f894 100644 --- a/packages/frontend-plugin-api/src/apis/definitions/AppTreeApi.ts +++ b/packages/frontend-plugin-api/src/apis/definitions/AppTreeApi.ts @@ -29,7 +29,7 @@ import { BackstagePlugin, Extension, ExtensionDataRef } from '../../wiring'; export interface AppNodeSpec { readonly id: string; readonly attachTo: { id: string; input: string }; - readonly extension: Extension<unknown>; + readonly extension: Extension<unknown, unknown>; readonly disabled: boolean; readonly config?: unknown; readonly source?: BackstagePlugin; diff --git a/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts b/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts index 2ad1404102..438da09b4a 100644 --- a/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts +++ b/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts @@ -28,6 +28,12 @@ export const IconBundleBlueprint = createExtensionBlueprint({ output: { icons: iconsDataRef, }, + config: { + schema: { + icons: z => z.string().default('blob'), + test: z => z.string(), + }, + }, factory: (params: { icons: { [key in string]: IconComponent } }) => params, dataRefs: { icons: iconsDataRef, diff --git a/packages/frontend-plugin-api/src/schema/createSchemaFromZod.test.ts b/packages/frontend-plugin-api/src/schema/createSchemaFromZod.test.ts index 90eba44249..477a1a58c6 100644 --- a/packages/frontend-plugin-api/src/schema/createSchemaFromZod.test.ts +++ b/packages/frontend-plugin-api/src/schema/createSchemaFromZod.test.ts @@ -25,10 +25,19 @@ describe('createSchemaFromZod', () => { }), ); - expect(() => parse({ derp: { bar: 'derp' } })).toThrow( + expect(() => { + // @ts-expect-error + return parse({ derp: { bar: 'derp' } }); + }).toThrow( `Missing required value at 'foo'; Expected number, received string at 'derp.bar'`, ); - expect(() => parse(undefined)).toThrow(`Missing required value`); - expect(() => parse('derp')).toThrow(`Expected object, received string`); + expect(() => { + // @ts-expect-error + return parse(undefined); + }).toThrow(`Missing required value`); + expect(() => { + // @ts-expect-error + return parse('derp'); + }).toThrow(`Expected object, received string`); }); }); diff --git a/packages/frontend-plugin-api/src/schema/createSchemaFromZod.ts b/packages/frontend-plugin-api/src/schema/createSchemaFromZod.ts index c69ef5dc60..9e63515ae4 100644 --- a/packages/frontend-plugin-api/src/schema/createSchemaFromZod.ts +++ b/packages/frontend-plugin-api/src/schema/createSchemaFromZod.ts @@ -25,7 +25,7 @@ import { PortableSchema } from './types'; */ export function createSchemaFromZod<TOutput, TInput>( schemaCreator: (zImpl: typeof z) => ZodSchema<TOutput, ZodTypeDef, TInput>, -): PortableSchema<TOutput> { +): PortableSchema<TOutput, TInput> { const schema = schemaCreator(z); return { // TODO: Types allow z.array etc here but it will break stuff diff --git a/packages/frontend-plugin-api/src/schema/types.ts b/packages/frontend-plugin-api/src/schema/types.ts index 9636d3b896..5644068e90 100644 --- a/packages/frontend-plugin-api/src/schema/types.ts +++ b/packages/frontend-plugin-api/src/schema/types.ts @@ -17,7 +17,7 @@ import { JsonObject } from '@backstage/types'; /** @public */ -export type PortableSchema<TOutput> = { - parse: (input: unknown) => TOutput; +export type PortableSchema<TOutput, TInput = TOutput> = { + parse: (input: TInput) => TOutput; schema: JsonObject; }; diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts index 468da21eb7..5b737746c2 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts @@ -334,6 +334,7 @@ describe('createExtension', () => { foo: 'x', bar: 'y', baz: 'z', + // @ts-expect-error qux: 'w', }), ).toEqual({ @@ -349,8 +350,9 @@ describe('createExtension', () => { foo: 'x', bar: 'bar', }); - expect(() => extension.configSchema?.parse({})).toThrow( - "Missing required value at 'foo'", - ); + expect(() => { + // @ts-expect-error + return extension.configSchema?.parse({}); + }).toThrow("Missing required value at 'foo'"); }); }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index ac91557906..cc2bec91c9 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -82,6 +82,7 @@ export interface CreateExtensionOptions< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, TConfig, + TConfigInput, TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, > { kind?: string; @@ -92,33 +93,38 @@ export interface CreateExtensionOptions< inputs?: TInputs; output: TOutput; /** @deprecated - use `config.schema` instead */ - configSchema?: PortableSchema<TConfig>; + configSchema?: PortableSchema<TConfig, TConfigInput>; config?: { schema: TConfigSchema; }; factory(context: { node: AppNode; - config: TConfig & { - [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; - }; + config: TConfig & + (string extends keyof TConfigSchema + ? {} + : { + [key in keyof TConfigSchema]: z.infer< + ReturnType<TConfigSchema[key]> + >; + }); inputs: Expand<ResolvedExtensionInputs<TInputs>>; }): Expand<ExtensionDataValues<TOutput>>; } /** @public */ -export interface ExtensionDefinition<TConfig> { +export interface ExtensionDefinition<TConfig, TConfigInput = TConfig> { $$type: '@backstage/ExtensionDefinition'; readonly kind?: string; readonly namespace?: string; readonly name?: string; readonly attachTo: { id: string; input: string }; readonly disabled: boolean; - readonly configSchema?: PortableSchema<TConfig>; + readonly configSchema?: PortableSchema<TConfig, TConfigInput>; } /** @internal */ -export interface InternalExtensionDefinition<TConfig> - extends ExtensionDefinition<TConfig> { +export interface InternalExtensionDefinition<TConfig, TConfigInput> + extends ExtensionDefinition<TConfig, TConfigInput> { readonly version: 'v1'; readonly inputs: AnyExtensionInputMap; readonly output: AnyExtensionDataMap; @@ -130,10 +136,13 @@ export interface InternalExtensionDefinition<TConfig> } /** @internal */ -export function toInternalExtensionDefinition<TConfig>( - overrides: ExtensionDefinition<TConfig>, -): InternalExtensionDefinition<TConfig> { - const internal = overrides as InternalExtensionDefinition<TConfig>; +export function toInternalExtensionDefinition<TConfig, TConfigInput>( + overrides: ExtensionDefinition<TConfig, TConfigInput>, +): InternalExtensionDefinition<TConfig, TConfigInput> { + const internal = overrides as InternalExtensionDefinition< + TConfig, + TConfigInput + >; if (internal.$$type !== '@backstage/ExtensionDefinition') { throw new Error( `Invalid extension definition instance, bad type '${internal.$$type}'`, @@ -152,10 +161,32 @@ export function createExtension< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, TConfig, + TConfigInput, TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, >( - options: CreateExtensionOptions<TOutput, TInputs, TConfig, TConfigSchema>, -): ExtensionDefinition<TConfig> { + options: CreateExtensionOptions< + TOutput, + TInputs, + TConfig, + TConfigInput, + TConfigSchema + >, +): ExtensionDefinition< + TConfig & + (string extends keyof TConfigSchema + ? {} + : { + [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; + }), + TConfigInput & + (string extends keyof TConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>; + }> + >) +> { const newConfigSchema = options.config?.schema; if (newConfigSchema && options.configSchema) { throw new Error(`Cannot provide both configSchema and config.schema`); @@ -205,5 +236,22 @@ export function createExtension< parts.push(`attachTo=${options.attachTo.id}@${options.attachTo.input}`); return `ExtensionDefinition{${parts.join(',')}}`; }, - } as InternalExtensionDefinition<TConfig>; + } as InternalExtensionDefinition< + TConfig & + (string extends keyof TConfigSchema + ? {} + : { + [key in keyof TConfigSchema]: z.infer< + ReturnType<TConfigSchema[key]> + >; + }), + TConfigInput & + (string extends keyof TConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>; + }> + >) + >; } diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts index ce3e650342..7393ca233e 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts @@ -67,6 +67,7 @@ export interface ExtensionBlueprint< TInputs extends AnyExtensionInputMap, TOutput extends AnyExtensionDataMap, TConfig extends { [key in string]: unknown }, + TConfigInput extends { [key in string]: unknown }, TDataRefs extends AnyExtensionDataMap, > { dataRefs: TDataRefs; @@ -125,7 +126,15 @@ export interface ExtensionBlueprint< [key in keyof TExtensionConfigSchema]: z.infer< ReturnType<TExtensionConfigSchema[key]> >; - } & TConfig + } & TConfig, + z.input< + z.ZodObject<{ + [key in keyof TExtensionConfigSchema]: ReturnType< + TExtensionConfigSchema[key] + >; + }> + > & + TConfigInput >; } @@ -199,7 +208,18 @@ class ExtensionBlueprintImpl< >; } & { [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; - } + }, + z.input< + z.ZodObject< + { + [key in keyof TExtensionConfigSchema]: ReturnType< + TExtensionConfigSchema[key] + >; + } & { + [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>; + } + > + > > { const schema = { ...this.options.config?.schema, @@ -279,6 +299,13 @@ export function createExtensionBlueprint< string extends keyof TConfigSchema ? {} : { [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>> }, + string extends keyof TConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>; + }> + >, TDataRefs > { return new ExtensionBlueprintImpl(options) as ExtensionBlueprint< @@ -290,6 +317,13 @@ export function createExtensionBlueprint< : { [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; }, + string extends keyof TConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>; + }> + >, TDataRefs >; } diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionOverrides.ts b/packages/frontend-plugin-api/src/wiring/createExtensionOverrides.ts index 1f88038944..75c43a36d2 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionOverrides.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionOverrides.ts @@ -23,7 +23,7 @@ import { ExtensionOverrides, FeatureFlagConfig } from './types'; /** @public */ export interface ExtensionOverridesOptions { - extensions: ExtensionDefinition<unknown>[]; + extensions: ExtensionDefinition<any, any>[]; featureFlags?: FeatureFlagConfig[]; } diff --git a/packages/frontend-plugin-api/src/wiring/createPlugin.ts b/packages/frontend-plugin-api/src/wiring/createPlugin.ts index 797c46e58e..b671d95d2f 100644 --- a/packages/frontend-plugin-api/src/wiring/createPlugin.ts +++ b/packages/frontend-plugin-api/src/wiring/createPlugin.ts @@ -34,7 +34,7 @@ export interface PluginOptions< id: string; routes?: Routes; externalRoutes?: ExternalRoutes; - extensions?: ExtensionDefinition<unknown>[]; + extensions?: ExtensionDefinition<any, any>[]; featureFlags?: FeatureFlagConfig[]; } diff --git a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts index 0a44de4ab4..eddd923702 100644 --- a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts +++ b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts @@ -26,16 +26,17 @@ import { import { PortableSchema } from '../schema'; /** @public */ -export interface Extension<TConfig> { +export interface Extension<TConfig, TConfigInput = TConfig> { $$type: '@backstage/Extension'; readonly id: string; readonly attachTo: { id: string; input: string }; readonly disabled: boolean; - readonly configSchema?: PortableSchema<TConfig>; + readonly configSchema?: PortableSchema<TConfig, TConfigInput>; } /** @internal */ -export interface InternalExtension<TConfig> extends Extension<TConfig> { +export interface InternalExtension<TConfig, TConfigInput> + extends Extension<TConfig, TConfigInput> { readonly version: 'v1'; readonly inputs: AnyExtensionInputMap; readonly output: AnyExtensionDataMap; @@ -47,10 +48,10 @@ export interface InternalExtension<TConfig> extends Extension<TConfig> { } /** @internal */ -export function toInternalExtension<TConfig>( - overrides: Extension<TConfig>, -): InternalExtension<TConfig> { - const internal = overrides as InternalExtension<TConfig>; +export function toInternalExtension<TConfig, TConfigInput>( + overrides: Extension<TConfig, TConfigInput>, +): InternalExtension<TConfig, TConfigInput> { + const internal = overrides as InternalExtension<TConfig, TConfigInput>; if (internal.$$type !== '@backstage/Extension') { throw new Error( `Invalid extension instance, bad type '${internal.$$type}'`, @@ -65,10 +66,10 @@ export function toInternalExtension<TConfig>( } /** @internal */ -export function resolveExtensionDefinition<TConfig>( - definition: ExtensionDefinition<TConfig>, +export function resolveExtensionDefinition<TConfig, TConfigInput>( + definition: ExtensionDefinition<TConfig, TConfigInput>, context?: { namespace?: string }, -): Extension<TConfig> { +): Extension<TConfig, TConfigInput> { const internalDefinition = toInternalExtensionDefinition(definition); const { name, kind, namespace: _, ...rest } = internalDefinition; const namespace = internalDefinition.namespace ?? context?.namespace; @@ -91,5 +92,5 @@ export function resolveExtensionDefinition<TConfig>( toString() { return `Extension{id=${id}}`; }, - } as Extension<TConfig>; + } as Extension<TConfig, TConfigInput>; } diff --git a/packages/frontend-test-utils/api-report.md b/packages/frontend-test-utils/api-report.md index 9629e13bfa..3b368394ca 100644 --- a/packages/frontend-test-utils/api-report.md +++ b/packages/frontend-test-utils/api-report.md @@ -39,10 +39,10 @@ export { ErrorWithContext }; // @public (undocumented) export class ExtensionTester { // (undocumented) - add<TConfig>( - extension: ExtensionDefinition<TConfig>, + add<TConfig, TConfigInput>( + extension: ExtensionDefinition<TConfig, TConfigInput>, options?: { - config?: TConfig; + config?: TConfigInput; }, ): ExtensionTester; // (undocumented) diff --git a/packages/frontend-test-utils/src/app/createExtensionTester.tsx b/packages/frontend-test-utils/src/app/createExtensionTester.tsx index a98879fbba..69c4b09d06 100644 --- a/packages/frontend-test-utils/src/app/createExtensionTester.tsx +++ b/packages/frontend-test-utils/src/app/createExtensionTester.tsx @@ -88,9 +88,9 @@ const TestAppNavExtension = createExtension({ /** @public */ export class ExtensionTester { /** @internal */ - static forSubject<TConfig>( - subject: ExtensionDefinition<TConfig>, - options?: { config?: TConfig }, + static forSubject<TConfig, TConfigInput>( + subject: ExtensionDefinition<TConfig, TConfigInput>, + options?: { config?: TConfigInput }, ): ExtensionTester { const tester = new ExtensionTester(); const { output, factory, ...rest } = toInternalExtensionDefinition(subject); @@ -107,7 +107,7 @@ export class ExtensionTester { path: '/', }), }); - tester.add(extension, options); + tester.add(extension, options as TConfigInput & {}); return tester; } @@ -117,9 +117,9 @@ export class ExtensionTester { config?: JsonValue; }>(); - add<TConfig>( - extension: ExtensionDefinition<TConfig>, - options?: { config?: TConfig }, + add<TConfig, TConfigInput>( + extension: ExtensionDefinition<TConfig, TConfigInput>, + options?: { config?: TConfigInput }, ): ExtensionTester { const { name, namespace } = extension; diff --git a/plugins/catalog-react/api-report-alpha.md b/plugins/catalog-react/api-report-alpha.md index d2bfb29458..1ffa67068f 100644 --- a/plugins/catalog-react/api-report-alpha.md +++ b/plugins/catalog-react/api-report-alpha.md @@ -115,7 +115,7 @@ export function createEntityCardExtension< config: TConfig; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }) => Promise<JSX.Element>; -}): ExtensionDefinition<TConfig>; +}): ExtensionDefinition<TConfig & {}, TConfig & {}>; // @alpha (undocumented) export function createEntityContentExtension< @@ -138,11 +138,18 @@ export function createEntityContentExtension< loader: (options: { inputs: Expand<ResolvedExtensionInputs<TInputs>>; }) => Promise<JSX.Element>; -}): ExtensionDefinition<{ - title: string; - path: string; - filter?: string | undefined; -}>; +}): ExtensionDefinition< + { + title: string; + path: string; + filter?: string | undefined; + }, + { + filter?: string | undefined; + title?: string | undefined; + path?: string | undefined; + } +>; // @alpha export function isOwnerOf(owner: Entity, entity: Entity): boolean; diff --git a/plugins/catalog/api-report-alpha.md b/plugins/catalog/api-report-alpha.md index 102e2a7aa3..a62b047c4c 100644 --- a/plugins/catalog/api-report-alpha.md +++ b/plugins/catalog/api-report-alpha.md @@ -99,14 +99,14 @@ export const catalogTranslationRef: TranslationRef< // @alpha (undocumented) export function createCatalogFilterExtension< TInputs extends AnyExtensionInputMap, - TConfig = never, + TConfig, >(options: { namespace?: string; name?: string; inputs?: TInputs; configSchema?: PortableSchema<TConfig>; loader: (options: { config: TConfig }) => Promise<JSX.Element>; -}): ExtensionDefinition<TConfig>; +}): ExtensionDefinition<TConfig & {}, TConfig & {}>; // @alpha (undocumented) const _default: BackstagePlugin< diff --git a/plugins/catalog/src/alpha/createCatalogFilterExtension.tsx b/plugins/catalog/src/alpha/createCatalogFilterExtension.tsx index 48ee647b81..d8a218f8f3 100644 --- a/plugins/catalog/src/alpha/createCatalogFilterExtension.tsx +++ b/plugins/catalog/src/alpha/createCatalogFilterExtension.tsx @@ -26,7 +26,7 @@ import { /** @alpha */ export function createCatalogFilterExtension< TInputs extends AnyExtensionInputMap, - TConfig = never, + TConfig, >(options: { namespace?: string; name?: string; diff --git a/plugins/search-react/api-report-alpha.md b/plugins/search-react/api-report-alpha.md index aea85d0f81..3da9ac23a4 100644 --- a/plugins/search-react/api-report-alpha.md +++ b/plugins/search-react/api-report-alpha.md @@ -25,7 +25,7 @@ export function createSearchResultListItemExtension< }, >( options: SearchResultItemExtensionOptions<TConfig>, -): ExtensionDefinition<TConfig>; +): ExtensionDefinition<TConfig & {}, TConfig & {}>; // @alpha (undocumented) export namespace createSearchResultListItemExtension { diff --git a/plugins/search/api-report-alpha.md b/plugins/search/api-report-alpha.md index db2999ba25..e9b86f1f87 100644 --- a/plugins/search/api-report-alpha.md +++ b/plugins/search/api-report-alpha.md @@ -17,18 +17,29 @@ const _default: BackstagePlugin< export default _default; // @alpha (undocumented) -export const searchApi: ExtensionDefinition<{}>; +export const searchApi: ExtensionDefinition<{}, {}>; // @alpha (undocumented) -export const searchNavItem: ExtensionDefinition<{ - title: string; -}>; +export const searchNavItem: ExtensionDefinition< + { + title: string; + }, + { + title?: string | undefined; + } +>; // @alpha (undocumented) -export const searchPage: ExtensionDefinition<{ - path: string; - noTrack: boolean; -}>; +export const searchPage: ExtensionDefinition< + { + path: string; + noTrack: boolean; + }, + { + path: string; + noTrack: boolean; + } +>; // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/techdocs/api-report-alpha.md b/plugins/techdocs/api-report-alpha.md index cf9f5fa9a3..04a0c5c512 100644 --- a/plugins/techdocs/api-report-alpha.md +++ b/plugins/techdocs/api-report-alpha.md @@ -23,13 +23,22 @@ const _default: BackstagePlugin< export default _default; // @alpha (undocumented) -export const techDocsSearchResultListItemExtension: ExtensionDefinition<{ - lineClamp: number; - noTrack: boolean; - asListItem: boolean; - asLink: boolean; - title?: string | undefined; -}>; +export const techDocsSearchResultListItemExtension: ExtensionDefinition< + { + lineClamp: number; + noTrack: boolean; + asListItem: boolean; + asLink: boolean; + title?: string | undefined; + }, + { + lineClamp: number; + noTrack: boolean; + asListItem: boolean; + asLink: boolean; + title?: string | undefined; + } +>; // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/user-settings/api-report-alpha.md b/plugins/user-settings/api-report-alpha.md index b06fd1e583..fdb2c5f6bf 100644 --- a/plugins/user-settings/api-report-alpha.md +++ b/plugins/user-settings/api-report-alpha.md @@ -18,9 +18,14 @@ const _default: BackstagePlugin< export default _default; // @alpha (undocumented) -export const settingsNavItem: ExtensionDefinition<{ - title: string; -}>; +export const settingsNavItem: ExtensionDefinition< + { + title: string; + }, + { + title?: string | undefined; + } +>; // @alpha (undocumented) export const userSettingsTranslationRef: TranslationRef< From 634909993c888a0857fba702ad2b692c96858933 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Wed, 24 Jul 2024 14:37:38 +0200 Subject: [PATCH 423/510] chore: added changeset Signed-off-by: blam <ben@blam.sh> --- .changeset/young-games-visit.md | 14 ++++++++++++++ packages/frontend-plugin-api/api-report.md | 10 ++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 .changeset/young-games-visit.md diff --git a/.changeset/young-games-visit.md b/.changeset/young-games-visit.md new file mode 100644 index 0000000000..467abcec86 --- /dev/null +++ b/.changeset/young-games-visit.md @@ -0,0 +1,14 @@ +--- +'@backstage/frontend-plugin-api': patch +'@backstage/frontend-test-utils': patch +'@backstage/frontend-app-api': patch +'@backstage/core-compat-api': patch +'@backstage/plugin-catalog-react': patch +'@backstage/plugin-user-settings': patch +'@backstage/plugin-search-react': patch +'@backstage/plugin-techdocs': patch +'@backstage/plugin-catalog': patch +'@backstage/plugin-search': patch +--- + +Added config input type to the extensions diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index c4a96cba59..2c92f863e8 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -1221,8 +1221,14 @@ export const IconBundleBlueprint: ExtensionBlueprint< {} >; }, - {}, - {}, + { + icons: string; + test: string; + }, + { + test: string; + icons?: string | undefined; + }, { icons: ConfigurableExtensionDataRef< 'core.icons', From e6e7d862fec44754faac302e6e4d7021a19b9ef0 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Wed, 24 Jul 2024 15:04:05 +0200 Subject: [PATCH 424/510] cli: use lowercase es2022 Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/shaggy-dodos-applaud.md | 5 +++++ packages/cli/src/lib/bundler/transforms.ts | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 .changeset/shaggy-dodos-applaud.md diff --git a/.changeset/shaggy-dodos-applaud.md b/.changeset/shaggy-dodos-applaud.md new file mode 100644 index 0000000000..b7f968aa39 --- /dev/null +++ b/.changeset/shaggy-dodos-applaud.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Switched the target from `'ES2022'` to `'es2022'` for better compatibility with older versions of `swc`. diff --git a/packages/cli/src/lib/bundler/transforms.ts b/packages/cli/src/lib/bundler/transforms.ts index 1be54f7a73..302b2fbe68 100644 --- a/packages/cli/src/lib/bundler/transforms.ts +++ b/packages/cli/src/lib/bundler/transforms.ts @@ -57,7 +57,7 @@ export const transforms = (options: TransformOptions): Transforms => { loader: require.resolve('swc-loader'), options: { jsc: { - target: 'ES2022', + target: 'es2022', externalHelpers: !isBackend, parser: { syntax: 'typescript', @@ -85,7 +85,7 @@ export const transforms = (options: TransformOptions): Transforms => { loader: require.resolve('swc-loader'), options: { jsc: { - target: 'ES2022', + target: 'es2022', externalHelpers: !isBackend, parser: { syntax: 'ecmascript', From 41fa9d58c50a12017dac05067e4ceb04d1748ee3 Mon Sep 17 00:00:00 2001 From: Nurit Izrailov <nuriti@spotify.com> Date: Wed, 24 Jul 2024 09:16:30 -0400 Subject: [PATCH 425/510] run yarn backstage-cli repo fix Signed-off-by: Nurit Izrailov <nuriti@spotify.com> --- plugins/kubernetes/package.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index 6c5a65dddd..d44d175211 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -14,9 +14,7 @@ ] }, "publishConfig": { - "access": "public", - "main": "dist/index.esm.js", - "types": "dist/index.d.ts" + "access": "public" }, "keywords": [ "backstage", From aac3c52d2229adf6bc19fb494b355942d9ec837b Mon Sep 17 00:00:00 2001 From: rghara <rghara@outlook.com> Date: Wed, 24 Jul 2024 11:33:41 -0400 Subject: [PATCH 426/510] In the Gettin Started/authentication document SignInPage is already imported. Removing the duplicate import that causes compilation error. import { SignInPage } from '@backstage/core-components'; Signed-off-by: rghara <rghara@outlook.com> --- docs/getting-started/config/authentication.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/getting-started/config/authentication.md b/docs/getting-started/config/authentication.md index 874964696a..e97ed3d89c 100644 --- a/docs/getting-started/config/authentication.md +++ b/docs/getting-started/config/authentication.md @@ -50,7 +50,6 @@ Open `packages/app/src/App.tsx` and below the last `import` line, add: ```typescript title="packages/app/src/App.tsx" import { githubAuthApiRef } from '@backstage/core-plugin-api'; -import { SignInPage } from '@backstage/core-components'; ``` Search for `const app = createApp({` in this file, and below `apis,` add: From 132529ae23a1295c294e42b55628d1fcc8cd033c Mon Sep 17 00:00:00 2001 From: raphtalia <59540801+raphtalia@users.noreply.github.com> Date: Wed, 24 Jul 2024 10:36:00 -0500 Subject: [PATCH 427/510] Add Cigna/Evernorth Signed-off-by: raphtalia <59540801+raphtalia@users.noreply.github.com> --- ADOPTERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ADOPTERS.md b/ADOPTERS.md index 870b4c93d4..3b534052f1 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -274,3 +274,4 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [Grupo OLX](https://www.olx.com.br/) | [@marciorgb](https://github.com/marciorgb), [@jeffbraga](https://github.com/jeffbraga), [@rogerfernandes](https://github.com/rogerfernandes), [@stockrt](https://github.com/stockrt) | At Grupo OLX, we are using Backstage to reduce friction and enhance developer autonomy by creating Golden Paths, which automate previously manual processes. Additionally, Backstage's catalog integrates various views of our organizational structure and workflows, offering a comprehensive overview of how different components interconnect. | | [DPG Media](https://www.dpgmediagroup.com) | [@benjidotsh](https://github.com/benjidotsh), [@lvstb](https://github.com/lvstb), [@ssliman](https://github.com/ssliman), [@edewel-beep](https://github.com/edewel-beep) | Access to infrastructure, documentation and internal tooling | | [Baloise](https://www.baloise.ch) | [@dweber019](https://github.com/dweber019), [@mikevader](https://github.com/mikevader) | We are using Backstage as internal developer protal for use cases like software catalog, documentation, infrastructure. | +| [Cigna](https://www.cigna.com/) / [Evernorth](https://www.evernorth.com/) | [@raphtalia](https://github.com/raphtalia), [Devon Paluso](mailto:Devon.Paluso@evernorth.com), [Bryan Rego](mailto:Bryan.Rego@evernorth.com), [Ian Skillings](mailto:Ian.Skillings@evernorth.com) | Internal developer portal providing TechDocs, software templates, centralized secret management, with information consolidation from ServiceNow, Okta, GitHub, GitLab, and WebEx. | From 4698e1f4d43b26c11d71192e267d5e9f950096a7 Mon Sep 17 00:00:00 2001 From: MT Lewis <mtlewis@users.noreply.github.com> Date: Wed, 24 Jul 2024 18:04:13 +0100 Subject: [PATCH 428/510] techdocs: add common package for annotation constants Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com> --- .changeset/quick-roses-juggle.md | 5 +++ plugins/techdocs-backend/package.json | 1 + plugins/techdocs-common/.eslintrc.js | 1 + plugins/techdocs-common/README.md | 3 ++ plugins/techdocs-common/api-report.md | 11 +++++ plugins/techdocs-common/catalog-info.yaml | 11 +++++ plugins/techdocs-common/package.json | 52 +++++++++++++++++++++++ plugins/techdocs-common/src/constants.ts | 20 +++++++++ plugins/techdocs-common/src/index.test.ts | 24 +++++++++++ plugins/techdocs-common/src/index.ts | 22 ++++++++++ plugins/techdocs-node/package.json | 1 + plugins/techdocs-react/package.json | 1 + plugins/techdocs/package.json | 1 + 13 files changed, 153 insertions(+) create mode 100644 .changeset/quick-roses-juggle.md create mode 100644 plugins/techdocs-common/.eslintrc.js create mode 100644 plugins/techdocs-common/README.md create mode 100644 plugins/techdocs-common/api-report.md create mode 100644 plugins/techdocs-common/catalog-info.yaml create mode 100644 plugins/techdocs-common/package.json create mode 100644 plugins/techdocs-common/src/constants.ts create mode 100644 plugins/techdocs-common/src/index.test.ts create mode 100644 plugins/techdocs-common/src/index.ts diff --git a/.changeset/quick-roses-juggle.md b/.changeset/quick-roses-juggle.md new file mode 100644 index 0000000000..981bd8591a --- /dev/null +++ b/.changeset/quick-roses-juggle.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs-common': minor +--- + +Initial release of the techdocs-common package. diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index 0bf2381a8c..fc862ad909 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -8,6 +8,7 @@ "pluginPackages": [ "@backstage/plugin-techdocs", "@backstage/plugin-techdocs-backend", + "@backstage/plugin-techdocs-common", "@backstage/plugin-techdocs-node", "@backstage/plugin-techdocs-react" ] diff --git a/plugins/techdocs-common/.eslintrc.js b/plugins/techdocs-common/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/techdocs-common/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/techdocs-common/README.md b/plugins/techdocs-common/README.md new file mode 100644 index 0000000000..be8bf64d0b --- /dev/null +++ b/plugins/techdocs-common/README.md @@ -0,0 +1,3 @@ +# @backstage/plugin-techdocs-common + +Common functionality for TechDocs diff --git a/plugins/techdocs-common/api-report.md b/plugins/techdocs-common/api-report.md new file mode 100644 index 0000000000..c7e1829a28 --- /dev/null +++ b/plugins/techdocs-common/api-report.md @@ -0,0 +1,11 @@ +## API Report File for "@backstage/plugin-techdocs-common" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +// @public (undocumented) +export const TECHDOCS_ANNOTATION = 'backstage.io/techdocs-ref'; + +// @public (undocumented) +export const TECHDOCS_EXTERNAL_ANNOTATION = 'backstage.io/techdocs-entity'; +``` diff --git a/plugins/techdocs-common/catalog-info.yaml b/plugins/techdocs-common/catalog-info.yaml new file mode 100644 index 0000000000..16c7e66638 --- /dev/null +++ b/plugins/techdocs-common/catalog-info.yaml @@ -0,0 +1,11 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-plugin-techdocs-common + title: '@backstage/plugin-techdocs-common' + description: >- + Common functionality for TechDocs +spec: + lifecycle: production + type: backstage-common-library + owner: techdocs-maintainers diff --git a/plugins/techdocs-common/package.json b/plugins/techdocs-common/package.json new file mode 100644 index 0000000000..3e9eebbd23 --- /dev/null +++ b/plugins/techdocs-common/package.json @@ -0,0 +1,52 @@ +{ + "name": "@backstage/plugin-techdocs-common", + "version": "0.0.0", + "description": "Common functionality for TechDocs", + "backstage": { + "role": "common-library", + "pluginId": "techdocs", + "pluginPackages": [ + "@backstage/plugin-techdocs", + "@backstage/plugin-techdocs-backend", + "@backstage/plugin-techdocs-common", + "@backstage/plugin-techdocs-node", + "@backstage/plugin-techdocs-react" + ] + }, + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "keywords": [ + "backstage", + "techdocs" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/techdocs-common" + }, + "bugs": { + "url": "https://github.com/backstage/backstage/issues" + }, + "license": "Apache-2.0", + "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], + "scripts": { + "build": "backstage-cli package build", + "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack", + "test": "backstage-cli package test" + }, + "devDependencies": { + "@backstage/cli": "workspace:^" + } +} diff --git a/plugins/techdocs-common/src/constants.ts b/plugins/techdocs-common/src/constants.ts new file mode 100644 index 0000000000..40187f41ce --- /dev/null +++ b/plugins/techdocs-common/src/constants.ts @@ -0,0 +1,20 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** @public */ +export const TECHDOCS_ANNOTATION = 'backstage.io/techdocs-ref'; +/** @public */ +export const TECHDOCS_EXTERNAL_ANNOTATION = 'backstage.io/techdocs-entity'; diff --git a/plugins/techdocs-common/src/index.test.ts b/plugins/techdocs-common/src/index.test.ts new file mode 100644 index 0000000000..555aa06f4c --- /dev/null +++ b/plugins/techdocs-common/src/index.test.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as anything from './'; + +describe('techdocs-common', () => { + // TODO: Test real things once they exist. + it('should exist', () => { + expect(anything).toBeTruthy(); + }); +}); diff --git a/plugins/techdocs-common/src/index.ts b/plugins/techdocs-common/src/index.ts new file mode 100644 index 0000000000..d5e7818f50 --- /dev/null +++ b/plugins/techdocs-common/src/index.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Common functionality for TechDocs + * + * @packageDocumentation + */ +export * from './constants'; diff --git a/plugins/techdocs-node/package.json b/plugins/techdocs-node/package.json index 615a0b7235..94711e8933 100644 --- a/plugins/techdocs-node/package.json +++ b/plugins/techdocs-node/package.json @@ -8,6 +8,7 @@ "pluginPackages": [ "@backstage/plugin-techdocs", "@backstage/plugin-techdocs-backend", + "@backstage/plugin-techdocs-common", "@backstage/plugin-techdocs-node", "@backstage/plugin-techdocs-react" ] diff --git a/plugins/techdocs-react/package.json b/plugins/techdocs-react/package.json index 2db27e2c60..ae1f72c8c9 100644 --- a/plugins/techdocs-react/package.json +++ b/plugins/techdocs-react/package.json @@ -8,6 +8,7 @@ "pluginPackages": [ "@backstage/plugin-techdocs", "@backstage/plugin-techdocs-backend", + "@backstage/plugin-techdocs-common", "@backstage/plugin-techdocs-node", "@backstage/plugin-techdocs-react" ] diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index b1717ce92e..2992c7a067 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -8,6 +8,7 @@ "pluginPackages": [ "@backstage/plugin-techdocs", "@backstage/plugin-techdocs-backend", + "@backstage/plugin-techdocs-common", "@backstage/plugin-techdocs-node", "@backstage/plugin-techdocs-react" ] From 4cda00c9968835174bed5925e4e0c24548063daf Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Wed, 24 Jul 2024 15:04:05 +0200 Subject: [PATCH 429/510] cli: use lowercase es2022 Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> Signed-off-by: Nishkarsh Raj <nishkarshraj000@gmail.com> --- .changeset/shaggy-dodos-applaud.md | 5 +++++ packages/cli/src/lib/bundler/transforms.ts | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 .changeset/shaggy-dodos-applaud.md diff --git a/.changeset/shaggy-dodos-applaud.md b/.changeset/shaggy-dodos-applaud.md new file mode 100644 index 0000000000..b7f968aa39 --- /dev/null +++ b/.changeset/shaggy-dodos-applaud.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Switched the target from `'ES2022'` to `'es2022'` for better compatibility with older versions of `swc`. diff --git a/packages/cli/src/lib/bundler/transforms.ts b/packages/cli/src/lib/bundler/transforms.ts index 1be54f7a73..302b2fbe68 100644 --- a/packages/cli/src/lib/bundler/transforms.ts +++ b/packages/cli/src/lib/bundler/transforms.ts @@ -57,7 +57,7 @@ export const transforms = (options: TransformOptions): Transforms => { loader: require.resolve('swc-loader'), options: { jsc: { - target: 'ES2022', + target: 'es2022', externalHelpers: !isBackend, parser: { syntax: 'typescript', @@ -85,7 +85,7 @@ export const transforms = (options: TransformOptions): Transforms => { loader: require.resolve('swc-loader'), options: { jsc: { - target: 'ES2022', + target: 'es2022', externalHelpers: !isBackend, parser: { syntax: 'ecmascript', From 93e8169b053ff6c5eb48ac139f7e83a391cade81 Mon Sep 17 00:00:00 2001 From: Nishkarsh Raj <nishkarshraj000@gmail.com> Date: Wed, 24 Jul 2024 18:45:19 +0000 Subject: [PATCH 430/510] Adding StatusNeo as Commercial Partners for Backstage.io Signed-off-by: Nishkarsh Raj <nishkarshraj000@gmail.com> --- microsite/src/pages/community/index.tsx | 5 +++++ microsite/static/img/partner-logo-statusneo.png | Bin 0 -> 4663 bytes 2 files changed, 5 insertions(+) create mode 100644 microsite/static/img/partner-logo-statusneo.png diff --git a/microsite/src/pages/community/index.tsx b/microsite/src/pages/community/index.tsx index c331638c78..a32f5edd13 100644 --- a/microsite/src/pages/community/index.tsx +++ b/microsite/src/pages/community/index.tsx @@ -96,6 +96,11 @@ const Community = () => { url: 'https://tanzu.vmware.com/developer-portal', logo: 'img/partner-logo-tanzubybroadcom.png', }, + { + name: 'StatusNeo', + url: 'https://statusneo.com/backstage', + logo: 'img/partner-logo-statusneo.png', + }, ]; //#endregion diff --git a/microsite/static/img/partner-logo-statusneo.png b/microsite/static/img/partner-logo-statusneo.png new file mode 100644 index 0000000000000000000000000000000000000000..4209ecaca30647db6ea50cc2ceb4ad2d8e07aa92 GIT binary patch literal 4663 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 literal 0 HcmV?d00001 From 69bd94040808db493e3be77d5daf717dfbaa8b5d Mon Sep 17 00:00:00 2001 From: MT Lewis <mtlewis@users.noreply.github.com> Date: Wed, 24 Jul 2024 18:03:55 +0100 Subject: [PATCH 431/510] techdocs: switch to using constants from techdocs-common for annotations Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com> --- .changeset/eighty-emus-leave.md | 7 +++++ plugins/techdocs-backend/package.json | 1 + .../search/DefaultTechDocsCollator.test.ts | 3 +- .../src/search/DefaultTechDocsCollator.ts | 3 +- plugins/techdocs-node/package.json | 1 + plugins/techdocs-node/src/helpers.test.ts | 29 ++++++++++--------- plugins/techdocs-node/src/helpers.ts | 11 ++----- .../src/stages/prepare/dir.test.ts | 7 +++-- .../techdocs-node/src/stages/prepare/dir.ts | 6 ++-- .../src/stages/prepare/preparers.ts | 6 ++-- plugins/techdocs/package.json | 1 + plugins/techdocs/src/EntityPageDocs.tsx | 3 +- plugins/techdocs/src/Router.tsx | 8 ++--- .../home/components/TechDocsCustomHome.tsx | 5 ++-- .../src/home/components/TechDocsPicker.tsx | 3 +- yarn.lock | 11 +++++++ 16 files changed, 61 insertions(+), 44 deletions(-) create mode 100644 .changeset/eighty-emus-leave.md diff --git a/.changeset/eighty-emus-leave.md b/.changeset/eighty-emus-leave.md new file mode 100644 index 0000000000..8e02c7cf94 --- /dev/null +++ b/.changeset/eighty-emus-leave.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-techdocs-backend': patch +'@backstage/plugin-techdocs-node': patch +'@backstage/plugin-techdocs': patch +--- + +Use annotation constants from new techdocs-common package. diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index fc862ad909..2b4f23b342 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -68,6 +68,7 @@ "@backstage/plugin-catalog-common": "workspace:^", "@backstage/plugin-permission-common": "workspace:^", "@backstage/plugin-search-backend-module-techdocs": "workspace:^", + "@backstage/plugin-techdocs-common": "workspace:^", "@backstage/plugin-techdocs-node": "workspace:^", "@types/express": "^4.17.6", "express": "^4.17.1", diff --git a/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.test.ts b/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.test.ts index 64b0917202..96f8cfd696 100644 --- a/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.test.ts +++ b/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.test.ts @@ -28,6 +28,7 @@ import { import { setupServer } from 'msw/node'; import { rest } from 'msw'; import { ConfigReader } from '@backstage/config'; +import { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common'; const logger = loggerToWinstonLogger(mockServices.logger.mock()); @@ -66,7 +67,7 @@ const expectedEntities: Entity[] = [ name: 'test-entity-with-docs', description: 'Documented description', annotations: { - 'backstage.io/techdocs-ref': './', + [TECHDOCS_ANNOTATION]: './', }, }, spec: { diff --git a/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.ts b/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.ts index b683127172..527846df79 100644 --- a/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.ts +++ b/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.ts @@ -37,6 +37,7 @@ import { CATALOG_FILTER_EXISTS, } from '@backstage/catalog-client'; import { TechDocsDocument } from '@backstage/plugin-techdocs-node'; +import { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common'; interface MkSearchIndexDoc { title: string; @@ -107,7 +108,7 @@ export class DefaultTechDocsCollator { ).getEntities( { filter: { - 'metadata.annotations.backstage.io/techdocs-ref': + [`metadata.annotations.${TECHDOCS_ANNOTATION}`]: CATALOG_FILTER_EXISTS, }, fields: [ diff --git a/plugins/techdocs-node/package.json b/plugins/techdocs-node/package.json index 94711e8933..16cf0d9155 100644 --- a/plugins/techdocs-node/package.json +++ b/plugins/techdocs-node/package.json @@ -61,6 +61,7 @@ "@backstage/integration": "workspace:^", "@backstage/integration-aws-node": "workspace:^", "@backstage/plugin-search-common": "workspace:^", + "@backstage/plugin-techdocs-common": "workspace:^", "@google-cloud/storage": "^7.0.0", "@smithy/node-http-handler": "^2.1.7", "@trendyol-js/openstack-swift-sdk": "^0.0.7", diff --git a/plugins/techdocs-node/src/helpers.test.ts b/plugins/techdocs-node/src/helpers.test.ts index 1b25abded3..4f77a5432b 100644 --- a/plugins/techdocs-node/src/helpers.test.ts +++ b/plugins/techdocs-node/src/helpers.test.ts @@ -27,6 +27,7 @@ import { ScmIntegrations } from '@backstage/integration'; import os from 'os'; import path from 'path'; import { Readable } from 'stream'; +import { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common'; import { getDocFilesFromRepository, getLocationForEntity, @@ -64,7 +65,7 @@ const metadataBase = { const goodAnnotation = { annotations: { - 'backstage.io/techdocs-ref': + [TECHDOCS_ANNOTATION]: 'url:https://github.com/backstage/backstage/blob/master/subfolder/', }, }; @@ -81,7 +82,7 @@ const mockEntityWithAnnotation: Entity = { const badAnnotation = { annotations: { - 'backstage.io/techdocs-ref': 'bad-annotation', + [TECHDOCS_ANNOTATION]: 'bad-annotation', }, }; @@ -102,7 +103,7 @@ afterEach(() => jest.resetAllMocks()); describe('parseReferenceAnnotation', () => { it('should parse annotation', () => { const parsedLocationAnnotation = parseReferenceAnnotation( - 'backstage.io/techdocs-ref', + TECHDOCS_ANNOTATION, mockEntityWithAnnotation, ); expect(parsedLocationAnnotation.type).toBe('url'); @@ -113,14 +114,14 @@ describe('parseReferenceAnnotation', () => { it('should throw error without annotation', () => { expect(() => { - parseReferenceAnnotation('backstage.io/techdocs-ref', entityBase); + parseReferenceAnnotation(TECHDOCS_ANNOTATION, entityBase); }).toThrow(/No location annotation/); }); it('should throw error with bad annotation', () => { expect(() => { parseReferenceAnnotation( - 'backstage.io/techdocs-ref', + TECHDOCS_ANNOTATION, mockEntityWithBadAnnotation, ); }).toThrow(/Unable to parse/); @@ -146,14 +147,14 @@ describe('transformDirLocation', () => { metadata: { name: 'test', annotations: { - 'backstage.io/techdocs-ref': techdocsRef, + [TECHDOCS_ANNOTATION]: techdocsRef, }, }, }; const result = transformDirLocation( entity, - parseReferenceAnnotation('backstage.io/techdocs-ref', entity), + parseReferenceAnnotation(TECHDOCS_ANNOTATION, entity), scmIntegrations, ); @@ -179,14 +180,14 @@ describe('transformDirLocation', () => { metadata: { name: 'test', annotations: { - 'backstage.io/techdocs-ref': techdocsRef, + [TECHDOCS_ANNOTATION]: techdocsRef, }, }, }; const result = transformDirLocation( entity, - parseReferenceAnnotation('backstage.io/techdocs-ref', entity), + parseReferenceAnnotation(TECHDOCS_ANNOTATION, entity), scmIntegrations, ); @@ -206,7 +207,7 @@ describe('transformDirLocation', () => { metadata: { name: 'test', annotations: { - 'backstage.io/techdocs-ref': 'dir:..', + [TECHDOCS_ANNOTATION]: 'dir:..', }, }, }; @@ -214,7 +215,7 @@ describe('transformDirLocation', () => { expect(() => transformDirLocation( entity, - parseReferenceAnnotation('backstage.io/techdocs-ref', entity), + parseReferenceAnnotation(TECHDOCS_ANNOTATION, entity), scmIntegrations, ), ).toThrow( @@ -234,7 +235,7 @@ describe('transformDirLocation', () => { metadata: { name: 'test', annotations: { - 'backstage.io/techdocs-ref': 'dir:.', + [TECHDOCS_ANNOTATION]: 'dir:.', }, }, }; @@ -242,7 +243,7 @@ describe('transformDirLocation', () => { expect(() => transformDirLocation( entity, - parseReferenceAnnotation('backstage.io/techdocs-ref', entity), + parseReferenceAnnotation(TECHDOCS_ANNOTATION, entity), scmIntegrations, ), ).toThrow(/Unable to resolve location type other/); @@ -262,7 +263,7 @@ describe('getLocationForEntity', () => { metadata: { name: 'test', annotations: { - 'backstage.io/techdocs-ref': 'dir:.', + [TECHDOCS_ANNOTATION]: 'dir:.', }, }, }; diff --git a/plugins/techdocs-node/src/helpers.ts b/plugins/techdocs-node/src/helpers.ts index c293d16896..d64c7fc289 100644 --- a/plugins/techdocs-node/src/helpers.ts +++ b/plugins/techdocs-node/src/helpers.ts @@ -23,6 +23,7 @@ import { } from '@backstage/catalog-model'; import { InputError } from '@backstage/errors'; import { ScmIntegrationRegistry } from '@backstage/integration'; +import { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common'; import path from 'path'; import { Logger } from 'winston'; import { PreparerResponse, RemoteProtocol } from './stages/prepare/types'; @@ -122,10 +123,7 @@ export const getLocationForEntity = ( entity: Entity, scmIntegration: ScmIntegrationRegistry, ): ParsedLocationAnnotation => { - const annotation = parseReferenceAnnotation( - 'backstage.io/techdocs-ref', - entity, - ); + const annotation = parseReferenceAnnotation(TECHDOCS_ANNOTATION, entity); switch (annotation.type) { case 'url': @@ -149,10 +147,7 @@ export const getDocFilesFromRepository = async ( entity: Entity, opts?: { etag?: string; logger?: Logger }, ): Promise<PreparerResponse> => { - const { target } = parseReferenceAnnotation( - 'backstage.io/techdocs-ref', - entity, - ); + const { target } = parseReferenceAnnotation(TECHDOCS_ANNOTATION, entity); opts?.logger?.debug(`Reading files from ${target}`); // readTree will throw NotModifiedError if etag has not changed. diff --git a/plugins/techdocs-node/src/stages/prepare/dir.test.ts b/plugins/techdocs-node/src/stages/prepare/dir.test.ts index 5fbd56264e..a26c423aaf 100644 --- a/plugins/techdocs-node/src/stages/prepare/dir.test.ts +++ b/plugins/techdocs-node/src/stages/prepare/dir.test.ts @@ -14,6 +14,7 @@ * limitations under the License. */ import { UrlReader, loggerToWinstonLogger } from '@backstage/backend-common'; +import { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common'; import { ConfigReader } from '@backstage/config'; import { DirectoryPreparer } from './dir'; import { mockServices } from '@backstage/backend-test-utils'; @@ -61,7 +62,7 @@ describe('directory preparer', () => { const mockEntity = createMockEntity({ 'backstage.io/managed-by-location': 'file:/directory/documented-component.yaml', - 'backstage.io/techdocs-ref': 'dir:./our-documentation', + [TECHDOCS_ANNOTATION]: 'dir:./our-documentation', }); const { preparedDir } = await directoryPreparer.prepare(mockEntity); @@ -77,7 +78,7 @@ describe('directory preparer', () => { const mockEntity = createMockEntity({ 'backstage.io/managed-by-location': 'file:/directory/documented-component.yaml', - 'backstage.io/techdocs-ref': 'dir:/our-documentation/techdocs', + [TECHDOCS_ANNOTATION]: 'dir:/our-documentation/techdocs', }); await expect(directoryPreparer.prepare(mockEntity)).rejects.toThrow( @@ -94,7 +95,7 @@ describe('directory preparer', () => { const mockEntity = createMockEntity({ 'backstage.io/managed-by-location': 'does-not-exist:https://github.com/backstage/backstage/blob/master/catalog-info.yaml', - 'backstage.io/techdocs-ref': 'dir:./docs', + [TECHDOCS_ANNOTATION]: 'dir:./docs', }); await expect(directoryPreparer.prepare(mockEntity)).rejects.toThrow( diff --git a/plugins/techdocs-node/src/stages/prepare/dir.ts b/plugins/techdocs-node/src/stages/prepare/dir.ts index 6be9510a51..1c18b17a1e 100644 --- a/plugins/techdocs-node/src/stages/prepare/dir.ts +++ b/plugins/techdocs-node/src/stages/prepare/dir.ts @@ -22,6 +22,7 @@ import { ScmIntegrationRegistry, ScmIntegrations, } from '@backstage/integration'; +import { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common'; import { Logger } from 'winston'; import { parseReferenceAnnotation, transformDirLocation } from '../../helpers'; import { @@ -70,10 +71,7 @@ export class DirectoryPreparer implements PreparerBase { entity: Entity, options?: PreparerOptions, ): Promise<PreparerResponse> { - const annotation = parseReferenceAnnotation( - 'backstage.io/techdocs-ref', - entity, - ); + const annotation = parseReferenceAnnotation(TECHDOCS_ANNOTATION, entity); const { type, target } = transformDirLocation( entity, annotation, diff --git a/plugins/techdocs-node/src/stages/prepare/preparers.ts b/plugins/techdocs-node/src/stages/prepare/preparers.ts index d0ba61bf40..f7df8b67f4 100644 --- a/plugins/techdocs-node/src/stages/prepare/preparers.ts +++ b/plugins/techdocs-node/src/stages/prepare/preparers.ts @@ -15,6 +15,7 @@ */ import { Entity } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; +import { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common'; import { parseReferenceAnnotation } from '../../helpers'; import { DirectoryPreparer } from './dir'; import { UrlPreparer } from './url'; @@ -78,10 +79,7 @@ export class Preparers implements PreparerBuilder { * @returns */ get(entity: Entity): PreparerBase { - const { type } = parseReferenceAnnotation( - 'backstage.io/techdocs-ref', - entity, - ); + const { type } = parseReferenceAnnotation(TECHDOCS_ANNOTATION, entity); const preparer = this.preparerMap.get(type); if (!preparer) { diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 2992c7a067..3558590938 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -72,6 +72,7 @@ "@backstage/plugin-catalog-react": "workspace:^", "@backstage/plugin-search-common": "workspace:^", "@backstage/plugin-search-react": "workspace:^", + "@backstage/plugin-techdocs-common": "workspace:^", "@backstage/plugin-techdocs-react": "workspace:^", "@backstage/theme": "workspace:^", "@material-ui/core": "^4.12.2", diff --git a/plugins/techdocs/src/EntityPageDocs.tsx b/plugins/techdocs/src/EntityPageDocs.tsx index af184bb1a8..07222190ae 100644 --- a/plugins/techdocs/src/EntityPageDocs.tsx +++ b/plugins/techdocs/src/EntityPageDocs.tsx @@ -19,14 +19,13 @@ import { getCompoundEntityRef, parseEntityRef, } from '@backstage/catalog-model'; +import { TECHDOCS_EXTERNAL_ANNOTATION } from '@backstage/plugin-techdocs-common'; import React from 'react'; import { TechDocsReaderPage } from './plugin'; import { TechDocsReaderPageContent } from './reader/components/TechDocsReaderPageContent'; import { TechDocsReaderPageSubheader } from './reader/components/TechDocsReaderPageSubheader'; -const TECHDOCS_EXTERNAL_ANNOTATION = 'backstage.io/techdocs-entity'; - type EntityPageDocsProps = { entity: Entity }; export const EntityPageDocs = ({ entity }: EntityPageDocsProps) => { diff --git a/plugins/techdocs/src/Router.tsx b/plugins/techdocs/src/Router.tsx index 719217a32d..87a53156d6 100644 --- a/plugins/techdocs/src/Router.tsx +++ b/plugins/techdocs/src/Router.tsx @@ -25,10 +25,10 @@ import { useEntity, MissingAnnotationEmptyState, } from '@backstage/plugin-catalog-react'; - -const TECHDOCS_ANNOTATION = 'backstage.io/techdocs-ref'; - -const TECHDOCS_EXTERNAL_ANNOTATION = 'backstage.io/techdocs-entity'; +import { + TECHDOCS_ANNOTATION, + TECHDOCS_EXTERNAL_ANNOTATION, +} from '@backstage/plugin-techdocs-common'; /** * Helper that takes in entity and returns true/false if TechDocs is available for the entity diff --git a/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx b/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx index 70bd946256..56d086acfc 100644 --- a/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx +++ b/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx @@ -39,6 +39,7 @@ import { ContentHeader, } from '@backstage/core-components'; import { useApi } from '@backstage/core-plugin-api'; +import { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common'; const panels = { DocsTable: DocsTable, @@ -153,7 +154,7 @@ export const TechDocsCustomHome = (props: TechDocsCustomHomeProps) => { } = useAsync(async () => { const response = await catalogApi.getEntities({ filter: { - 'metadata.annotations.backstage.io/techdocs-ref': CATALOG_FILTER_EXISTS, + [`metadata.annotations.${TECHDOCS_ANNOTATION}`]: CATALOG_FILTER_EXISTS, }, fields: [ 'apiVersion', @@ -165,7 +166,7 @@ export const TechDocsCustomHome = (props: TechDocsCustomHomeProps) => { ], }); return response.items.filter((entity: Entity) => { - return !!entity.metadata.annotations?.['backstage.io/techdocs-ref']; + return !!entity.metadata.annotations?.[TECHDOCS_ANNOTATION]; }); }); diff --git a/plugins/techdocs/src/home/components/TechDocsPicker.tsx b/plugins/techdocs/src/home/components/TechDocsPicker.tsx index 32c7b800eb..f7bd2430a1 100644 --- a/plugins/techdocs/src/home/components/TechDocsPicker.tsx +++ b/plugins/techdocs/src/home/components/TechDocsPicker.tsx @@ -21,11 +21,12 @@ import { EntityFilter, useEntityList, } from '@backstage/plugin-catalog-react'; +import { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common'; class TechDocsFilter implements EntityFilter { getCatalogFilters(): Record<string, string | symbol | (string | symbol)[]> { return { - 'metadata.annotations.backstage.io/techdocs-ref': CATALOG_FILTER_EXISTS, + [`metadata.annotations.${TECHDOCS_ANNOTATION}`]: CATALOG_FILTER_EXISTS, }; } } diff --git a/yarn.lock b/yarn.lock index 8471404d21..a95a29be28 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7740,6 +7740,7 @@ __metadata: "@backstage/plugin-catalog-common": "workspace:^" "@backstage/plugin-permission-common": "workspace:^" "@backstage/plugin-search-backend-module-techdocs": "workspace:^" + "@backstage/plugin-techdocs-common": "workspace:^" "@backstage/plugin-techdocs-node": "workspace:^" "@types/express": ^4.17.6 express: ^4.17.1 @@ -7755,6 +7756,14 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-techdocs-common@workspace:^, @backstage/plugin-techdocs-common@workspace:plugins/techdocs-common": + version: 0.0.0-use.local + resolution: "@backstage/plugin-techdocs-common@workspace:plugins/techdocs-common" + dependencies: + "@backstage/cli": "workspace:^" + languageName: unknown + linkType: soft + "@backstage/plugin-techdocs-module-addons-contrib@workspace:^, @backstage/plugin-techdocs-module-addons-contrib@workspace:plugins/techdocs-module-addons-contrib": version: 0.0.0-use.local resolution: "@backstage/plugin-techdocs-module-addons-contrib@workspace:plugins/techdocs-module-addons-contrib" @@ -7803,6 +7812,7 @@ __metadata: "@backstage/integration": "workspace:^" "@backstage/integration-aws-node": "workspace:^" "@backstage/plugin-search-common": "workspace:^" + "@backstage/plugin-techdocs-common": "workspace:^" "@google-cloud/storage": ^7.0.0 "@smithy/node-http-handler": ^2.1.7 "@trendyol-js/openstack-swift-sdk": ^0.0.7 @@ -7876,6 +7886,7 @@ __metadata: "@backstage/plugin-catalog-react": "workspace:^" "@backstage/plugin-search-common": "workspace:^" "@backstage/plugin-search-react": "workspace:^" + "@backstage/plugin-techdocs-common": "workspace:^" "@backstage/plugin-techdocs-module-addons-contrib": "workspace:^" "@backstage/plugin-techdocs-react": "workspace:^" "@backstage/test-utils": "workspace:^" From 963106f8456ad5aa44cfb1ab58ddaf219111d9ab Mon Sep 17 00:00:00 2001 From: Chap Ambrose <cambrose@salesforce.com> Date: Wed, 24 Jul 2024 15:05:07 -0500 Subject: [PATCH 432/510] fix typo in heroku docs Signed-off-by: Chap Ambrose <cambrose@salesforce.com> --- docs/deployment/heroku.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/deployment/heroku.md b/docs/deployment/heroku.md index d285e4b397..51d0b4b439 100644 --- a/docs/deployment/heroku.md +++ b/docs/deployment/heroku.md @@ -104,7 +104,7 @@ heroku open -a <your-app> View logs: ```shell -heroku heroku -a <your-app> +heroku logs -a <your-app> ``` ## Docker From 51240ee9f790a9a54e851b8e359faf8dd470ce85 Mon Sep 17 00:00:00 2001 From: Thomas Cardonne <thomas.cardonne@adevinta.com> Date: Thu, 25 Jul 2024 00:18:15 +0200 Subject: [PATCH 433/510] fix(catalog-backend): preserve default allowedLocationTypes Signed-off-by: Thomas Cardonne <thomas.cardonne@adevinta.com> --- .changeset/odd-books-share.md | 5 +++++ plugins/catalog-backend/src/service/CatalogPlugin.ts | 10 ++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 .changeset/odd-books-share.md diff --git a/.changeset/odd-books-share.md b/.changeset/odd-books-share.md new file mode 100644 index 0000000000..858a2564ad --- /dev/null +++ b/.changeset/odd-books-share.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Preserve default `allowedLocationTypes` when `setAllowedLocationTypes()` of `CatalogLocationsExtensionPoint` is not called. diff --git a/plugins/catalog-backend/src/service/CatalogPlugin.ts b/plugins/catalog-backend/src/service/CatalogPlugin.ts index 2f5fd9103d..269100e586 100644 --- a/plugins/catalog-backend/src/service/CatalogPlugin.ts +++ b/plugins/catalog-backend/src/service/CatalogPlugin.ts @@ -46,7 +46,7 @@ import { ForwardedError } from '@backstage/errors'; class CatalogLocationsExtensionPointImpl implements CatalogLocationsExtensionPoint { - #locationTypes = new Array<string>(); + #locationTypes: string[] | undefined; setAllowedLocationTypes(locationTypes: Array<string>) { this.#locationTypes = locationTypes; @@ -293,9 +293,11 @@ export const catalogPlugin = createBackendPlugin({ builder.addPermissionRules(...permissionExtensions.permissionRules); builder.setFieldFormatValidators(modelExtensions.fieldValidators); - builder.setAllowedLocationTypes( - locationTypeExtensions.allowedLocationTypes, - ); + if (locationTypeExtensions.allowedLocationTypes) { + builder.setAllowedLocationTypes( + locationTypeExtensions.allowedLocationTypes, + ); + } const { processingEngine, router } = await builder.build(); From 7e5c374cfeb1161a99ab4467e267cf3faf2dea23 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Jul 2024 09:00:53 +0000 Subject: [PATCH 434/510] chore(deps): update github/codeql-action action to v3.25.14 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- .github/workflows/sync_snyk-monitor.yml | 2 +- .github/workflows/verify_codeql.yml | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index ecf18d71ad..354a76760b 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -67,6 +67,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: 'Upload to code-scanning' - uses: github/codeql-action/upload-sarif@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10 + uses: github/codeql-action/upload-sarif@5cf07d8b700b67e235fbb65cbc84f69c0cf10464 # v3.25.14 with: sarif_file: results.sarif diff --git a/.github/workflows/sync_snyk-monitor.yml b/.github/workflows/sync_snyk-monitor.yml index b1e50397ce..44699964a6 100644 --- a/.github/workflows/sync_snyk-monitor.yml +++ b/.github/workflows/sync_snyk-monitor.yml @@ -58,6 +58,6 @@ jobs: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} NODE_OPTIONS: --max-old-space-size=7168 - name: Upload Snyk report - uses: github/codeql-action/upload-sarif@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10 + uses: github/codeql-action/upload-sarif@5cf07d8b700b67e235fbb65cbc84f69c0cf10464 # v3.25.14 with: sarif_file: snyk.sarif diff --git a/.github/workflows/verify_codeql.yml b/.github/workflows/verify_codeql.yml index e19187b6ce..b2fb2dc6ec 100644 --- a/.github/workflows/verify_codeql.yml +++ b/.github/workflows/verify_codeql.yml @@ -55,7 +55,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10 + uses: github/codeql-action/init@5cf07d8b700b67e235fbb65cbc84f69c0cf10464 # v3.25.14 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -66,7 +66,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10 + uses: github/codeql-action/autobuild@5cf07d8b700b67e235fbb65cbc84f69c0cf10464 # v3.25.14 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -80,4 +80,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10 + uses: github/codeql-action/analyze@5cf07d8b700b67e235fbb65cbc84f69c0cf10464 # v3.25.14 From ef87e06e5b21663f516101fbb4e53d5d87d1fa80 Mon Sep 17 00:00:00 2001 From: Teo ShaoWei <teo_shaowei@estl.sg> Date: Wed, 24 Jul 2024 20:11:23 +0800 Subject: [PATCH 435/510] fix: scaffolder action catalog:write not working in nested folders From the design of `catalog:write`, it is meant to support writing to a nested file path, e.g. `backstage/catalog-info.yaml`. However, if the directory doesn't exists, then `fs.writeFile` will throw an error. This commit fixed the issue by using `fs.outputFile` instead which will create the parent directory if it does not exist: https://github.com/jprichardson/node-fs-extra/blob/master/docs/outputFile.md The test `'should support a custom filename'` in `write.test.ts` did not catch this issue because `fs` is mocked. It is better to use fake instead of mock, e.g. create a throwaway temp folder for the tests since the file operations are part of the feature. However fixing of the tests as a whole is out of scope for this PR. Signed-off-by: ShaoWei Teo <tookunokaze@gmail.com> --- .changeset/thick-hotels-know.md | 5 +++++ .../actions/builtin/catalog/write.examples.test.ts | 4 ++-- .../scaffolder/actions/builtin/catalog/write.test.ts | 12 ++++++------ .../src/scaffolder/actions/builtin/catalog/write.ts | 2 +- 4 files changed, 14 insertions(+), 9 deletions(-) create mode 100644 .changeset/thick-hotels-know.md diff --git a/.changeset/thick-hotels-know.md b/.changeset/thick-hotels-know.md new file mode 100644 index 0000000000..a2331b6df2 --- /dev/null +++ b/.changeset/thick-hotels-know.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Fix scaffolder action catalog:write to work in nested folders. diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.examples.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.examples.test.ts index e6b4bcde47..f900e87a1d 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.examples.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.examples.test.ts @@ -55,8 +55,8 @@ describe('catalog:write', () => { input: yaml.parse(examples[0].example).steps[0].input, }); - expect(fsMock.writeFile).toHaveBeenCalledTimes(1); - expect(fsMock.writeFile).toHaveBeenCalledWith( + expect(fsMock.outputFile).toHaveBeenCalledTimes(1); + expect(fsMock.outputFile).toHaveBeenCalledWith( resolvePath(mockContext.workspacePath, 'catalog-info.yaml'), yaml.stringify(entity), ); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.test.ts index 658e4365bf..469b4d5c6d 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.test.ts @@ -59,8 +59,8 @@ describe('catalog:write', () => { }, }); - expect(fsMock.writeFile).toHaveBeenCalledTimes(1); - expect(fsMock.writeFile).toHaveBeenCalledWith( + expect(fsMock.outputFile).toHaveBeenCalledTimes(1); + expect(fsMock.outputFile).toHaveBeenCalledWith( resolvePath(mockContext.workspacePath, 'catalog-info.yaml'), yaml.stringify(entity), ); @@ -88,8 +88,8 @@ describe('catalog:write', () => { }, }); - expect(fsMock.writeFile).toHaveBeenCalledTimes(1); - expect(fsMock.writeFile).toHaveBeenCalledWith( + expect(fsMock.outputFile).toHaveBeenCalledTimes(1); + expect(fsMock.outputFile).toHaveBeenCalledWith( resolvePath(mockContext.workspacePath, 'some-dir/entity-info.yaml'), yaml.stringify(entity), ); @@ -118,8 +118,8 @@ describe('catalog:write', () => { 'backstage.io/source-template': 'template:default/test-skeleton', }; - expect(fsMock.writeFile).toHaveBeenCalledTimes(1); - expect(fsMock.writeFile).toHaveBeenCalledWith( + expect(fsMock.outputFile).toHaveBeenCalledTimes(1); + expect(fsMock.outputFile).toHaveBeenCalledWith( resolvePath(mockContext.workspacePath, 'catalog-info.yaml'), yaml.stringify(expectedEntity), ); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts index a957adb71a..29ce6c986d 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts @@ -54,7 +54,7 @@ export function createCatalogWriteAction() { const path = filePath ?? 'catalog-info.yaml'; ctx.logger.info(`Writing ${path}`); - await fs.writeFile( + await fs.outputFile( resolveSafeChildPath(ctx.workspacePath, path), yaml.stringify({ ...entity, From cc21fa8f4e599273357339eaaca378a840272754 Mon Sep 17 00:00:00 2001 From: Nishkarsh Raj <nishkarshraj000@gmail.com> Date: Thu, 25 Jul 2024 14:25:27 +0000 Subject: [PATCH 436/510] Making StatusNeo Partner logo consistent with color scheme Signed-off-by: Nishkarsh Raj <nishkarshraj000@gmail.com> --- .../static/img/partner-logo-statusneo.png | Bin 4663 -> 4396 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/microsite/static/img/partner-logo-statusneo.png b/microsite/static/img/partner-logo-statusneo.png index 4209ecaca30647db6ea50cc2ceb4ad2d8e07aa92..61a676a2207109feb905815cadd6735df1653f3a 100644 GIT binary patch literal 4396 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 SsCe!FmC)BV(n4w2hyM?ImwcB1 literal 4663 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 From 6988f07886abd44898cf9c3e216e9bb30a85c107 Mon Sep 17 00:00:00 2001 From: Valber Junior <84424883+ValberJunior@users.noreply.github.com> Date: Thu, 25 Jul 2024 11:44:49 -0300 Subject: [PATCH 437/510] Create infracost.yaml Signed-off-by: Valber Junior <84424883+ValberJunior@users.noreply.github.com> --- microsite/data/plugins/infracost.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 microsite/data/plugins/infracost.yaml diff --git a/microsite/data/plugins/infracost.yaml b/microsite/data/plugins/infracost.yaml new file mode 100644 index 0000000000..977309d924 --- /dev/null +++ b/microsite/data/plugins/infracost.yaml @@ -0,0 +1,14 @@ +--- +title: VeeCode Infracost +author: VeeCode Platform +authorUrl: https://platform.vee.codes/ +category: FinOps +description: The Infracost plug-in works in conjunction with terraform and provides a graphical representation and cost estimate data for your entity at your respective provider. +iconUrl: https://veecode-platform.github.io/support/imgs/logo_5.svg +npmPackageName: '@veecode-platform/backstage-plugin-infracost' +tags: + - finops + - infracost + - estimate + - terraform +addedDate: '2024-07-25' From 3c2976d7ea93f1b0137424b7c83737d880efbb7b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Jul 2024 14:51:30 +0000 Subject: [PATCH 438/510] chore(deps): update actions/setup-node action to v4.0.3 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/api-breaking-changes.yml | 2 +- .github/workflows/ci.yml | 6 +++--- .github/workflows/deploy_docker-image.yml | 2 +- .github/workflows/deploy_microsite.yml | 2 +- .github/workflows/deploy_nightly.yml | 2 +- .github/workflows/deploy_packages.yml | 4 ++-- .github/workflows/sync_code-formatting.yml | 2 +- .github/workflows/sync_release-manifest.yml | 2 +- .github/workflows/sync_snyk-github-issues.yml | 2 +- .github/workflows/verify_accessibility.yml | 2 +- .github/workflows/verify_e2e-kubernetes.yml | 2 +- .github/workflows/verify_e2e-linux.yml | 2 +- .github/workflows/verify_e2e-windows.yml | 2 +- .github/workflows/verify_microsite.yml | 2 +- .github/workflows/verify_microsite_accessibility.yml | 2 +- .github/workflows/verify_storybook.yml | 2 +- .github/workflows/verify_windows.yml | 2 +- 17 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/api-breaking-changes.yml b/.github/workflows/api-breaking-changes.yml index e334a29b82..c39fdf7f7c 100644 --- a/.github/workflows/api-breaking-changes.yml +++ b/.github/workflows/api-breaking-changes.yml @@ -27,7 +27,7 @@ jobs: run: git fetch --depth 1 origin ${{ github.base_ref }} - name: setup-node - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: 18.x registry-url: https://registry.npmjs.org/ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 135076ba40..168d6205e4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,7 +35,7 @@ jobs: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth @@ -71,7 +71,7 @@ jobs: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth @@ -216,7 +216,7 @@ jobs: run: git fetch origin ${{ github.event.pull_request.base.ref }} - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth diff --git a/.github/workflows/deploy_docker-image.yml b/.github/workflows/deploy_docker-image.yml index 8b4709337a..9f305f9a20 100644 --- a/.github/workflows/deploy_docker-image.yml +++ b/.github/workflows/deploy_docker-image.yml @@ -31,7 +31,7 @@ jobs: ref: ${{ github.event.client_payload.version && env.RELEASE_VERSION || github.ref }} - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth diff --git a/.github/workflows/deploy_microsite.yml b/.github/workflows/deploy_microsite.yml index a0cdae5774..be46bcfaa0 100644 --- a/.github/workflows/deploy_microsite.yml +++ b/.github/workflows/deploy_microsite.yml @@ -31,7 +31,7 @@ jobs: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: use node.js 18.x - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: 18.x registry-url: https://registry.npmjs.org/ # Needed for auth diff --git a/.github/workflows/deploy_nightly.yml b/.github/workflows/deploy_nightly.yml index db9489dbb8..5488b9a189 100644 --- a/.github/workflows/deploy_nightly.yml +++ b/.github/workflows/deploy_nightly.yml @@ -22,7 +22,7 @@ jobs: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: use node.js 18.x - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: 18.x registry-url: https://registry.npmjs.org/ # Needed for auth diff --git a/.github/workflows/deploy_packages.yml b/.github/workflows/deploy_packages.yml index 81e95fab97..7ae5637986 100644 --- a/.github/workflows/deploy_packages.yml +++ b/.github/workflows/deploy_packages.yml @@ -77,7 +77,7 @@ jobs: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth @@ -161,7 +161,7 @@ jobs: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth diff --git a/.github/workflows/sync_code-formatting.yml b/.github/workflows/sync_code-formatting.yml index 9886c94830..da6bd2592d 100644 --- a/.github/workflows/sync_code-formatting.yml +++ b/.github/workflows/sync_code-formatting.yml @@ -20,7 +20,7 @@ jobs: fetch-depth: 0 - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth diff --git a/.github/workflows/sync_release-manifest.yml b/.github/workflows/sync_release-manifest.yml index 6d02309f8a..62dd7e0c13 100644 --- a/.github/workflows/sync_release-manifest.yml +++ b/.github/workflows/sync_release-manifest.yml @@ -19,7 +19,7 @@ jobs: ref: v${{ github.event.client_payload.version }} - name: use node.js 18.x - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: 18.x registry-url: https://registry.npmjs.org/ # Needed for auth diff --git a/.github/workflows/sync_snyk-github-issues.yml b/.github/workflows/sync_snyk-github-issues.yml index 1cdc0cb22a..1209545da1 100644 --- a/.github/workflows/sync_snyk-github-issues.yml +++ b/.github/workflows/sync_snyk-github-issues.yml @@ -19,7 +19,7 @@ jobs: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: use node.js 18.x - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: 18.x registry-url: https://registry.npmjs.org/ # Needed for auth diff --git a/.github/workflows/verify_accessibility.yml b/.github/workflows/verify_accessibility.yml index bb46bbd4c1..386306dcb1 100644 --- a/.github/workflows/verify_accessibility.yml +++ b/.github/workflows/verify_accessibility.yml @@ -26,7 +26,7 @@ jobs: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Use Node.js 18.x - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: 18.x - name: yarn install diff --git a/.github/workflows/verify_e2e-kubernetes.yml b/.github/workflows/verify_e2e-kubernetes.yml index b7465945ea..4647505cbf 100644 --- a/.github/workflows/verify_e2e-kubernetes.yml +++ b/.github/workflows/verify_e2e-kubernetes.yml @@ -29,7 +29,7 @@ jobs: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth diff --git a/.github/workflows/verify_e2e-linux.yml b/.github/workflows/verify_e2e-linux.yml index d6491f1e3c..fa303ce1c6 100644 --- a/.github/workflows/verify_e2e-linux.yml +++ b/.github/workflows/verify_e2e-linux.yml @@ -53,7 +53,7 @@ jobs: git config --global user.name 'GitHub e2e user' - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth diff --git a/.github/workflows/verify_e2e-windows.yml b/.github/workflows/verify_e2e-windows.yml index d7575cadf7..bc782c4bd3 100644 --- a/.github/workflows/verify_e2e-windows.yml +++ b/.github/workflows/verify_e2e-windows.yml @@ -50,7 +50,7 @@ jobs: git config --global user.name 'GitHub e2e user' - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth diff --git a/.github/workflows/verify_microsite.yml b/.github/workflows/verify_microsite.yml index 1a5bc8075b..08dcddde8e 100644 --- a/.github/workflows/verify_microsite.yml +++ b/.github/workflows/verify_microsite.yml @@ -31,7 +31,7 @@ jobs: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: use node.js 18.x - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: 18.x - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5 diff --git a/.github/workflows/verify_microsite_accessibility.yml b/.github/workflows/verify_microsite_accessibility.yml index c9ed1696cd..220e2633c3 100644 --- a/.github/workflows/verify_microsite_accessibility.yml +++ b/.github/workflows/verify_microsite_accessibility.yml @@ -22,7 +22,7 @@ jobs: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Use Node.js 18.x - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: 18.x diff --git a/.github/workflows/verify_storybook.yml b/.github/workflows/verify_storybook.yml index 83ddac8429..2f93b67616 100644 --- a/.github/workflows/verify_storybook.yml +++ b/.github/workflows/verify_storybook.yml @@ -37,7 +37,7 @@ jobs: fetch-depth: 0 # Required to retrieve git history - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth diff --git a/.github/workflows/verify_windows.yml b/.github/workflows/verify_windows.yml index 736193cad6..109e2ee96e 100644 --- a/.github/workflows/verify_windows.yml +++ b/.github/workflows/verify_windows.yml @@ -36,7 +36,7 @@ jobs: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth From 7f191a480d4665cfae3a4080be90eaae0e193937 Mon Sep 17 00:00:00 2001 From: Valber Junior <84424883+ValberJunior@users.noreply.github.com> Date: Thu, 25 Jul 2024 12:05:57 -0300 Subject: [PATCH 439/510] Update infracost.yaml Signed-off-by: Valber Junior <84424883+ValberJunior@users.noreply.github.com> --- microsite/data/plugins/infracost.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/microsite/data/plugins/infracost.yaml b/microsite/data/plugins/infracost.yaml index 977309d924..b6ead655d5 100644 --- a/microsite/data/plugins/infracost.yaml +++ b/microsite/data/plugins/infracost.yaml @@ -4,6 +4,7 @@ author: VeeCode Platform authorUrl: https://platform.vee.codes/ category: FinOps description: The Infracost plug-in works in conjunction with terraform and provides a graphical representation and cost estimate data for your entity at your respective provider. +documentation: https://platform.vee.codes/plugin/Infracost iconUrl: https://veecode-platform.github.io/support/imgs/logo_5.svg npmPackageName: '@veecode-platform/backstage-plugin-infracost' tags: From 22736b6156e491542b74c5c3ccb0235a5c80a7f0 Mon Sep 17 00:00:00 2001 From: Raghunandan Balachandran <raghunandan@spotify.com> Date: Wed, 24 Jul 2024 09:36:32 +0200 Subject: [PATCH 440/510] Update project areas and codeowners Signed-off-by: Raghunandan Balachandran <raghunandan@spotify.com> --- .github/CODEOWNERS | 16 +++++++--------- OWNERS.md | 18 +++++++++++++++--- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9cd3bc0690..a0c83a42bd 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -9,10 +9,10 @@ yarn.lock @backstage/maintainers @backst */yarn.lock @backstage/maintainers @backstage-service /.changeset/*.md /beps/0001-notifications-system @backstage/maintainers @backstage/notifications-maintainers -/docs/assets/search @backstage/discoverability-maintainers -/docs/features/search @backstage/discoverability-maintainers +/docs/assets/search @backstage/search-maintainers +/docs/features/search @backstage/search-maintainers /docs/features/techdocs @backstage/techdocs-maintainers -/docs/plugins/integrating-search-into-plugins.md @backstage/discoverability-maintainers +/docs/plugins/integrating-search-into-plugins.md @backstage/search-maintainers /packages/cli/src/commands/onboard @backstage/sharks /packages/backend-openapi-utils @backstage/maintainers @backstage/reviewers @backstage/openapi-tooling-maintainers /packages/techdocs-cli @backstage/techdocs-maintainers @@ -50,8 +50,8 @@ yarn.lock @backstage/maintainers @backst /plugins/explore-react @backstage/maintainers @backstage/reviewers @backstage/sda-se-reviewers /plugins/fossa @backstage/maintainers @backstage/reviewers @backstage/sda-se-reviewers /plugins/git-release-manager @backstage/maintainers @backstage/reviewers @erikengervall -/plugins/home @backstage/discoverability-maintainers -/plugins/home-* @backstage/discoverability-maintainers +/plugins/home @backstage/home-maintainers +/plugins/home-* @backstage/home-maintainers /plugins/kafka @backstage/maintainers @backstage/reviewers @andrewthauer /plugins/kafka-backend @backstage/maintainers @backstage/reviewers @andrewthauer /plugins/kubernetes @backstage/kubernetes-maintainers @@ -70,13 +70,11 @@ yarn.lock @backstage/maintainers @backst /plugins/rollbar-backend @backstage/maintainers @backstage/reviewers @andrewthauer /plugins/scaffolder @backstage/maintainers @backstage/reviewers @backstage/scaffolder-maintainers /plugins/scaffolder-* @backstage/maintainers @backstage/reviewers @backstage/scaffolder-maintainers -/plugins/search @backstage/discoverability-maintainers -/plugins/search-* @backstage/discoverability-maintainers +/plugins/search @backstage/search-maintainers +/plugins/search-* @backstage/search-maintainers /plugins/signals @backstage/maintainers @backstage/notifications-maintainers /plugins/signals-* @backstage/maintainers @backstage/notifications-maintainers /plugins/sonarqube @backstage/maintainers @backstage/reviewers @backstage/sda-se-reviewers -/plugins/stack-overflow @backstage/discoverability-maintainers -/plugins/stack-overflow-backend @backstage/discoverability-maintainers /plugins/techdocs @backstage/techdocs-maintainers /plugins/techdocs-* @backstage/techdocs-maintainers /plugins/user-settings-backend @backstage/maintainers @backstage/reviewers @backstage/sda-se-reviewers diff --git a/OWNERS.md b/OWNERS.md index 5012181d21..53113ac84d 100644 --- a/OWNERS.md +++ b/OWNERS.md @@ -32,11 +32,11 @@ Scope: The catalog plugin and catalog model | Patrik Oldsberg | Spotify | Cubic Belugas | [Rugvip](https://github.com/Rugvip) | `Rugvip#0019` | | Vincenzo Scamporlino | Spotify | Cubic Belugas | [vinzscam](http://github.com/vinzscam) | `vinzscam#6944` | -### Discoverability +### Home -Team: @backstage/discoverability-maintainers +Team: @backstage/home-maintainers -Scope: Discoverability within Backstage, including the home page, information architecture, and search +Scope: The Backstage home page and information architecture | Name | Organization | Team | GitHub | Discord | | ------------------------ | ------------ | -------------- | ---------------------------------------- | ----------------- | @@ -46,6 +46,18 @@ Scope: Discoverability within Backstage, including the home page, information ar | Raghunandan Balachandran | Spotify | Infinite Buck$ | [soapraj](http://github.com/soapraj) | raghunandanb#1114 | | Bailey Brooks | Spotify | Infinite Buck$ | [bailey](http://github.com/bailey) | \_bailey4 | +### Search + +Team: @backstage/search-maintainers + +Scope: The Backstage Search plugin + +| Name | Organization | Team | GitHub | Discord | +| ------------------------ | ------------ | -------------- | ----------------------------------------------| ----------------- | +| Emma Indal | Spotify | Infinite Buck$ | [emmaindal](http://github.com/emmaindal) | emmaindal#7503 | +| Raghunandan Balachandran | Spotify | Infinite Buck$ | [soapraj](http://github.com/soapraj) | raghunandanb#1114 | +| Alex Lorenzi | Spotify | ProTean | [AlexLorenzi](https://github.com/AlexLorenzi) | alexlorenzi | + ### Helm Charts Team: @backstage/helm-chart-maintainers From 518d03fa77197bf15981e99603b892e4046fca68 Mon Sep 17 00:00:00 2001 From: Raghunandan Balachandran <raghunandan@spotify.com> Date: Wed, 24 Jul 2024 09:36:57 +0200 Subject: [PATCH 441/510] Update github workflows Signed-off-by: Raghunandan Balachandran <raghunandan@spotify.com> --- .github/issue-labeler.yml | 2 +- .github/labeler.yml | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/issue-labeler.yml b/.github/issue-labeler.yml index 6d74ce8902..c6c6ef115f 100644 --- a/.github/issue-labeler.yml +++ b/.github/issue-labeler.yml @@ -1,6 +1,6 @@ area:techdocs: - '/(techdocs|tech-docs|tech docs)/i' -area:discoverability: +area:search: - '/search/i' area:events: - '/events/i' diff --git a/.github/labeler.yml b/.github/labeler.yml index a58da1d2f7..e6568091b8 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -4,7 +4,11 @@ area:catalog: - plugins/catalog/**/* - plugins/catalog-*/**/* - packages/catalog-*/**/* -area:discoverability: # search + home +area:home: + - changed-files: + - any-glob-to-any-file: + - plugins/home/**/* +area:search: - changed-files: - any-glob-to-any-file: - plugins/search/**/* From c085f90135657dd9b7d4cba58cb9d19c3af0d1d0 Mon Sep 17 00:00:00 2001 From: Raghunandan Balachandran <raghunandan@spotify.com> Date: Wed, 24 Jul 2024 09:37:23 +0200 Subject: [PATCH 442/510] Update home plugin ownership Signed-off-by: Raghunandan Balachandran <raghunandan@spotify.com> --- plugins/home-react/catalog-info.yaml | 2 +- plugins/home/catalog-info.yaml | 2 +- plugins/home/src/plugin.test.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/home-react/catalog-info.yaml b/plugins/home-react/catalog-info.yaml index 28109b9ddc..7022206fb9 100644 --- a/plugins/home-react/catalog-info.yaml +++ b/plugins/home-react/catalog-info.yaml @@ -9,4 +9,4 @@ metadata: spec: lifecycle: experimental type: backstage-web-library - owner: discoverability-maintainers + owner: home-maintainers diff --git a/plugins/home/catalog-info.yaml b/plugins/home/catalog-info.yaml index 1b23d4b83b..eefc114313 100644 --- a/plugins/home/catalog-info.yaml +++ b/plugins/home/catalog-info.yaml @@ -7,4 +7,4 @@ metadata: spec: lifecycle: experimental type: backstage-frontend-plugin - owner: discoverability-maintainers + owner: home-maintainers diff --git a/plugins/home/src/plugin.test.ts b/plugins/home/src/plugin.test.ts index 1526bd0c61..904481c98e 100644 --- a/plugins/home/src/plugin.test.ts +++ b/plugins/home/src/plugin.test.ts @@ -24,7 +24,7 @@ describe('home', () => { // Temporarily ensure we are installing a working version of the react-grid-layout library // For more details, see: https://github.com/react-grid-layout/react-grid-layout/issues/1959 - // TODO(@backstage/discoverability-maintainers): Delete this once the sub-dependency issue has been resolved. + // TODO(@backstage/home-maintainers): Delete this once the sub-dependency issue has been resolved. it('should pin react-grid-layout version to 1.3.4', async () => { expect(packageJson.dependencies['react-grid-layout']).toBe('1.3.4'); }); From 8ecb7a5e84128f257b26b5cf9941906f0ad2f734 Mon Sep 17 00:00:00 2001 From: Raghunandan Balachandran <raghunandan@spotify.com> Date: Wed, 24 Jul 2024 09:37:39 +0200 Subject: [PATCH 443/510] Update search plugin ownership Signed-off-by: Raghunandan Balachandran <raghunandan@spotify.com> --- plugins/search-backend-module-catalog/catalog-info.yaml | 2 +- plugins/search-backend-module-elasticsearch/catalog-info.yaml | 2 +- .../src/engines/ElasticSearchSearchEngine.ts | 2 +- plugins/search-backend-module-explore/catalog-info.yaml | 2 +- plugins/search-backend-module-pg/catalog-info.yaml | 2 +- .../src/PgSearchEngine/PgSearchEngineIndexer.ts | 2 +- .../catalog-info.yaml | 2 +- plugins/search-backend-module-techdocs/catalog-info.yaml | 2 +- plugins/search-backend-node/catalog-info.yaml | 2 +- plugins/search-backend/catalog-info.yaml | 2 +- plugins/search-common/catalog-info.yaml | 2 +- plugins/search-react/catalog-info.yaml | 2 +- plugins/search/catalog-info.yaml | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/plugins/search-backend-module-catalog/catalog-info.yaml b/plugins/search-backend-module-catalog/catalog-info.yaml index d36627848e..c826ea3edf 100644 --- a/plugins/search-backend-module-catalog/catalog-info.yaml +++ b/plugins/search-backend-module-catalog/catalog-info.yaml @@ -7,4 +7,4 @@ metadata: spec: lifecycle: experimental type: backstage-backend-plugin-module - owner: discoverability-maintainers + owner: search-maintainers diff --git a/plugins/search-backend-module-elasticsearch/catalog-info.yaml b/plugins/search-backend-module-elasticsearch/catalog-info.yaml index 300d1034c9..f2ee291f2b 100644 --- a/plugins/search-backend-module-elasticsearch/catalog-info.yaml +++ b/plugins/search-backend-module-elasticsearch/catalog-info.yaml @@ -7,4 +7,4 @@ metadata: spec: lifecycle: production type: backstage-backend-plugin-module - owner: discoverability-maintainers + owner: search-maintainers diff --git a/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts b/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts index 93312c9fba..0832aaea85 100644 --- a/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts +++ b/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts @@ -313,7 +313,7 @@ export class ElasticSearchSearchEngine implements SearchEngine { }); // Attempt cleanup upon failure. - // todo(@backstage/discoverability-maintainers): Consider introducing a more + // todo(@backstage/search-maintainers): Consider introducing a more // formal mechanism for handling such errors in BatchSearchEngineIndexer and // replacing this handler with it. See: #17291 indexer.on('error', async e => { diff --git a/plugins/search-backend-module-explore/catalog-info.yaml b/plugins/search-backend-module-explore/catalog-info.yaml index 237e7a0f98..51ebb70df9 100644 --- a/plugins/search-backend-module-explore/catalog-info.yaml +++ b/plugins/search-backend-module-explore/catalog-info.yaml @@ -7,4 +7,4 @@ metadata: spec: lifecycle: experimental type: backstage-backend-plugin-module - owner: discoverability-maintainers + owner: search-maintainers diff --git a/plugins/search-backend-module-pg/catalog-info.yaml b/plugins/search-backend-module-pg/catalog-info.yaml index 47b9717882..eae771518e 100644 --- a/plugins/search-backend-module-pg/catalog-info.yaml +++ b/plugins/search-backend-module-pg/catalog-info.yaml @@ -7,4 +7,4 @@ metadata: spec: lifecycle: experimental type: backstage-backend-plugin-module - owner: discoverability-maintainers + owner: search-maintainers diff --git a/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngineIndexer.ts b/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngineIndexer.ts index ab5ae8be54..c460889bd4 100644 --- a/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngineIndexer.ts +++ b/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngineIndexer.ts @@ -104,7 +104,7 @@ export class PgSearchEngineIndexer extends BatchSearchEngineIndexer { * therefore an open connection to PG. This handler ensures we close the * transaction and associated connection. * - * todo(@backstage/discoverability-maintainers): Consider introducing a more + * todo(@backstage/search-maintainers): Consider introducing a more * formal mechanism for handling such errors in BatchSearchEngineIndexer and * replacing this method with it. See: #17291 * diff --git a/plugins/search-backend-module-stack-overflow-collator/catalog-info.yaml b/plugins/search-backend-module-stack-overflow-collator/catalog-info.yaml index ed73bd0eca..9d77a5a00d 100644 --- a/plugins/search-backend-module-stack-overflow-collator/catalog-info.yaml +++ b/plugins/search-backend-module-stack-overflow-collator/catalog-info.yaml @@ -7,4 +7,4 @@ metadata: spec: lifecycle: experimental type: backstage-backend-plugin-module - owner: discoverability-maintainers + owner: search-maintainers diff --git a/plugins/search-backend-module-techdocs/catalog-info.yaml b/plugins/search-backend-module-techdocs/catalog-info.yaml index a0bbfc5bb7..11a14c8dc3 100644 --- a/plugins/search-backend-module-techdocs/catalog-info.yaml +++ b/plugins/search-backend-module-techdocs/catalog-info.yaml @@ -7,4 +7,4 @@ metadata: spec: lifecycle: experimental type: backstage-backend-plugin-module - owner: discoverability-maintainers + owner: search-maintainers diff --git a/plugins/search-backend-node/catalog-info.yaml b/plugins/search-backend-node/catalog-info.yaml index 5f6b36256f..7d3629bd20 100644 --- a/plugins/search-backend-node/catalog-info.yaml +++ b/plugins/search-backend-node/catalog-info.yaml @@ -9,4 +9,4 @@ metadata: spec: lifecycle: production type: backstage-node-library - owner: discoverability-maintainers + owner: search-maintainers diff --git a/plugins/search-backend/catalog-info.yaml b/plugins/search-backend/catalog-info.yaml index 2b8c7ee346..977ad12539 100644 --- a/plugins/search-backend/catalog-info.yaml +++ b/plugins/search-backend/catalog-info.yaml @@ -7,4 +7,4 @@ metadata: spec: lifecycle: production type: backstage-backend-plugin - owner: discoverability-maintainers + owner: search-maintainers diff --git a/plugins/search-common/catalog-info.yaml b/plugins/search-common/catalog-info.yaml index d7e77a8d10..d1d9c4909c 100644 --- a/plugins/search-common/catalog-info.yaml +++ b/plugins/search-common/catalog-info.yaml @@ -9,4 +9,4 @@ metadata: spec: lifecycle: production type: backstage-common-library - owner: discoverability-maintainers + owner: search-maintainers diff --git a/plugins/search-react/catalog-info.yaml b/plugins/search-react/catalog-info.yaml index 799b3d19c3..c6c39dcb0d 100644 --- a/plugins/search-react/catalog-info.yaml +++ b/plugins/search-react/catalog-info.yaml @@ -6,4 +6,4 @@ metadata: spec: lifecycle: production type: backstage-web-library - owner: discoverability-maintainers + owner: search-maintainers diff --git a/plugins/search/catalog-info.yaml b/plugins/search/catalog-info.yaml index e1e4ae21da..cb2d5f3641 100644 --- a/plugins/search/catalog-info.yaml +++ b/plugins/search/catalog-info.yaml @@ -7,4 +7,4 @@ metadata: spec: lifecycle: production type: backstage-frontend-plugin - owner: discoverability-maintainers + owner: search-maintainers From 4dfd3c18f5572ec8f657186db0088b829fbcdfa2 Mon Sep 17 00:00:00 2001 From: Raghunandan Balachandran <raghunandan@spotify.com> Date: Wed, 24 Jul 2024 10:53:58 +0200 Subject: [PATCH 444/510] Add changeset Signed-off-by: Raghunandan Balachandran <raghunandan@spotify.com> --- .changeset/yellow-clocks-fail.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .changeset/yellow-clocks-fail.md diff --git a/.changeset/yellow-clocks-fail.md b/.changeset/yellow-clocks-fail.md new file mode 100644 index 0000000000..36e2d4b804 --- /dev/null +++ b/.changeset/yellow-clocks-fail.md @@ -0,0 +1,17 @@ +--- +'@backstage/plugin-search-backend-module-stack-overflow-collator': patch +'@backstage/plugin-search-backend-module-elasticsearch': patch +'@backstage/plugin-search-backend-module-techdocs': patch +'@backstage/plugin-search-backend-module-catalog': patch +'@backstage/plugin-search-backend-module-explore': patch +'@backstage/plugin-search-backend-module-pg': patch +'@backstage/plugin-search-backend-node': patch +'@backstage/plugin-search-backend': patch +'@backstage/plugin-search-common': patch +'@backstage/plugin-search-react': patch +'@backstage/plugin-home-react': patch +'@backstage/plugin-search': patch +'@backstage/plugin-home': patch +--- + +Update ownership for home and search plugins From c64c46769a3782b6442db8497eca812dfd92c47f Mon Sep 17 00:00:00 2001 From: Raghunandan Balachandran <raghunandan@spotify.com> Date: Wed, 24 Jul 2024 14:40:03 +0200 Subject: [PATCH 445/510] Prettier fix Signed-off-by: Raghunandan Balachandran <raghunandan@spotify.com> --- OWNERS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OWNERS.md b/OWNERS.md index 53113ac84d..b145205539 100644 --- a/OWNERS.md +++ b/OWNERS.md @@ -53,7 +53,7 @@ Team: @backstage/search-maintainers Scope: The Backstage Search plugin | Name | Organization | Team | GitHub | Discord | -| ------------------------ | ------------ | -------------- | ----------------------------------------------| ----------------- | +| ------------------------ | ------------ | -------------- | --------------------------------------------- | ----------------- | | Emma Indal | Spotify | Infinite Buck$ | [emmaindal](http://github.com/emmaindal) | emmaindal#7503 | | Raghunandan Balachandran | Spotify | Infinite Buck$ | [soapraj](http://github.com/soapraj) | raghunandanb#1114 | | Alex Lorenzi | Spotify | ProTean | [AlexLorenzi](https://github.com/AlexLorenzi) | alexlorenzi | From 1383f4c98cb16ed97f1e5064b30beb94b934dcdf Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Fri, 26 Jul 2024 10:04:55 +0200 Subject: [PATCH 446/510] Update .changeset/neat-bears-divide.md Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/neat-bears-divide.md | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/.changeset/neat-bears-divide.md b/.changeset/neat-bears-divide.md index b40db6c7bd..a94b17f74d 100644 --- a/.changeset/neat-bears-divide.md +++ b/.changeset/neat-bears-divide.md @@ -1,28 +1,5 @@ --- -'@backstage/config-loader': major +'@backstage/config-loader': patch --- -**BREAKING** The `env` property on the `ConfigSourcesDefaultOptions` interface allows for undefined members. - -This change makes `ConfigSourcesDefaultOptions.env` consistent with other parts of this package and the wider -`node` ecosystem. Specifically, with this update `ConfigSourcesDefaultOptions.env`'s types match: - -#### EnvConfigSource - -- [`EnvConfigSource.constructor`](https://github.com/backstage/backstage/blob/c780320418b7775f18fc0d2cc279ee7db9c7cb25/packages/config-loader/src/sources/EnvConfigSource.ts#L68) -- [`EnvConfigSourceOptions`](https://github.com/backstage/backstage/blob/c780320418b7775f18fc0d2cc279ee7db9c7cb25/packages/config-loader/src/sources/EnvConfigSource.ts#L31) -- [`readEnvConfig`](https://github.com/backstage/backstage/blob/c780320418b7775f18fc0d2cc279ee7db9c7cb25/packages/config-loader/src/sources/EnvConfigSource.ts#L114) - -#### NodeJS process.env - -- [`ProcessEnv`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/aa121ee3a7a3caa16433b66c1103df5904f612ea/types/node/v18/process.d.ts#L137) - which extends [`Dict`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/aa121ee3a7a3caa16433b66c1103df5904f612ea/types/node/v18/globals.d.ts#L333-L335) - -While this is a somewhat trivial change, it does loosen typings on a public interface, so by definition it's a breaking -change and a major version bump. - -You may meed to update your backstage instance if you have built an implementation of `ConfigSources` or any other -functionality that relies on `ConfigSourcesDefaultOptions`. This change means you'll have to update that code to account -for the possibility of `undefined` values inside `ConfigSourcesDefaultOptions.env`, although it is very likely already -accounted for as the typings for [`process.env`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/aa121ee3a7a3caa16433b66c1103df5904f612ea/types/node/v18/process.d.ts#L137) -already include the possibility of [`undefined`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/aa121ee3a7a3caa16433b66c1103df5904f612ea/types/node/v18/globals.d.ts#L333-L335). +The `env` option of `ConfigSources.default` now correctly allows undefined members. From d21d3079fc5950762b7619667bbb321b524520e4 Mon Sep 17 00:00:00 2001 From: parmar-abhinav <abhinav.parmar@infosys.com> Date: Fri, 26 Jul 2024 13:38:08 +0530 Subject: [PATCH 447/510] Added examples for github:environment:create action and improve its test cases Signed-off-by: parmar-abhinav <abhinav.parmar@infosys.com> --- .changeset/big-eagles-grab.md | 5 + .../src/actions/gitHubEnvironment.examples.ts | 206 +++++++ .../githubEnvironment.examples.test.ts | 518 ++++++++++++++++++ 3 files changed, 729 insertions(+) create mode 100644 .changeset/big-eagles-grab.md diff --git a/.changeset/big-eagles-grab.md b/.changeset/big-eagles-grab.md new file mode 100644 index 0000000000..9ece8f64df --- /dev/null +++ b/.changeset/big-eagles-grab.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-github': patch +--- + +Added examples for github:environment:create action and improve its test cases diff --git a/plugins/scaffolder-backend-module-github/src/actions/gitHubEnvironment.examples.ts b/plugins/scaffolder-backend-module-github/src/actions/gitHubEnvironment.examples.ts index 606424bef0..7c5f7efa3d 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/gitHubEnvironment.examples.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/gitHubEnvironment.examples.ts @@ -96,4 +96,210 @@ export const examples: TemplateExample[] = [ ], }), }, + { + description: 'Create a GitHub Environment with Custom Tag Policies', + example: yaml.stringify({ + steps: [ + { + action: 'github:environment:create', + name: 'Create Environment', + input: { + repoUrl: 'github.com?repo=repository&owner=owner', + name: 'envname', + customTagPolicyNames: ['release/*/*', 'v*.*.*'], + }, + }, + ], + }), + }, + { + description: + 'Create a GitHub Environment with Both Branch and Tag Policies', + example: yaml.stringify({ + steps: [ + { + action: 'github:environment:create', + name: 'Create Environment', + input: { + repoUrl: 'github.com?repo=repository&owner=owner', + name: 'envname', + deploymentBranchPolicy: { + protected_branches: false, + custom_branch_policies: true, + }, + customBranchPolicyNames: ['feature/*', 'hotfix/*'], + customTagPolicyNames: ['release/*', 'v*'], + }, + }, + ], + }), + }, + { + description: 'Create a GitHub Environment with Full Configuration', + example: yaml.stringify({ + steps: [ + { + action: 'github:environment:create', + name: 'Create Environment', + input: { + repoUrl: 'github.com?repo=repository&owner=owner', + name: 'envname', + deploymentBranchPolicy: { + protected_branches: false, + custom_branch_policies: true, + }, + customBranchPolicyNames: ['dev/*', 'test/*'], + customTagPolicyNames: ['v1.*', 'v2.*'], + environmentVariables: { + API_KEY: '123456789', + NODE_ENV: 'production', + }, + secrets: { + DATABASE_URL: 'supersecretdatabaseurl', + API_SECRET: 'supersecretapisecret', + }, + token: 'ghp_abcdef1234567890', + }, + }, + ], + }), + }, + { + description: 'Create a GitHub Environment with Only Token Authentication', + example: yaml.stringify({ + steps: [ + { + action: 'github:environment:create', + name: 'Create Environment', + input: { + repoUrl: 'github.com?repo=repository&owner=owner', + name: 'envname', + token: 'ghp_abcdef1234567890', + }, + }, + ], + }), + }, + { + description: 'Create a GitHub Environment with No Deployment Policies', + example: yaml.stringify({ + steps: [ + { + action: 'github:environment:create', + name: 'Create Environment', + input: { + repoUrl: 'github.com?repo=repository&owner=owner', + name: 'envname', + deploymentBranchPolicy: null, + }, + }, + ], + }), + }, + { + description: + 'Create a GitHub Environment with Custom Branch and Tag Policies', + example: yaml.stringify({ + steps: [ + { + action: 'github:environment:create', + name: 'Create Environment', + input: { + repoUrl: 'github.com?repo=repository&owner=owner', + name: 'envname', + deploymentBranchPolicy: { + protected_branches: false, + custom_branch_policies: true, + }, + customBranchPolicyNames: ['release/*', 'hotfix/*'], + customTagPolicyNames: ['v*', 'release-*'], + }, + }, + ], + }), + }, + { + description: 'Create a GitHub Environment with Environment Variables Only', + example: yaml.stringify({ + steps: [ + { + action: 'github:environment:create', + name: 'Create Environment', + input: { + repoUrl: 'github.com?repo=repository&owner=owner', + name: 'envname', + environmentVariables: { + VAR1: 'value1', + VAR2: 'value2', + }, + }, + }, + ], + }), + }, + { + description: 'Create a GitHub Environment with Deployment Secrets Only', + example: yaml.stringify({ + steps: [ + { + action: 'github:environment:create', + name: 'Create Environment', + input: { + repoUrl: 'github.com?repo=repository&owner=owner', + name: 'envname', + secrets: { + SECRET1: 'secretvalue1', + SECRET2: 'secretvalue2', + }, + }, + }, + ], + }), + }, + { + description: + 'Create a GitHub Environment with Deployment Branch Policy and Token', + example: yaml.stringify({ + steps: [ + { + action: 'github:environment:create', + name: 'Create Environment', + input: { + repoUrl: 'github.com?repo=repository&owner=owner', + name: 'envname', + deploymentBranchPolicy: { + protected_branches: true, + custom_branch_policies: false, + }, + token: 'ghp_abcdef1234567890', + }, + }, + ], + }), + }, + { + description: + 'Create a GitHub Environment with Environment Variables, Secrets, and Token', + example: yaml.stringify({ + steps: [ + { + action: 'github:environment:create', + name: 'Create Environment', + input: { + repoUrl: 'github.com?repo=repository&owner=owner', + name: 'envname', + environmentVariables: { + VAR1: 'value1', + VAR2: 'value2', + }, + secrets: { + SECRET1: 'secretvalue1', + SECRET2: 'secretvalue2', + }, + token: 'ghp_abcdef1234567890', + }, + }, + ], + }), + }, ]; diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.examples.test.ts index e41e642ca0..c8b133859b 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.examples.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.examples.test.ts @@ -264,4 +264,522 @@ describe('github:environment:create examples', () => { encrypted_value: expect.any(String), }); }); + + it(`should ${examples[4].description}`, async () => { + const input = yaml.parse(examples[4].example).steps[0].input; + + await action.handler({ + ...mockContext, + input, + }); + + expect( + mockOctokit.rest.repos.createOrUpdateEnvironment, + ).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repository', + environment_name: 'envname', + deployment_branch_policy: null, + }); + + expect( + mockOctokit.rest.repos.createDeploymentBranchPolicy, + ).toHaveBeenCalledTimes(2); + expect( + mockOctokit.rest.repos.createDeploymentBranchPolicy, + ).toHaveBeenCalledWith({ + environment_name: 'envname', + name: 'release/*/*', + owner: 'owner', + repo: 'repository', + type: 'tag', + }); + expect( + mockOctokit.rest.repos.createDeploymentBranchPolicy, + ).toHaveBeenCalledWith({ + environment_name: 'envname', + name: 'v*.*.*', + owner: 'owner', + repo: 'repository', + type: 'tag', + }); + + expect( + mockOctokit.rest.actions.createEnvironmentVariable, + ).not.toHaveBeenCalled(); + + expect( + mockOctokit.rest.actions.createOrUpdateEnvironmentSecret, + ).not.toHaveBeenCalled(); + }); + + it(`should ${examples[5].description}`, async () => { + const input = yaml.parse(examples[5].example).steps[0].input; + + await action.handler({ + ...mockContext, + input, + }); + + expect( + mockOctokit.rest.repos.createOrUpdateEnvironment, + ).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repository', + environment_name: 'envname', + deployment_branch_policy: { + custom_branch_policies: true, + protected_branches: false, + }, + }); + + expect( + mockOctokit.rest.repos.createDeploymentBranchPolicy, + ).toHaveBeenCalledTimes(4); + expect( + mockOctokit.rest.repos.createDeploymentBranchPolicy, + ).toHaveBeenCalledWith({ + environment_name: 'envname', + name: 'release/*', + owner: 'owner', + repo: 'repository', + type: 'tag', + }); + expect( + mockOctokit.rest.repos.createDeploymentBranchPolicy, + ).toHaveBeenCalledWith({ + environment_name: 'envname', + name: 'feature/*', + owner: 'owner', + repo: 'repository', + type: 'branch', + }); + + expect( + mockOctokit.rest.actions.createEnvironmentVariable, + ).not.toHaveBeenCalled(); + + expect( + mockOctokit.rest.actions.createOrUpdateEnvironmentSecret, + ).not.toHaveBeenCalled(); + }); + + it(`should ${examples[6].description}`, async () => { + const input = yaml.parse(examples[6].example).steps[0].input; + + await action.handler({ + ...mockContext, + input, + }); + + expect( + mockOctokit.rest.repos.createOrUpdateEnvironment, + ).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repository', + environment_name: 'envname', + deployment_branch_policy: { + custom_branch_policies: true, + protected_branches: false, + }, + }); + + expect( + mockOctokit.rest.repos.createDeploymentBranchPolicy, + ).toHaveBeenCalledTimes(4); + expect( + mockOctokit.rest.repos.createDeploymentBranchPolicy, + ).toHaveBeenCalledWith({ + environment_name: 'envname', + name: 'dev/*', + owner: 'owner', + repo: 'repository', + type: 'branch', + }); + expect( + mockOctokit.rest.repos.createDeploymentBranchPolicy, + ).toHaveBeenCalledWith({ + environment_name: 'envname', + name: 'test/*', + owner: 'owner', + repo: 'repository', + type: 'branch', + }); + + expect( + mockOctokit.rest.actions.createEnvironmentVariable, + ).toHaveBeenCalledTimes(2); + + expect( + mockOctokit.rest.actions.createEnvironmentVariable, + ).toHaveBeenCalledWith({ + environment_name: 'envname', + name: 'API_KEY', + owner: 'owner', + repo: 'repository', + repository_id: 'repoid', + value: '123456789', + }); + expect( + mockOctokit.rest.actions.createEnvironmentVariable, + ).toHaveBeenCalledWith({ + environment_name: 'envname', + name: 'NODE_ENV', + owner: 'owner', + repo: 'repository', + repository_id: 'repoid', + value: 'production', + }); + + expect( + mockOctokit.rest.actions.createOrUpdateEnvironmentSecret, + ).toHaveBeenCalledTimes(2); + expect( + mockOctokit.rest.actions.createOrUpdateEnvironmentSecret, + ).toHaveBeenCalledWith({ + encrypted_value: expect.any(String), + environment_name: 'envname', + key_id: 'keyid', + owner: 'owner', + repo: 'repository', + repository_id: 'repoid', + secret_name: 'API_SECRET', + }); + expect( + mockOctokit.rest.actions.createOrUpdateEnvironmentSecret, + ).toHaveBeenCalledWith({ + encrypted_value: expect.any(String), + environment_name: 'envname', + key_id: 'keyid', + owner: 'owner', + repo: 'repository', + repository_id: 'repoid', + secret_name: 'DATABASE_URL', + }); + }); + + it(`should ${examples[7].description}`, async () => { + const input = yaml.parse(examples[7].example).steps[0].input; + + await action.handler({ + ...mockContext, + input, + }); + + expect( + mockOctokit.rest.repos.createOrUpdateEnvironment, + ).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repository', + environment_name: 'envname', + deployment_branch_policy: null, + }); + + expect( + mockOctokit.rest.repos.createDeploymentBranchPolicy, + ).not.toHaveBeenCalled(); + + expect( + mockOctokit.rest.actions.createEnvironmentVariable, + ).not.toHaveBeenCalled(); + + expect( + mockOctokit.rest.actions.createOrUpdateEnvironmentSecret, + ).not.toHaveBeenCalled(); + }); + + it(`should ${examples[8].description}`, async () => { + const input = yaml.parse(examples[8].example).steps[0].input; + + await action.handler({ + ...mockContext, + input, + }); + + expect( + mockOctokit.rest.repos.createOrUpdateEnvironment, + ).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repository', + environment_name: 'envname', + deployment_branch_policy: null, + }); + + expect( + mockOctokit.rest.repos.createDeploymentBranchPolicy, + ).not.toHaveBeenCalled(); + + expect( + mockOctokit.rest.actions.createEnvironmentVariable, + ).not.toHaveBeenCalled(); + + expect( + mockOctokit.rest.actions.createOrUpdateEnvironmentSecret, + ).not.toHaveBeenCalled(); + }); + + it(`should ${examples[9].description}`, async () => { + const input = yaml.parse(examples[9].example).steps[0].input; + + await action.handler({ + ...mockContext, + input, + }); + + expect( + mockOctokit.rest.repos.createOrUpdateEnvironment, + ).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repository', + environment_name: 'envname', + deployment_branch_policy: { + custom_branch_policies: true, + protected_branches: false, + }, + }); + + expect( + mockOctokit.rest.repos.createDeploymentBranchPolicy, + ).toHaveBeenCalledTimes(4); + expect( + mockOctokit.rest.repos.createDeploymentBranchPolicy, + ).toHaveBeenCalledWith({ + environment_name: 'envname', + name: 'release/*', + owner: 'owner', + repo: 'repository', + type: 'branch', + }); + expect( + mockOctokit.rest.repos.createDeploymentBranchPolicy, + ).toHaveBeenCalledWith({ + environment_name: 'envname', + name: 'hotfix/*', + owner: 'owner', + repo: 'repository', + type: 'branch', + }); + expect( + mockOctokit.rest.repos.createDeploymentBranchPolicy, + ).toHaveBeenCalledWith({ + environment_name: 'envname', + name: 'v*', + owner: 'owner', + repo: 'repository', + type: 'tag', + }); + + expect( + mockOctokit.rest.actions.createEnvironmentVariable, + ).not.toHaveBeenCalled(); + + expect( + mockOctokit.rest.actions.createOrUpdateEnvironmentSecret, + ).not.toHaveBeenCalled(); + }); + + it(`should ${examples[10].description}`, async () => { + const input = yaml.parse(examples[10].example).steps[0].input; + + await action.handler({ + ...mockContext, + input, + }); + + expect( + mockOctokit.rest.repos.createOrUpdateEnvironment, + ).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repository', + environment_name: 'envname', + deployment_branch_policy: null, + }); + + expect( + mockOctokit.rest.repos.createDeploymentBranchPolicy, + ).not.toHaveBeenCalled(); + + expect( + mockOctokit.rest.actions.createEnvironmentVariable, + ).toHaveBeenCalledTimes(2); + expect( + mockOctokit.rest.actions.createEnvironmentVariable, + ).toHaveBeenCalledWith({ + environment_name: 'envname', + name: 'VAR1', + owner: 'owner', + repo: 'repository', + repository_id: 'repoid', + value: 'value1', + }); + expect( + mockOctokit.rest.actions.createEnvironmentVariable, + ).toHaveBeenCalledWith({ + environment_name: 'envname', + name: 'VAR2', + owner: 'owner', + repo: 'repository', + repository_id: 'repoid', + value: 'value2', + }); + + expect( + mockOctokit.rest.actions.createOrUpdateEnvironmentSecret, + ).not.toHaveBeenCalled(); + }); + + it(`should ${examples[11].description}`, async () => { + const input = yaml.parse(examples[11].example).steps[0].input; + + await action.handler({ + ...mockContext, + input, + }); + + expect( + mockOctokit.rest.repos.createOrUpdateEnvironment, + ).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repository', + environment_name: 'envname', + deployment_branch_policy: null, + }); + + expect( + mockOctokit.rest.repos.createDeploymentBranchPolicy, + ).not.toHaveBeenCalled(); + + expect( + mockOctokit.rest.actions.createEnvironmentVariable, + ).not.toHaveBeenCalled(); + expect( + mockOctokit.rest.actions.createOrUpdateEnvironmentSecret, + ).toHaveBeenCalledTimes(2); + expect( + mockOctokit.rest.actions.createOrUpdateEnvironmentSecret, + ).toHaveBeenCalledWith({ + encrypted_value: expect.any(String), + environment_name: 'envname', + key_id: 'keyid', + owner: 'owner', + repo: 'repository', + repository_id: 'repoid', + secret_name: 'SECRET1', + }); + expect( + mockOctokit.rest.actions.createOrUpdateEnvironmentSecret, + ).toHaveBeenCalledWith({ + encrypted_value: expect.any(String), + environment_name: 'envname', + key_id: 'keyid', + owner: 'owner', + repo: 'repository', + repository_id: 'repoid', + secret_name: 'SECRET2', + }); + }); + + it(`should ${examples[12].description}`, async () => { + const input = yaml.parse(examples[12].example).steps[0].input; + + await action.handler({ + ...mockContext, + input, + }); + + expect( + mockOctokit.rest.repos.createOrUpdateEnvironment, + ).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repository', + environment_name: 'envname', + deployment_branch_policy: { + custom_branch_policies: false, + protected_branches: true, + }, + }); + + expect( + mockOctokit.rest.repos.createDeploymentBranchPolicy, + ).not.toHaveBeenCalled(); + + expect( + mockOctokit.rest.actions.createEnvironmentVariable, + ).not.toHaveBeenCalled(); + expect( + mockOctokit.rest.actions.createOrUpdateEnvironmentSecret, + ).not.toHaveBeenCalled(); + }); + + it(`should ${examples[13].description}`, async () => { + const input = yaml.parse(examples[13].example).steps[0].input; + + await action.handler({ + ...mockContext, + input, + }); + + expect( + mockOctokit.rest.repos.createOrUpdateEnvironment, + ).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repository', + environment_name: 'envname', + deployment_branch_policy: null, + }); + + expect( + mockOctokit.rest.repos.createDeploymentBranchPolicy, + ).not.toHaveBeenCalled(); + + expect( + mockOctokit.rest.actions.createEnvironmentVariable, + ).toHaveBeenCalledTimes(2); + expect( + mockOctokit.rest.actions.createEnvironmentVariable, + ).toHaveBeenCalledWith({ + environment_name: 'envname', + name: 'VAR1', + owner: 'owner', + repo: 'repository', + repository_id: 'repoid', + value: 'value1', + }); + expect( + mockOctokit.rest.actions.createEnvironmentVariable, + ).toHaveBeenCalledWith({ + environment_name: 'envname', + name: 'VAR2', + owner: 'owner', + repo: 'repository', + repository_id: 'repoid', + value: 'value2', + }); + + expect( + mockOctokit.rest.actions.createOrUpdateEnvironmentSecret, + ).toHaveBeenCalledTimes(2); + expect( + mockOctokit.rest.actions.createOrUpdateEnvironmentSecret, + ).toHaveBeenCalledWith({ + encrypted_value: expect.any(String), + environment_name: 'envname', + key_id: 'keyid', + owner: 'owner', + repo: 'repository', + repository_id: 'repoid', + secret_name: 'SECRET1', + }); + expect( + mockOctokit.rest.actions.createOrUpdateEnvironmentSecret, + ).toHaveBeenCalledWith({ + encrypted_value: expect.any(String), + environment_name: 'envname', + key_id: 'keyid', + owner: 'owner', + repo: 'repository', + repository_id: 'repoid', + secret_name: 'SECRET2', + }); + }); }); From 733cc4f85a5be33969d35ce62da36a1e66b11204 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Fri, 26 Jul 2024 11:59:04 +0200 Subject: [PATCH 448/510] frontend-plugin-api: add the ability for extension data refs to encapsulate values Co-authored-by: blam <ben@blam.sh> Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .../src/wiring/createExtensionDataRef.test.ts | 19 +++++- .../src/wiring/createExtensionDataRef.ts | 65 ++++++++++++------- 2 files changed, 58 insertions(+), 26 deletions(-) diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.test.ts b/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.test.ts index f979a7def0..4b652298f1 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.test.ts @@ -14,7 +14,10 @@ * limitations under the License. */ -import { createExtensionDataRef } from './createExtensionDataRef'; +import { + ExtensionDataValue, + createExtensionDataRef, +} from './createExtensionDataRef'; describe('createExtensionDataRef', () => { it('can be created and read', () => { @@ -34,4 +37,18 @@ describe('createExtensionDataRef', () => { expect(refOptional.id).toBe('foo'); expect(String(refOptional)).toBe('ExtensionDataRef{id=foo,optional=true}'); }); + + it('can be used to encapsulate a value', () => { + const ref = createExtensionDataRef<string>().with({ id: 'foo' }); + const val: ExtensionDataValue<string, 'foo'> = ref('hello'); + expect(val).toEqual({ + $$type: '@backstage/ExtensionDataValue', + id: 'foo', + value: 'hello', + }); + // @ts-expect-error + ref(3); + // @ts-expect-error + ref(); + }); }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.ts b/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.ts index a1c7b462f2..7e0ff7587e 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.ts @@ -14,29 +14,37 @@ * limitations under the License. */ +/** @public */ +export type ExtensionDataValue<TData, TId extends string> = { + readonly $$type: '@backstage/ExtensionDataValue'; + readonly id: TId; + readonly value: TData; +}; + /** @public */ export type ExtensionDataRef< TData, TId extends string = string, TConfig extends { optional?: true } = {}, > = { - id: TId; - T: TData; - config: TConfig; - $$type: '@backstage/ExtensionDataRef'; + readonly $$type: '@backstage/ExtensionDataRef'; + readonly id: TId; + readonly T: TData; + readonly config: TConfig; }; /** @public */ export interface ConfigurableExtensionDataRef< - TId extends string, TData, + TId extends string, TConfig extends { optional?: true } = {}, > extends ExtensionDataRef<TData, TId, TConfig> { optional(): ConfigurableExtensionDataRef< - TId, TData, + TId, TData & { optional: true } >; + (t: TData): ExtensionDataValue<TData, TId>; } /** @@ -45,36 +53,43 @@ export interface ConfigurableExtensionDataRef< */ export function createExtensionDataRef<TData>( id: string, -): ConfigurableExtensionDataRef<string, TData>; +): ConfigurableExtensionDataRef<TData, string>; /** @public */ export function createExtensionDataRef<TData>(): { with<TId extends string>(options: { id: TId; - }): ConfigurableExtensionDataRef<TId, TData>; + }): ConfigurableExtensionDataRef<TData, TId>; }; export function createExtensionDataRef<TData>(id?: string): - | ConfigurableExtensionDataRef<string, TData> + | ConfigurableExtensionDataRef<TData, string> | { with<TId extends string>(options: { id: TId; - }): ConfigurableExtensionDataRef<TId, TData>; + }): ConfigurableExtensionDataRef<TData, TId>; } { const createRef = <TId extends string>(refId: TId) => - ({ - id: refId, - $$type: '@backstage/ExtensionDataRef', - config: {}, - optional() { - return { - ...this, - config: { ...this.config, optional: true }, - }; - }, - toString() { - const optional = Boolean(this.config.optional); - return `ExtensionDataRef{id=${refId},optional=${optional}}`; - }, - } as ConfigurableExtensionDataRef<TId, TData, { optional?: true }>); + Object.assign( + (value: TData): ExtensionDataValue<TData, TId> => ({ + $$type: '@backstage/ExtensionDataValue', + id: refId, + value, + }), + { + id: refId, + $$type: '@backstage/ExtensionDataRef', + config: {}, + optional() { + return { + ...this, + config: { ...this.config, optional: true }, + }; + }, + toString() { + const optional = Boolean(this.config.optional); + return `ExtensionDataRef{id=${refId},optional=${optional}}`; + }, + } as ConfigurableExtensionDataRef<TData, TId, { optional?: true }>, + ); if (id) { return createRef(id); } From cd9f3a526e34320fb1cd5166bb23ba8f41a10a0f Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Fri, 26 Jul 2024 13:56:14 +0200 Subject: [PATCH 449/510] frontend-plugin-api: update createExtensionInput to accept an array of refs too + tests Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .../src/wiring/createExtensionInput.test.ts | 181 ++++++++++++++++++ .../src/wiring/createExtensionInput.ts | 60 +++++- 2 files changed, 238 insertions(+), 3 deletions(-) create mode 100644 packages/frontend-plugin-api/src/wiring/createExtensionInput.test.ts diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionInput.test.ts b/packages/frontend-plugin-api/src/wiring/createExtensionInput.test.ts new file mode 100644 index 0000000000..0025789c73 --- /dev/null +++ b/packages/frontend-plugin-api/src/wiring/createExtensionInput.test.ts @@ -0,0 +1,181 @@ +/* + * 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 { createExtensionDataRef } from './createExtensionDataRef'; +import { ExtensionInput, createExtensionInput } from './createExtensionInput'; + +const stringDataRef = createExtensionDataRef<string>().with({ id: 'str' }); +const numberDataRef = createExtensionDataRef<number>().with({ id: 'num' }); + +function unused(..._any: any[]) {} + +describe('createExtensionInput', () => { + it('should create a regular input', () => { + const input = createExtensionInput([stringDataRef, numberDataRef]); + expect(input).toEqual({ + $$type: '@backstage/ExtensionInput', + extensionData: [stringDataRef, numberDataRef], + config: { singleton: false, optional: false }, + }); + + const x1: ExtensionInput< + typeof stringDataRef | typeof numberDataRef, + never, + { singleton: false; optional: false } + > = input; + // @ts-expect-error + const x2: ExtensionInput< + typeof stringDataRef, + never, + { singleton: false; optional: false } + > = input; + // @ts-expect-error + const x3: ExtensionInput< + typeof stringDataRef | typeof numberDataRef, + never, + { singleton: true; optional: false } + > = input; + // @ts-expect-error + const x4: ExtensionInput< + typeof stringDataRef | typeof numberDataRef, + never, + { singleton: false; optional: true } + > = input; + + unused(x1, x2, x3, x4); + }); + + it('should create a singleton input', () => { + const input = createExtensionInput([stringDataRef, numberDataRef], { + singleton: true, + }); + expect(input).toEqual({ + $$type: '@backstage/ExtensionInput', + extensionData: [stringDataRef, numberDataRef], + config: { singleton: true, optional: false }, + }); + + const x1: ExtensionInput< + typeof stringDataRef | typeof numberDataRef, + never, + { singleton: true; optional: false } + > = input; + // @ts-expect-error + const x2: ExtensionInput< + typeof stringDataRef, + never, + { singleton: true; optional: false } + > = input; + // @ts-expect-error + const x3: ExtensionInput< + typeof stringDataRef | typeof numberDataRef, + never, + { singleton: false; optional: false } + > = input; + // @ts-expect-error + const x4: ExtensionInput< + typeof stringDataRef | typeof numberDataRef, + never, + { singleton: false; optional: true } + > = input; + + unused(x1, x2, x3, x4); + }); + + it('should create an optional singleton input', () => { + const input = createExtensionInput([stringDataRef, numberDataRef], { + singleton: true, + optional: true, + }); + expect(input).toEqual({ + $$type: '@backstage/ExtensionInput', + extensionData: [stringDataRef, numberDataRef], + config: { singleton: true, optional: true }, + }); + + const x1: ExtensionInput< + typeof stringDataRef | typeof numberDataRef, + never, + { singleton: true; optional: true } + > = input; + // @ts-expect-error + const x2: ExtensionInput< + typeof stringDataRef, + never, + { singleton: true; optional: true } + > = input; + // @ts-expect-error + const x3: ExtensionInput< + typeof stringDataRef | typeof numberDataRef, + never, + { singleton: false; optional: false } + > = input; + // @ts-expect-error + const x4: ExtensionInput< + typeof stringDataRef | typeof numberDataRef, + never, + { singleton: false; optional: true } + > = input; + + unused(x1, x2, x3, x4); + }); + + it('should not allow duplicate data refs', () => { + expect(() => + createExtensionInput([stringDataRef, stringDataRef], { singleton: true }), + ).toThrow("ExtensionInput may not have duplicate data refs: 'str'"); + }); + + describe('old api', () => { + it('should create a regular input', () => { + const input = createExtensionInput({ + str: stringDataRef, + num: numberDataRef, + }); + expect(input).toEqual({ + $$type: '@backstage/ExtensionInput', + extensionData: { str: stringDataRef, num: numberDataRef }, + config: { singleton: false, optional: false }, + }); + + const x1: ExtensionInput< + never, + { str: typeof stringDataRef; num: typeof numberDataRef }, + { singleton: false; optional: false } + > = input; + // @ts-expect-error + const x2: ExtensionInput< + never, + { str: typeof numberDataRef; num: typeof stringDataRef }, // switched + { singleton: false; optional: false } + > = input; + // @ts-expect-error + const x3: ExtensionInput< + never, + { str: typeof stringDataRef; num: typeof numberDataRef }, + { singleton: true; optional: false } + > = input; + // @ts-expect-error + const x4: ExtensionInput< + never, + { str: typeof stringDataRef; num: typeof numberDataRef }, + { singleton: false; optional: true } + > = input; + + unused(x1, x2, x3, x4); + }); + }); +}); diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts b/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts index 1fd8fea972..3c09fcdaeb 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts @@ -15,31 +15,85 @@ */ import { AnyExtensionDataMap } from './createExtension'; +import { ExtensionDataRef } from './createExtensionDataRef'; /** @public */ export interface ExtensionInput< - TExtensionData extends AnyExtensionDataMap, + TExtensionData extends ExtensionDataRef<unknown, string, { optional?: true }>, + TExtensionDataMap extends AnyExtensionDataMap, TConfig extends { singleton: boolean; optional: boolean }, > { $$type: '@backstage/ExtensionInput'; - extensionData: TExtensionData; + extensionData: TExtensionData | TExtensionDataMap; config: TConfig; } +/** + * @public + * @deprecated Use the following form instead: `createExtensionInput([dataRef1, dataRef2])` + */ +export function createExtensionInput< + TExtensionDataMap extends AnyExtensionDataMap, + TConfig extends { singleton?: boolean; optional?: boolean }, +>( + extensionData: TExtensionDataMap, + config?: TConfig, +): ExtensionInput< + never, + TExtensionDataMap, + { + singleton: TConfig['singleton'] extends true ? true : false; + optional: TConfig['optional'] extends true ? true : false; + } +>; /** @public */ export function createExtensionInput< - TExtensionData extends AnyExtensionDataMap, + UExtensionData extends ExtensionDataRef<unknown, string, { optional?: true }>, + TConfig extends { singleton?: boolean; optional?: boolean }, +>( + extensionData: Array<UExtensionData>, + config?: TConfig, +): ExtensionInput< + UExtensionData, + never, + { + singleton: TConfig['singleton'] extends true ? true : false; + optional: TConfig['optional'] extends true ? true : false; + } +>; +export function createExtensionInput< + TExtensionData extends ExtensionDataRef<unknown, string, { optional?: true }>, + TExtensionDataMap extends AnyExtensionDataMap, TConfig extends { singleton?: boolean; optional?: boolean }, >( extensionData: TExtensionData, config?: TConfig, ): ExtensionInput< TExtensionData, + TExtensionDataMap, { singleton: TConfig['singleton'] extends true ? true : false; optional: TConfig['optional'] extends true ? true : false; } > { + if (Array.isArray(extensionData)) { + const seen = new Set(); + const duplicates = []; + for (const dataRef of extensionData) { + if (seen.has(dataRef.id)) { + duplicates.push(dataRef.id); + } else { + seen.add(dataRef.id); + } + } + if (duplicates.length > 0) { + throw new Error( + `ExtensionInput may not have duplicate data refs: '${duplicates.join( + "', '", + )}'`, + ); + } + } return { $$type: '@backstage/ExtensionInput', extensionData, From 0d9c38f1b806e25b3a85bf56f2c14feef8fc8a1c Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Fri, 26 Jul 2024 15:24:21 +0200 Subject: [PATCH 450/510] frontend-plugin-api: add new version of createExtension that avoids data maps Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .../src/wiring/createExtension.test.ts | 113 ++++++++-- .../src/wiring/createExtension.ts | 193 ++++++++++++++++-- .../src/wiring/createExtensionDataRef.ts | 7 + 3 files changed, 285 insertions(+), 28 deletions(-) diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts index 5b737746c2..febc7ec133 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts @@ -18,7 +18,8 @@ import { createExtension } from './createExtension'; import { createExtensionDataRef } from './createExtensionDataRef'; import { createExtensionInput } from './createExtensionInput'; -const stringData = createExtensionDataRef<string>().with({ id: 'string' }); +const stringDataRef = createExtensionDataRef<string>().with({ id: 'string' }); +const numberDataRef = createExtensionDataRef<number>().with({ id: 'number' }); function unused(..._any: any[]) {} @@ -28,7 +29,7 @@ describe('createExtension', () => { namespace: 'test', attachTo: { id: 'root', input: 'default' }, output: { - foo: stringData, + foo: stringDataRef, }, }; const extension = createExtension({ @@ -42,11 +43,11 @@ describe('createExtension', () => { expect(extension.namespace).toBe('test'); // When declared as an error function without a block the TypeScript errors - // are a more specific and will point at the property that is problematic. + // are a more specific and will often point at the property that is problematic. + // @ts-expect-error createExtension({ ...baseConfig, factory: () => ({ - // @ts-expect-error foo: 3, }), }); @@ -166,8 +167,8 @@ describe('createExtension', () => { namespace: 'test', attachTo: { id: 'root', input: 'default' }, output: { - foo: stringData, - bar: stringData.optional(), + foo: stringDataRef, + bar: stringDataRef.optional(), }, }; const extension = createExtension({ @@ -185,18 +186,18 @@ describe('createExtension', () => { bar: 'baz', }), }); + // @ts-expect-error createExtension({ ...baseConfig, factory: () => ({ - // @ts-expect-error foo: 3, }), }); + // @ts-expect-error createExtension({ ...baseConfig, factory: () => ({ foo: 'bar', - // @ts-expect-error bar: 3, }), }); @@ -237,18 +238,18 @@ describe('createExtension', () => { attachTo: { id: 'root', input: 'default' }, inputs: { mixed: createExtensionInput({ - required: stringData, - optional: stringData.optional(), + required: stringDataRef, + optional: stringDataRef.optional(), }), onlyRequired: createExtensionInput({ - required: stringData, + required: stringDataRef, }), onlyOptional: createExtensionInput({ - optional: stringData.optional(), + optional: stringDataRef.optional(), }), }, output: { - foo: stringData, + foo: stringDataRef, }, factory({ inputs }) { const a1: string = inputs.mixed?.[0].output.required; @@ -304,7 +305,7 @@ describe('createExtension', () => { }, }, output: { - foo: stringData, + foo: stringDataRef, }, factory({ config }) { const a1: string = config.foo; @@ -355,4 +356,88 @@ describe('createExtension', () => { return extension.configSchema?.parse({}); }).toThrow("Missing required value at 'foo'"); }); + + it('should new form of inputs and outputs', () => { + createExtension({ + namespace: 'test', + attachTo: { id: 'root', input: 'default' }, + inputs: { + header: createExtensionInput([stringDataRef.optional()], { + optional: true, + singleton: true, + }), + content: createExtensionInput([stringDataRef, numberDataRef], { + optional: false, + singleton: true, + }), + }, + output: [stringDataRef], + factory({ inputs }) { + const headerStr = inputs.header?.get(stringDataRef); + const contentStr = inputs.content.get(stringDataRef); + const contentNum = inputs.content.get(numberDataRef); + + // @ts-expect-error + inputs.header?.get(numberDataRef); + + // @ts-expect-error + const x1: string = headerStr; // string | undefined + + unused(x1); + + return [stringDataRef(contentStr.repeat(contentNum))]; + }, + }); + + // Double output + createExtension({ + namespace: 'test', + attachTo: { id: 'root', input: 'default' }, + output: [stringDataRef], + // @ts-expect-error + factory() { + return [stringDataRef('hello'), stringDataRef('hello')]; + }, + }); + + // Missing output + createExtension({ + namespace: 'test', + attachTo: { id: 'root', input: 'default' }, + output: [stringDataRef, numberDataRef], + // @ts-expect-error + factory() { + return [stringDataRef('hello')]; + }, + }); + + createExtension({ + namespace: 'test', + attachTo: { id: 'root', input: 'default' }, + output: [stringDataRef, numberDataRef], + factory() { + return [stringDataRef('hello'), numberDataRef(4)]; + }, + }); + + createExtension({ + namespace: 'test', + attachTo: { id: 'root', input: 'default' }, + output: [stringDataRef, numberDataRef.optional()], + factory() { + return [stringDataRef('hello'), numberDataRef(4)]; + }, + }); + + createExtension({ + namespace: 'test', + attachTo: { id: 'root', input: 'default' }, + output: [stringDataRef, numberDataRef.optional()], + factory() { + return [stringDataRef('hello')]; + }, + }); + + expect(true).toBe(true); + }); }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index cc2bec91c9..c514750a84 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -17,17 +17,26 @@ import { AppNode } from '../apis'; import { PortableSchema, createSchemaFromZod } from '../schema'; import { Expand } from '../types'; -import { ExtensionDataRef } from './createExtensionDataRef'; +import { + AnyExtensionDataRef, + ExtensionDataRef, + ExtensionDataValue, +} from './createExtensionDataRef'; import { ExtensionInput } from './createExtensionInput'; import { z } from 'zod'; -/** @public */ + +/** + * @public + * @deprecated Extension data maps will be removed. + */ export type AnyExtensionDataMap = { - [name in string]: ExtensionDataRef<unknown, string, { optional?: true }>; + [name in string]: AnyExtensionDataRef; }; /** @public */ export type AnyExtensionInputMap = { [inputName in string]: ExtensionInput< + AnyExtensionDataRef, AnyExtensionDataMap, { optional: boolean; singleton: boolean } >; @@ -36,6 +45,7 @@ export type AnyExtensionInputMap = { /** * Converts an extension data map into the matching concrete data values type. * @public + * @deprecated Extension data maps will be removed. */ export type ExtensionDataValues<TExtensionData extends AnyExtensionDataMap> = { [DataName in keyof TExtensionData as TExtensionData[DataName]['config'] extends { @@ -51,22 +61,41 @@ export type ExtensionDataValues<TExtensionData extends AnyExtensionDataMap> = { : never]?: TExtensionData[DataName]['T']; }; +/** @public */ +export type ExtensionDataContainer<UExtensionData extends AnyExtensionDataRef> = + { + get<TId extends UExtensionData['id']>( + ref: ExtensionDataRef<any, TId, any>, + ): UExtensionData extends ExtensionDataRef<infer IData, TId, infer IConfig> + ? IConfig['optional'] extends true + ? IData | undefined + : IData + : never; + }; + /** * Convert a single extension input into a matching resolved input. * @public */ -export type ResolvedExtensionInput<TExtensionData extends AnyExtensionDataMap> = - { - node: AppNode; - output: ExtensionDataValues<TExtensionData>; - }; +export type ResolvedExtensionInput< + TExtensionData extends AnyExtensionDataMap | AnyExtensionDataRef, +> = [TExtensionData] extends [AnyExtensionDataRef] + ? { + node: AppNode; + } & ExtensionDataContainer<TExtensionData> + : TExtensionData extends AnyExtensionDataMap + ? { + node: AppNode; + output: ExtensionDataValues<TExtensionData>; + } + : never; /** * Converts an extension input map into a matching collection of resolved inputs. * @public */ export type ResolvedExtensionInputs< - TInputs extends { [name in string]: ExtensionInput<any, any> }, + TInputs extends { [name in string]: ExtensionInput<any, any, any> }, > = { [InputName in keyof TInputs]: false extends TInputs[InputName]['config']['singleton'] ? Array<Expand<ResolvedExtensionInput<TInputs[InputName]['extensionData']>>> @@ -77,8 +106,11 @@ export type ResolvedExtensionInputs< >; }; -/** @public */ -export interface CreateExtensionOptions< +/** + * @public + * @deprecated This way of structuring the options is deprecated, this type will be removed in the future + */ +export interface LegacyCreateExtensionOptions< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, TConfig, @@ -111,6 +143,61 @@ export interface CreateExtensionOptions< }): Expand<ExtensionDataValues<TOutput>>; } +// TODO(Rugvip): This creates a permutation of all possible output tuples, +// taking the optionality into account. It's not optimal, since it might hurt +// performance for large outputs, doesn't provide a very clear error message, +// and doesn't allow us to refactor to allow for a generator. +/** @public */ +type ExtensionFactoryOutput< + URef extends AnyExtensionDataRef, + TPickRef extends AnyExtensionDataRef = URef, +> = [URef] extends [never] + ? [] + : TPickRef extends ExtensionDataRef<infer IData, infer IId, infer IConfig> + ? + | (IConfig['optional'] extends true + ? ExtensionFactoryOutput<Exclude<URef, TPickRef>> + : never) + | [ + ExtensionDataValue<IData, IId>, + ...ExtensionFactoryOutput<Exclude<URef, TPickRef>>, + ] + : never; + +/** @public */ +export type CreateExtensionOptions< + UOutput extends AnyExtensionDataRef, + TInputs extends AnyExtensionInputMap, + TConfig, + TConfigInput, + TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, +> = { + kind?: string; + namespace?: string; + name?: string; + attachTo: { id: string; input: string }; + disabled?: boolean; + inputs?: TInputs; + output: Array<UOutput>; + /** @deprecated - use `config.schema` instead */ + configSchema?: PortableSchema<TConfig, TConfigInput>; + config?: { + schema: TConfigSchema; + }; + factory(context: { + node: AppNode; + config: TConfig & + (string extends keyof TConfigSchema + ? {} + : { + [key in keyof TConfigSchema]: z.infer< + ReturnType<TConfigSchema[key]> + >; + }); + inputs: Expand<ResolvedExtensionInputs<TInputs>>; + }): ExtensionFactoryOutput<UOutput>; +}; + /** @public */ export interface ExtensionDefinition<TConfig, TConfigInput = TConfig> { $$type: '@backstage/ExtensionDefinition'; @@ -127,12 +214,12 @@ export interface InternalExtensionDefinition<TConfig, TConfigInput> extends ExtensionDefinition<TConfig, TConfigInput> { readonly version: 'v1'; readonly inputs: AnyExtensionInputMap; - readonly output: AnyExtensionDataMap; + readonly output: AnyExtensionDataMap | Array<AnyExtensionDataRef>; factory(context: { node: AppNode; config: TConfig; inputs: ResolvedExtensionInputs<any>; - }): ExtensionDataValues<any>; + }): ExtensionDataValues<any> | Iterable<ExtensionDataValue<any, any>>; } /** @internal */ @@ -157,6 +244,46 @@ export function toInternalExtensionDefinition<TConfig, TConfigInput>( } /** @public */ +export function createExtension< + UOutput extends AnyExtensionDataRef, + TInputs extends { + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + never, + { optional: boolean; singleton: boolean } + >; + }, + TConfig, + TConfigInput, + TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, +>( + options: CreateExtensionOptions< + UOutput, + TInputs, + TConfig, + TConfigInput, + TConfigSchema + >, +): ExtensionDefinition< + TConfig & + (string extends keyof TConfigSchema + ? {} + : { + [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; + }), + TConfigInput & + (string extends keyof TConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>; + }> + >) +>; +/** + * @public + * @deprecated - use the array format of `output` instead, see TODO-doc-link + */ export function createExtension< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, @@ -164,7 +291,7 @@ export function createExtension< TConfigInput, TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, >( - options: CreateExtensionOptions< + options: LegacyCreateExtensionOptions< TOutput, TInputs, TConfig, @@ -186,6 +313,44 @@ export function createExtension< [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>; }> >) +>; +export function createExtension< + UOutput extends AnyExtensionDataRef, + TInputs extends AnyExtensionInputMap, + TConfig, + TConfigInput, + TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, +>( + options: + | CreateExtensionOptions< + UOutput, + TInputs, + TConfig, + TConfigInput, + TConfigSchema + > + | LegacyCreateExtensionOptions< + AnyExtensionDataMap, + TInputs, + TConfig, + TConfigInput, + TConfigSchema + >, +): ExtensionDefinition< + TConfig & + (string extends keyof TConfigSchema + ? {} + : { + [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; + }), + TConfigInput & + (string extends keyof TConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>; + }> + >) > { const newConfigSchema = options.config?.schema; if (newConfigSchema && options.configSchema) { diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.ts b/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.ts index 7e0ff7587e..f4b348ae51 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.ts @@ -33,6 +33,13 @@ export type ExtensionDataRef< readonly config: TConfig; }; +/** @public */ +export type AnyExtensionDataRef = ExtensionDataRef< + unknown, + string, + { optional?: true } +>; + /** @public */ export interface ConfigurableExtensionDataRef< TData, From f4958c9a721221a42de5c1c73793f05c05d52674 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Fri, 26 Jul 2024 16:49:54 +0200 Subject: [PATCH 451/510] frontend-plugin-api: update createExtension to use union-based verification of factory outputs Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .../src/wiring/createExtension.test.ts | 112 ++++++++++-------- .../src/wiring/createExtension.ts | 49 ++++---- 2 files changed, 86 insertions(+), 75 deletions(-) diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts index febc7ec133..bbf2e539d1 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts @@ -357,7 +357,68 @@ describe('createExtension', () => { }).toThrow("Missing required value at 'foo'"); }); - it('should new form of inputs and outputs', () => { + it('should support new form of outputs', () => { + // @ts-expect-error + createExtension({ + namespace: 'test', + attachTo: { id: 'root', input: 'default' }, + output: [stringDataRef, numberDataRef], + factory() { + return []; // Missing all outputs + }, + }); + + // @ts-expect-error + createExtension({ + namespace: 'test', + attachTo: { id: 'root', input: 'default' }, + output: [stringDataRef, numberDataRef], + factory() { + return [stringDataRef('hello')]; // Missing number output + }, + }); + + // Duplicate output, we won't attempt to handle this a compile time and instead error out at runtime + createExtension({ + namespace: 'test', + attachTo: { id: 'root', input: 'default' }, + output: [stringDataRef], + factory() { + return [stringDataRef('hello'), stringDataRef('hello')]; + }, + }); + + createExtension({ + namespace: 'test', + attachTo: { id: 'root', input: 'default' }, + output: [stringDataRef, numberDataRef], + factory() { + return [stringDataRef('hello'), numberDataRef(4)]; + }, + }); + + createExtension({ + namespace: 'test', + attachTo: { id: 'root', input: 'default' }, + output: [stringDataRef, numberDataRef.optional()], + factory() { + return [stringDataRef('hello'), numberDataRef(4)]; + }, + }); + + createExtension({ + namespace: 'test', + attachTo: { id: 'root', input: 'default' }, + output: [stringDataRef, numberDataRef.optional()], + factory() { + return [stringDataRef('hello')]; // Missing number output, but it's optional so that's allowed + }, + }); + + expect(true).toBe(true); + }); + + it('should support new form of inputs', () => { createExtension({ namespace: 'test', attachTo: { id: 'root', input: 'default' }, @@ -389,55 +450,6 @@ describe('createExtension', () => { }, }); - // Double output - createExtension({ - namespace: 'test', - attachTo: { id: 'root', input: 'default' }, - output: [stringDataRef], - // @ts-expect-error - factory() { - return [stringDataRef('hello'), stringDataRef('hello')]; - }, - }); - - // Missing output - createExtension({ - namespace: 'test', - attachTo: { id: 'root', input: 'default' }, - output: [stringDataRef, numberDataRef], - // @ts-expect-error - factory() { - return [stringDataRef('hello')]; - }, - }); - - createExtension({ - namespace: 'test', - attachTo: { id: 'root', input: 'default' }, - output: [stringDataRef, numberDataRef], - factory() { - return [stringDataRef('hello'), numberDataRef(4)]; - }, - }); - - createExtension({ - namespace: 'test', - attachTo: { id: 'root', input: 'default' }, - output: [stringDataRef, numberDataRef.optional()], - factory() { - return [stringDataRef('hello'), numberDataRef(4)]; - }, - }); - - createExtension({ - namespace: 'test', - attachTo: { id: 'root', input: 'default' }, - output: [stringDataRef, numberDataRef.optional()], - factory() { - return [stringDataRef('hello')]; - }, - }); - expect(true).toBe(true); }); }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index c514750a84..cfce13d494 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -143,27 +143,6 @@ export interface LegacyCreateExtensionOptions< }): Expand<ExtensionDataValues<TOutput>>; } -// TODO(Rugvip): This creates a permutation of all possible output tuples, -// taking the optionality into account. It's not optimal, since it might hurt -// performance for large outputs, doesn't provide a very clear error message, -// and doesn't allow us to refactor to allow for a generator. -/** @public */ -type ExtensionFactoryOutput< - URef extends AnyExtensionDataRef, - TPickRef extends AnyExtensionDataRef = URef, -> = [URef] extends [never] - ? [] - : TPickRef extends ExtensionDataRef<infer IData, infer IId, infer IConfig> - ? - | (IConfig['optional'] extends true - ? ExtensionFactoryOutput<Exclude<URef, TPickRef>> - : never) - | [ - ExtensionDataValue<IData, IId>, - ...ExtensionFactoryOutput<Exclude<URef, TPickRef>>, - ] - : never; - /** @public */ export type CreateExtensionOptions< UOutput extends AnyExtensionDataRef, @@ -171,6 +150,7 @@ export type CreateExtensionOptions< TConfig, TConfigInput, TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, + UFactoryOutput extends ExtensionDataValue<any, any>, > = { kind?: string; namespace?: string; @@ -195,8 +175,23 @@ export type CreateExtensionOptions< >; }); inputs: Expand<ResolvedExtensionInputs<TInputs>>; - }): ExtensionFactoryOutput<UOutput>; -}; + }): Iterable<UFactoryOutput>; +} & (( + UOutput extends any + ? UOutput['config']['optional'] extends true + ? never + : UOutput['id'] + : never +) extends infer IRequiredOutputIds + ? [IRequiredOutputIds] extends [UFactoryOutput['id']] + ? {} + : { + 'Error: The extension factory is missing the following outputs': Exclude< + IRequiredOutputIds, + UFactoryOutput['id'] + >; + } + : never); /** @public */ export interface ExtensionDefinition<TConfig, TConfigInput = TConfig> { @@ -256,13 +251,15 @@ export function createExtension< TConfig, TConfigInput, TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, + UFactoryOutput extends ExtensionDataValue<any, any>, >( options: CreateExtensionOptions< UOutput, TInputs, TConfig, TConfigInput, - TConfigSchema + TConfigSchema, + UFactoryOutput >, ): ExtensionDefinition< TConfig & @@ -320,6 +317,7 @@ export function createExtension< TConfig, TConfigInput, TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, + UFactoryOutput extends ExtensionDataValue<any, any>, >( options: | CreateExtensionOptions< @@ -327,7 +325,8 @@ export function createExtension< TInputs, TConfig, TConfigInput, - TConfigSchema + TConfigSchema, + UFactoryOutput > | LegacyCreateExtensionOptions< AnyExtensionDataMap, From 760d99b138c916bcb20f1bb372390ff2c4fdd7d5 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Fri, 26 Jul 2024 17:03:13 +0200 Subject: [PATCH 452/510] frontend-plugin-api: refactor to use LegacyExtensionInput type Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .../src/wiring/createExtensionInput.test.ts | 30 ++++---------- .../src/wiring/createExtensionInput.ts | 41 +++++++++++++------ 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionInput.test.ts b/packages/frontend-plugin-api/src/wiring/createExtensionInput.test.ts index 0025789c73..e401adc675 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionInput.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionInput.test.ts @@ -15,7 +15,11 @@ */ import { createExtensionDataRef } from './createExtensionDataRef'; -import { ExtensionInput, createExtensionInput } from './createExtensionInput'; +import { + ExtensionInput, + LegacyExtensionInput, + createExtensionInput, +} from './createExtensionInput'; const stringDataRef = createExtensionDataRef<string>().with({ id: 'str' }); const numberDataRef = createExtensionDataRef<number>().with({ id: 'num' }); @@ -33,25 +37,21 @@ describe('createExtensionInput', () => { const x1: ExtensionInput< typeof stringDataRef | typeof numberDataRef, - never, { singleton: false; optional: false } > = input; // @ts-expect-error const x2: ExtensionInput< typeof stringDataRef, - never, { singleton: false; optional: false } > = input; // @ts-expect-error const x3: ExtensionInput< typeof stringDataRef | typeof numberDataRef, - never, { singleton: true; optional: false } > = input; // @ts-expect-error const x4: ExtensionInput< typeof stringDataRef | typeof numberDataRef, - never, { singleton: false; optional: true } > = input; @@ -70,25 +70,21 @@ describe('createExtensionInput', () => { const x1: ExtensionInput< typeof stringDataRef | typeof numberDataRef, - never, { singleton: true; optional: false } > = input; // @ts-expect-error const x2: ExtensionInput< typeof stringDataRef, - never, { singleton: true; optional: false } > = input; // @ts-expect-error const x3: ExtensionInput< typeof stringDataRef | typeof numberDataRef, - never, { singleton: false; optional: false } > = input; // @ts-expect-error const x4: ExtensionInput< typeof stringDataRef | typeof numberDataRef, - never, { singleton: false; optional: true } > = input; @@ -108,25 +104,21 @@ describe('createExtensionInput', () => { const x1: ExtensionInput< typeof stringDataRef | typeof numberDataRef, - never, { singleton: true; optional: true } > = input; // @ts-expect-error const x2: ExtensionInput< typeof stringDataRef, - never, { singleton: true; optional: true } > = input; // @ts-expect-error const x3: ExtensionInput< typeof stringDataRef | typeof numberDataRef, - never, { singleton: false; optional: false } > = input; // @ts-expect-error const x4: ExtensionInput< typeof stringDataRef | typeof numberDataRef, - never, { singleton: false; optional: true } > = input; @@ -151,26 +143,22 @@ describe('createExtensionInput', () => { config: { singleton: false, optional: false }, }); - const x1: ExtensionInput< - never, + const x1: LegacyExtensionInput< { str: typeof stringDataRef; num: typeof numberDataRef }, { singleton: false; optional: false } > = input; // @ts-expect-error - const x2: ExtensionInput< - never, + const x2: LegacyExtensionInput< { str: typeof numberDataRef; num: typeof stringDataRef }, // switched { singleton: false; optional: false } > = input; // @ts-expect-error - const x3: ExtensionInput< - never, + const x3: LegacyExtensionInput< { str: typeof stringDataRef; num: typeof numberDataRef }, { singleton: true; optional: false } > = input; // @ts-expect-error - const x4: ExtensionInput< - never, + const x4: LegacyExtensionInput< { str: typeof stringDataRef; num: typeof numberDataRef }, { singleton: false; optional: true } > = input; diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts b/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts index 3c09fcdaeb..5627bdecc2 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts @@ -20,11 +20,23 @@ import { ExtensionDataRef } from './createExtensionDataRef'; /** @public */ export interface ExtensionInput< TExtensionData extends ExtensionDataRef<unknown, string, { optional?: true }>, + TConfig extends { singleton: boolean; optional: boolean }, +> { + $$type: '@backstage/ExtensionInput'; + extensionData: TExtensionData; + config: TConfig; +} + +/** + * @public + * @deprecated This type will be removed. Use `ExtensionInput` instead. + */ +export interface LegacyExtensionInput< TExtensionDataMap extends AnyExtensionDataMap, TConfig extends { singleton: boolean; optional: boolean }, > { $$type: '@backstage/ExtensionInput'; - extensionData: TExtensionData | TExtensionDataMap; + extensionData: TExtensionDataMap; config: TConfig; } @@ -38,8 +50,7 @@ export function createExtensionInput< >( extensionData: TExtensionDataMap, config?: TConfig, -): ExtensionInput< - never, +): LegacyExtensionInput< TExtensionDataMap, { singleton: TConfig['singleton'] extends true ? true : false; @@ -55,7 +66,6 @@ export function createExtensionInput< config?: TConfig, ): ExtensionInput< UExtensionData, - never, { singleton: TConfig['singleton'] extends true ? true : false; optional: TConfig['optional'] extends true ? true : false; @@ -68,14 +78,21 @@ export function createExtensionInput< >( extensionData: TExtensionData, config?: TConfig, -): ExtensionInput< - TExtensionData, - TExtensionDataMap, - { - singleton: TConfig['singleton'] extends true ? true : false; - optional: TConfig['optional'] extends true ? true : false; - } -> { +): + | LegacyExtensionInput< + TExtensionDataMap, + { + singleton: TConfig['singleton'] extends true ? true : false; + optional: TConfig['optional'] extends true ? true : false; + } + > + | ExtensionInput< + TExtensionData, + { + singleton: TConfig['singleton'] extends true ? true : false; + optional: TConfig['optional'] extends true ? true : false; + } + > { if (Array.isArray(extensionData)) { const seen = new Set(); const duplicates = []; From e7a720ac2c19a1b53fa364c160842a0034b8414e Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Fri, 26 Jul 2024 17:07:28 +0200 Subject: [PATCH 453/510] frontend-plugin-api: refactor to use two disctict internal extension definitions Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .../src/wiring/createExtension.test.ts | 178 +++++++++--------- .../src/wiring/createExtension.ts | 93 +++++---- 2 files changed, 154 insertions(+), 117 deletions(-) diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts index bbf2e539d1..327639af37 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts @@ -40,7 +40,7 @@ describe('createExtension', () => { }; }, }); - expect(extension.namespace).toBe('test'); + expect(extension).toMatchObject({ version: 'v1', namespace: 'test' }); // When declared as an error function without a block the TypeScript errors // are a more specific and will often point at the property that is problematic. @@ -177,7 +177,7 @@ describe('createExtension', () => { foo: 'bar', }), }); - expect(extension.namespace).toBe('test'); + expect(extension).toMatchObject({ version: 'v1', namespace: 'test' }); createExtension({ ...baseConfig, @@ -287,7 +287,7 @@ describe('createExtension', () => { }; }, }); - expect(extension.namespace).toBe('test'); + expect(extension).toMatchObject({ version: 'v1', namespace: 'test' }); expect(String(extension)).toBe( 'ExtensionDefinition{namespace=test,attachTo=root@default}', ); @@ -325,7 +325,7 @@ describe('createExtension', () => { }; }, }); - expect(extension.namespace).toBe('test'); + expect(extension).toMatchObject({ version: 'v1', namespace: 'test' }); expect(String(extension)).toBe( 'ExtensionDefinition{namespace=test,attachTo=root@default}', ); @@ -358,98 +358,108 @@ describe('createExtension', () => { }); it('should support new form of outputs', () => { - // @ts-expect-error - createExtension({ - namespace: 'test', - attachTo: { id: 'root', input: 'default' }, - output: [stringDataRef, numberDataRef], - factory() { - return []; // Missing all outputs - }, - }); + expect( + // @ts-expect-error + createExtension({ + namespace: 'test', + attachTo: { id: 'root', input: 'default' }, + output: [stringDataRef, numberDataRef], + factory() { + return []; // Missing all outputs + }, + }), + ).toMatchObject({ version: 'v2' }); - // @ts-expect-error - createExtension({ - namespace: 'test', - attachTo: { id: 'root', input: 'default' }, - output: [stringDataRef, numberDataRef], - factory() { - return [stringDataRef('hello')]; // Missing number output - }, - }); + expect( + // @ts-expect-error + createExtension({ + namespace: 'test', + attachTo: { id: 'root', input: 'default' }, + output: [stringDataRef, numberDataRef], + factory() { + return [stringDataRef('hello')]; // Missing number output + }, + }), + ).toMatchObject({ version: 'v2' }); // Duplicate output, we won't attempt to handle this a compile time and instead error out at runtime - createExtension({ - namespace: 'test', - attachTo: { id: 'root', input: 'default' }, - output: [stringDataRef], - factory() { - return [stringDataRef('hello'), stringDataRef('hello')]; - }, - }); + expect( + createExtension({ + namespace: 'test', + attachTo: { id: 'root', input: 'default' }, + output: [stringDataRef], + factory() { + return [stringDataRef('hello'), stringDataRef('hello')]; + }, + }), + ).toMatchObject({ version: 'v2' }); - createExtension({ - namespace: 'test', - attachTo: { id: 'root', input: 'default' }, - output: [stringDataRef, numberDataRef], - factory() { - return [stringDataRef('hello'), numberDataRef(4)]; - }, - }); + expect( + createExtension({ + namespace: 'test', + attachTo: { id: 'root', input: 'default' }, + output: [stringDataRef, numberDataRef], + factory() { + return [stringDataRef('hello'), numberDataRef(4)]; + }, + }), + ).toMatchObject({ version: 'v2' }); - createExtension({ - namespace: 'test', - attachTo: { id: 'root', input: 'default' }, - output: [stringDataRef, numberDataRef.optional()], - factory() { - return [stringDataRef('hello'), numberDataRef(4)]; - }, - }); + expect( + createExtension({ + namespace: 'test', + attachTo: { id: 'root', input: 'default' }, + output: [stringDataRef, numberDataRef.optional()], + factory() { + return [stringDataRef('hello'), numberDataRef(4)]; + }, + }), + ).toMatchObject({ version: 'v2' }); - createExtension({ - namespace: 'test', - attachTo: { id: 'root', input: 'default' }, - output: [stringDataRef, numberDataRef.optional()], - factory() { - return [stringDataRef('hello')]; // Missing number output, but it's optional so that's allowed - }, - }); - - expect(true).toBe(true); + expect( + createExtension({ + namespace: 'test', + attachTo: { id: 'root', input: 'default' }, + output: [stringDataRef, numberDataRef.optional()], + factory() { + return [stringDataRef('hello')]; // Missing number output, but it's optional so that's allowed + }, + }), + ).toMatchObject({ version: 'v2' }); }); it('should support new form of inputs', () => { - createExtension({ - namespace: 'test', - attachTo: { id: 'root', input: 'default' }, - inputs: { - header: createExtensionInput([stringDataRef.optional()], { - optional: true, - singleton: true, - }), - content: createExtensionInput([stringDataRef, numberDataRef], { - optional: false, - singleton: true, - }), - }, - output: [stringDataRef], - factory({ inputs }) { - const headerStr = inputs.header?.get(stringDataRef); - const contentStr = inputs.content.get(stringDataRef); - const contentNum = inputs.content.get(numberDataRef); + expect( + createExtension({ + namespace: 'test', + attachTo: { id: 'root', input: 'default' }, + inputs: { + header: createExtensionInput([stringDataRef.optional()], { + optional: true, + singleton: true, + }), + content: createExtensionInput([stringDataRef, numberDataRef], { + optional: false, + singleton: true, + }), + }, + output: [stringDataRef], + factory({ inputs }) { + const headerStr = inputs.header?.get(stringDataRef); + const contentStr = inputs.content.get(stringDataRef); + const contentNum = inputs.content.get(numberDataRef); - // @ts-expect-error - inputs.header?.get(numberDataRef); + // @ts-expect-error + inputs.header?.get(numberDataRef); - // @ts-expect-error - const x1: string = headerStr; // string | undefined + // @ts-expect-error + const x1: string = headerStr; // string | undefined - unused(x1); + unused(x1); - return [stringDataRef(contentStr.repeat(contentNum))]; - }, - }); - - expect(true).toBe(true); + return [stringDataRef(contentStr.repeat(contentNum))]; + }, + }), + ).toMatchObject({ version: 'v2' }); }); }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index cfce13d494..6727a92419 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -22,7 +22,7 @@ import { ExtensionDataRef, ExtensionDataValue, } from './createExtensionDataRef'; -import { ExtensionInput } from './createExtensionInput'; +import { ExtensionInput, LegacyExtensionInput } from './createExtensionInput'; import { z } from 'zod'; /** @@ -33,10 +33,12 @@ export type AnyExtensionDataMap = { [name in string]: AnyExtensionDataRef; }; -/** @public */ +/** + * @public + * @deprecated This type will be removed. + */ export type AnyExtensionInputMap = { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, + [inputName in string]: LegacyExtensionInput< AnyExtensionDataMap, { optional: boolean; singleton: boolean } >; @@ -95,7 +97,7 @@ export type ResolvedExtensionInput< * @public */ export type ResolvedExtensionInputs< - TInputs extends { [name in string]: ExtensionInput<any, any, any> }, + TInputs extends { [name in string]: ExtensionInput<any, any> }, > = { [InputName in keyof TInputs]: false extends TInputs[InputName]['config']['singleton'] ? Array<Expand<ResolvedExtensionInput<TInputs[InputName]['extensionData']>>> @@ -146,7 +148,12 @@ export interface LegacyCreateExtensionOptions< /** @public */ export type CreateExtensionOptions< UOutput extends AnyExtensionDataRef, - TInputs extends AnyExtensionInputMap, + TInputs extends { + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { optional: boolean; singleton: boolean } + >; + }, TConfig, TConfigInput, TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, @@ -205,17 +212,40 @@ export interface ExtensionDefinition<TConfig, TConfigInput = TConfig> { } /** @internal */ -export interface InternalExtensionDefinition<TConfig, TConfigInput> - extends ExtensionDefinition<TConfig, TConfigInput> { - readonly version: 'v1'; - readonly inputs: AnyExtensionInputMap; - readonly output: AnyExtensionDataMap | Array<AnyExtensionDataRef>; - factory(context: { - node: AppNode; - config: TConfig; - inputs: ResolvedExtensionInputs<any>; - }): ExtensionDataValues<any> | Iterable<ExtensionDataValue<any, any>>; -} +export type InternalExtensionDefinition<TConfig, TConfigInput> = + ExtensionDefinition<TConfig, TConfigInput> & + ( + | { + readonly version: 'v1'; + readonly inputs: AnyExtensionInputMap; + readonly output: AnyExtensionDataMap; + factory(context: { + node: AppNode; + config: TConfig; + inputs: ResolvedExtensionInputs<AnyExtensionInputMap>; + }): ExtensionDataValues<any>; + } + | { + readonly version: 'v2'; + readonly inputs: { + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { optional: boolean; singleton: boolean } + >; + }; + readonly output: Array<AnyExtensionDataRef>; + factory(context: { + node: AppNode; + config: TConfig; + inputs: ResolvedExtensionInputs<{ + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { optional: boolean; singleton: boolean } + >; + }>; + }): Iterable<ExtensionDataValue<any, any>>; + } + ); /** @internal */ export function toInternalExtensionDefinition<TConfig, TConfigInput>( @@ -230,9 +260,10 @@ export function toInternalExtensionDefinition<TConfig, TConfigInput>( `Invalid extension definition instance, bad type '${internal.$$type}'`, ); } - if (internal.version !== 'v1') { + const version = internal.version; + if (version !== 'v1' && version !== 'v2') { throw new Error( - `Invalid extension definition instance, bad version '${internal.version}'`, + `Invalid extension definition instance, bad version '${version}'`, ); } return internal; @@ -244,7 +275,6 @@ export function createExtension< TInputs extends { [inputName in string]: ExtensionInput< AnyExtensionDataRef, - never, { optional: boolean; singleton: boolean } >; }, @@ -313,7 +343,13 @@ export function createExtension< >; export function createExtension< UOutput extends AnyExtensionDataRef, - TInputs extends AnyExtensionInputMap, + TInputs extends { + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { optional: boolean; singleton: boolean } + >; + }, + TLegacyInputs extends AnyExtensionInputMap, TConfig, TConfigInput, TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, @@ -330,7 +366,7 @@ export function createExtension< > | LegacyCreateExtensionOptions< AnyExtensionDataMap, - TInputs, + TLegacyInputs, TConfig, TConfigInput, TConfigSchema @@ -367,7 +403,7 @@ export function createExtension< return { $$type: '@backstage/ExtensionDefinition', - version: 'v1', + version: Symbol.iterator in options.output ? 'v2' : 'v1', kind: options.kind, namespace: options.namespace, name: options.name, @@ -376,16 +412,7 @@ export function createExtension< inputs: options.inputs ?? {}, output: options.output, configSchema, - factory({ inputs, config, ...rest }) { - // TODO: Simplify this, but TS wouldn't infer the input type for some reason - return options.factory({ - inputs: inputs as Expand<ResolvedExtensionInputs<TInputs>>, - config: config as TConfig & { - [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; - }, - ...rest, - }); - }, + factory: options.factory, toString() { const parts: string[] = []; if (options.kind) { From ea25c0bf335b623244c01bd51ed1821dbfeac6b7 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Fri, 26 Jul 2024 17:17:05 +0200 Subject: [PATCH 454/510] frontend-plugin-api: export new types Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- packages/frontend-plugin-api/src/wiring/index.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/frontend-plugin-api/src/wiring/index.ts b/packages/frontend-plugin-api/src/wiring/index.ts index 6d20368225..baada41ae8 100644 --- a/packages/frontend-plugin-api/src/wiring/index.ts +++ b/packages/frontend-plugin-api/src/wiring/index.ts @@ -17,6 +17,7 @@ export { coreExtensionData } from './coreExtensionData'; export { createExtension, + type ExtensionDataContainer, type ExtensionDefinition, type CreateExtensionOptions, type ExtensionDataValues, @@ -28,10 +29,13 @@ export { export { createExtensionInput, type ExtensionInput, + type LegacyExtensionInput, } from './createExtensionInput'; export { createExtensionDataRef, + type AnyExtensionDataRef, type ExtensionDataRef, + type ExtensionDataValue, type ConfigurableExtensionDataRef, } from './createExtensionDataRef'; export { createPlugin, type PluginOptions } from './createPlugin'; From b207f69ba1f5fa6c07f2d55d07871da3912c6e31 Mon Sep 17 00:00:00 2001 From: MT Lewis <mtlewis@users.noreply.github.com> Date: Sat, 27 Jul 2024 14:04:22 +0100 Subject: [PATCH 455/510] yarn-plugin: memoize manifest fetching Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com> --- packages/yarn-plugin/package.json | 1 + .../src/resolver/BackstageResolver.test.ts | 29 +++++++++++++++++++ packages/yarn-plugin/src/util.ts | 8 ++++- yarn.lock | 1 + 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/packages/yarn-plugin/package.json b/packages/yarn-plugin/package.json index fd70dc8600..206adeddbe 100644 --- a/packages/yarn-plugin/package.json +++ b/packages/yarn-plugin/package.json @@ -35,6 +35,7 @@ "@yarnpkg/core": "^4.0.3", "@yarnpkg/fslib": "^3.0.2", "chalk": "^4.0.0", + "lodash": "^4.17.21", "semver": "^7.6.0" }, "devDependencies": { diff --git a/packages/yarn-plugin/src/resolver/BackstageResolver.test.ts b/packages/yarn-plugin/src/resolver/BackstageResolver.test.ts index 4cc0c1c9f2..6c7157ebe9 100644 --- a/packages/yarn-plugin/src/resolver/BackstageResolver.test.ts +++ b/packages/yarn-plugin/src/resolver/BackstageResolver.test.ts @@ -16,6 +16,7 @@ import { structUtils } from '@yarnpkg/core'; import { npath, ppath } from '@yarnpkg/fslib'; +import { getManifestByVersion } from '@backstage/release-manifests'; import { BackstageResolver } from './BackstageResolver'; import { createMockDirectory } from '@backstage/backend-test-utils'; @@ -31,6 +32,10 @@ jest.mock('@backstage/release-manifests', () => ({ }), })); +const getManifestByVersionMock = getManifestByVersion as jest.MockedFunction< + typeof getManifestByVersion +>; + describe('BackstageResolver', () => { const mockDir = createMockDirectory(); let backstageResolver: BackstageResolver; @@ -177,5 +182,29 @@ describe('BackstageResolver', () => { ), ).rejects.toThrow(/invalid backstage version/i); }); + + it('memoizes manifest retrieval', async () => { + const descriptor1 = structUtils.makeDescriptor( + structUtils.makeIdent('backstage', 'core'), + 'backstage:1.23.45', + ); + + for (let i = 0; i < 5; i++) { + await backstageResolver.getCandidates(descriptor1); + } + + expect(getManifestByVersionMock).toHaveBeenCalledTimes(1); + + const descriptor2 = structUtils.makeDescriptor( + structUtils.makeIdent('backstage', 'core'), + 'backstage:6.78.90', + ); + + for (let i = 0; i < 5; i++) { + await backstageResolver.getCandidates(descriptor2); + } + + expect(getManifestByVersionMock).toHaveBeenCalledTimes(2); + }); }); }); diff --git a/packages/yarn-plugin/src/util.ts b/packages/yarn-plugin/src/util.ts index 8431e23cfa..0b613a477c 100644 --- a/packages/yarn-plugin/src/util.ts +++ b/packages/yarn-plugin/src/util.ts @@ -16,11 +16,17 @@ import { ppath, xfs } from '@yarnpkg/fslib'; import { valid as semverValid } from 'semver'; -import { getManifestByVersion } from '@backstage/release-manifests'; +import { memoize } from 'lodash'; +import { getManifestByVersion as getManifestByVersionBase } from '@backstage/release-manifests'; import { BACKSTAGE_JSON, findPaths } from '@backstage/cli-common'; import { Descriptor, structUtils } from '@yarnpkg/core'; import { PROTOCOL } from './constants'; +const getManifestByVersion = memoize( + getManifestByVersionBase, + ({ version }) => version, +); + export const getCurrentBackstageVersion = () => { const workspaceRoot = ppath.resolve(findPaths(ppath.cwd()).targetRoot); diff --git a/yarn.lock b/yarn.lock index ad55a72897..155c0eeb9e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -45239,6 +45239,7 @@ __metadata: "@yarnpkg/core": ^4.0.3 "@yarnpkg/fslib": ^3.0.2 chalk: ^4.0.0 + lodash: ^4.17.21 nodemon: ^3.0.1 semver: ^7.6.0 languageName: unknown From e2e84edf7b500a60e9fa0faf6da852160947cc8c Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Fri, 26 Jul 2024 17:25:44 +0200 Subject: [PATCH 456/510] frontend-plugin-api: add v2 extension and resolution Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .../wiring/resolveExtensionDefinition.test.ts | 54 +++++++++++++--- .../src/wiring/resolveExtensionDefinition.ts | 63 ++++++++++++++----- 2 files changed, 93 insertions(+), 24 deletions(-) diff --git a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.test.ts b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.test.ts index 8970cfe168..e1bfcbfc11 100644 --- a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.test.ts +++ b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.test.ts @@ -17,14 +17,54 @@ import { ExtensionDefinition } from './createExtension'; import { resolveExtensionDefinition } from './resolveExtensionDefinition'; -const baseDef = { - $$type: '@backstage/ExtensionDefinition', - version: 'v1', - attachTo: { id: '', input: '' }, - disabled: false, -}; - describe('resolveExtensionDefinition', () => { + const baseDef = { + $$type: '@backstage/ExtensionDefinition', + version: 'v2', + attachTo: { id: '', input: '' }, + disabled: false, + }; + + it.each([ + [{ namespace: 'ns' }, 'ns'], + [{ namespace: 'n' }, 'n'], + [{ namespace: 'ns', name: 'n' }, 'ns/n'], + [{ kind: 'k', namespace: 'ns' }, 'k:ns'], + [{ kind: 'k', namespace: 'ns', name: 'n' }, 'k:ns/n'], + ])(`should resolve extension IDs %s`, (definition, expected) => { + const resolved = resolveExtensionDefinition({ + ...baseDef, + ...definition, + } as ExtensionDefinition<unknown>); + expect(resolved.id).toBe(expected); + expect(String(resolved)).toBe(`Extension{id=${expected}}`); + }); + + it('should fail to resolve extension ID without namespace', () => { + expect(() => + resolveExtensionDefinition({ + ...baseDef, + kind: 'k', + } as ExtensionDefinition<unknown>), + ).toThrow( + 'Extension must declare an explicit namespace or name as it could not be resolved from context, kind=k namespace=undefined name=undefined', + ); + expect(() => + resolveExtensionDefinition(baseDef as ExtensionDefinition<unknown>), + ).toThrow( + 'Extension must declare an explicit namespace or name as it could not be resolved from context, kind=undefined namespace=undefined name=undefined', + ); + }); +}); + +describe('old resolveExtensionDefinition', () => { + const baseDef = { + $$type: '@backstage/ExtensionDefinition', + version: 'v1', + attachTo: { id: '', input: '' }, + disabled: false, + }; + it.each([ [{ namespace: 'ns' }, 'ns'], [{ namespace: 'n' }, 'n'], diff --git a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts index eddd923702..18b6f0a653 100644 --- a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts +++ b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts @@ -24,6 +24,11 @@ import { toInternalExtensionDefinition, } from './createExtension'; import { PortableSchema } from '../schema'; +import { ExtensionInput } from './createExtensionInput'; +import { + AnyExtensionDataRef, + ExtensionDataValue, +} from './createExtensionDataRef'; /** @public */ export interface Extension<TConfig, TConfigInput = TConfig> { @@ -35,17 +40,42 @@ export interface Extension<TConfig, TConfigInput = TConfig> { } /** @internal */ -export interface InternalExtension<TConfig, TConfigInput> - extends Extension<TConfig, TConfigInput> { - readonly version: 'v1'; - readonly inputs: AnyExtensionInputMap; - readonly output: AnyExtensionDataMap; - factory(options: { - node: AppNode; - config: TConfig; - inputs: ResolvedExtensionInputs<any>; - }): ExtensionDataValues<any>; -} +export type InternalExtension<TConfig, TConfigInput> = Extension< + TConfig, + TConfigInput +> & + ( + | { + readonly version: 'v1'; + readonly inputs: AnyExtensionInputMap; + readonly output: AnyExtensionDataMap; + factory(options: { + node: AppNode; + config: TConfig; + inputs: ResolvedExtensionInputs<AnyExtensionInputMap>; + }): ExtensionDataValues<any>; + } + | { + readonly version: 'v2'; + readonly inputs: { + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { optional: boolean; singleton: boolean } + >; + }; + readonly output: Array<AnyExtensionDataRef>; + factory(options: { + node: AppNode; + config: TConfig; + inputs: ResolvedExtensionInputs<{ + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { optional: boolean; singleton: boolean } + >; + }>; + }): Iterable<ExtensionDataValue<any, any>>; + } + ); /** @internal */ export function toInternalExtension<TConfig, TConfigInput>( @@ -57,10 +87,9 @@ export function toInternalExtension<TConfig, TConfigInput>( `Invalid extension instance, bad type '${internal.$$type}'`, ); } - if (internal.version !== 'v1') { - throw new Error( - `Invalid extension instance, bad version '${internal.version}'`, - ); + const version = internal.version; + if (version !== 'v1' && version !== 'v2') { + throw new Error(`Invalid extension instance, bad version '${version}'`); } return internal; } @@ -87,10 +116,10 @@ export function resolveExtensionDefinition<TConfig, TConfigInput>( return { ...rest, $$type: '@backstage/Extension', - version: 'v1', + version: internalDefinition.version, id, toString() { return `Extension{id=${id}}`; }, - } as Extension<TConfig, TConfigInput>; + } as InternalExtension<TConfig, TConfigInput>; } From 0d24c1fa3e3409a10542b37b9b465f2ed977e2e7 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Sat, 27 Jul 2024 11:10:53 +0200 Subject: [PATCH 457/510] frontend-plugin-api: more fixes for new extension io structure Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .../src/wiring/createExtension.ts | 22 ++++---- .../wiring/createExtensionBlueprint.test.tsx | 8 +-- .../src/wiring/createExtensionInput.ts | 52 ++++++++++++------- 3 files changed, 46 insertions(+), 36 deletions(-) diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index 6727a92419..4034ef7238 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -80,15 +80,15 @@ export type ExtensionDataContainer<UExtensionData extends AnyExtensionDataRef> = * @public */ export type ResolvedExtensionInput< - TExtensionData extends AnyExtensionDataMap | AnyExtensionDataRef, -> = [TExtensionData] extends [AnyExtensionDataRef] + TExtensionInput extends ExtensionInput<any, any>, +> = TExtensionInput['extensionData'] extends Array<AnyExtensionDataRef> ? { node: AppNode; - } & ExtensionDataContainer<TExtensionData> - : TExtensionData extends AnyExtensionDataMap + } & ExtensionDataContainer<TExtensionInput['extensionData'][number]> + : TExtensionInput['extensionData'] extends AnyExtensionDataMap ? { node: AppNode; - output: ExtensionDataValues<TExtensionData>; + output: ExtensionDataValues<TExtensionInput['extensionData']>; } : never; @@ -97,15 +97,15 @@ export type ResolvedExtensionInput< * @public */ export type ResolvedExtensionInputs< - TInputs extends { [name in string]: ExtensionInput<any, any> }, + TInputs extends { + [name in string]: ExtensionInput<any, any> | LegacyExtensionInput<any, any>; + }, > = { [InputName in keyof TInputs]: false extends TInputs[InputName]['config']['singleton'] - ? Array<Expand<ResolvedExtensionInput<TInputs[InputName]['extensionData']>>> + ? Array<Expand<ResolvedExtensionInput<TInputs[InputName]>>> : false extends TInputs[InputName]['config']['optional'] - ? Expand<ResolvedExtensionInput<TInputs[InputName]['extensionData']>> - : Expand< - ResolvedExtensionInput<TInputs[InputName]['extensionData']> | undefined - >; + ? Expand<ResolvedExtensionInput<TInputs[InputName]>> + : Expand<ResolvedExtensionInput<TInputs[InputName]> | undefined>; }; /** diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx index cb8855d892..e4cb9e26f1 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx @@ -57,13 +57,7 @@ describe('createExtensionBlueprint', () => { name: 'my-extension', namespace: undefined, output: { - element: { - $$type: '@backstage/ExtensionDataRef', - config: {}, - id: 'core.reactElement', - optional: expect.any(Function), - toString: expect.any(Function), - }, + element: coreExtensionData.reactElement, }, factory: expect.any(Function), toString: expect.any(Function), diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts b/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts index 5627bdecc2..b7efb13e6e 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts @@ -23,7 +23,7 @@ export interface ExtensionInput< TConfig extends { singleton: boolean; optional: boolean }, > { $$type: '@backstage/ExtensionInput'; - extensionData: TExtensionData; + extensionData: Array<TExtensionData>; config: TConfig; } @@ -76,7 +76,7 @@ export function createExtensionInput< TExtensionDataMap extends AnyExtensionDataMap, TConfig extends { singleton?: boolean; optional?: boolean }, >( - extensionData: TExtensionData, + extensionData: Array<TExtensionData> | TExtensionDataMap, config?: TConfig, ): | LegacyExtensionInput< @@ -93,22 +93,24 @@ export function createExtensionInput< optional: TConfig['optional'] extends true ? true : false; } > { - if (Array.isArray(extensionData)) { - const seen = new Set(); - const duplicates = []; - for (const dataRef of extensionData) { - if (seen.has(dataRef.id)) { - duplicates.push(dataRef.id); - } else { - seen.add(dataRef.id); + if (process.env.NODE_ENV !== 'production') { + if (Array.isArray(extensionData)) { + const seen = new Set(); + const duplicates = []; + for (const dataRef of extensionData) { + if (seen.has(dataRef.id)) { + duplicates.push(dataRef.id); + } else { + seen.add(dataRef.id); + } + } + if (duplicates.length > 0) { + throw new Error( + `ExtensionInput may not have duplicate data refs: '${duplicates.join( + "', '", + )}'`, + ); } - } - if (duplicates.length > 0) { - throw new Error( - `ExtensionInput may not have duplicate data refs: '${duplicates.join( - "', '", - )}'`, - ); } } return { @@ -122,5 +124,19 @@ export function createExtensionInput< ? true : false, }, - }; + } as + | LegacyExtensionInput< + TExtensionDataMap, + { + singleton: TConfig['singleton'] extends true ? true : false; + optional: TConfig['optional'] extends true ? true : false; + } + > + | ExtensionInput< + TExtensionData, + { + singleton: TConfig['singleton'] extends true ? true : false; + optional: TConfig['optional'] extends true ? true : false; + } + >; } From 3f7029edf0f69fc9c9d1f52fa82208dcce044915 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Sat, 27 Jul 2024 17:01:52 +0200 Subject: [PATCH 458/510] frontend-app-api: add support for v2 extensions Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .../src/tree/instantiateAppNodeTree.test.ts | 1537 ++++++++++++----- .../src/tree/instantiateAppNodeTree.ts | 214 ++- 2 files changed, 1237 insertions(+), 514 deletions(-) diff --git a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts index a82c8d99ee..b4090185a3 100644 --- a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts +++ b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts @@ -17,6 +17,8 @@ import { AppNode, Extension, + ExtensionInput, + ResolvedExtensionInput, createExtension, createExtensionDataRef, createExtensionInput, @@ -38,27 +40,6 @@ const inputMirrorDataRef = createExtensionDataRef<unknown>().with({ id: 'mirror', }); -const simpleExtension = resolveExtensionDefinition( - createExtension({ - namespace: 'app', - name: 'test', - attachTo: { id: 'ignored', input: 'ignored' }, - output: { - test: testDataRef, - other: otherDataRef.optional(), - }, - configSchema: createSchemaFromZod(z => - z.object({ - output: z.string().default('test'), - other: z.number().optional(), - }), - ), - factory({ config }) { - return { test: config.output, other: config.other }; - }, - }), -); - function makeSpec<TConfig, TConfigInput>( extension: Extension<TConfig, TConfigInput>, spec?: Partial<AppNodeSpec>, @@ -100,78 +81,54 @@ function makeInstanceWithId<TConfig, TConfigInput>( } describe('instantiateAppNodeTree', () => { - it('should instantiate a single node', () => { - const tree = resolveAppTree('root-node', [ - makeSpec(simpleExtension, { id: 'root-node' }), - ]); - expect(tree.root.instance).not.toBeDefined(); - instantiateAppNodeTree(tree.root); - expect(tree.root.instance).toBeDefined(); - expect(tree.root.instance?.getData(testDataRef)).toBe('test'); - - // Multiple calls should have no effect - instantiateAppNodeTree(tree.root); - expect(tree.root.instance).toBeDefined(); - }); - - it('should not instantiate disabled nodes', () => { - const tree = resolveAppTree('root-node', [ - makeSpec(simpleExtension, { id: 'root-node', disabled: true }), - ]); - expect(tree.root.instance).not.toBeDefined(); - instantiateAppNodeTree(tree.root); - expect(tree.root.instance).not.toBeDefined(); - }); - - it('should instantiate a node with attachments', () => { - const tree = resolveAppTree('root-node', [ - makeSpec( - resolveExtensionDefinition( - createExtension({ - namespace: 'root-node', - attachTo: { id: 'ignored', input: 'ignored' }, - inputs: { - test: createExtensionInput({ test: testDataRef }), - }, - output: { - inputMirror: inputMirrorDataRef, - }, - factory({ inputs }) { - return { inputMirror: inputs }; - }, + describe('v1', () => { + const simpleExtension = resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'test', + attachTo: { id: 'ignored', input: 'ignored' }, + output: { + test: testDataRef, + other: otherDataRef.optional(), + }, + configSchema: createSchemaFromZod(z => + z.object({ + output: z.string().default('test'), + other: z.number().optional(), }), ), - ), - makeSpec(simpleExtension, { - id: 'child-node', - attachTo: { id: 'root-node', input: 'test' }, + factory({ config }) { + return { test: config.output, other: config.other }; + }, }), - ]); + ); - const childNode = tree.nodes.get('child-node'); - expect(childNode).toBeDefined(); + it('should instantiate a single node', () => { + const tree = resolveAppTree('root-node', [ + makeSpec(simpleExtension, { id: 'root-node' }), + ]); + expect(tree.root.instance).not.toBeDefined(); + instantiateAppNodeTree(tree.root); + expect(tree.root.instance).toBeDefined(); + expect(tree.root.instance?.getData(testDataRef)).toBe('test'); - expect(tree.root.instance).not.toBeDefined(); - expect(childNode?.instance).not.toBeDefined(); - instantiateAppNodeTree(tree.root); - expect(tree.root.instance).toBeDefined(); - expect(childNode?.instance).toBeDefined(); - expect(tree.root.instance?.getData(inputMirrorDataRef)).toMatchObject({ - test: [ - { node: { spec: { id: 'child-node' } }, output: { test: 'test' } }, - ], + // Multiple calls should have no effect + instantiateAppNodeTree(tree.root); + expect(tree.root.instance).toBeDefined(); }); - // Multiple calls should have no effect - instantiateAppNodeTree(tree.root); - expect(tree.root.instance).toBeDefined(); - expect(childNode?.instance).toBeDefined(); - }); + it('should not instantiate disabled nodes', () => { + const tree = resolveAppTree('root-node', [ + makeSpec(simpleExtension, { id: 'root-node', disabled: true }), + ]); + expect(tree.root.instance).not.toBeDefined(); + instantiateAppNodeTree(tree.root); + expect(tree.root.instance).not.toBeDefined(); + }); - it('should not instantiate disabled attachments', () => { - const tree = resolveAppTree('root-node', [ - { - ...makeSpec( + it('should instantiate a node with attachments', () => { + const tree = resolveAppTree('root-node', [ + makeSpec( resolveExtensionDefinition( createExtension({ namespace: 'root-node', @@ -188,437 +145,1061 @@ describe('instantiateAppNodeTree', () => { }), ), ), - }, - { - ...makeSpec(simpleExtension), - id: 'child-node', - // Using an invalid input should not be an error when disabled - attachTo: { id: 'root-node', input: 'invalid' }, - disabled: true, - }, - ]); + makeSpec(simpleExtension, { + id: 'child-node', + attachTo: { id: 'root-node', input: 'test' }, + }), + ]); - const childNode = tree.nodes.get('child-node'); - expect(childNode).toBeDefined(); + const childNode = tree.nodes.get('child-node'); + expect(childNode).toBeDefined(); - expect(tree.root.instance).not.toBeDefined(); - expect(childNode?.instance).not.toBeDefined(); - instantiateAppNodeTree(tree.root); - expect(tree.root.instance).toBeDefined(); - expect(childNode?.instance).not.toBeDefined(); - expect(tree.root.instance?.getData(inputMirrorDataRef)).toEqual({ - test: [], - }); - }); -}); + expect(tree.root.instance).not.toBeDefined(); + expect(childNode?.instance).not.toBeDefined(); + instantiateAppNodeTree(tree.root); + expect(tree.root.instance).toBeDefined(); + expect(childNode?.instance).toBeDefined(); + expect(tree.root.instance?.getData(inputMirrorDataRef)).toMatchObject({ + test: [ + { node: { spec: { id: 'child-node' } }, output: { test: 'test' } }, + ], + }); -describe('createAppNodeInstance', () => { - it('should create a simple extension instance', () => { - const attachments = new Map(); - const instance = createAppNodeInstance({ - node: makeNode(simpleExtension), - attachments, + // Multiple calls should have no effect + instantiateAppNodeTree(tree.root); + expect(tree.root.instance).toBeDefined(); + expect(childNode?.instance).toBeDefined(); }); - expect(Array.from(instance.getDataRefs())).toEqual([ - testDataRef, - otherDataRef.optional(), - ]); - expect(instance.getData(testDataRef)).toEqual('test'); - }); - - it('should create an extension with different kind of inputs', () => { - const attachments = new Map([ - [ - 'optionalSingletonPresent', - [ - makeInstanceWithId(simpleExtension, { - output: 'optionalSingletonPresent', - }), - ], - ], - [ - 'singleton', - [ - makeInstanceWithId(simpleExtension, { - output: 'singleton', - other: 2, - }), - ], - ], - [ - 'many', - [ - makeInstanceWithId(simpleExtension, { output: 'many1' }), - makeInstanceWithId(simpleExtension, { output: 'many2', other: 3 }), - ], - ], - ]); - const instance = createAppNodeInstance({ - attachments, - node: makeNode( - resolveExtensionDefinition( - createExtension({ - namespace: 'app', - name: 'test', - attachTo: { id: 'ignored', input: 'ignored' }, - inputs: { - optionalSingletonPresent: createExtensionInput( - { - test: testDataRef, - other: otherDataRef.optional(), - }, - { singleton: true, optional: true }, - ), - optionalSingletonMissing: createExtensionInput( - { - test: testDataRef, - other: otherDataRef.optional(), - }, - { singleton: true, optional: true }, - ), - singleton: createExtensionInput( - { - test: testDataRef, - other: otherDataRef.optional(), - }, - { singleton: true }, - ), - many: createExtensionInput({ - test: testDataRef, - other: otherDataRef.optional(), - }), - }, - output: { - inputMirror: inputMirrorDataRef, - }, - factory({ inputs }) { - return { inputMirror: inputs }; - }, - }), - ), - ), - }); - - expect(Array.from(instance.getDataRefs())).toEqual([inputMirrorDataRef]); - expect(instance.getData(inputMirrorDataRef)).toMatchObject({ - optionalSingletonPresent: { - node: { spec: { id: 'app/test' } }, - output: { test: 'optionalSingletonPresent' }, - }, - singleton: { - node: { spec: { id: 'app/test' } }, - output: { test: 'singleton', other: 2 }, - }, - many: [ - { node: { spec: { id: 'app/test' } }, output: { test: 'many1' } }, + it('should not instantiate disabled attachments', () => { + const tree = resolveAppTree('root-node', [ { - node: { spec: { id: 'app/test' } }, - output: { test: 'many2', other: 3 }, + ...makeSpec( + resolveExtensionDefinition( + createExtension({ + namespace: 'root-node', + attachTo: { id: 'ignored', input: 'ignored' }, + inputs: { + test: createExtensionInput({ test: testDataRef }), + }, + output: { + inputMirror: inputMirrorDataRef, + }, + factory({ inputs }) { + return { inputMirror: inputs }; + }, + }), + ), + ), }, - ], + { + ...makeSpec(simpleExtension), + id: 'child-node', + // Using an invalid input should not be an error when disabled + attachTo: { id: 'root-node', input: 'invalid' }, + disabled: true, + }, + ]); + + const childNode = tree.nodes.get('child-node'); + expect(childNode).toBeDefined(); + + expect(tree.root.instance).not.toBeDefined(); + expect(childNode?.instance).not.toBeDefined(); + instantiateAppNodeTree(tree.root); + expect(tree.root.instance).toBeDefined(); + expect(childNode?.instance).not.toBeDefined(); + expect(tree.root.instance?.getData(inputMirrorDataRef)).toEqual({ + test: [], + }); + }); + + describe('createAppNodeInstance', () => { + it('should create a simple extension instance', () => { + const attachments = new Map(); + const instance = createAppNodeInstance({ + node: makeNode(simpleExtension), + attachments, + }); + + expect(Array.from(instance.getDataRefs())).toEqual([ + testDataRef, + otherDataRef.optional(), + ]); + expect(instance.getData(testDataRef)).toEqual('test'); + }); + + it('should create an extension with different kind of inputs', () => { + const attachments = new Map([ + [ + 'optionalSingletonPresent', + [ + makeInstanceWithId(simpleExtension, { + output: 'optionalSingletonPresent', + }), + ], + ], + [ + 'singleton', + [ + makeInstanceWithId(simpleExtension, { + output: 'singleton', + other: 2, + }), + ], + ], + [ + 'many', + [ + makeInstanceWithId(simpleExtension, { output: 'many1' }), + makeInstanceWithId(simpleExtension, { + output: 'many2', + other: 3, + }), + ], + ], + ]); + const instance = createAppNodeInstance({ + attachments, + node: makeNode( + resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'test', + attachTo: { id: 'ignored', input: 'ignored' }, + inputs: { + optionalSingletonPresent: createExtensionInput( + { + test: testDataRef, + other: otherDataRef.optional(), + }, + { singleton: true, optional: true }, + ), + optionalSingletonMissing: createExtensionInput( + { + test: testDataRef, + other: otherDataRef.optional(), + }, + { singleton: true, optional: true }, + ), + singleton: createExtensionInput( + { + test: testDataRef, + other: otherDataRef.optional(), + }, + { singleton: true }, + ), + many: createExtensionInput({ + test: testDataRef, + other: otherDataRef.optional(), + }), + }, + output: { + inputMirror: inputMirrorDataRef, + }, + factory({ inputs }) { + return { inputMirror: inputs }; + }, + }), + ), + ), + }); + + expect(Array.from(instance.getDataRefs())).toEqual([ + inputMirrorDataRef, + ]); + expect(instance.getData(inputMirrorDataRef)).toMatchObject({ + optionalSingletonPresent: { + node: { spec: { id: 'app/test' } }, + output: { test: 'optionalSingletonPresent' }, + }, + singleton: { + node: { spec: { id: 'app/test' } }, + output: { test: 'singleton', other: 2 }, + }, + many: [ + { node: { spec: { id: 'app/test' } }, output: { test: 'many1' } }, + { + node: { spec: { id: 'app/test' } }, + output: { test: 'many2', other: 3 }, + }, + ], + }); + }); + + it('should refuse to create an extension with invalid config', () => { + expect(() => + createAppNodeInstance({ + node: makeNode(simpleExtension, { + config: { other: 'not-a-number' }, + }), + attachments: new Map(), + }), + ).toThrow( + "Invalid configuration for extension 'app/test'; caused by Error: Expected number, received string at 'other'", + ); + }); + + it('should forward extension factory errors', () => { + expect(() => + createAppNodeInstance({ + node: makeNode( + resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'test', + attachTo: { id: 'ignored', input: 'ignored' }, + output: {}, + factory() { + const error = new Error('NOPE'); + error.name = 'NopeError'; + throw error; + }, + }), + ), + ), + attachments: new Map(), + }), + ).toThrow( + "Failed to instantiate extension 'app/test'; caused by NopeError: NOPE", + ); + }); + + it('should refuse to create an instance with duplicate output', () => { + expect(() => + createAppNodeInstance({ + node: makeNode( + resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'test', + attachTo: { id: 'ignored', input: 'ignored' }, + output: { + test1: testDataRef, + test2: testDataRef, + }, + factory({}) { + return { test1: 'test', test2: 'test2' }; + }, + }), + ), + ), + attachments: new Map(), + }), + ).toThrow( + "Failed to instantiate extension 'app/test', duplicate extension data 'test' received via output 'test2'", + ); + }); + + it('should refuse to create an instance with disconnected output data', () => { + expect(() => + createAppNodeInstance({ + node: makeNode( + resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'test', + attachTo: { id: 'ignored', input: 'ignored' }, + output: { + test: testDataRef, + }, + factory({}) { + return { nonexistent: 'test' } as any; + }, + }), + ), + ), + attachments: new Map(), + }), + ).toThrow( + "Failed to instantiate extension 'app/test', unknown output provided via 'nonexistent'", + ); + }); + + it('should refuse to create an instance with missing required input', () => { + expect(() => + createAppNodeInstance({ + node: makeNode( + resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'test', + attachTo: { id: 'ignored', input: 'ignored' }, + inputs: { + singleton: createExtensionInput( + { + test: testDataRef, + }, + { singleton: true }, + ), + }, + output: {}, + factory: () => ({}), + }), + ), + ), + attachments: new Map(), + }), + ).toThrow( + "Failed to instantiate extension 'app/test', input 'singleton' is required but was not received", + ); + }); + + it('should warn when creating an instance with undeclared inputs', () => { + const { warn } = withLogCollector(['warn'], () => + createAppNodeInstance({ + attachments: new Map([ + [ + 'declared', + [ + makeInstanceWithId(simpleExtension, { + output: 'many1', + }), + ], + ], + [ + 'undeclared', + [ + makeInstanceWithId(simpleExtension, { + output: 'many1', + }), + ], + ], + ]), + node: makeNode( + resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'parent', + attachTo: { id: 'ignored', input: 'ignored' }, + inputs: { + declared: createExtensionInput({ + test: testDataRef, + }), + }, + output: {}, + factory: () => ({}), + }), + ), + ), + }), + ); + + expect(warn).toEqual([ + "The extension 'app/test' is attached to the input 'undeclared' of the extension 'app/parent', but it has no such input (candidates are 'declared')", + ]); + }); + + it('should refuse to create an instance with multiple undeclared inputs', () => { + const { warn } = withLogCollector(['warn'], () => + createAppNodeInstance({ + attachments: new Map([ + [ + 'undeclared1', + [makeInstanceWithId(simpleExtension, { output: 'many1' })], + ], + [ + 'undeclared2', + [ + makeInstanceWithId(simpleExtension, { output: 'many1' }), + makeInstanceWithId(simpleExtension, { output: 'many1' }), + ], + ], + ]), + node: makeNode( + resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'parent', + attachTo: { id: 'ignored', input: 'ignored' }, + output: {}, + factory: () => ({}), + }), + ), + ), + }), + ); + + expect(warn).toEqual([ + "The extension 'app/test' is attached to the input 'undeclared1' of the extension 'app/parent', but it has no inputs", + "The extensions 'app/test', 'app/test' are attached to the input 'undeclared2' of the extension 'app/parent', but it has no inputs", + ]); + }); + + it('should refuse to create an instance with multiple inputs for required singleton', () => { + expect(() => + createAppNodeInstance({ + attachments: new Map([ + [ + 'singleton', + [ + makeInstanceWithId(simpleExtension, { output: 'many1' }), + makeInstanceWithId(simpleExtension, { output: 'many2' }), + ], + ], + ]), + node: makeNode( + resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'test', + attachTo: { id: 'ignored', input: 'ignored' }, + inputs: { + singleton: createExtensionInput( + { + test: testDataRef, + }, + { singleton: true }, + ), + }, + output: {}, + factory: () => ({}), + }), + ), + ), + }), + ).toThrow( + "Failed to instantiate extension 'app/test', expected exactly one 'singleton' input but received multiple: 'app/test', 'app/test'", + ); + }); + + it('should refuse to create an instance with multiple inputs for optional singleton', () => { + expect(() => + createAppNodeInstance({ + attachments: new Map([ + [ + 'singleton', + [ + makeInstanceWithId(simpleExtension, { output: 'many1' }), + makeInstanceWithId(simpleExtension, { output: 'many2' }), + ], + ], + ]), + node: makeNode( + resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'test', + attachTo: { id: 'ignored', input: 'ignored' }, + inputs: { + singleton: createExtensionInput( + { + test: testDataRef, + }, + { singleton: true, optional: true }, + ), + }, + output: {}, + factory: () => ({}), + }), + ), + ), + }), + ).toThrow( + "Failed to instantiate extension 'app/test', expected at most one 'singleton' input but received multiple: 'app/test', 'app/test'", + ); + }); + + it('should refuse to create an instance with multiple inputs that did not provide required data', () => { + expect(() => + createAppNodeInstance({ + attachments: new Map([ + ['singleton', [makeInstanceWithId(simpleExtension, undefined)]], + ]), + node: makeNode( + resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'test', + attachTo: { id: 'ignored', input: 'ignored' }, + inputs: { + singleton: createExtensionInput( + { + other: otherDataRef, + }, + { singleton: true }, + ), + }, + output: {}, + factory: () => ({}), + }), + ), + ), + }), + ).toThrowErrorMatchingInlineSnapshot( + `"Failed to instantiate extension 'app/test', extension 'app/test' could not be attached because its output data ('test', 'other') does not match what the input 'singleton' requires ('other')"`, + ); + }); }); }); - it('should refuse to create an extension with invalid config', () => { - expect(() => - createAppNodeInstance({ - node: makeNode(simpleExtension, { config: { other: 'not-a-number' } }), - attachments: new Map(), - }), - ).toThrow( - "Invalid configuration for extension 'app/test'; caused by Error: Expected number, received string at 'other'", - ); - }); - - it('should forward extension factory errors', () => { - expect(() => - createAppNodeInstance({ - node: makeNode( - resolveExtensionDefinition( - createExtension({ - namespace: 'app', - name: 'test', - attachTo: { id: 'ignored', input: 'ignored' }, - output: {}, - factory() { - const error = new Error('NOPE'); - error.name = 'NopeError'; - throw error; - }, - }), - ), + describe('v2', () => { + const simpleExtension = resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'test', + attachTo: { id: 'ignored', input: 'ignored' }, + output: [testDataRef, otherDataRef.optional()], + configSchema: createSchemaFromZod(z => + z.object({ + output: z.string().default('test'), + other: z.number().optional(), + }), ), - attachments: new Map(), + factory({ config }) { + return [ + testDataRef(config.output), + ...(config.other ? [otherDataRef(config.other)] : []), + ]; + }, }), - ).toThrow( - "Failed to instantiate extension 'app/test'; caused by NopeError: NOPE", ); - }); - it('should refuse to create an instance with duplicate output', () => { - expect(() => - createAppNodeInstance({ - node: makeNode( - resolveExtensionDefinition( - createExtension({ - namespace: 'app', - name: 'test', - attachTo: { id: 'ignored', input: 'ignored' }, - output: { - test1: testDataRef, - test2: testDataRef, - }, - factory({}) { - return { test1: 'test', test2: 'test2' }; - }, - }), - ), - ), - attachments: new Map(), - }), - ).toThrow( - "Failed to instantiate extension 'app/test', duplicate extension data 'test' received via output 'test2'", - ); - }); - - it('should refuse to create an instance with disconnected output data', () => { - expect(() => - createAppNodeInstance({ - node: makeNode( - resolveExtensionDefinition( - createExtension({ - namespace: 'app', - name: 'test', - attachTo: { id: 'ignored', input: 'ignored' }, - output: { - test: testDataRef, - }, - factory({}) { - return { nonexistent: 'test' } as any; - }, - }), - ), - ), - attachments: new Map(), - }), - ).toThrow( - "Failed to instantiate extension 'app/test', unknown output provided via 'nonexistent'", - ); - }); - - it('should refuse to create an instance with missing required input', () => { - expect(() => - createAppNodeInstance({ - node: makeNode( - resolveExtensionDefinition( - createExtension({ - namespace: 'app', - name: 'test', - attachTo: { id: 'ignored', input: 'ignored' }, - inputs: { - singleton: createExtensionInput( - { - test: testDataRef, + function mirrorInputs(ctx: { + inputs: { + [name in string]: + | undefined + | ResolvedExtensionInput< + ExtensionInput<any, { singleton: boolean; optional: boolean }> + > + | Array< + ResolvedExtensionInput< + ExtensionInput<any, { singleton: boolean; optional: boolean }> + > + >; + }; + }) { + return [ + inputMirrorDataRef( + Object.fromEntries( + Object.entries(ctx.inputs).map(([k, v]) => [ + k, + Array.isArray(v) + ? v.map(vi => ({ + node: vi.node, + test: vi.get(testDataRef), + other: vi.get(otherDataRef), + })) + : { + node: v?.node, + test: v?.get(testDataRef), + other: v?.get(otherDataRef), }, - { singleton: true }, - ), + ]), + ), + ), + ]; + } + + it('should instantiate a single node', () => { + const tree = resolveAppTree('root-node', [ + makeSpec(simpleExtension, { id: 'root-node' }), + ]); + expect(tree.root.instance).not.toBeDefined(); + instantiateAppNodeTree(tree.root); + expect(tree.root.instance).toBeDefined(); + expect(tree.root.instance?.getData(testDataRef)).toBe('test'); + + // Multiple calls should have no effect + instantiateAppNodeTree(tree.root); + expect(tree.root.instance).toBeDefined(); + }); + + it('should not instantiate disabled nodes', () => { + const tree = resolveAppTree('root-node', [ + makeSpec(simpleExtension, { id: 'root-node', disabled: true }), + ]); + expect(tree.root.instance).not.toBeDefined(); + instantiateAppNodeTree(tree.root); + expect(tree.root.instance).not.toBeDefined(); + }); + + it('should instantiate a node with attachments', () => { + const tree = resolveAppTree('root-node', [ + makeSpec( + resolveExtensionDefinition( + createExtension({ + namespace: 'root-node', + attachTo: { id: 'ignored', input: 'ignored' }, + inputs: { + test: createExtensionInput([testDataRef]), }, - output: {}, - factory: () => ({}), + output: [inputMirrorDataRef], + factory: mirrorInputs, }), ), ), - attachments: new Map(), - }), - ).toThrow( - "Failed to instantiate extension 'app/test', input 'singleton' is required but was not received", - ); - }); + makeSpec(simpleExtension, { + id: 'child-node', + attachTo: { id: 'root-node', input: 'test' }, + }), + ]); - it('should warn when creating an instance with undeclared inputs', () => { - const { warn } = withLogCollector(['warn'], () => - createAppNodeInstance({ - attachments: new Map([ + const childNode = tree.nodes.get('child-node'); + expect(childNode).toBeDefined(); + + expect(tree.root.instance).not.toBeDefined(); + expect(childNode?.instance).not.toBeDefined(); + instantiateAppNodeTree(tree.root); + expect(tree.root.instance).toBeDefined(); + expect(childNode?.instance).toBeDefined(); + expect(tree.root.instance?.getData(inputMirrorDataRef)).toMatchObject({ + test: [{ node: { spec: { id: 'child-node' } }, test: 'test' }], + }); + + // Multiple calls should have no effect + instantiateAppNodeTree(tree.root); + expect(tree.root.instance).toBeDefined(); + expect(childNode?.instance).toBeDefined(); + }); + + it('should not instantiate disabled attachments', () => { + const tree = resolveAppTree('root-node', [ + { + ...makeSpec( + resolveExtensionDefinition( + createExtension({ + namespace: 'root-node', + attachTo: { id: 'ignored', input: 'ignored' }, + inputs: { + test: createExtensionInput([testDataRef]), + }, + output: [inputMirrorDataRef], + factory: mirrorInputs, + }), + ), + ), + }, + { + ...makeSpec(simpleExtension), + id: 'child-node', + // Using an invalid input should not be an error when disabled + attachTo: { id: 'root-node', input: 'invalid' }, + disabled: true, + }, + ]); + + const childNode = tree.nodes.get('child-node'); + expect(childNode).toBeDefined(); + + expect(tree.root.instance).not.toBeDefined(); + expect(childNode?.instance).not.toBeDefined(); + instantiateAppNodeTree(tree.root); + expect(tree.root.instance).toBeDefined(); + expect(childNode?.instance).not.toBeDefined(); + expect(tree.root.instance?.getData(inputMirrorDataRef)).toEqual({ + test: [], + }); + }); + + describe('createAppNodeInstance', () => { + it('should create a simple extension instance', () => { + const attachments = new Map(); + const instance = createAppNodeInstance({ + node: makeNode(simpleExtension), + attachments, + }); + + expect(Array.from(instance.getDataRefs())).toEqual([testDataRef]); + expect(instance.getData(testDataRef)).toEqual('test'); + }); + + it('should create an extension with different kind of inputs', () => { + const attachments = new Map([ [ - 'declared', + 'optionalSingletonPresent', [ makeInstanceWithId(simpleExtension, { - output: 'many1', + output: 'optionalSingletonPresent', }), ], ], [ - 'undeclared', + 'singleton', [ makeInstanceWithId(simpleExtension, { - output: 'many1', + output: 'singleton', + other: 2, }), ], ], - ]), - node: makeNode( - resolveExtensionDefinition( - createExtension({ - namespace: 'app', - name: 'parent', - attachTo: { id: 'ignored', input: 'ignored' }, - inputs: { - declared: createExtensionInput({ - test: testDataRef, + [ + 'many', + [ + makeInstanceWithId(simpleExtension, { output: 'many1' }), + makeInstanceWithId(simpleExtension, { + output: 'many2', + other: 3, + }), + ], + ], + ]); + + const instance = createAppNodeInstance({ + attachments, + node: makeNode( + resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'test', + attachTo: { id: 'ignored', input: 'ignored' }, + inputs: { + optionalSingletonPresent: createExtensionInput( + [testDataRef, otherDataRef.optional()], + { singleton: true, optional: true }, + ), + optionalSingletonMissing: createExtensionInput( + [testDataRef, otherDataRef.optional()], + { singleton: true, optional: true }, + ), + singleton: createExtensionInput( + [testDataRef, otherDataRef.optional()], + { singleton: true }, + ), + many: createExtensionInput([ + testDataRef, + otherDataRef.optional(), + ]), + }, + output: [inputMirrorDataRef], + factory: mirrorInputs, + }), + ), + ), + }); + + expect(Array.from(instance.getDataRefs())).toEqual([ + inputMirrorDataRef, + ]); + expect(instance.getData(inputMirrorDataRef)).toMatchObject({ + optionalSingletonPresent: { + node: { spec: { id: 'app/test' } }, + test: 'optionalSingletonPresent', + }, + singleton: { + node: { spec: { id: 'app/test' } }, + test: 'singleton', + other: 2, + }, + many: [ + { node: { spec: { id: 'app/test' } }, test: 'many1' }, + { + node: { spec: { id: 'app/test' } }, + test: 'many2', + other: 3, + }, + ], + }); + }); + + it('should refuse to create an extension with invalid config', () => { + expect(() => + createAppNodeInstance({ + node: makeNode(simpleExtension, { + config: { other: 'not-a-number' }, + }), + attachments: new Map(), + }), + ).toThrow( + "Invalid configuration for extension 'app/test'; caused by Error: Expected number, received string at 'other'", + ); + }); + + it('should forward extension factory errors', () => { + expect(() => + createAppNodeInstance({ + node: makeNode( + resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'test', + attachTo: { id: 'ignored', input: 'ignored' }, + output: [], + factory() { + const error = new Error('NOPE'); + error.name = 'NopeError'; + throw error; + }, }), - }, - output: {}, - factory: () => ({}), - }), - ), - ), - }), - ); + ), + ), + attachments: new Map(), + }), + ).toThrow( + "Failed to instantiate extension 'app/test'; caused by NopeError: NOPE", + ); + }); - expect(warn).toEqual([ - "The extension 'app/test' is attached to the input 'undeclared' of the extension 'app/parent', but it has no such input (candidates are 'declared')", - ]); - }); - - it('should refuse to create an instance with multiple undeclared inputs', () => { - const { warn } = withLogCollector(['warn'], () => - createAppNodeInstance({ - attachments: new Map([ - [ - 'undeclared1', - [makeInstanceWithId(simpleExtension, { output: 'many1' })], - ], - [ - 'undeclared2', - [ - makeInstanceWithId(simpleExtension, { output: 'many1' }), - makeInstanceWithId(simpleExtension, { output: 'many1' }), - ], - ], - ]), - node: makeNode( - resolveExtensionDefinition( - createExtension({ - namespace: 'app', - name: 'parent', - attachTo: { id: 'ignored', input: 'ignored' }, - output: {}, - factory: () => ({}), - }), - ), - ), - }), - ); - - expect(warn).toEqual([ - "The extension 'app/test' is attached to the input 'undeclared1' of the extension 'app/parent', but it has no inputs", - "The extensions 'app/test', 'app/test' are attached to the input 'undeclared2' of the extension 'app/parent', but it has no inputs", - ]); - }); - - it('should refuse to create an instance with multiple inputs for required singleton', () => { - expect(() => - createAppNodeInstance({ - attachments: new Map([ - [ - 'singleton', - [ - makeInstanceWithId(simpleExtension, { output: 'many1' }), - makeInstanceWithId(simpleExtension, { output: 'many2' }), - ], - ], - ]), - node: makeNode( - resolveExtensionDefinition( - createExtension({ - namespace: 'app', - name: 'test', - attachTo: { id: 'ignored', input: 'ignored' }, - inputs: { - singleton: createExtensionInput( - { - test: testDataRef, + it('should refuse to create an instance with duplicate output', () => { + expect(() => + createAppNodeInstance({ + node: makeNode( + resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'test', + attachTo: { id: 'ignored', input: 'ignored' }, + output: [testDataRef, testDataRef], + factory({}) { + return [testDataRef('test'), testDataRef('test2')]; }, - { singleton: true }, - ), - }, - output: {}, - factory: () => ({}), - }), - ), - ), - }), - ).toThrow( - "Failed to instantiate extension 'app/test', expected exactly one 'singleton' input but received multiple: 'app/test', 'app/test'", - ); - }); + }), + ), + ), + attachments: new Map(), + }), + ).toThrow( + "Failed to instantiate extension 'app/test', duplicate extension data output 'test'", + ); + }); - it('should refuse to create an instance with multiple inputs for optional singleton', () => { - expect(() => - createAppNodeInstance({ - attachments: new Map([ - [ - 'singleton', - [ - makeInstanceWithId(simpleExtension, { output: 'many1' }), - makeInstanceWithId(simpleExtension, { output: 'many2' }), - ], - ], - ]), - node: makeNode( - resolveExtensionDefinition( - createExtension({ - namespace: 'app', - name: 'test', - attachTo: { id: 'ignored', input: 'ignored' }, - inputs: { - singleton: createExtensionInput( - { - test: testDataRef, + it('should refuse to create an instance without required', () => { + expect(() => + createAppNodeInstance({ + node: makeNode( + resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'test', + attachTo: { id: 'ignored', input: 'ignored' }, + output: [testDataRef], + factory({}) { + return [] as any; }, - { singleton: true, optional: true }, - ), - }, - output: {}, - factory: () => ({}), - }), - ), - ), - }), - ).toThrow( - "Failed to instantiate extension 'app/test', expected at most one 'singleton' input but received multiple: 'app/test', 'app/test'", - ); - }); + }), + ), + ), + attachments: new Map(), + }), + ).toThrow( + "Failed to instantiate extension 'app/test', missing required extension data output 'test'", + ); + }); - it('should refuse to create an instance with multiple inputs that did not provide required data', () => { - expect(() => - createAppNodeInstance({ - attachments: new Map([ - ['singleton', [makeInstanceWithId(simpleExtension, undefined)]], - ]), - node: makeNode( - resolveExtensionDefinition( - createExtension({ - namespace: 'app', - name: 'test', - attachTo: { id: 'ignored', input: 'ignored' }, - inputs: { - singleton: createExtensionInput( - { - other: otherDataRef, + it('should refuse to create an instance with unknown output data', () => { + expect(() => + createAppNodeInstance({ + node: makeNode( + resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'test', + attachTo: { id: 'ignored', input: 'ignored' }, + output: [], + factory({}) { + return [testDataRef('test')] as any; }, - { singleton: true }, - ), - }, - output: {}, - factory: () => ({}), - }), - ), - ), - }), - ).toThrowErrorMatchingInlineSnapshot( - `"Failed to instantiate extension 'app/test', extension 'app/test' could not be attached because its output data ('test', 'other') does not match what the input 'singleton' requires ('other')"`, - ); + }), + ), + ), + attachments: new Map(), + }), + ).toThrow( + "Failed to instantiate extension 'app/test', unexpected output 'test'", + ); + }); + + it('should refuse to create an instance with missing required input', () => { + expect(() => + createAppNodeInstance({ + node: makeNode( + resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'test', + attachTo: { id: 'ignored', input: 'ignored' }, + inputs: { + singleton: createExtensionInput([testDataRef], { + singleton: true, + }), + }, + output: [], + factory: () => [], + }), + ), + ), + attachments: new Map(), + }), + ).toThrow( + "Failed to instantiate extension 'app/test', input 'singleton' is required but was not received", + ); + }); + + it('should warn when creating an instance with undeclared inputs', () => { + const { warn } = withLogCollector(['warn'], () => + createAppNodeInstance({ + attachments: new Map([ + [ + 'declared', + [ + makeInstanceWithId(simpleExtension, { + output: 'many1', + }), + ], + ], + [ + 'undeclared', + [ + makeInstanceWithId(simpleExtension, { + output: 'many1', + }), + ], + ], + ]), + node: makeNode( + resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'parent', + attachTo: { id: 'ignored', input: 'ignored' }, + inputs: { + declared: createExtensionInput([testDataRef]), + }, + output: [], + factory: () => [], + }), + ), + ), + }), + ); + + expect(warn).toEqual([ + "The extension 'app/test' is attached to the input 'undeclared' of the extension 'app/parent', but it has no such input (candidates are 'declared')", + ]); + }); + + it('should refuse to create an instance with multiple undeclared inputs', () => { + const { warn } = withLogCollector(['warn'], () => + createAppNodeInstance({ + attachments: new Map([ + [ + 'undeclared1', + [makeInstanceWithId(simpleExtension, { output: 'many1' })], + ], + [ + 'undeclared2', + [ + makeInstanceWithId(simpleExtension, { output: 'many1' }), + makeInstanceWithId(simpleExtension, { output: 'many1' }), + ], + ], + ]), + node: makeNode( + resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'parent', + attachTo: { id: 'ignored', input: 'ignored' }, + output: [], + factory: () => [], + }), + ), + ), + }), + ); + + expect(warn).toEqual([ + "The extension 'app/test' is attached to the input 'undeclared1' of the extension 'app/parent', but it has no inputs", + "The extensions 'app/test', 'app/test' are attached to the input 'undeclared2' of the extension 'app/parent', but it has no inputs", + ]); + }); + + it('should refuse to create an instance with multiple inputs for required singleton', () => { + expect(() => + createAppNodeInstance({ + attachments: new Map([ + [ + 'singleton', + [ + makeInstanceWithId(simpleExtension, { output: 'many1' }), + makeInstanceWithId(simpleExtension, { output: 'many2' }), + ], + ], + ]), + node: makeNode( + resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'test', + attachTo: { id: 'ignored', input: 'ignored' }, + inputs: { + singleton: createExtensionInput([testDataRef], { + singleton: true, + }), + }, + output: [], + factory: () => [], + }), + ), + ), + }), + ).toThrow( + "Failed to instantiate extension 'app/test', expected exactly one 'singleton' input but received multiple: 'app/test', 'app/test'", + ); + }); + + it('should refuse to create an instance with multiple inputs for optional singleton', () => { + expect(() => + createAppNodeInstance({ + attachments: new Map([ + [ + 'singleton', + [ + makeInstanceWithId(simpleExtension, { output: 'many1' }), + makeInstanceWithId(simpleExtension, { output: 'many2' }), + ], + ], + ]), + node: makeNode( + resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'test', + attachTo: { id: 'ignored', input: 'ignored' }, + inputs: { + singleton: createExtensionInput([testDataRef], { + singleton: true, + optional: true, + }), + }, + output: [], + factory: () => [], + }), + ), + ), + }), + ).toThrow( + "Failed to instantiate extension 'app/test', expected at most one 'singleton' input but received multiple: 'app/test', 'app/test'", + ); + }); + + it('should refuse to create an instance with multiple inputs that did not provide required data', () => { + expect(() => + createAppNodeInstance({ + attachments: new Map([ + ['singleton', [makeInstanceWithId(simpleExtension, undefined)]], + ]), + node: makeNode( + resolveExtensionDefinition( + createExtension({ + namespace: 'app', + name: 'test', + attachTo: { id: 'ignored', input: 'ignored' }, + inputs: { + singleton: createExtensionInput([otherDataRef], { + singleton: true, + }), + }, + output: [], + factory: () => [], + }), + ), + ), + }), + ).toThrowErrorMatchingInlineSnapshot( + `"Failed to instantiate extension 'app/test', extension 'app/test' could not be attached because its output data ('test') does not match what the input 'singleton' requires ('other')"`, + ); + }); + }); }); }); diff --git a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.ts b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.ts index 63eca749b7..65626e0be1 100644 --- a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.ts +++ b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.ts @@ -16,8 +16,11 @@ import { AnyExtensionDataMap, + AnyExtensionDataRef, AnyExtensionInputMap, + ExtensionDataContainer, ExtensionDataRef, + ExtensionInput, ResolvedExtensionInputs, } from '@backstage/frontend-plugin-api'; import mapValues from 'lodash/mapValues'; @@ -29,7 +32,7 @@ type Mutable<T> = { -readonly [P in keyof T]: T[P]; }; -function resolveInputData( +function resolveInputDataMap( dataMap: AnyExtensionDataMap, attachment: AppNode, inputName: string, @@ -54,35 +57,76 @@ function resolveInputData( }); } -function resolveInputs( +function resolveInputDataContainer( + extensionData: Array<AnyExtensionDataRef>, + attachment: AppNode, + inputName: string, +): { node: AppNode } & ExtensionDataContainer<AnyExtensionDataRef> { + const dataMap = new Map<string, unknown>(); + + for (const ref of extensionData) { + if (dataMap.has(ref.id)) { + throw new Error(`Unexpected duplicate input data '${ref.id}'`); + } + const value = attachment.instance?.getData(ref); + if (value === undefined && !ref.config.optional) { + const expected = extensionData + .filter(r => !r.config.optional) + .map(r => `'${r.id}'`) + .join(', '); + + const provided = [...(attachment.instance?.getDataRefs() ?? [])] + .map(r => `'${r.id}'`) + .join(', '); + + throw new Error( + `extension '${attachment.spec.id}' could not be attached because its output data (${provided}) does not match what the input '${inputName}' requires (${expected})`, + ); + } + + dataMap.set(ref.id, value); + } + + return { + node: attachment, + get(ref) { + return dataMap.get(ref.id); + }, + } as { node: AppNode } & ExtensionDataContainer<AnyExtensionDataRef>; +} + +function reportUndeclaredAttachments( id: string, - inputMap: AnyExtensionInputMap, + inputMap: { [name in string]: unknown }, attachments: ReadonlyMap<string, AppNode[]>, -): ResolvedExtensionInputs<AnyExtensionInputMap> { +) { const undeclaredAttachments = Array.from(attachments.entries()).filter( ([inputName]) => inputMap[inputName] === undefined, ); - if (process.env.NODE_ENV !== 'production') { - const inputNames = Object.keys(inputMap); + const inputNames = Object.keys(inputMap); - for (const [name, nodes] of undeclaredAttachments) { - const pl = nodes.length > 1; - // eslint-disable-next-line no-console - console.warn( - [ - `The extension${pl ? 's' : ''} '${nodes - .map(n => n.spec.id) - .join("', '")}' ${pl ? 'are' : 'is'}`, - `attached to the input '${name}' of the extension '${id}', but it`, - inputNames.length === 0 - ? 'has no inputs' - : `has no such input (candidates are '${inputNames.join("', '")}')`, - ].join(' '), - ); - } + for (const [name, nodes] of undeclaredAttachments) { + const pl = nodes.length > 1; + // eslint-disable-next-line no-console + console.warn( + [ + `The extension${pl ? 's' : ''} '${nodes + .map(n => n.spec.id) + .join("', '")}' ${pl ? 'are' : 'is'}`, + `attached to the input '${name}' of the extension '${id}', but it`, + inputNames.length === 0 + ? 'has no inputs' + : `has no such input (candidates are '${inputNames.join("', '")}')`, + ].join(' '), + ); } +} +function resolveV1Inputs( + inputMap: AnyExtensionInputMap, + attachments: ReadonlyMap<string, AppNode[]>, +): ResolvedExtensionInputs<AnyExtensionInputMap> { return mapValues(inputMap, (input, inputName) => { const attachedNodes = attachments.get(inputName) ?? []; @@ -104,7 +148,7 @@ function resolveInputs( } return { node: attachedNodes[0], - output: resolveInputData( + output: resolveInputDataMap( input.extensionData, attachedNodes[0], inputName, @@ -114,11 +158,62 @@ function resolveInputs( return attachedNodes.map(attachment => ({ node: attachment, - output: resolveInputData(input.extensionData, attachment, inputName), + output: resolveInputDataMap(input.extensionData, attachment, inputName), })); }) as ResolvedExtensionInputs<AnyExtensionInputMap>; } +function resolveV2Inputs( + inputMap: { + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { optional: boolean; singleton: boolean } + >; + }, + attachments: ReadonlyMap<string, AppNode[]>, +): ResolvedExtensionInputs<{ + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { optional: boolean; singleton: boolean } + >; +}> { + return mapValues(inputMap, (input, inputName) => { + const attachedNodes = attachments.get(inputName) ?? []; + + if (input.config.singleton) { + if (attachedNodes.length > 1) { + const attachedNodeIds = attachedNodes.map(e => e.spec.id); + throw Error( + `expected ${ + input.config.optional ? 'at most' : 'exactly' + } one '${inputName}' input but received multiple: '${attachedNodeIds.join( + "', '", + )}'`, + ); + } else if (attachedNodes.length === 0) { + if (input.config.optional) { + return undefined; + } + throw Error(`input '${inputName}' is required but was not received`); + } + return resolveInputDataContainer( + input.extensionData, + attachedNodes[0], + inputName, + ); + } + + return attachedNodes.map(attachment => + resolveInputDataContainer(input.extensionData, attachment, inputName), + ); + }) as ResolvedExtensionInputs<{ + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { optional: boolean; singleton: boolean } + >; + }>; +} + /** @internal */ export function createAppNodeInstance(options: { node: AppNode; @@ -141,24 +236,71 @@ export function createAppNodeInstance(options: { try { const internalExtension = toInternalExtension(extension); - const namedOutputs = internalExtension.factory({ - node, - config: parsedConfig, - inputs: resolveInputs(id, internalExtension.inputs, attachments), - }); + if (process.env.NODE_ENV !== 'production') { + reportUndeclaredAttachments(id, internalExtension.inputs, attachments); + } - for (const [name, output] of Object.entries(namedOutputs)) { - const ref = internalExtension.output[name]; - if (!ref) { - throw new Error(`unknown output provided via '${name}'`); + if (internalExtension.version === 'v1') { + const namedOutputs = internalExtension.factory({ + node, + config: parsedConfig, + inputs: resolveV1Inputs(internalExtension.inputs, attachments), + }); + + for (const [name, output] of Object.entries(namedOutputs)) { + const ref = internalExtension.output[name]; + if (!ref) { + throw new Error(`unknown output provided via '${name}'`); + } + if (extensionData.has(ref.id)) { + throw new Error( + `duplicate extension data '${ref.id}' received via output '${name}'`, + ); + } + extensionData.set(ref.id, output); + extensionDataRefs.add(ref); } - if (extensionData.has(ref.id)) { + } else if (internalExtension.version === 'v2') { + const outputDataValues = internalExtension.factory({ + node, + config: parsedConfig, + inputs: resolveV2Inputs(internalExtension.inputs, attachments), + }); + + const outputDataMap = new Map<string, unknown>(); + for (const value of outputDataValues) { + if (outputDataMap.has(value.id)) { + throw new Error(`duplicate extension data output '${value.id}'`); + } + outputDataMap.set(value.id, value.value); + } + + for (const ref of internalExtension.output) { + const value = outputDataMap.get(ref.id); + outputDataMap.delete(ref.id); + if (value === undefined) { + if (!ref.config.optional) { + throw new Error( + `missing required extension data output '${ref.id}'`, + ); + } + } else { + extensionData.set(ref.id, value); + extensionDataRefs.add(ref); + } + } + + if (outputDataMap.size > 0) { throw new Error( - `duplicate extension data '${ref.id}' received via output '${name}'`, + `unexpected output '${Array.from(outputDataMap.keys()).join( + "', '", + )}'`, ); } - extensionData.set(ref.id, output); - extensionDataRefs.add(ref); + } else { + throw new Error( + `unexpected extension version '${(internalExtension as any).version}'`, + ); } } catch (e) { throw new Error( From a93fa18a1e1751fc3f0a7dc875930649ae7e3c11 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Sat, 27 Jul 2024 17:02:32 +0200 Subject: [PATCH 459/510] frontend-test-utils: update to support v2 extensions Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .../src/app/createExtensionTester.tsx | 56 ++++++++++++++----- 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/packages/frontend-test-utils/src/app/createExtensionTester.tsx b/packages/frontend-test-utils/src/app/createExtensionTester.tsx index 69c4b09d06..81b74c9fce 100644 --- a/packages/frontend-test-utils/src/app/createExtensionTester.tsx +++ b/packages/frontend-test-utils/src/app/createExtensionTester.tsx @@ -19,6 +19,7 @@ import { MemoryRouter, Link } from 'react-router-dom'; import { RenderResult, render } from '@testing-library/react'; import { createSpecializedApp } from '@backstage/frontend-app-api'; import { + ExtensionDataValue, ExtensionDefinition, IconComponent, RouteRef, @@ -93,21 +94,48 @@ export class ExtensionTester { options?: { config?: TConfigInput }, ): ExtensionTester { const tester = new ExtensionTester(); - const { output, factory, ...rest } = toInternalExtensionDefinition(subject); + const internal = toInternalExtensionDefinition(subject); + // attaching to app/routes to render as index route - const extension = createExtension({ - ...rest, - attachTo: { id: 'app/routes', input: 'routes' }, - output: { - ...output, - path: coreExtensionData.routePath, - }, - factory: params => ({ - ...factory(params), - path: '/', - }), - }); - tester.add(extension, options as TConfigInput & {}); + if (internal.version === 'v1') { + tester.add( + createExtension({ + ...internal, + attachTo: { id: 'app/routes', input: 'routes' }, + output: { + ...internal.output, + path: coreExtensionData.routePath, + }, + factory: params => ({ + ...internal.factory(params as any), + path: '/', + }), + }), + options as TConfigInput & {}, + ); + } else if (internal.version === 'v2') { + tester.add( + createExtension({ + ...internal, + attachTo: { id: 'app/routes', input: 'routes' }, + output: internal.output.find( + ref => ref.id === coreExtensionData.routePath.id, + ) + ? internal.output + : [...internal.output, coreExtensionData.routePath], + factory: params => { + const parentOutput = Array.from( + internal.factory(params) as Iterable< + ExtensionDataValue<any, any> + >, + ).filter(val => val.id !== coreExtensionData.routePath.id); + + return [...parentOutput, coreExtensionData.routePath('/')]; + }, + }), + options as TConfigInput & {}, + ); + } return tester; } From 2ba97666dd41c065d20cfb0ee2ba9e1fc77d48eb Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Sat, 27 Jul 2024 17:09:44 +0200 Subject: [PATCH 460/510] update API reports for extension v2 Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- packages/frontend-plugin-api/api-report.md | 329 ++++++++++++++---- .../frontend-plugin-api/src/wiring/index.ts | 1 + plugins/catalog-react/api-report-alpha.md | 6 +- plugins/home/api-report-alpha.md | 2 +- plugins/search-react/api-report-alpha.md | 2 +- 5 files changed, 261 insertions(+), 79 deletions(-) diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index 2c92f863e8..96c7675c0d 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -147,20 +147,23 @@ export { AnyApiFactory }; export { AnyApiRef }; -// @public (undocumented) +// @public @deprecated (undocumented) export type AnyExtensionDataMap = { - [name in string]: ExtensionDataRef< - unknown, - string, - { - optional?: true; - } - >; + [name in string]: AnyExtensionDataRef; }; // @public (undocumented) +export type AnyExtensionDataRef = ExtensionDataRef< + unknown, + string, + { + optional?: true; + } +>; + +// @public @deprecated (undocumented) export type AnyExtensionInputMap = { - [inputName in string]: ExtensionInput< + [inputName in string]: LegacyExtensionInput< AnyExtensionDataMap, { optional: boolean; @@ -318,16 +321,18 @@ export { configApiRef }; // @public (undocumented) export interface ConfigurableExtensionDataRef< - TId extends string, TData, + TId extends string, TConfig extends { optional?: true; } = {}, > extends ExtensionDataRef<TData, TId, TConfig> { + // (undocumented) + (t: TData): ExtensionDataValue<TData, TId>; // (undocumented) optional(): ConfigurableExtensionDataRef< - TId, TData, + TId, TData & { optional: true; } @@ -351,14 +356,14 @@ export type CoreErrorBoundaryFallbackProps = { // @public (undocumented) export const coreExtensionData: { reactElement: ConfigurableExtensionDataRef< - 'core.reactElement', JSX_2.Element, + 'core.reactElement', {} >; - routePath: ConfigurableExtensionDataRef<'core.routing.path', string, {}>; + routePath: ConfigurableExtensionDataRef<string, 'core.routing.path', {}>; routeRef: ConfigurableExtensionDataRef< - 'core.routing.ref', RouteRef<AnyRouteRefParams>, + 'core.routing.ref', {} >; }; @@ -397,8 +402,8 @@ export function createApiExtension< export namespace createApiExtension { const // (undocumented) factoryDataRef: ConfigurableExtensionDataRef< - 'core.api.factory', AnyApiFactory, + 'core.api.factory', {} >; } @@ -455,10 +460,10 @@ export function createAppRootWrapperExtension< export namespace createAppRootWrapperExtension { const // (undocumented) componentDataRef: ConfigurableExtensionDataRef< - 'app.root.wrapper', React_2.ComponentType<{ children?: React_2.ReactNode; }>, + 'app.root.wrapper', {} >; } @@ -493,11 +498,11 @@ export function createComponentExtension< export namespace createComponentExtension { const // (undocumented) componentDataRef: ConfigurableExtensionDataRef< - 'core.component.component', { ref: ComponentRef; impl: ComponentType; }, + 'core.component.component', {} >; } @@ -508,6 +513,50 @@ export function createComponentRef<T extends {} = {}>(options: { }): ComponentRef<T>; // @public (undocumented) +export function createExtension< + UOutput extends AnyExtensionDataRef, + TInputs extends { + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { + optional: boolean; + singleton: boolean; + } + >; + }, + TConfig, + TConfigInput, + TConfigSchema extends { + [key: string]: (zImpl: typeof z) => z.ZodType; + }, + UFactoryOutput extends ExtensionDataValue<any, any>, +>( + options: CreateExtensionOptions< + UOutput, + TInputs, + TConfig, + TConfigInput, + TConfigSchema, + UFactoryOutput + >, +): ExtensionDefinition< + TConfig & + (string extends keyof TConfigSchema + ? {} + : { + [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; + }), + TConfigInput & + (string extends keyof TConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>; + }> + >) +>; + +// @public @deprecated (undocumented) export function createExtension< TOutput extends AnyExtensionDataMap, TInputs extends AnyExtensionInputMap, @@ -517,7 +566,7 @@ export function createExtension< [key: string]: (zImpl: typeof z) => z.ZodType; }, >( - options: CreateExtensionOptions< + options: LegacyCreateExtensionOptions< TOutput, TInputs, TConfig, @@ -624,27 +673,27 @@ export interface CreateExtensionBlueprintOptions< // @public @deprecated (undocumented) export function createExtensionDataRef<TData>( id: string, -): ConfigurableExtensionDataRef<string, TData>; +): ConfigurableExtensionDataRef<TData, string>; // @public (undocumented) export function createExtensionDataRef<TData>(): { with<TId extends string>(options: { id: TId; - }): ConfigurableExtensionDataRef<TId, TData>; + }): ConfigurableExtensionDataRef<TData, TId>; }; -// @public (undocumented) +// @public @deprecated (undocumented) export function createExtensionInput< - TExtensionData extends AnyExtensionDataMap, + TExtensionDataMap extends AnyExtensionDataMap, TConfig extends { singleton?: boolean; optional?: boolean; }, >( - extensionData: TExtensionData, + extensionData: TExtensionDataMap, config?: TConfig, -): ExtensionInput< - TExtensionData, +): LegacyExtensionInput< + TExtensionDataMap, { singleton: TConfig['singleton'] extends true ? true : false; optional: TConfig['optional'] extends true ? true : false; @@ -652,29 +701,62 @@ export function createExtensionInput< >; // @public (undocumented) -export interface CreateExtensionOptions< - TOutput extends AnyExtensionDataMap, - TInputs extends AnyExtensionInputMap, +export function createExtensionInput< + UExtensionData extends ExtensionDataRef< + unknown, + string, + { + optional?: true; + } + >, + TConfig extends { + singleton?: boolean; + optional?: boolean; + }, +>( + extensionData: Array<UExtensionData>, + config?: TConfig, +): ExtensionInput< + UExtensionData, + { + singleton: TConfig['singleton'] extends true ? true : false; + optional: TConfig['optional'] extends true ? true : false; + } +>; + +// @public (undocumented) +export type CreateExtensionOptions< + UOutput extends AnyExtensionDataRef, + TInputs extends { + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { + optional: boolean; + singleton: boolean; + } + >; + }, TConfig, TConfigInput, TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType; }, -> { - // (undocumented) + UFactoryOutput extends ExtensionDataValue<any, any>, +> = { + kind?: string; + namespace?: string; + name?: string; attachTo: { id: string; input: string; }; - // (undocumented) + disabled?: boolean; + inputs?: TInputs; + output: Array<UOutput>; + configSchema?: PortableSchema<TConfig, TConfigInput>; config?: { schema: TConfigSchema; }; - // @deprecated (undocumented) - configSchema?: PortableSchema<TConfig, TConfigInput>; - // (undocumented) - disabled?: boolean; - // (undocumented) factory(context: { node: AppNode; config: TConfig & @@ -686,18 +768,23 @@ export interface CreateExtensionOptions< >; }); inputs: Expand<ResolvedExtensionInputs<TInputs>>; - }): Expand<ExtensionDataValues<TOutput>>; - // (undocumented) - inputs?: TInputs; - // (undocumented) - kind?: string; - // (undocumented) - name?: string; - // (undocumented) - namespace?: string; - // (undocumented) - output: TOutput; -} + }): Iterable<UFactoryOutput>; +} & (( + UOutput extends any + ? UOutput['config']['optional'] extends true + ? never + : UOutput['id'] + : never +) extends infer IRequiredOutputIds + ? [IRequiredOutputIds] extends [UFactoryOutput['id']] + ? {} + : { + 'Error: The extension factory is missing the following outputs': Exclude< + IRequiredOutputIds, + UFactoryOutput['id'] + >; + } + : never); // @public (undocumented) export function createExtensionOverrides( @@ -750,12 +837,12 @@ export function createNavItemExtension(options: { export namespace createNavItemExtension { const // (undocumented) targetDataRef: ConfigurableExtensionDataRef< - 'core.nav-item.target', { title: string; icon: IconComponent_2; routeRef: RouteRef<undefined>; }, + 'core.nav-item.target', {} >; } @@ -772,11 +859,11 @@ export function createNavLogoExtension(options: { export namespace createNavLogoExtension { const // (undocumented) logoElementsDataRef: ConfigurableExtensionDataRef< - 'core.nav-logo.logo-elements', { logoIcon?: JSX.Element | undefined; logoFull?: JSX.Element | undefined; }, + 'core.nav-logo.logo-elements', {} >; } @@ -866,10 +953,10 @@ export function createRouterExtension< export namespace createRouterExtension { const // (undocumented) componentDataRef: ConfigurableExtensionDataRef< - 'app.router.wrapper', React_2.ComponentType<{ children?: React_2.ReactNode; }>, + 'app.router.wrapper', {} >; } @@ -903,8 +990,8 @@ export function createSignInPageExtension< export namespace createSignInPageExtension { const // (undocumented) componentDataRef: ConfigurableExtensionDataRef< - 'core.sign-in-page.component', React_2.ComponentType<SignInPageProps>, + 'core.sign-in-page.component', {} >; } @@ -927,8 +1014,8 @@ export function createThemeExtension( export namespace createThemeExtension { const // (undocumented) themeDataRef: ConfigurableExtensionDataRef< - 'core.theme.theme', AppTheme, + 'core.theme.theme', {} >; } @@ -943,7 +1030,6 @@ export function createTranslationExtension(options: { export namespace createTranslationExtension { const // (undocumented) translationDataRef: ConfigurableExtensionDataRef< - 'core.translation.translation', | TranslationResource<string> | TranslationMessages< string, @@ -952,6 +1038,7 @@ export namespace createTranslationExtension { }, boolean >, + 'core.translation.translation', {} >; } @@ -1083,6 +1170,18 @@ export interface ExtensionBoundaryProps { routable?: boolean; } +// @public (undocumented) +export type ExtensionDataContainer<UExtensionData extends AnyExtensionDataRef> = + { + get<TId extends UExtensionData['id']>( + ref: ExtensionDataRef<any, TId, any>, + ): UExtensionData extends ExtensionDataRef<infer IData, TId, infer IConfig> + ? IConfig['optional'] extends true + ? IData | undefined + : IData + : never; + }; + // @public (undocumented) export type ExtensionDataRef< TData, @@ -1091,13 +1190,20 @@ export type ExtensionDataRef< optional?: true; } = {}, > = { - id: TId; - T: TData; - config: TConfig; - $$type: '@backstage/ExtensionDataRef'; + readonly $$type: '@backstage/ExtensionDataRef'; + readonly id: TId; + readonly T: TData; + readonly config: TConfig; }; -// @public +// @public (undocumented) +export type ExtensionDataValue<TData, TId extends string> = { + readonly $$type: '@backstage/ExtensionDataValue'; + readonly id: TId; + readonly value: TData; +}; + +// @public @deprecated export type ExtensionDataValues<TExtensionData extends AnyExtensionDataMap> = { [DataName in keyof TExtensionData as TExtensionData[DataName]['config'] extends { optional: true; @@ -1135,7 +1241,13 @@ export interface ExtensionDefinition<TConfig, TConfigInput = TConfig> { // @public (undocumented) export interface ExtensionInput< - TExtensionData extends AnyExtensionDataMap, + TExtensionData extends ExtensionDataRef< + unknown, + string, + { + optional?: true; + } + >, TConfig extends { singleton: boolean; optional: boolean; @@ -1146,7 +1258,7 @@ export interface ExtensionInput< // (undocumented) config: TConfig; // (undocumented) - extensionData: TExtensionData; + extensionData: Array<TExtensionData>; } // @public (undocumented) @@ -1214,10 +1326,10 @@ export const IconBundleBlueprint: ExtensionBlueprint< AnyExtensionInputMap, { icons: ConfigurableExtensionDataRef< - 'core.icons', { [x: string]: IconComponent; }, + 'core.icons', {} >; }, @@ -1231,10 +1343,10 @@ export const IconBundleBlueprint: ExtensionBlueprint< }, { icons: ConfigurableExtensionDataRef< - 'core.icons', { [x: string]: IconComponent; }, + 'core.icons', {} >; } @@ -1265,6 +1377,70 @@ export { IdentityApi }; export { identityApiRef }; +// @public @deprecated (undocumented) +export interface LegacyCreateExtensionOptions< + TOutput extends AnyExtensionDataMap, + TInputs extends AnyExtensionInputMap, + TConfig, + TConfigInput, + TConfigSchema extends { + [key: string]: (zImpl: typeof z) => z.ZodType; + }, +> { + // (undocumented) + attachTo: { + id: string; + input: string; + }; + // (undocumented) + config?: { + schema: TConfigSchema; + }; + // @deprecated (undocumented) + configSchema?: PortableSchema<TConfig, TConfigInput>; + // (undocumented) + disabled?: boolean; + // (undocumented) + factory(context: { + node: AppNode; + config: TConfig & + (string extends keyof TConfigSchema + ? {} + : { + [key in keyof TConfigSchema]: z.infer< + ReturnType<TConfigSchema[key]> + >; + }); + inputs: Expand<ResolvedExtensionInputs<TInputs>>; + }): Expand<ExtensionDataValues<TOutput>>; + // (undocumented) + inputs?: TInputs; + // (undocumented) + kind?: string; + // (undocumented) + name?: string; + // (undocumented) + namespace?: string; + // (undocumented) + output: TOutput; +} + +// @public @deprecated (undocumented) +export interface LegacyExtensionInput< + TExtensionDataMap extends AnyExtensionDataMap, + TConfig extends { + singleton: boolean; + optional: boolean; + }, +> { + // (undocumented) + $$type: '@backstage/ExtensionInput'; + // (undocumented) + config: TConfig; + // (undocumented) + extensionData: TExtensionDataMap; +} + export { microsoftAuthApiRef }; export { OAuthApi }; @@ -1315,25 +1491,30 @@ export { ProfileInfo }; export { ProfileInfoApi }; // @public -export type ResolvedExtensionInput<TExtensionData extends AnyExtensionDataMap> = - { - node: AppNode; - output: ExtensionDataValues<TExtensionData>; - }; +export type ResolvedExtensionInput< + TExtensionInput extends ExtensionInput<any, any>, +> = TExtensionInput['extensionData'] extends Array<AnyExtensionDataRef> + ? { + node: AppNode; + } & ExtensionDataContainer<TExtensionInput['extensionData'][number]> + : TExtensionInput['extensionData'] extends AnyExtensionDataMap + ? { + node: AppNode; + output: ExtensionDataValues<TExtensionInput['extensionData']>; + } + : never; // @public export type ResolvedExtensionInputs< TInputs extends { - [name in string]: ExtensionInput<any, any>; + [name in string]: ExtensionInput<any, any> | LegacyExtensionInput<any, any>; }, > = { [InputName in keyof TInputs]: false extends TInputs[InputName]['config']['singleton'] - ? Array<Expand<ResolvedExtensionInput<TInputs[InputName]['extensionData']>>> + ? Array<Expand<ResolvedExtensionInput<TInputs[InputName]>>> : false extends TInputs[InputName]['config']['optional'] - ? Expand<ResolvedExtensionInput<TInputs[InputName]['extensionData']>> - : Expand< - ResolvedExtensionInput<TInputs[InputName]['extensionData']> | undefined - >; + ? Expand<ResolvedExtensionInput<TInputs[InputName]>> + : Expand<ResolvedExtensionInput<TInputs[InputName]> | undefined>; }; // @public diff --git a/packages/frontend-plugin-api/src/wiring/index.ts b/packages/frontend-plugin-api/src/wiring/index.ts index baada41ae8..4b99ba8ebc 100644 --- a/packages/frontend-plugin-api/src/wiring/index.ts +++ b/packages/frontend-plugin-api/src/wiring/index.ts @@ -23,6 +23,7 @@ export { type ExtensionDataValues, type ResolvedExtensionInput, type ResolvedExtensionInputs, + type LegacyCreateExtensionOptions, type AnyExtensionInputMap, type AnyExtensionDataMap, } from './createExtension'; diff --git a/plugins/catalog-react/api-report-alpha.md b/plugins/catalog-react/api-report-alpha.md index 1ffa67068f..206c0160e2 100644 --- a/plugins/catalog-react/api-report-alpha.md +++ b/plugins/catalog-react/api-report-alpha.md @@ -18,18 +18,18 @@ import { TranslationRef } from '@backstage/core-plugin-api/alpha'; // @alpha (undocumented) export const catalogExtensionData: { entityContentTitle: ConfigurableExtensionDataRef< - 'catalog.entity-content-title', string, + 'catalog.entity-content-title', {} >; entityFilterFunction: ConfigurableExtensionDataRef< - 'catalog.entity-filter-function', (entity: Entity) => boolean, + 'catalog.entity-filter-function', {} >; entityFilterExpression: ConfigurableExtensionDataRef< - 'catalog.entity-filter-expression', string, + 'catalog.entity-filter-expression', {} >; }; diff --git a/plugins/home/api-report-alpha.md b/plugins/home/api-report-alpha.md index 1dd3da96be..eb693a8e6f 100644 --- a/plugins/home/api-report-alpha.md +++ b/plugins/home/api-report-alpha.md @@ -12,8 +12,8 @@ export default _default; // @alpha (undocumented) export const titleExtensionDataRef: ConfigurableExtensionDataRef< - 'title', string, + 'title', {} >; diff --git a/plugins/search-react/api-report-alpha.md b/plugins/search-react/api-report-alpha.md index 3da9ac23a4..c6e011fe41 100644 --- a/plugins/search-react/api-report-alpha.md +++ b/plugins/search-react/api-report-alpha.md @@ -31,11 +31,11 @@ export function createSearchResultListItemExtension< export namespace createSearchResultListItemExtension { const // (undocumented) itemDataRef: ConfigurableExtensionDataRef< - 'search.search-result-list-item.item', { predicate?: SearchResultItemExtensionPredicate | undefined; component: SearchResultItemExtensionComponent; }, + 'search.search-result-list-item.item', {} >; } From f011d1b28e60a078cc699b7ec220824770454abc Mon Sep 17 00:00:00 2001 From: Kurt King <kurtaking@gmail.com> Date: Sun, 28 Jul 2024 06:48:06 -0600 Subject: [PATCH 461/510] docs: fix typos Signed-off-by: Kurt King <kurtaking@gmail.com> --- .changeset/tall-snakes-fix.md | 5 +++++ docs/backend-system/building-backends/08-migrating.md | 6 +++--- .../src/services/definitions/AuthService.ts | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 .changeset/tall-snakes-fix.md diff --git a/.changeset/tall-snakes-fix.md b/.changeset/tall-snakes-fix.md new file mode 100644 index 0000000000..68ab55bf9d --- /dev/null +++ b/.changeset/tall-snakes-fix.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-plugin-api': patch +--- + +fix typo in getPluginRequestToken comments diff --git a/docs/backend-system/building-backends/08-migrating.md b/docs/backend-system/building-backends/08-migrating.md index c6db44078e..67104c7ba9 100644 --- a/docs/backend-system/building-backends/08-migrating.md +++ b/docs/backend-system/building-backends/08-migrating.md @@ -497,7 +497,7 @@ catalog: providers: githubOrg: - id: production - githubUrl: 'https://github.com', + githubUrl: 'https://github.com' orgs: ['backstage'] schedule: frequency: PT30M @@ -536,8 +536,8 @@ catalog: providers: githubOrg: - id: production - githubUrl: 'https://github.com', - orgs: ['org-a', 'org-b'], + githubUrl: 'https://github.com' + orgs: ['org-a', 'org-b'] schedule: frequency: PT30M timeout: PT15M diff --git a/packages/backend-plugin-api/src/services/definitions/AuthService.ts b/packages/backend-plugin-api/src/services/definitions/AuthService.ts index dce5e9be3b..1e0cf6e56b 100644 --- a/packages/backend-plugin-api/src/services/definitions/AuthService.ts +++ b/packages/backend-plugin-api/src/services/definitions/AuthService.ts @@ -208,7 +208,7 @@ export interface AuthService { * * @remarks * - * This method should be called before each request. Do not cold on to the + * This method should be called before each request. Do not hold on to the * issued token and reuse it for future calls. */ getPluginRequestToken(options: { From 137fa342b4bf43c91e91d3b0b947b8d37c9e233e Mon Sep 17 00:00:00 2001 From: MT Lewis <mtlewis@users.noreply.github.com> Date: Sun, 28 Jul 2024 14:00:10 +0100 Subject: [PATCH 462/510] permission-common: add MetadataResponseSerializedRule from permission-node Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com> --- .changeset/nine-seahorses-relate.md | 5 ++++ plugins/permission-common/api-report.md | 9 ++++++ plugins/permission-common/package.json | 3 +- plugins/permission-common/src/types/index.ts | 1 + .../src/types/integration.ts | 30 +++++++++++++++++++ yarn.lock | 1 + 6 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 .changeset/nine-seahorses-relate.md create mode 100644 plugins/permission-common/src/types/integration.ts diff --git a/.changeset/nine-seahorses-relate.md b/.changeset/nine-seahorses-relate.md new file mode 100644 index 0000000000..9a5bb43823 --- /dev/null +++ b/.changeset/nine-seahorses-relate.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-permission-common': patch +--- + +Add the MetadataResponseSerializedRule type from @backstage/plugin-permission-node, since this type might be used in frontend code. diff --git a/plugins/permission-common/api-report.md b/plugins/permission-common/api-report.md index e9935c612d..12dd49d090 100644 --- a/plugins/permission-common/api-report.md +++ b/plugins/permission-common/api-report.md @@ -5,6 +5,7 @@ ```ts import { Config } from '@backstage/config'; import { JsonPrimitive } from '@backstage/types'; +import zodToJsonSchema from 'zod-to-json-schema'; // @public export type AllOfCriteria<TQuery> = { @@ -125,6 +126,14 @@ export function isResourcePermission<T extends string = string>( // @public export function isUpdatePermission(permission: Permission): boolean; +// @public +export type MetadataResponseSerializedRule = { + name: string; + description: string; + resourceType: string; + paramsSchema?: ReturnType<typeof zodToJsonSchema>; +}; + // @public export type NotCriteria<TQuery> = { not: PermissionCriteria<TQuery>; diff --git a/plugins/permission-common/package.json b/plugins/permission-common/package.json index 8d6f54fac0..585fc00531 100644 --- a/plugins/permission-common/package.json +++ b/plugins/permission-common/package.json @@ -53,7 +53,8 @@ "@backstage/types": "workspace:^", "cross-fetch": "^4.0.0", "uuid": "^9.0.0", - "zod": "^3.22.4" + "zod": "^3.22.4", + "zod-to-json-schema": "^3.20.4" }, "devDependencies": { "@backstage/cli": "workspace:^", diff --git a/plugins/permission-common/src/types/index.ts b/plugins/permission-common/src/types/index.ts index 5702f47c1c..1d2243447f 100644 --- a/plugins/permission-common/src/types/index.ts +++ b/plugins/permission-common/src/types/index.ts @@ -40,6 +40,7 @@ export type { NotCriteria, } from './api'; export type { DiscoveryApi } from './discovery'; +export type { MetadataResponseSerializedRule } from './integration'; export type { BasicPermission, PermissionAttributes, diff --git a/plugins/permission-common/src/types/integration.ts b/plugins/permission-common/src/types/integration.ts new file mode 100644 index 0000000000..6c208bb775 --- /dev/null +++ b/plugins/permission-common/src/types/integration.ts @@ -0,0 +1,30 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import zodToJsonSchema from 'zod-to-json-schema'; + +/** + * Serialized permission rules, with the paramsSchema + * converted from a ZodSchema to a JsonSchema. + * + * @public + */ +export type MetadataResponseSerializedRule = { + name: string; + description: string; + resourceType: string; + paramsSchema?: ReturnType<typeof zodToJsonSchema>; +}; diff --git a/yarn.lock b/yarn.lock index ad55a72897..794f848f55 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6723,6 +6723,7 @@ __metadata: msw: ^1.0.0 uuid: ^9.0.0 zod: ^3.22.4 + zod-to-json-schema: ^3.20.4 languageName: unknown linkType: soft From 5cd98780233fcce8d4ea7066eb45c2ad816c0ef8 Mon Sep 17 00:00:00 2001 From: MT Lewis <mtlewis@users.noreply.github.com> Date: Sun, 28 Jul 2024 14:15:50 +0100 Subject: [PATCH 463/510] permission-node: re-export MetadataResponseSerializedRule from permission-common Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com> --- .changeset/olive-books-sort.md | 5 +++++ plugins/permission-node/api-report.md | 11 +++-------- .../integration/createPermissionIntegrationRouter.ts | 10 ++++------ 3 files changed, 12 insertions(+), 14 deletions(-) create mode 100644 .changeset/olive-books-sort.md diff --git a/.changeset/olive-books-sort.md b/.changeset/olive-books-sort.md new file mode 100644 index 0000000000..d7bfd925ce --- /dev/null +++ b/.changeset/olive-books-sort.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-permission-node': patch +--- + +The MetadataResponseSerializedRule type has been moved to @backstage/plugin-permission-common, and should be imported from there going forward. To avoid an immediate breaking change, this type is still re-exported from this package, but is marked as deprecated and will be removed in a future release. diff --git a/plugins/permission-node/api-report.md b/plugins/permission-node/api-report.md index 81460ef630..8a90a39728 100644 --- a/plugins/permission-node/api-report.md +++ b/plugins/permission-node/api-report.md @@ -17,6 +17,7 @@ import { DefinitivePolicyDecision } from '@backstage/plugin-permission-common'; import { DiscoveryService } from '@backstage/backend-plugin-api'; import express from 'express'; import { IdentifiedPermissionMessage } from '@backstage/plugin-permission-common'; +import { MetadataResponseSerializedRule as MetadataResponseSerializedRule_2 } from '@backstage/plugin-permission-common'; import { NotCriteria } from '@backstage/plugin-permission-common'; import { Permission } from '@backstage/plugin-permission-common'; import { PermissionCondition } from '@backstage/plugin-permission-common'; @@ -29,7 +30,6 @@ import { QueryPermissionRequest } from '@backstage/plugin-permission-common'; import { ResourcePermission } from '@backstage/plugin-permission-common'; import { TokenManagerService } from '@backstage/backend-plugin-api'; import { z } from 'zod'; -import zodToJsonSchema from 'zod-to-json-schema'; // @public export type ApplyConditionsRequest = { @@ -194,13 +194,8 @@ export type MetadataResponse = { rules: MetadataResponseSerializedRule[]; }; -// @public -export type MetadataResponseSerializedRule = { - name: string; - description: string; - resourceType: string; - paramsSchema?: ReturnType<typeof zodToJsonSchema>; -}; +// @public @deprecated +export type MetadataResponseSerializedRule = MetadataResponseSerializedRule_2; // @public export type PermissionIntegrationRouterOptions< diff --git a/plugins/permission-node/src/integration/createPermissionIntegrationRouter.ts b/plugins/permission-node/src/integration/createPermissionIntegrationRouter.ts index 4a52c33f18..7793d8ab8e 100644 --- a/plugins/permission-node/src/integration/createPermissionIntegrationRouter.ts +++ b/plugins/permission-node/src/integration/createPermissionIntegrationRouter.ts @@ -24,6 +24,7 @@ import { AuthorizeResult, DefinitivePolicyDecision, IdentifiedPermissionMessage, + MetadataResponseSerializedRule as CommonMetadataResponseSerializedRule, Permission, PermissionCondition, PermissionCriteria, @@ -109,13 +110,10 @@ export type ApplyConditionsResponse = { * converted from a ZodSchema to a JsonSchema. * * @public + * @deprecated Please import from `@backstage/plugin-permission-common` instead. */ -export type MetadataResponseSerializedRule = { - name: string; - description: string; - resourceType: string; - paramsSchema?: ReturnType<typeof zodToJsonSchema>; -}; +export type MetadataResponseSerializedRule = + CommonMetadataResponseSerializedRule; /** * Response type for the .metadata endpoint. From 6c1081c9cba8c4be6e9acc3f4437c2c3b9b3c96a Mon Sep 17 00:00:00 2001 From: Andre Wanlin <awanlin@spotify.com> Date: Sun, 28 Jul 2024 13:03:59 -0500 Subject: [PATCH 464/510] Updated various Docker items Signed-off-by: Andre Wanlin <awanlin@spotify.com> --- .changeset/seven-eggs-admire.md | 5 ++++ docs/deployment/docker.md | 25 +++++++++++-------- .../software-catalog/configuration.md | 14 +++++++++++ .../default-app/app-config.production.yaml | 20 +++++++++++++-- .../default-app/packages/backend/Dockerfile | 3 +++ 5 files changed, 55 insertions(+), 12 deletions(-) create mode 100644 .changeset/seven-eggs-admire.md diff --git a/.changeset/seven-eggs-admire.md b/.changeset/seven-eggs-admire.md new file mode 100644 index 0000000000..d68b38e2d7 --- /dev/null +++ b/.changeset/seven-eggs-admire.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Updated dockerfile and `app-config.production.yaml` to make it easier to get started with example data diff --git a/docs/deployment/docker.md b/docs/deployment/docker.md index 154f68c7d1..d47cb248f8 100644 --- a/docs/deployment/docker.md +++ b/docs/deployment/docker.md @@ -92,11 +92,14 @@ RUN tar xzf skeleton.tar.gz && rm skeleton.tar.gz RUN --mount=type=cache,target=/home/node/.cache/yarn,sharing=locked,uid=1000,gid=1000 \ yarn install --frozen-lockfile --production --network-timeout 300000 +# This will include the examples, if you don't need these simply remove this line +COPY --chown=node:node examples ./examples + # Then copy the rest of the backend bundle, along with any other files we might want. COPY --chown=node:node packages/backend/dist/bundle.tar.gz app-config*.yaml ./ RUN tar xzf bundle.tar.gz && rm bundle.tar.gz -CMD ["node", "packages/backend", "--config", "app-config.yaml"] +CMD ["node", "packages/backend", "--config", "app-config.yaml", "--config", "app-config.production.yaml"] ``` For more details on how the `backend:bundle` command and the `skeleton.tar.gz` @@ -251,12 +254,15 @@ RUN --mount=type=cache,target=/home/node/.cache/yarn,sharing=locked,uid=1000,gid COPY --from=build --chown=node:node /app/packages/backend/dist/bundle/ ./ # Copy any other files that we need at runtime -COPY --chown=node:node app-config.yaml ./ +COPY --chown=node:node app-config*.yaml ./ + +# This will include the examples, if you don't need these simply remove this line +COPY --chown=node:node examples ./examples # This switches many Node.js dependencies to production mode. ENV NODE_ENV production -CMD ["node", "packages/backend", "--config", "app-config.yaml"] +CMD ["node", "packages/backend", "--config", "app-config.yaml", "--config", "app-config.production.yaml"] ``` Note that a newly created Backstage app will typically not have a `plugins/` @@ -277,6 +283,7 @@ packages/*/dist packages/*/node_modules plugins/*/dist plugins/*/node_modules +*.local.yaml ``` Once you have added both the `Dockerfile` and `.dockerignore` to the root of @@ -312,14 +319,12 @@ first step in doing so is to remove the `app-backend` plugin from the backend package, which is done as follows: 1. Delete `packages/backend/src/plugins/app.ts` -2. Remove the following lines from `packages/backend/src/index.ts`: - ```tsx - import app from './plugins/app'; - // ... - const appEnv = useHotMemoize(module, () => createEnv('app')); - // ... - .addRouter('', await app(appEnv)); +2. Remove the following line from `packages/backend/src/index.ts`: + + ```ts + backend.add(import('@backstage/plugin-app-backend/alpha')); ``` + 3. Remove the `@backstage/plugin-app-backend` and the app package dependency (e.g. `app`) from `packages/backend/package.json`. If you don't remove the app package dependency the app will still be built and bundled with the diff --git a/docs/features/software-catalog/configuration.md b/docs/features/software-catalog/configuration.md index 17d5f49205..67382aa6ce 100644 --- a/docs/features/software-catalog/configuration.md +++ b/docs/features/software-catalog/configuration.md @@ -58,6 +58,20 @@ catalog: target: ../../examples/all.yaml ``` +:::note +There might be cases where you need to test some `file` configurations in a Docker container. In a case like this, as the backend is serving the frontend in a default setup, the path would be from the root. Also, you need to **make sure to copy your files into your container**. + +Using the example above that would look like this: + +```yaml +catalog: + locations: + - type: file + target: ./examples/all.yaml +``` + +::: + ### Integration Processors Integrations may simply provide a mechanism to handle `url` location type for an diff --git a/packages/create-app/templates/default-app/app-config.production.yaml b/packages/create-app/templates/default-app/app-config.production.yaml index 5532d9067e..5d426f5392 100644 --- a/packages/create-app/templates/default-app/app-config.production.yaml +++ b/packages/create-app/templates/default-app/app-config.production.yaml @@ -30,10 +30,26 @@ backend: auth: providers: - guest: null + guest: {} catalog: # Overrides the default list locations from app-config.yaml as these contain example data. # See https://backstage.io/docs/features/software-catalog/#adding-components-to-the-catalog for more details # on how to get entities into the catalog. - locations: [] + locations: + # Local example data, replace this with your production config, these are intended for demo use only. + # File locations are relative to the backend process, typically in a deployed context, such as in a Docker container, this will be the root + - type: file + target: ./examples/entities.yaml + + # Local example template + - type: file + target: ./examples/template/template.yaml + rules: + - allow: [Template] + + # Local example organizational data + - type: file + target: ./examples/org.yaml + rules: + - allow: [User, Group] diff --git a/packages/create-app/templates/default-app/packages/backend/Dockerfile b/packages/create-app/templates/default-app/packages/backend/Dockerfile index 18548e9337..bef67b5ce7 100644 --- a/packages/create-app/templates/default-app/packages/backend/Dockerfile +++ b/packages/create-app/templates/default-app/packages/backend/Dockerfile @@ -45,6 +45,9 @@ RUN tar xzf skeleton.tar.gz && rm skeleton.tar.gz RUN --mount=type=cache,target=/home/node/.cache/yarn,sharing=locked,uid=1000,gid=1000 \ yarn install --frozen-lockfile --production --network-timeout 300000 +# This will include the examples, if you don't need these simply remove this line +COPY --chown=node:node examples ./examples + # Then copy the rest of the backend bundle, along with any other files we might want. COPY --chown=node:node packages/backend/dist/bundle.tar.gz app-config*.yaml ./ RUN tar xzf bundle.tar.gz && rm bundle.tar.gz From 47bc4046c57c7bdd10e7f20c2463fd447f505750 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Sun, 28 Jul 2024 21:24:03 +0200 Subject: [PATCH 465/510] frontend-plugin-api: add initial support for v2 extensions for blueprints Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/dry-squids-tap.md | 8 +- packages/frontend-plugin-api/api-report.md | 143 +++++++++++------- .../src/extensions/IconBundleBlueprint.ts | 8 +- .../src/wiring/createExtension.ts | 38 +++-- .../wiring/createExtensionBlueprint.test.tsx | 54 ++----- .../src/wiring/createExtensionBlueprint.ts | 137 ++++++++++++----- .../src/wiring/createExtensionDataRef.ts | 6 + .../frontend-plugin-api/src/wiring/index.ts | 1 + 8 files changed, 235 insertions(+), 160 deletions(-) diff --git a/.changeset/dry-squids-tap.md b/.changeset/dry-squids-tap.md index 613ec4b7cb..0a95332eed 100644 --- a/.changeset/dry-squids-tap.md +++ b/.changeset/dry-squids-tap.md @@ -11,13 +11,9 @@ This allows the creation of extension instances with the following pattern: const EntityCardBlueprint = createExtensionBlueprint({ kind: 'entity-card', attachTo: { id: 'test', input: 'default' }, - output: { - element: coreExtensionData.reactElement, - }, + output: [coreExtensionData.reactElement], factory(params: { text: string }) { - return { - element: <h1>{params.text}</h1>, - }; + return [coreExtensionData.reactElement(<h1>{params.text}</h1>)]; }, }); diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index 96c7675c0d..d37f0a3a56 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -593,24 +593,38 @@ export function createExtension< // @public export function createExtensionBlueprint< TParams, - TInputs extends AnyExtensionInputMap, - TOutput extends AnyExtensionDataMap, + UOutput extends AnyExtensionDataRef, + TInputs extends { + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { + optional: boolean; + singleton: boolean; + } + >; + }, + UExtraOutput extends AnyExtensionDataRef, TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType; }, - TDataRefs extends AnyExtensionDataMap = never, + UFactoryOutput extends ExtensionDataValue<any, any>, + TDataRefs extends { + [name in string]: AnyExtensionDataRef; + } = never, >( options: CreateExtensionBlueprintOptions< TParams, + UOutput, TInputs, - TOutput, TConfigSchema, + UFactoryOutput, TDataRefs >, ): ExtensionBlueprint< TParams, + UOutput, TInputs, - TOutput, + UExtraOutput, string extends keyof TConfigSchema ? {} : { @@ -627,29 +641,38 @@ export function createExtensionBlueprint< >; // @public (undocumented) -export interface CreateExtensionBlueprintOptions< +export type CreateExtensionBlueprintOptions< TParams, - TInputs extends AnyExtensionInputMap, - TOutput extends AnyExtensionDataMap, + UOutput extends AnyExtensionDataRef, + TInputs extends { + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { + optional: boolean; + singleton: boolean; + } + >; + }, TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType; }, - TDataRefs extends AnyExtensionDataMap, -> { - // (undocumented) + UFactoryOutput extends ExtensionDataValue<any, any>, + TDataRefs extends { + [name in string]: AnyExtensionDataRef; + }, +> = { + kind: string; + namespace?: string; attachTo: { id: string; input: string; }; - // (undocumented) + disabled?: boolean; + inputs?: TInputs; + output: Array<UOutput>; config?: { schema: TConfigSchema; }; - // (undocumented) - dataRefs?: TDataRefs; - // (undocumented) - disabled?: boolean; - // (undocumented) factory( params: TParams, context: { @@ -659,16 +682,9 @@ export interface CreateExtensionBlueprintOptions< }; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, - ): Expand<ExtensionDataValues<TOutput>>; - // (undocumented) - inputs?: TInputs; - // (undocumented) - kind: string; - // (undocumented) - namespace?: string; - // (undocumented) - output: TOutput; -} + ): Iterable<UFactoryOutput>; + dataRefs?: TDataRefs; +} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>; // @public @deprecated (undocumented) export function createExtensionDataRef<TData>( @@ -769,22 +785,7 @@ export type CreateExtensionOptions< }); inputs: Expand<ResolvedExtensionInputs<TInputs>>; }): Iterable<UFactoryOutput>; -} & (( - UOutput extends any - ? UOutput['config']['optional'] extends true - ? never - : UOutput['id'] - : never -) extends infer IRequiredOutputIds - ? [IRequiredOutputIds] extends [UFactoryOutput['id']] - ? {} - : { - 'Error: The extension factory is missing the following outputs': Exclude< - IRequiredOutputIds, - UFactoryOutput['id'] - >; - } - : never); +} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>; // @public (undocumented) export function createExtensionOverrides( @@ -1081,15 +1082,26 @@ export interface Extension<TConfig, TConfigInput = TConfig> { // @public (undocumented) export interface ExtensionBlueprint< TParams, - TInputs extends AnyExtensionInputMap, - TOutput extends AnyExtensionDataMap, + UOutput extends AnyExtensionDataRef, + TInputs extends { + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { + optional: boolean; + singleton: boolean; + } + >; + }, + UExtraOutput extends AnyExtensionDataRef, TConfig extends { [key in string]: unknown; }, TConfigInput extends { [key in string]: unknown; }, - TDataRefs extends AnyExtensionDataMap, + TDataRefs extends { + [name in string]: AnyExtensionDataRef; + }, > { // (undocumented) dataRefs: TDataRefs; @@ -1097,6 +1109,7 @@ export interface ExtensionBlueprint< TExtensionConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType; }, + UFactoryOutput extends ExtensionDataValue<any, any>, >( args: { namespace?: string; @@ -1107,7 +1120,7 @@ export interface ExtensionBlueprint< }; disabled?: boolean; inputs?: TInputs; - output?: TOutput; + output?: Array<UExtraOutput>; config?: { schema: TExtensionConfigSchema & { [KName in keyof TConfig]?: `Error: Config key '${KName & @@ -1115,7 +1128,7 @@ export interface ExtensionBlueprint< }; }; } & ( - | { + | ({ factory( originalFactory: ( params: TParams, @@ -1123,7 +1136,7 @@ export interface ExtensionBlueprint< config?: TConfig; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, - ) => Expand<ExtensionDataValues<TOutput>>, + ) => Iterable<ExtensionDataRefToValue<UOutput>>, context: { node: AppNode; config: TConfig & { @@ -1133,8 +1146,11 @@ export interface ExtensionBlueprint< }; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, - ): Expand<ExtensionDataValues<TOutput>>; - } + ): Iterable<UFactoryOutput>; + } & VerifyExtensionFactoryOutput< + UOutput & UExtraOutput, + UFactoryOutput + >) | { params: TParams; } @@ -1196,6 +1212,12 @@ export type ExtensionDataRef< readonly config: TConfig; }; +// @public (undocumented) +export type ExtensionDataRefToValue<TDataRef extends AnyExtensionDataRef> = + TDataRef extends ExtensionDataRef<infer IData, infer IId, any> + ? ExtensionDataValue<IData, IId> + : never; + // @public (undocumented) export type ExtensionDataValue<TData, TId extends string> = { readonly $$type: '@backstage/ExtensionDataValue'; @@ -1323,16 +1345,23 @@ export const IconBundleBlueprint: ExtensionBlueprint< [x: string]: IconComponent; }; }, - AnyExtensionInputMap, + ConfigurableExtensionDataRef< + { + [x: string]: IconComponent; + }, + 'core.icons', + {} + >, { - icons: ConfigurableExtensionDataRef< + [x: string]: ExtensionInput< + AnyExtensionDataRef, { - [x: string]: IconComponent; - }, - 'core.icons', - {} + optional: boolean; + singleton: boolean; + } >; }, + AnyExtensionDataRef, { icons: string; test: string; diff --git a/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts b/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts index 438da09b4a..deeabdb44c 100644 --- a/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts +++ b/packages/frontend-plugin-api/src/extensions/IconBundleBlueprint.ts @@ -25,16 +25,16 @@ export const IconBundleBlueprint = createExtensionBlueprint({ kind: 'icon-bundle', namespace: 'app', attachTo: { id: 'app', input: 'icons' }, - output: { - icons: iconsDataRef, - }, + output: [iconsDataRef], config: { schema: { icons: z => z.string().default('blob'), test: z => z.string(), }, }, - factory: (params: { icons: { [key in string]: IconComponent } }) => params, + factory: (params: { icons: { [key in string]: IconComponent } }) => [ + iconsDataRef(params.icons), + ], dataRefs: { icons: iconsDataRef, }, diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index 4034ef7238..4d31982ed3 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -145,6 +145,27 @@ export interface LegacyCreateExtensionOptions< }): Expand<ExtensionDataValues<TOutput>>; } +/** @ignore */ +export type VerifyExtensionFactoryOutput< + UDeclaredOutput extends AnyExtensionDataRef, + UFactoryOutput extends ExtensionDataValue<any, any>, +> = ( + UDeclaredOutput extends any + ? UDeclaredOutput['config']['optional'] extends true + ? never + : UDeclaredOutput['id'] + : never +) extends infer IRequiredOutputIds + ? [IRequiredOutputIds] extends [UFactoryOutput['id']] + ? {} + : { + 'Error: The extension factory is missing the following outputs': Exclude< + IRequiredOutputIds, + UFactoryOutput['id'] + >; + } + : never; + /** @public */ export type CreateExtensionOptions< UOutput extends AnyExtensionDataRef, @@ -183,22 +204,7 @@ export type CreateExtensionOptions< }); inputs: Expand<ResolvedExtensionInputs<TInputs>>; }): Iterable<UFactoryOutput>; -} & (( - UOutput extends any - ? UOutput['config']['optional'] extends true - ? never - : UOutput['id'] - : never -) extends infer IRequiredOutputIds - ? [IRequiredOutputIds] extends [UFactoryOutput['id']] - ? {} - : { - 'Error: The extension factory is missing the following outputs': Exclude< - IRequiredOutputIds, - UFactoryOutput['id'] - >; - } - : never); +} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>; /** @public */ export interface ExtensionDefinition<TConfig, TConfigInput = TConfig> { diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx index e4cb9e26f1..8b364f33c1 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx @@ -27,13 +27,9 @@ describe('createExtensionBlueprint', () => { const TestExtensionBlueprint = createExtensionBlueprint({ kind: 'test-extension', attachTo: { id: 'test', input: 'default' }, - output: { - element: coreExtensionData.reactElement, - }, + output: [coreExtensionData.reactElement], factory(params: { text: string }) { - return { - element: <h1>{params.text}</h1>, - }; + return [coreExtensionData.reactElement(<h1>{params.text}</h1>)]; }, }); @@ -56,12 +52,10 @@ describe('createExtensionBlueprint', () => { kind: 'test-extension', name: 'my-extension', namespace: undefined, - output: { - element: coreExtensionData.reactElement, - }, + output: [coreExtensionData.reactElement], factory: expect.any(Function), toString: expect.any(Function), - version: 'v1', + version: 'v2', }); const { container } = createExtensionTester(extension).render(); @@ -72,13 +66,9 @@ describe('createExtensionBlueprint', () => { const TestExtensionBlueprint = createExtensionBlueprint({ kind: 'test-extension', attachTo: { id: 'test', input: 'default' }, - output: { - element: coreExtensionData.reactElement, - }, + output: [coreExtensionData.reactElement], factory(params: { text: string }) { - return { - element: <h1>{params.text}</h1>, - }; + return [coreExtensionData.reactElement(<h1>{params.text}</h1>)]; }, }); @@ -103,16 +93,12 @@ describe('createExtensionBlueprint', () => { const TestExtensionBlueprint = createExtensionBlueprint({ kind: 'test-extension', attachTo: { id: 'test', input: 'default' }, - output: { - element: coreExtensionData.reactElement, - }, + output: [coreExtensionData.reactElement], dataRefs: { data: dataRef, }, factory(params: { text: string }) { - return { - element: <h1>{params.text}</h1>, - }; + return [coreExtensionData.reactElement(<h1>{params.text}</h1>)]; }, }); @@ -125,9 +111,7 @@ describe('createExtensionBlueprint', () => { const TestExtensionBlueprint = createExtensionBlueprint({ kind: 'test-extension', attachTo: { id: 'test', input: 'default' }, - output: { - element: coreExtensionData.reactElement, - }, + output: [coreExtensionData.reactElement], config: { schema: { text: z => z.string(), @@ -142,9 +126,7 @@ describe('createExtensionBlueprint', () => { expect(config.text).toBe('Hello, world!'); - return { - element: <h1>{config.text}</h1>, - }; + return [coreExtensionData.reactElement(<h1>{config.text}</h1>)]; }, }); @@ -188,18 +170,14 @@ describe('createExtensionBlueprint', () => { const TestExtensionBlueprint = createExtensionBlueprint({ kind: 'test-extension', attachTo: { id: 'test', input: 'default' }, - output: { - element: coreExtensionData.reactElement, - }, + output: [coreExtensionData.reactElement], config: { schema: { text: z => z.string(), }, }, factory(params: { text: string }) { - return { - element: <div>{params.text}</div>, - }; + return [coreExtensionData.reactElement(<div>{params.text}</div>)]; }, }); @@ -224,16 +202,12 @@ describe('createExtensionBlueprint', () => { const TestExtensionBlueprint = createExtensionBlueprint({ kind: 'test-extension', attachTo: { id: 'test', input: 'default' }, - output: { - element: coreExtensionData.reactElement, - }, + output: [coreExtensionData.reactElement], factory(_, { config }) { // @ts-expect-error const b = config.something; - return { - element: <div />, - }; + return [coreExtensionData.reactElement(<div />)]; }, }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts index 7393ca233e..b579cc207a 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts @@ -17,31 +17,42 @@ import { AppNode } from '../apis'; import { Expand } from '../types'; import { - AnyExtensionDataMap, - AnyExtensionInputMap, - ExtensionDataValues, + CreateExtensionOptions, ExtensionDefinition, ResolvedExtensionInputs, + VerifyExtensionFactoryOutput, createExtension, } from './createExtension'; import { z } from 'zod'; +import { ExtensionInput } from './createExtensionInput'; +import { + AnyExtensionDataRef, + ExtensionDataRefToValue, + ExtensionDataValue, +} from './createExtensionDataRef'; /** * @public */ -export interface CreateExtensionBlueprintOptions< +export type CreateExtensionBlueprintOptions< TParams, - TInputs extends AnyExtensionInputMap, - TOutput extends AnyExtensionDataMap, + UOutput extends AnyExtensionDataRef, + TInputs extends { + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { optional: boolean; singleton: boolean } + >; + }, TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType }, - TDataRefs extends AnyExtensionDataMap, -> { + UFactoryOutput extends ExtensionDataValue<any, any>, + TDataRefs extends { [name in string]: AnyExtensionDataRef }, +> = { kind: string; namespace?: string; attachTo: { id: string; input: string }; disabled?: boolean; inputs?: TInputs; - output: TOutput; + output: Array<UOutput>; config?: { schema: TConfigSchema; }; @@ -54,21 +65,27 @@ export interface CreateExtensionBlueprintOptions< }; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, - ): Expand<ExtensionDataValues<TOutput>>; + ): Iterable<UFactoryOutput>; dataRefs?: TDataRefs; -} +} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>; /** * @public */ export interface ExtensionBlueprint< TParams, - TInputs extends AnyExtensionInputMap, - TOutput extends AnyExtensionDataMap, + UOutput extends AnyExtensionDataRef, + TInputs extends { + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { optional: boolean; singleton: boolean } + >; + }, + UExtraOutput extends AnyExtensionDataRef, TConfig extends { [key in string]: unknown }, TConfigInput extends { [key in string]: unknown }, - TDataRefs extends AnyExtensionDataMap, + TDataRefs extends { [name in string]: AnyExtensionDataRef }, > { dataRefs: TDataRefs; @@ -82,6 +99,7 @@ export interface ExtensionBlueprint< TExtensionConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType; }, + UFactoryOutput extends ExtensionDataValue<any, any>, >( args: { namespace?: string; @@ -89,7 +107,7 @@ export interface ExtensionBlueprint< attachTo?: { id: string; input: string }; disabled?: boolean; inputs?: TInputs; - output?: TOutput; + output?: Array<UExtraOutput>; config?: { schema: TExtensionConfigSchema & { [KName in keyof TConfig]?: `Error: Config key '${KName & @@ -97,7 +115,7 @@ export interface ExtensionBlueprint< }; }; } & ( - | { + | ({ factory( originalFactory: ( params: TParams, @@ -105,7 +123,7 @@ export interface ExtensionBlueprint< config?: TConfig; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, - ) => Expand<ExtensionDataValues<TOutput>>, + ) => Iterable<ExtensionDataRefToValue<UOutput>>, context: { node: AppNode; config: TConfig & { @@ -115,8 +133,11 @@ export interface ExtensionBlueprint< }; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, - ): Expand<ExtensionDataValues<TOutput>>; - } + ): Iterable<UFactoryOutput>; + } & VerifyExtensionFactoryOutput< + UOutput & UExtraOutput, + UFactoryOutput + >) | { params: TParams; } @@ -143,17 +164,24 @@ export interface ExtensionBlueprint< */ class ExtensionBlueprintImpl< TParams, - TInputs extends AnyExtensionInputMap, - TOutput extends AnyExtensionDataMap, + UOutput extends AnyExtensionDataRef, + TInputs extends { + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { optional: boolean; singleton: boolean } + >; + }, + UExtraOutput extends AnyExtensionDataRef, TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType }, - TDataRefs extends AnyExtensionDataMap, + TDataRefs extends { [name in string]: AnyExtensionDataRef }, > { constructor( private readonly options: CreateExtensionBlueprintOptions< TParams, + UOutput, TInputs, - TOutput, TConfigSchema, + any, TDataRefs >, ) { @@ -166,13 +194,14 @@ class ExtensionBlueprintImpl< TExtensionConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType; }, + UFactoryOutput extends ExtensionDataValue<any, any>, >(args: { namespace?: string; name?: string; attachTo?: { id: string; input: string }; disabled?: boolean; inputs?: TInputs; - output?: TOutput; + output?: Array<UExtraOutput>; params?: TParams; config?: { schema: TExtensionConfigSchema; @@ -188,7 +217,7 @@ class ExtensionBlueprintImpl< }; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, - ) => Expand<ExtensionDataValues<TOutput>>, + ) => Iterable<ExtensionDataRefToValue<UOutput>>, context: { node: AppNode; config: { @@ -200,7 +229,7 @@ class ExtensionBlueprintImpl< }; inputs: Expand<ResolvedExtensionInputs<TInputs>>; }, - ): Expand<ExtensionDataValues<TOutput>>; + ): Iterable<UFactoryOutput>; }): ExtensionDefinition< { [key in keyof TExtensionConfigSchema]: z.infer< @@ -232,7 +261,7 @@ class ExtensionBlueprintImpl< attachTo: args.attachTo ?? this.options.attachTo, disabled: args.disabled ?? this.options.disabled, inputs: args.inputs ?? this.options.inputs, - output: args.output ?? this.options.output, + output: [...(args.output ?? []), ...this.options.output], config: Object.keys(schema).length === 0 ? undefined : { schema }, factory: ({ node, config, inputs }) => { if (args.factory) { @@ -247,12 +276,13 @@ class ExtensionBlueprintImpl< }; inputs?: Expand<ResolvedExtensionInputs<TInputs>>; }, - ) => - this.options.factory(innerParams, { + ): Iterable<ExtensionDataRefToValue<UOutput>> => { + return this.options.factory(innerParams, { node, config: innerContext?.config ?? config, inputs: innerContext?.inputs ?? inputs, - }), + }); + }, { node, config, @@ -268,7 +298,30 @@ class ExtensionBlueprintImpl< } throw new Error('Either params or factory must be provided'); }, - }); + } as CreateExtensionOptions< + UOutput, + TInputs, + { + [key in keyof TExtensionConfigSchema]: z.infer< + ReturnType<TExtensionConfigSchema[key]> + >; + } & { + [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>; + }, + z.input< + z.ZodObject< + { + [key in keyof TExtensionConfigSchema]: ReturnType< + TExtensionConfigSchema[key] + >; + } & { + [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>; + } + > + >, + TConfigSchema, + UFactoryOutput + >); } } @@ -280,22 +333,31 @@ class ExtensionBlueprintImpl< */ export function createExtensionBlueprint< TParams, - TInputs extends AnyExtensionInputMap, - TOutput extends AnyExtensionDataMap, + UOutput extends AnyExtensionDataRef, + TInputs extends { + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { optional: boolean; singleton: boolean } + >; + }, + UExtraOutput extends AnyExtensionDataRef, TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType }, - TDataRefs extends AnyExtensionDataMap = never, + UFactoryOutput extends ExtensionDataValue<any, any>, + TDataRefs extends { [name in string]: AnyExtensionDataRef } = never, >( options: CreateExtensionBlueprintOptions< TParams, + UOutput, TInputs, - TOutput, TConfigSchema, + UFactoryOutput, TDataRefs >, ): ExtensionBlueprint< TParams, + UOutput, TInputs, - TOutput, + UExtraOutput, string extends keyof TConfigSchema ? {} : { [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>> }, @@ -310,8 +372,9 @@ export function createExtensionBlueprint< > { return new ExtensionBlueprintImpl(options) as ExtensionBlueprint< TParams, + UOutput, TInputs, - TOutput, + UExtraOutput, string extends keyof TConfigSchema ? {} : { diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.ts b/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.ts index f4b348ae51..c77aa8c394 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.ts @@ -33,6 +33,12 @@ export type ExtensionDataRef< readonly config: TConfig; }; +/** @public */ +export type ExtensionDataRefToValue<TDataRef extends AnyExtensionDataRef> = + TDataRef extends ExtensionDataRef<infer IData, infer IId, any> + ? ExtensionDataValue<IData, IId> + : never; + /** @public */ export type AnyExtensionDataRef = ExtensionDataRef< unknown, diff --git a/packages/frontend-plugin-api/src/wiring/index.ts b/packages/frontend-plugin-api/src/wiring/index.ts index 4b99ba8ebc..a17dfedc16 100644 --- a/packages/frontend-plugin-api/src/wiring/index.ts +++ b/packages/frontend-plugin-api/src/wiring/index.ts @@ -36,6 +36,7 @@ export { createExtensionDataRef, type AnyExtensionDataRef, type ExtensionDataRef, + type ExtensionDataRefToValue, type ExtensionDataValue, type ConfigurableExtensionDataRef, } from './createExtensionDataRef'; From feb0734e021a16050689f6acdd61564016e818d9 Mon Sep 17 00:00:00 2001 From: Andre Wanlin <awanlin@spotify.com> Date: Sun, 28 Jul 2024 15:39:40 -0500 Subject: [PATCH 466/510] Updated intro title Signed-off-by: Andre Wanlin <awanlin@spotify.com> --- docs/getting-started/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/index.md b/docs/getting-started/index.md index 99fdb3d8ed..8bb30d1db8 100644 --- a/docs/getting-started/index.md +++ b/docs/getting-started/index.md @@ -1,6 +1,6 @@ --- id: index -title: Installing a standalone server +title: Creating your Backstage App sidebar_label: Introduction description: How to install Backstage for your own use. --- From 120e195aca449ba1972827a987d59587bb9f1308 Mon Sep 17 00:00:00 2001 From: Andre Wanlin <awanlin@spotify.com> Date: Sun, 28 Jul 2024 18:26:07 -0500 Subject: [PATCH 467/510] Updated mkdocs Signed-off-by: Andre Wanlin <awanlin@spotify.com> --- mkdocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index f163005377..8527d68c28 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -20,7 +20,7 @@ nav: - Support and community: 'overview/support.md' - Logo assets: 'overview/logos.md' - Getting Started: - - Installing a standalone server: 'getting-started/index.md' + - Creating your Backstage App: 'getting-started/index.md' - Configuring Backstage: - Database: 'getting-started/config/database.md' - Authentication: 'getting-started/config/authentication.md' From 3be9aeb1dd94a849d88d02fd859f12f3ed80ab5a Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg <poldsberg@gmail.com> Date: Mon, 29 Jul 2024 09:46:00 +0200 Subject: [PATCH 468/510] changesets: add changeset for v2 extensions Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> --- .changeset/green-planets-reflect.md | 6 +++ .changeset/rare-foxes-compete.md | 57 +++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 .changeset/green-planets-reflect.md create mode 100644 .changeset/rare-foxes-compete.md diff --git a/.changeset/green-planets-reflect.md b/.changeset/green-planets-reflect.md new file mode 100644 index 0000000000..513f0480a5 --- /dev/null +++ b/.changeset/green-planets-reflect.md @@ -0,0 +1,6 @@ +--- +'@backstage/frontend-test-utils': patch +'@backstage/frontend-app-api': patch +--- + +Added support for v2 extensions, which declare their inputs and outputs without using a data map. diff --git a/.changeset/rare-foxes-compete.md b/.changeset/rare-foxes-compete.md new file mode 100644 index 0000000000..64dd9b557e --- /dev/null +++ b/.changeset/rare-foxes-compete.md @@ -0,0 +1,57 @@ +--- +'@backstage/frontend-plugin-api': patch +--- + +Extensions have been changed to be declared with an array of inputs and outputs, rather than a map of named data refs. This change was made to reduce confusion around the role of the input and output names, as well as enable more powerful APIs for overriding extensions. + +An extension that was previously declared like this: + +```tsx +const exampleExtension = createExtension({ + name: 'example', + inputs: { + items: createExtensionInput({ + element: coreExtensionData.reactElement, + }), + }, + output: { + element: coreExtensionData.reactElement, + }, + factory({ inputs }) { + return { + element: ( + <div> + Example + {inputs.items.map(item => { + return <div>{item.output.element}</div>; + })} + </div> + ), + }; + }, +}); +``` + +Should be migrated to the following: + +```tsx +const exampleExtension = createExtension({ + name: 'example', + inputs: { + items: createExtensionInput([coreExtensionData.reactElement]), + }, + output: [coreExtensionData.reactElement], + factory({ inputs }) { + return [ + coreExtensionData.reactElement( + <div> + Example + {inputs.items.map(item => { + return <div>{item.get(coreExtensionData.reactElement)}</div>; + })} + </div>, + ), + ]; + }, +}); +``` From fa7c1807798402bb399ffb6fb000feb8fff93272 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 07:46:51 +0000 Subject: [PATCH 469/510] chore(deps): update snyk/actions digest to 6312a53 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/sync_snyk-github-issues.yml | 2 +- .github/workflows/sync_snyk-monitor.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/sync_snyk-github-issues.yml b/.github/workflows/sync_snyk-github-issues.yml index 1209545da1..af2e4da251 100644 --- a/.github/workflows/sync_snyk-github-issues.yml +++ b/.github/workflows/sync_snyk-github-issues.yml @@ -29,7 +29,7 @@ jobs: cache-prefix: ${{ runner.os }}-v18.x - name: Create Snyk report - uses: snyk/actions/node@640e31719aac3e44867d239dc86c20c3e34c8e4f # master + uses: snyk/actions/node@6312a53377a551c0258438bf25fb8f378afbc977 # master continue-on-error: true # Snyk CLI exits with error when vulnerabilities are found with: args: > diff --git a/.github/workflows/sync_snyk-monitor.yml b/.github/workflows/sync_snyk-monitor.yml index 44699964a6..1bdf0d30cf 100644 --- a/.github/workflows/sync_snyk-monitor.yml +++ b/.github/workflows/sync_snyk-monitor.yml @@ -31,7 +31,7 @@ jobs: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Monitor and Synchronize Snyk Policies - uses: snyk/actions/node@640e31719aac3e44867d239dc86c20c3e34c8e4f # master + uses: snyk/actions/node@6312a53377a551c0258438bf25fb8f378afbc977 # master with: command: monitor args: > @@ -46,7 +46,7 @@ jobs: # Above we run the `monitor` command, this runs the `test` command which is # the one that generates the SARIF report that we can upload to GitHub. - name: Create Snyk report - uses: snyk/actions/node@640e31719aac3e44867d239dc86c20c3e34c8e4f # master + uses: snyk/actions/node@6312a53377a551c0258438bf25fb8f378afbc977 # master continue-on-error: true # To make sure that SARIF upload gets called with: args: > From 069f452521877b739b5ba8df336a7047530455d4 Mon Sep 17 00:00:00 2001 From: Ben Lambert <blam@spotify.com> Date: Mon, 29 Jul 2024 10:06:10 +0200 Subject: [PATCH 470/510] Update tall-snakes-fix.md Signed-off-by: blam <ben@blam.sh> --- .changeset/tall-snakes-fix.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/tall-snakes-fix.md b/.changeset/tall-snakes-fix.md index 68ab55bf9d..351c781375 100644 --- a/.changeset/tall-snakes-fix.md +++ b/.changeset/tall-snakes-fix.md @@ -2,4 +2,4 @@ '@backstage/backend-plugin-api': patch --- -fix typo in getPluginRequestToken comments +fix typo in `getPluginRequestToken` comments From 725f470575edb11e26201548da903a88458ee82b Mon Sep 17 00:00:00 2001 From: Ben Lambert <ben@blam.sh> Date: Mon, 29 Jul 2024 10:08:32 +0200 Subject: [PATCH 471/510] Update thick-hotels-know.md Signed-off-by: Ben Lambert <ben@blam.sh> --- .changeset/thick-hotels-know.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/thick-hotels-know.md b/.changeset/thick-hotels-know.md index a2331b6df2..f0c7129256 100644 --- a/.changeset/thick-hotels-know.md +++ b/.changeset/thick-hotels-know.md @@ -2,4 +2,4 @@ '@backstage/plugin-scaffolder-backend': patch --- -Fix scaffolder action catalog:write to work in nested folders. +Fix scaffolder action `catalog:write` to write to directories that don't already exist From c7b14edcaf4512067cb37f95d08184476775ad10 Mon Sep 17 00:00:00 2001 From: Dane Elwell <dane.elwell@ans.co.uk> Date: Fri, 26 Jul 2024 13:11:13 +0100 Subject: [PATCH 472/510] Add new excludeRepos option to the Gitlab provider Signed-off-by: Dane Elwell <dane.elwell@ans.co.uk> --- .changeset/red-radios-promise.md | 5 ++ docs/integrations/gitlab/discovery.md | 1 + .../api-report.md | 1 + .../catalog-backend-module-gitlab/config.d.ts | 5 ++ .../src/__testUtils__/mocks.ts | 27 +++++++++++ .../src/lib/types.ts | 5 ++ .../GitlabDiscoveryEntityProvider.test.ts | 33 +++++++++++++ .../GitlabDiscoveryEntityProvider.ts | 7 +++ .../src/providers/config.test.ts | 46 +++++++++++++++++++ .../src/providers/config.ts | 3 ++ 10 files changed, 133 insertions(+) create mode 100644 .changeset/red-radios-promise.md diff --git a/.changeset/red-radios-promise.md b/.changeset/red-radios-promise.md new file mode 100644 index 0000000000..66ee1cc614 --- /dev/null +++ b/.changeset/red-radios-promise.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-gitlab': patch +--- + +Adds new optional excludeRepos configuration option to the Gitlab catalog provider. diff --git a/docs/integrations/gitlab/discovery.md b/docs/integrations/gitlab/discovery.md index 13ffd79801..70f12f181e 100644 --- a/docs/integrations/gitlab/discovery.md +++ b/docs/integrations/gitlab/discovery.md @@ -153,6 +153,7 @@ catalog: group: example-group # Optional. Group and subgroup (if needed) to look for repositories. If not present the whole instance will be scanned entityFilename: catalog-info.yaml # Optional. Defaults to `catalog-info.yaml` projectPattern: '[\s\S]*' # Optional. Filters found projects based on provided patter. Defaults to `[\s\S]*`, which means to not filter anything + excludeRepos: [] # Optional. A list of project paths that should be excluded from discovery, e.g. group/subgroup/repo. Should not start or end with a slash. schedule: # Same options as in TaskScheduleDefinition. Optional for the Legacy Backend System # supports cron, ISO duration, "human duration" as used in code frequency: { minutes: 30 } diff --git a/plugins/catalog-backend-module-gitlab/api-report.md b/plugins/catalog-backend-module-gitlab/api-report.md index 2b78c67205..0a1e4b7d36 100644 --- a/plugins/catalog-backend-module-gitlab/api-report.md +++ b/plugins/catalog-backend-module-gitlab/api-report.md @@ -110,6 +110,7 @@ export type GitlabProviderConfig = { orgEnabled?: boolean; schedule?: TaskScheduleDefinition; skipForkedRepos?: boolean; + excludeRepos?: string[]; }; // @public diff --git a/plugins/catalog-backend-module-gitlab/config.d.ts b/plugins/catalog-backend-module-gitlab/config.d.ts index 7d183b6e58..9f009ee478 100644 --- a/plugins/catalog-backend-module-gitlab/config.d.ts +++ b/plugins/catalog-backend-module-gitlab/config.d.ts @@ -63,6 +63,11 @@ export interface Config { * (Optional) Skip forked repository */ skipForkedRepos?: boolean; + /** + * (Optional) A list of strings containing the paths of the repositories to skip + * Should be in the format group/subgroup/repo, with no leading or trailing slashes. + */ + excludeRepos?: string[]; }; }; }; diff --git a/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts b/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts index 798df32695..4a173c6b50 100644 --- a/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts +++ b/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts @@ -299,6 +299,33 @@ export const config_single_integration_skip_forks: MockObject = { }, }; +export const config_single_integration_exclude_repos: MockObject = { + integrations: { + gitlab: [ + { + host: 'example.com', + apiBaseUrl: 'https://example.com/api/v4', + token: '1234', + }, + ], + }, + catalog: { + providers: { + gitlab: { + 'test-id': { + host: 'example.com', + group: 'group1', + excludeRepos: ['group1/test-repo1'], + schedule: { + frequency: 'PT30M', + timeout: 'PT3M', + }, + }, + }, + }, + }, +}; + export const config_no_schedule: MockObject = { integrations: { gitlab: [ diff --git a/plugins/catalog-backend-module-gitlab/src/lib/types.ts b/plugins/catalog-backend-module-gitlab/src/lib/types.ts index 0b9ea6a868..69c8ed5f92 100644 --- a/plugins/catalog-backend-module-gitlab/src/lib/types.ts +++ b/plugins/catalog-backend-module-gitlab/src/lib/types.ts @@ -201,6 +201,11 @@ export type GitlabProviderConfig = { * If the project is a fork, skip repository */ skipForkedRepos?: boolean; + /** + * List of repositories to exclude from discovery, should be the full path to the repository, e.g. `group/project` + * Paths should not start or end with a slash. + */ + excludeRepos?: string[]; }; /** diff --git a/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.test.ts b/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.test.ts index 473e547a57..f5e167e564 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.test.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.test.ts @@ -130,6 +130,7 @@ describe('GitlabDiscoveryEntityProvider - configuration', () => { ); }); }); + describe('GitlabDiscoveryEntityProvider - refresh', () => { it('should apply full update on scheduled execution', async () => { const config = new ConfigReader(mock.config_no_org_integration); @@ -231,6 +232,38 @@ describe('GitlabDiscoveryEntityProvider - refresh', () => { }); }); + it('should filter repositories that are excluded', async () => { + const config = new ConfigReader( + mock.config_single_integration_exclude_repos, + ); + const schedule = new PersistingTaskRunner(); + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + const provider = GitlabDiscoveryEntityProvider.fromConfig(config, { + logger, + schedule, + })[0]; + + await provider.connect(entityProviderConnection); + + await provider.refresh(logger); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'full', + entities: mock.expected_location_entities_default_branch.filter( + entity => + !entity.entity.metadata.annotations[ + 'backstage.io/managed-by-location' + ].includes('test-repo1') && + !entity.entity.metadata.annotations[ + 'backstage.io/managed-by-location' + ].includes('awesome'), + ), + }); + }); + // branch and fallback branch are undefined in the config it('should ingest catalog from project default branch only', async () => { const config = new ConfigReader(mock.config_single_integration); diff --git a/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.ts b/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.ts index b2ef475d9d..bbd90795be 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.ts @@ -470,6 +470,13 @@ export class GitlabDiscoveryEntityProvider implements EntityProvider { return false; } + if (this.config.excludeRepos?.includes(project.path_with_namespace ?? '')) { + this.logger.debug( + `Skipping project ${project.path_with_namespace} as it is excluded.`, + ); + return false; + } + const project_branch = this.config.branch ?? project.default_branch ?? diff --git a/plugins/catalog-backend-module-gitlab/src/providers/config.test.ts b/plugins/catalog-backend-module-gitlab/src/providers/config.test.ts index 4418dba50b..28df8c88b7 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/config.test.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/config.test.ts @@ -60,6 +60,7 @@ describe('config', () => { allowInherited: false, schedule: undefined, skipForkedRepos: false, + excludeRepos: [], restrictUsersToGroup: false, }), ); @@ -99,6 +100,7 @@ describe('config', () => { allowInherited: false, schedule: undefined, skipForkedRepos: false, + excludeRepos: [], restrictUsersToGroup: false, }), ); @@ -139,11 +141,54 @@ describe('config', () => { allowInherited: false, schedule: undefined, restrictUsersToGroup: false, + excludeRepos: [], skipForkedRepos: true, }), ); }); + it('valid config with excludeRepos', () => { + const config = new ConfigReader({ + catalog: { + providers: { + gitlab: { + test: { + group: 'group', + host: 'host', + branch: 'not-master', + fallbackBranch: 'main', + entityFilename: 'custom-file.yaml', + skipForkedRepos: false, + excludeRepos: ['foo/bar', 'quz/qux'], + }, + }, + }, + }, + }); + + const result = readGitlabConfigs(config); + expect(result).toHaveLength(1); + result.forEach(r => + expect(r).toStrictEqual({ + id: 'test', + group: 'group', + branch: 'not-master', + fallbackBranch: 'main', + host: 'host', + catalogFile: 'custom-file.yaml', + projectPattern: /[\s\S]*/, + groupPattern: /[\s\S]*/, + userPattern: /[\s\S]*/, + orgEnabled: false, + allowInherited: false, + schedule: undefined, + restrictUsersToGroup: false, + skipForkedRepos: false, + excludeRepos: ['foo/bar', 'quz/qux'], + }), + ); + }); + it('valid config with schedule', () => { const config = new ConfigReader({ catalog: { @@ -181,6 +226,7 @@ describe('config', () => { allowInherited: false, skipForkedRepos: false, restrictUsersToGroup: false, + excludeRepos: [], schedule: { frequency: { minutes: 30 }, timeout: { diff --git a/plugins/catalog-backend-module-gitlab/src/providers/config.ts b/plugins/catalog-backend-module-gitlab/src/providers/config.ts index 68eba7165a..d26cba5328 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/config.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/config.ts @@ -47,6 +47,8 @@ function readGitlabConfig(id: string, config: Config): GitlabProviderConfig { config.getOptionalBoolean('allowInherited') ?? false; const skipForkedRepos: boolean = config.getOptionalBoolean('skipForkedRepos') ?? false; + const excludeRepos: string[] = + config.getOptionalStringArray('excludeRepos') ?? []; const schedule = config.has('schedule') ? readTaskScheduleDefinitionFromConfig(config.getConfig('schedule')) @@ -68,6 +70,7 @@ function readGitlabConfig(id: string, config: Config): GitlabProviderConfig { orgEnabled, allowInherited, skipForkedRepos, + excludeRepos, restrictUsersToGroup, }; } From edc977dd9647122f5d7203860ae1f68f9cfa0c04 Mon Sep 17 00:00:00 2001 From: Ben Lambert <blam@spotify.com> Date: Mon, 29 Jul 2024 13:36:06 +0200 Subject: [PATCH 473/510] Delete .changeset/yellow-clocks-fail.md Signed-off-by: Ben Lambert <blam@spotify.com> --- .changeset/yellow-clocks-fail.md | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 .changeset/yellow-clocks-fail.md diff --git a/.changeset/yellow-clocks-fail.md b/.changeset/yellow-clocks-fail.md deleted file mode 100644 index 36e2d4b804..0000000000 --- a/.changeset/yellow-clocks-fail.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -'@backstage/plugin-search-backend-module-stack-overflow-collator': patch -'@backstage/plugin-search-backend-module-elasticsearch': patch -'@backstage/plugin-search-backend-module-techdocs': patch -'@backstage/plugin-search-backend-module-catalog': patch -'@backstage/plugin-search-backend-module-explore': patch -'@backstage/plugin-search-backend-module-pg': patch -'@backstage/plugin-search-backend-node': patch -'@backstage/plugin-search-backend': patch -'@backstage/plugin-search-common': patch -'@backstage/plugin-search-react': patch -'@backstage/plugin-home-react': patch -'@backstage/plugin-search': patch -'@backstage/plugin-home': patch ---- - -Update ownership for home and search plugins From 3479c956b71d4693350e3188f3ed79ff4561ffae Mon Sep 17 00:00:00 2001 From: Ben Lambert <ben@blam.sh> Date: Mon, 29 Jul 2024 13:50:52 +0200 Subject: [PATCH 474/510] Update red-radios-promise.md Signed-off-by: Ben Lambert <ben@blam.sh> --- .changeset/red-radios-promise.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/red-radios-promise.md b/.changeset/red-radios-promise.md index 66ee1cc614..ea876c3480 100644 --- a/.changeset/red-radios-promise.md +++ b/.changeset/red-radios-promise.md @@ -2,4 +2,4 @@ '@backstage/plugin-catalog-backend-module-gitlab': patch --- -Adds new optional excludeRepos configuration option to the Gitlab catalog provider. +Adds new optional `excludeRepos` configuration option to the Gitlab catalog provider. From 3fcb1313ff60b682ca5c44909a3e102f96681581 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Wed, 24 Jul 2024 17:09:29 +0200 Subject: [PATCH 475/510] chore: implementing some other apis for testing extensions without a react tree Signed-off-by: blam <ben@blam.sh> --- packages/frontend-test-utils/package.json | 1 + .../src/app/createExtensionTester.test.tsx | 135 ++++++++++++++ .../src/app/createExtensionTester.tsx | 167 +++++++++++++++--- yarn.lock | 1 + 4 files changed, 277 insertions(+), 27 deletions(-) diff --git a/packages/frontend-test-utils/package.json b/packages/frontend-test-utils/package.json index 1d0b00132b..89a3eb10db 100644 --- a/packages/frontend-test-utils/package.json +++ b/packages/frontend-test-utils/package.json @@ -31,6 +31,7 @@ "test": "backstage-cli package test" }, "dependencies": { + "@backstage/config": "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 f59d44f6d7..889c815fc7 100644 --- a/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx +++ b/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx @@ -24,6 +24,8 @@ import { createApiExtension, createApiFactory, createExtension, + createExtensionDataRef, + createExtensionInput, createSchemaFromZod, useAnalytics, useApi, @@ -31,6 +33,10 @@ import { import { MockAnalyticsApi } from '../apis'; import { createExtensionTester } from './createExtensionTester'; +const stringDataRef = createExtensionDataRef<string>().with({ + id: 'test.string', +}); + describe('createExtensionTester', () => { const defaultDefinition = { namespace: 'test', @@ -229,4 +235,133 @@ describe('createExtensionTester', () => { ), ); }); + + it('should return the correct dataRef when called', () => { + const extension = createExtension({ + namespace: 'test', + attachTo: { id: 'ignored', input: 'ignored' }, + output: { text: stringDataRef }, + factory: () => ({ text: 'test-text' }), + }); + + const tester = createExtensionTester(extension); + + expect(tester.data(stringDataRef)).toBe('test-text'); + }); + + it('should throw an error if trying to access an instance not provided to the tester', () => { + const extension = createExtension({ + namespace: 'test', + name: 'e1', + attachTo: { id: 'ignored', input: 'ignored' }, + output: { text: stringDataRef }, + factory: () => ({ text: 'test-text' }), + }); + + const extension2 = createExtension({ + namespace: 'test', + name: 'e2', + attachTo: { id: 'ignored', input: 'ignored' }, + output: { text: stringDataRef }, + factory: () => ({ text: 'test-text' }), + }); + + const tester = createExtensionTester(extension); + + expect(() => tester.query(extension2)).toThrow( + "Extension with ID 'test/e2' not found, please make sure it's added to the tester", + ); + }); + + it('should throw an error if trying to access an instance which is not part of the tree', () => { + const extension = createExtension({ + namespace: 'test', + name: 'e1', + attachTo: { id: 'ignored', input: 'ignored' }, + output: { text: stringDataRef }, + factory: () => ({ text: 'test-text' }), + }); + + const extension2 = createExtension({ + namespace: 'test', + name: 'e2', + attachTo: { id: 'ignored', input: 'ignored' }, + output: { text: stringDataRef }, + factory: () => ({ text: 'test-text' }), + }); + + const tester = createExtensionTester(extension).add(extension2); + + expect(() => tester.query(extension2)).toThrow( + "Extension with ID 'test/e2' has not been instantiated, because it is not part of the test subject's extension tree", + ); + }); + + // TODO: this should be implemented + // eslint-disable-next-line jest/no-disabled-tests + it.skip('should allow querying an extension and getting outputs', () => { + const extension = createExtension({ + namespace: 'test', + name: 'e1', + attachTo: { id: 'ignored', input: 'ignored' }, + output: { text: stringDataRef }, + inputs: { + input: createExtensionInput( + { + output: stringDataRef, + }, + { singleton: true }, + ), + }, + factory: ({ inputs }) => ({ + text: `nest-${inputs.input.output.output}`, + }), + }); + + const extension2 = createExtension({ + namespace: 'test', + name: 'e2', + attachTo: { id: 'test/e1', input: 'blob' }, + output: { text: stringDataRef }, + factory: () => ({ text: 'test-text' }), + }); + + const tester = createExtensionTester(extension).add(extension2); + + expect(tester.query(extension).data(stringDataRef)).toBe('nest-test-text'); + expect(tester.query(extension2).data(stringDataRef)).toBe('test-text'); + // @ts-expect-error + expect(tester.query(extension).input('input').data(stringDataRef)).toBe( + 'nest-test-text', + ); + }); + + // TODO: this should be implemented + // eslint-disable-next-line jest/no-disabled-tests + it.skip('should allow defining inputs to extensions without a corresponding extension definition', () => { + const extension = createExtension({ + namespace: 'test', + name: 'e1', + attachTo: { id: 'ignored', input: 'ignored' }, + output: { text: stringDataRef }, + inputs: { + input: createExtensionInput( + { + output: stringDataRef, + }, + { singleton: true }, + ), + }, + factory: ({ inputs }) => ({ + text: `nest-${inputs.input.output.output}`, + }), + }); + + const tester = createExtensionTester(extension, { + // @ts-expect-error + inputs: { input: 'test-text' }, + }); + + expect(tester.query(extension).data(stringDataRef)).toBe('nest-test-text'); + }); }); diff --git a/packages/frontend-test-utils/src/app/createExtensionTester.tsx b/packages/frontend-test-utils/src/app/createExtensionTester.tsx index 81b74c9fce..1d41958a09 100644 --- a/packages/frontend-test-utils/src/app/createExtensionTester.tsx +++ b/packages/frontend-test-utils/src/app/createExtensionTester.tsx @@ -20,6 +20,10 @@ import { RenderResult, render } from '@testing-library/react'; import { createSpecializedApp } from '@backstage/frontend-app-api'; import { ExtensionDataValue, + AppNode, + AppTree, + Extension, + ExtensionDataRef, ExtensionDefinition, IconComponent, RouteRef, @@ -31,12 +35,20 @@ import { createRouterExtension, useRouteRef, } from '@backstage/frontend-plugin-api'; -import { MockConfigApi } from '@backstage/test-utils'; +import { Config, ConfigReader } from '@backstage/config'; 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 { toInternalExtensionDefinition } from '../../../frontend-plugin-api/src/wiring/createExtension'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { resolveAppTree } from '../../../frontend-app-api/src/tree/resolveAppTree'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { resolveAppNodeSpecs } from '../../../frontend-app-api/src/tree/resolveAppNodeSpecs'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { instantiateAppNodeTree } from '../../../frontend-app-api/src/tree/instantiateAppNodeTree'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { readAppExtensionsConfig } from '../../../frontend-app-api/src/tree/readAppExtensionsConfig'; const NavItem = (props: { routeRef: RouteRef<undefined>; @@ -86,6 +98,35 @@ const TestAppNavExtension = createExtension({ }, }); +/** @public */ +export class ExtensionQuery { + #node: AppNode; + + constructor(node: AppNode) { + this.#node = node; + } + + get node() { + return this.#node; + } + + get instance() { + const instance = this.#node.instance; + if (!instance) { + throw new Error( + `Unable to access the instance of extension with ID '${ + this.#node.spec.id + }'`, + ); + } + return instance; + } + + data<T>(ref: ExtensionDataRef<T>): T | undefined { + return this.instance.getData(ref); + } +} + /** @public */ export class ExtensionTester { /** @internal */ @@ -139,8 +180,11 @@ export class ExtensionTester { return tester; } + #tree?: AppTree; + readonly #extensions = new Array<{ id: string; + extension: Extension<any>; definition: ExtensionDefinition<any>; config?: JsonValue; }>(); @@ -149,6 +193,12 @@ export class ExtensionTester { extension: ExtensionDefinition<TConfig, TConfigInput>, options?: { config?: TConfigInput }, ): ExtensionTester { + if (this.#tree) { + throw new Error( + 'Cannot add more extensions accessing the extension tree', + ); + } + const { name, namespace } = extension; const definition = { @@ -157,10 +207,11 @@ export class ExtensionTester { name: !namespace && !name ? 'test' : name, }; - const { id } = resolveExtensionDefinition(definition); + const resolvedExtension = resolveExtensionDefinition(definition); this.#extensions.push({ - id, + id: resolvedExtension.id, + extension: resolvedExtension, definition, config: options?.config as JsonValue, }); @@ -168,38 +219,42 @@ export class ExtensionTester { return this; } + data<T>(ref: ExtensionDataRef<T>): T | undefined { + const tree = this.#resolveTree(); + + return new ExtensionQuery(tree.root).data(ref); + } + + query(id: string | ExtensionDefinition<any, any>): ExtensionQuery { + const tree = this.#resolveTree(); + + const actualId = + typeof id === 'string' ? id : resolveExtensionDefinition(id).id; + + const node = tree.nodes.get(actualId); + + if (!node) { + throw new Error( + `Extension with ID '${actualId}' not found, please make sure it's added to the tester.`, + ); + } else if (!node.instance) { + throw new Error( + `Extension with ID '${actualId}' has not been instantiated, because it is not part of the test subject's extension tree.`, + ); + } + return new ExtensionQuery(node); + } + render(options?: { config?: JsonObject }): RenderResult { const { config = {} } = options ?? {}; - const [subject, ...rest] = this.#extensions; + const [subject] = 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({ @@ -215,11 +270,69 @@ export class ExtensionTester { ], }), ], - config: new MockConfigApi(finalConfig), + config: this.#getConfig(config), }); return render(app.createRoot()); } + + #resolveTree() { + if (this.#tree) { + return this.#tree; + } + + const [subject] = this.#extensions; + if (!subject) { + throw new Error( + 'No subject found. At least one extension should be added to the tester.', + ); + } + + const tree = resolveAppTree( + subject.id, + resolveAppNodeSpecs({ + features: [], + builtinExtensions: this.#extensions.map(_ => _.extension), + parameters: readAppExtensionsConfig(this.#getConfig()), + }), + ); + + instantiateAppNodeTree(tree.root); + + this.#tree = tree; + + return tree; + } + + #getConfig(additionalConfig?: JsonObject): Config { + const [subject, ...rest] = this.#extensions; + + const extensionsConfig: JsonArray = [ + ...rest.map(extension => ({ + [extension.id]: { + config: extension.config, + }, + })), + { + [subject.id]: { + config: subject.config, + disabled: false, + }, + }, + ]; + + return ConfigReader.fromConfigs([ + { context: 'render-config', data: additionalConfig ?? {} }, + { + context: 'test', + data: { + app: { + extensions: extensionsConfig, + }, + }, + }, + ]); + } } /** @public */ diff --git a/yarn.lock b/yarn.lock index 155c0eeb9e..135cd07035 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4546,6 +4546,7 @@ __metadata: resolution: "@backstage/frontend-test-utils@workspace:packages/frontend-test-utils" dependencies: "@backstage/cli": "workspace:^" + "@backstage/config": "workspace:^" "@backstage/frontend-app-api": "workspace:^" "@backstage/frontend-plugin-api": "workspace:^" "@backstage/test-utils": "workspace:^" From 820944913c16ea1fc3c0b0c4d027c8d56126ab2e Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Wed, 24 Jul 2024 17:10:24 +0200 Subject: [PATCH 476/510] chore: added changeset Signed-off-by: blam <ben@blam.sh> --- .changeset/clever-pans-brake.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/clever-pans-brake.md diff --git a/.changeset/clever-pans-brake.md b/.changeset/clever-pans-brake.md new file mode 100644 index 0000000000..1f49c7a842 --- /dev/null +++ b/.changeset/clever-pans-brake.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-test-utils': patch +--- + +Added new APIs for testing extensions From 85ef461b0c53e5eb28c01c6ce7fdaeffc5edb7b0 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Mon, 29 Jul 2024 11:46:28 +0200 Subject: [PATCH 477/510] chore: fixing api-reports Signed-off-by: blam <ben@blam.sh> --- packages/frontend-test-utils/api-report.md | 18 ++++++++++++++++++ packages/frontend-test-utils/src/app/index.ts | 1 + 2 files changed, 19 insertions(+) diff --git a/packages/frontend-test-utils/api-report.md b/packages/frontend-test-utils/api-report.md index 3b368394ca..3aa9069219 100644 --- a/packages/frontend-test-utils/api-report.md +++ b/packages/frontend-test-utils/api-report.md @@ -7,7 +7,10 @@ import { AnalyticsApi } from '@backstage/frontend-plugin-api'; import { AnalyticsEvent } from '@backstage/frontend-plugin-api'; +import { AppNode } from '@backstage/frontend-plugin-api'; +import { AppNodeInstance } from '@backstage/frontend-plugin-api'; import { ErrorWithContext } from '@backstage/test-utils'; +import { ExtensionDataRef } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { JsonObject } from '@backstage/types'; import { MockConfigApi } from '@backstage/test-utils'; @@ -36,6 +39,17 @@ export function createExtensionTester<TConfig>( export { ErrorWithContext }; +// @public (undocumented) +export class ExtensionQuery { + constructor(node: AppNode); + // (undocumented) + data<T>(ref: ExtensionDataRef<T>): T | undefined; + // (undocumented) + get instance(): AppNodeInstance; + // (undocumented) + get node(): AppNode; +} + // @public (undocumented) export class ExtensionTester { // (undocumented) @@ -46,6 +60,10 @@ export class ExtensionTester { }, ): ExtensionTester; // (undocumented) + data<T>(ref: ExtensionDataRef<T>): T | undefined; + // (undocumented) + query(id: string | ExtensionDefinition<any, any>): ExtensionQuery; + // (undocumented) render(options?: { config?: JsonObject }): RenderResult; } diff --git a/packages/frontend-test-utils/src/app/index.ts b/packages/frontend-test-utils/src/app/index.ts index 2351561022..6c6ef26e4c 100644 --- a/packages/frontend-test-utils/src/app/index.ts +++ b/packages/frontend-test-utils/src/app/index.ts @@ -17,6 +17,7 @@ export { createExtensionTester, type ExtensionTester, + type ExtensionQuery, } from './createExtensionTester'; export { renderInTestApp, type TestAppOptions } from './renderInTestApp'; From 5c6554ef58e6f62d9eccac90468217e7ac843084 Mon Sep 17 00:00:00 2001 From: Stephen Glass <stephen@stephen.glass> Date: Mon, 29 Jul 2024 10:51:59 -0400 Subject: [PATCH 478/510] update changeset spelling Signed-off-by: Stephen Glass <stephen@stephen.glass> --- .changeset/spicy-lies-listen.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/spicy-lies-listen.md b/.changeset/spicy-lies-listen.md index b293345e3b..6bc5e95846 100644 --- a/.changeset/spicy-lies-listen.md +++ b/.changeset/spicy-lies-listen.md @@ -2,4 +2,4 @@ '@backstage/plugin-scaffolder': patch --- -Fix helper text margin for scaffolder EntityNamePicker and EntityTagsPicker when using outlined textfield +Fix helper text margin for scaffolder EntityNamePicker and EntityTagsPicker when using outlined text field From 89370df3cccf535aa3caa9edde0be4317c1e0c79 Mon Sep 17 00:00:00 2001 From: Andre Wanlin <awanlin@spotify.com> Date: Mon, 29 Jul 2024 15:58:38 -0500 Subject: [PATCH 479/510] Added common auth provider sign-in errors Signed-off-by: Andre Wanlin <awanlin@spotify.com> --- ...ider-not-configured-to-support-sign-in.png | Bin 0 -> 15787 bytes .../auth/github-unable-to-reolve-identity.png | Bin 0 -> 14521 bytes docs/auth/identity-resolver.md | 19 ++++++++++++++++++ 3 files changed, 19 insertions(+) create mode 100644 docs/assets/auth/github-provider-not-configured-to-support-sign-in.png create mode 100644 docs/assets/auth/github-unable-to-reolve-identity.png diff --git a/docs/assets/auth/github-provider-not-configured-to-support-sign-in.png b/docs/assets/auth/github-provider-not-configured-to-support-sign-in.png new file mode 100644 index 0000000000000000000000000000000000000000..1bbd94ecc39c74ce1cee6d18304ad2f511ce7c7a GIT binary patch literal 15787 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 literal 0 HcmV?d00001 diff --git a/docs/assets/auth/github-unable-to-reolve-identity.png b/docs/assets/auth/github-unable-to-reolve-identity.png new file mode 100644 index 0000000000000000000000000000000000000000..622fd75a4a80ce516c58dfc429d453c5157d78f4 GIT binary patch literal 14521 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 literal 0 HcmV?d00001 diff --git a/docs/auth/identity-resolver.md b/docs/auth/identity-resolver.md index 5efb592270..6eb52e5708 100644 --- a/docs/auth/identity-resolver.md +++ b/docs/auth/identity-resolver.md @@ -403,3 +403,22 @@ const customAuth = createBackendModule({ ``` Remember to `backend.add` the created module just like above. + +## Common Sign-In Resolver Errors + +There are two common Sign-In Resolver errors you might run into. + +First is: "The 'Auth Provider Name' provider is not configured to support sign-in". Here is what this looks like for the GitHub Auth provider: + +![The GitHub provider is not configured to support sign-in](../assets/auth/github-provider-not-configured-to-support-sign-in.png) + +This error can be caused by the following: + +- The `signIn.resolvers` have not be added to your Auth Provider configuration. Adding this will resolve the error. +- There is a syntax error in your Auth Provider configuration. Running `yarn backstage-cli config:check --strict` will help identify the syntax error. + +The second common error is: "Failed to sign-in, unable to resolve user identity". Here is what this looks like for the GitHub Auth provider: + +![Failed to sign-in, unable to resolve user identity](../assets/auth/github-unable-to-reolve-identity.png) + +This error is caused by the Sign-In Resolver you configured being unable to find a matching User in the Catalog. To fix this you need to import User, and Group, data from some source of truth for this data at your Organization. To do this you can use one of the existing Org Data providers like the ones for [Entra ID (Azure AD/MS Graph)](../integrations/azure/org.md), [GitHub](../integrations/github/org.md), [GitLab](../integrations/gitlab/org.md), etc. or if none of those fit your needs you can create a [Custom Entity Provider](../features/software-catalog/external-integrations.md#custom-entity-providers). From b54f0544b174bc817f3741c254c05278287203a6 Mon Sep 17 00:00:00 2001 From: Kevin L <kevin.lecouvey@gmail.com> Date: Tue, 30 Jul 2024 06:13:26 -0400 Subject: [PATCH 480/510] Updated the Gerrit integration docs Signed-off-by: Kevin L <kevin.lecouvey@gmail.com> --- docs/integrations/gerrit/discovery--old.md | 73 ++++++++++++++++++++++ docs/integrations/gerrit/discovery.md | 22 +++---- 2 files changed, 83 insertions(+), 12 deletions(-) create mode 100644 docs/integrations/gerrit/discovery--old.md diff --git a/docs/integrations/gerrit/discovery--old.md b/docs/integrations/gerrit/discovery--old.md new file mode 100644 index 0000000000..250de80bdf --- /dev/null +++ b/docs/integrations/gerrit/discovery--old.md @@ -0,0 +1,73 @@ +--- +id: discovery--old +title: Gerrit Discovery +sidebar_label: Discovery +# prettier-ignore +description: Automatically discovering catalog entities from Gerrit repositories +--- + +:::info +This documentation is written for the old backend which has been replaced by [the new backend system](../../backend-system/index.md), being the default since Backstage [version 1.24](../../releases/v1.24.0.md). If have migrated to the new backend system, you may want to read [its own article](./discovery.md) instead. Otherwise, [consider migrating](../../backend-system/building-backends/08-migrating.md)! +::: + +The Gerrit integration has a special entity provider for discovering catalog entities +from Gerrit repositories. The provider uses the "List Projects" API in Gerrit to get +a list of repositories and will automatically ingest all `catalog-info.yaml` files +stored in the root of the matching projects. + +## Installation + +As this provider is not one of the default providers, you will first need to install +the Gerrit provider plugin: + +```bash title="From your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-gerrit +``` + +Then add the plugin to the plugin catalog `packages/backend/src/plugins/catalog.ts`: + +```ts +/* packages/backend/src/plugins/catalog.ts */ +import { GerritEntityProvider } from '@backstage/plugin-catalog-backend-module-gerrit'; +const builder = await CatalogBuilder.create(env); +/** ... other processors and/or providers ... */ +builder.addEntityProvider( + GerritEntityProvider.fromConfig(env.config, { + logger: env.logger, + scheduler: env.scheduler, + }), +); +``` + +## Configuration + +To use the discovery processor, you'll need a Gerrit integration +[set up](locations.md). Then you can add any number of providers. + +```yaml +# app-config.yaml +catalog: + providers: + gerrit: + yourProviderId: # identifies your dataset / provider independent of config changes + host: gerrit-your-company.com + branch: master # Optional + query: 'state=ACTIVE&prefix=webapps' + schedule: + # supports cron, ISO duration, "human duration" as used in code + frequency: { minutes: 30 } + # supports ISO duration, "human duration" as used in code + timeout: { minutes: 3 } + backend: + host: gerrit-your-company.com + branch: master # Optional + query: 'state=ACTIVE&prefix=backend' +``` + +The provider configuration is composed of three parts: + +- **`host`**: the host of the Gerrit integration to use. +- **`branch`** _(optional)_: the branch where we will look for catalog entities (defaults to "master"). +- **`query`**: this string is directly used as the argument to the "List Project" API. + Typically, you will want to have some filter here to exclude projects that will + never contain any catalog files. diff --git a/docs/integrations/gerrit/discovery.md b/docs/integrations/gerrit/discovery.md index 96dfbd47fb..eca0417871 100644 --- a/docs/integrations/gerrit/discovery.md +++ b/docs/integrations/gerrit/discovery.md @@ -6,6 +6,10 @@ sidebar_label: Discovery description: Automatically discovering catalog entities from Gerrit repositories --- +:::info +This documentation is written for [the new backend system](../../backend-system/index.md) which is the default since Backstage [version 1.24](../../releases/v1.24.0.md). If you are still on the old backend system, you may want to read [its own article](./discovery--old.md) instead, and [consider migrating](../../backend-system/building-backends/08-migrating.md)! +::: + The Gerrit integration has a special entity provider for discovering catalog entities from Gerrit repositories. The provider uses the "List Projects" API in Gerrit to get a list of repositories and will automatically ingest all `catalog-info.yaml` files @@ -20,19 +24,13 @@ the Gerrit provider plugin: yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-gerrit ``` -Then add the plugin to the plugin catalog `packages/backend/src/plugins/catalog.ts`: +Then update your backend by adding the following line: -```ts -/* packages/backend/src/plugins/catalog.ts */ -import { GerritEntityProvider } from '@backstage/plugin-catalog-backend-module-gerrit'; -const builder = await CatalogBuilder.create(env); -/** ... other processors and/or providers ... */ -builder.addEntityProvider( - GerritEntityProvider.fromConfig(env.config, { - logger: env.logger, - scheduler: env.scheduler, - }), -); +```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 */ ``` ## Configuration From 35e49534dcc817e567354b77afc02bea8cb8ff21 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 10:55:20 +0000 Subject: [PATCH 481/510] Update JamesIves/github-pages-deploy-action action to v4.6.3 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/deploy_microsite.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy_microsite.yml b/.github/workflows/deploy_microsite.yml index be46bcfaa0..eafa4a8fcd 100644 --- a/.github/workflows/deploy_microsite.yml +++ b/.github/workflows/deploy_microsite.yml @@ -66,7 +66,7 @@ jobs: run: ls microsite/build && ls microsite/build/storybook - name: Deploy both microsite and storybook to gh-pages - uses: JamesIves/github-pages-deploy-action@5c6e9e9f3672ce8fd37b9856193d2a537941e66c # v4.6.1 + uses: JamesIves/github-pages-deploy-action@94f3c658273cf92fb48ef99e5fbc02bd2dc642b2 # v4.6.3 with: branch: gh-pages folder: microsite/build From 33b9e24dddb5d37866045f3364fcdb86dbf6a375 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 11:07:41 +0000 Subject: [PATCH 482/510] Update actions/upload-artifact action to v4.3.4 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pr-review-comment-trigger.yaml | 2 +- .github/workflows/scorecard.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr-review-comment-trigger.yaml b/.github/workflows/pr-review-comment-trigger.yaml index ccf02d5aee..d6f36da686 100644 --- a/.github/workflows/pr-review-comment-trigger.yaml +++ b/.github/workflows/pr-review-comment-trigger.yaml @@ -30,7 +30,7 @@ jobs: run: | mkdir -p ./pr echo $PR_NUMBER > ./pr/pr_number - - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + - uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 with: name: pr_number-${{ github.event.pull_request.number }} path: pr/ diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 354a76760b..4ef8cc7181 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -58,7 +58,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: 'Upload artifact' - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 with: name: SARIF file path: results.sarif From 93fc1a00ab602eaa59f3fe78e3624c582784f21b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 12:08:38 +0000 Subject: [PATCH 483/510] Update dependency @backstage-community/plugin-explore-common to ^0.0.4 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .changeset/renovate-f04beb1.md | 5 +++++ plugins/search-backend-module-explore/package.json | 2 +- yarn.lock | 10 +++++----- 3 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 .changeset/renovate-f04beb1.md diff --git a/.changeset/renovate-f04beb1.md b/.changeset/renovate-f04beb1.md new file mode 100644 index 0000000000..12d24ccc53 --- /dev/null +++ b/.changeset/renovate-f04beb1.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search-backend-module-explore': patch +--- + +Updated dependency `@backstage-community/plugin-explore-common` to `^0.0.4`. diff --git a/plugins/search-backend-module-explore/package.json b/plugins/search-backend-module-explore/package.json index 8d531a6a37..a4411d558c 100644 --- a/plugins/search-backend-module-explore/package.json +++ b/plugins/search-backend-module-explore/package.json @@ -48,7 +48,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage-community/plugin-explore-common": "^0.0.3", + "@backstage-community/plugin-explore-common": "^0.0.4", "@backstage/backend-common": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/backend-tasks": "workspace:^", diff --git a/yarn.lock b/yarn.lock index abced626ec..13c930cc5a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3384,10 +3384,10 @@ __metadata: languageName: node linkType: hard -"@backstage-community/plugin-explore-common@npm:^0.0.3": - version: 0.0.3 - resolution: "@backstage-community/plugin-explore-common@npm:0.0.3" - checksum: 54b81496122c11bd16cbb71c4fcc92e6bf16b5e4f580fc8043dbea35955447d67b463a40065e629ed81ef3aeeb36d1f41d445b7fa4d8ab7e0036a296b361e398 +"@backstage-community/plugin-explore-common@npm:^0.0.4": + version: 0.0.4 + resolution: "@backstage-community/plugin-explore-common@npm:0.0.4" + checksum: 0c27253dd79dcb56236d382f7591e20eb87f374878b091a690b3fede23ff652aefa3b074a58bd5b51462cc44faab12a97ee82443dcc6106f121212417b9c4cf9 languageName: node linkType: hard @@ -7398,7 +7398,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-search-backend-module-explore@workspace:plugins/search-backend-module-explore" dependencies: - "@backstage-community/plugin-explore-common": ^0.0.3 + "@backstage-community/plugin-explore-common": ^0.0.4 "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-tasks": "workspace:^" From dfcc2c84f18f8aebe0a4571b77d43f3afa7966ac Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 12:21:30 +0000 Subject: [PATCH 484/510] Update dependency @backstage-community/plugin-puppetdb to v0.1.19 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 abced626ec..9dcb29721e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3392,14 +3392,14 @@ __metadata: linkType: hard "@backstage-community/plugin-puppetdb@npm:^0.1.18": - version: 0.1.18 - resolution: "@backstage-community/plugin-puppetdb@npm:0.1.18" + version: 0.1.19 + resolution: "@backstage-community/plugin-puppetdb@npm:0.1.19" dependencies: - "@backstage/catalog-model": ^1.4.5 - "@backstage/core-components": ^0.14.4 - "@backstage/core-plugin-api": ^1.9.2 + "@backstage/catalog-model": ^1.5.0 + "@backstage/core-components": ^0.14.9 + "@backstage/core-plugin-api": ^1.9.3 "@backstage/errors": ^1.2.4 - "@backstage/plugin-catalog-react": ^1.11.3 + "@backstage/plugin-catalog-react": ^1.12.2 "@material-ui/core": ^4.12.2 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react-use: ^17.2.4 @@ -3407,7 +3407,7 @@ __metadata: 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 - checksum: d0e4fe3f818aa05c527d773d558291b97f3a4fee1b1a765e0e6f5a2f36ca1897e3933e92abdeffeb8b33701c21314eb3565900ff78624fe1d5eff3ee2781cfff + checksum: abe5e3b5b9772b5cdc17074f58f38bdbf81516afe7b9241e06844729608ec2a56899437a7cf82d4c8f3608038c15217bd6ea971f41dbce2934e7b05986bfcc10 languageName: node linkType: hard @@ -3852,7 +3852,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/catalog-model@^1.4.3, @backstage/catalog-model@^1.4.5, @backstage/catalog-model@^1.5.0, @backstage/catalog-model@workspace:^, @backstage/catalog-model@workspace:packages/catalog-model": +"@backstage/catalog-model@^1.4.3, @backstage/catalog-model@^1.5.0, @backstage/catalog-model@workspace:^, @backstage/catalog-model@workspace:packages/catalog-model": version: 0.0.0-use.local resolution: "@backstage/catalog-model@workspace:packages/catalog-model" dependencies: @@ -5829,7 +5829,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-react@npm:^1.11.3, @backstage/plugin-catalog-react@npm:^1.9.3": +"@backstage/plugin-catalog-react@npm:^1.12.2, @backstage/plugin-catalog-react@npm:^1.9.3": version: 1.12.2 resolution: "@backstage/plugin-catalog-react@npm:1.12.2" dependencies: From 58bbb3edca3a621dbfc6b1592238e193dfcc6133 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 12:26:11 +0000 Subject: [PATCH 485/510] Version Packages (next) --- .changeset/pre.json | 31 +- docs/releases/v1.30.0-next.1-changelog.md | 4063 +++++++++++++++++ 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 | 43 + packages/app-next/package.json | 2 +- packages/app/CHANGELOG.md | 41 + packages/app/package.json | 2 +- packages/backend-app-api/CHANGELOG.md | 17 + packages/backend-app-api/package.json | 2 +- packages/backend-common/CHANGELOG.md | 16 + packages/backend-common/package.json | 2 +- packages/backend-defaults/CHANGELOG.md | 20 + packages/backend-defaults/package.json | 2 +- .../CHANGELOG.md | 26 + .../package.json | 2 +- packages/backend-legacy/CHANGELOG.md | 42 + packages/backend-legacy/package.json | 2 +- packages/backend-openapi-utils/CHANGELOG.md | 8 + packages/backend-openapi-utils/package.json | 2 +- packages/backend-plugin-api/CHANGELOG.md | 13 + packages/backend-plugin-api/package.json | 2 +- packages/backend-tasks/CHANGELOG.md | 11 + packages/backend-tasks/package.json | 2 +- packages/backend-test-utils/CHANGELOG.md | 14 + packages/backend-test-utils/package.json | 2 +- packages/backend/CHANGELOG.md | 37 + packages/backend/package.json | 2 +- packages/cli/CHANGELOG.md | 17 + packages/cli/package.json | 2 +- packages/config-loader/CHANGELOG.md | 15 + packages/config-loader/package.json | 2 +- packages/core-app-api/package.json | 2 +- packages/core-compat-api/CHANGELOG.md | 10 + packages/core-compat-api/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 | 17 + packages/frontend-app-api/package.json | 2 +- packages/frontend-plugin-api/CHANGELOG.md | 66 + 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 | 12 + packages/repo-tools/package.json | 2 +- .../techdocs-cli-embedded-app/CHANGELOG.md | 19 + .../techdocs-cli-embedded-app/package.json | 2 +- packages/techdocs-cli/CHANGELOG.md | 11 + packages/techdocs-cli/package.json | 2 +- packages/test-utils/CHANGELOG.md | 13 + packages/test-utils/package.json | 2 +- plugins/api-docs/CHANGELOG.md | 15 + plugins/api-docs/package.json | 2 +- plugins/app-backend/CHANGELOG.md | 14 + plugins/app-backend/package.json | 2 +- plugins/app-node/CHANGELOG.md | 8 + plugins/app-node/package.json | 2 +- plugins/app-visualizer/CHANGELOG.md | 9 + plugins/app-visualizer/package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- plugins/auth-backend/CHANGELOG.md | 30 + plugins/auth-backend/package.json | 2 +- plugins/auth-node/CHANGELOG.md | 13 + plugins/auth-node/package.json | 2 +- .../catalog-backend-module-aws/CHANGELOG.md | 17 + .../catalog-backend-module-aws/package.json | 2 +- .../catalog-backend-module-azure/CHANGELOG.md | 13 + .../catalog-backend-module-azure/package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 17 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../catalog-backend-module-gcp/CHANGELOG.md | 13 + .../catalog-backend-module-gcp/package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 17 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 16 + .../package.json | 2 +- .../CHANGELOG.md | 16 + .../package.json | 2 +- .../catalog-backend-module-ldap/CHANGELOG.md | 14 + .../catalog-backend-module-ldap/package.json | 2 +- .../catalog-backend-module-logs/CHANGELOG.md | 9 + .../catalog-backend-module-logs/package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 15 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- plugins/catalog-backend/CHANGELOG.md | 23 + plugins/catalog-backend/package.json | 2 +- plugins/catalog-common/CHANGELOG.md | 9 + plugins/catalog-common/package.json | 2 +- plugins/catalog-graph/CHANGELOG.md | 14 + plugins/catalog-graph/package.json | 2 +- plugins/catalog-import/CHANGELOG.md | 18 + plugins/catalog-import/package.json | 2 +- plugins/catalog-node/CHANGELOG.md | 14 + plugins/catalog-node/package.json | 2 +- plugins/catalog-react/CHANGELOG.md | 20 + plugins/catalog-react/package.json | 2 +- .../CHANGELOG.md | 7 + .../package.json | 2 +- plugins/catalog/CHANGELOG.md | 22 + plugins/catalog/package.json | 2 +- plugins/devtools-backend/CHANGELOG.md | 16 + plugins/devtools-backend/package.json | 2 +- plugins/devtools-common/CHANGELOG.md | 8 + plugins/devtools-common/package.json | 2 +- plugins/devtools/CHANGELOG.md | 13 + plugins/devtools/package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../events-backend-module-azure/CHANGELOG.md | 8 + .../events-backend-module-azure/package.json | 2 +- .../CHANGELOG.md | 8 + .../package.json | 2 +- .../events-backend-module-gerrit/CHANGELOG.md | 8 + .../events-backend-module-gerrit/package.json | 2 +- .../events-backend-module-github/CHANGELOG.md | 9 + .../events-backend-module-github/package.json | 2 +- .../events-backend-module-gitlab/CHANGELOG.md | 9 + .../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 | 10 + plugins/events-backend/package.json | 2 +- plugins/events-node/CHANGELOG.md | 7 + plugins/events-node/package.json | 2 +- .../example-todo-list-backend/CHANGELOG.md | 10 + .../example-todo-list-backend/package.json | 2 +- plugins/example-todo-list-common/CHANGELOG.md | 7 + plugins/example-todo-list-common/package.json | 2 +- plugins/home/CHANGELOG.md | 17 + plugins/home/package.json | 2 +- plugins/kubernetes-backend/CHANGELOG.md | 20 + plugins/kubernetes-backend/package.json | 2 +- plugins/kubernetes-cluster/CHANGELOG.md | 12 + plugins/kubernetes-cluster/package.json | 2 +- plugins/kubernetes-common/CHANGELOG.md | 9 + plugins/kubernetes-common/package.json | 2 +- plugins/kubernetes-node/CHANGELOG.md | 10 + plugins/kubernetes-node/package.json | 2 +- plugins/kubernetes-react/CHANGELOG.md | 12 + plugins/kubernetes-react/package.json | 2 +- plugins/kubernetes/CHANGELOG.md | 15 + plugins/kubernetes/package.json | 2 +- .../CHANGELOG.md | 60 + .../package.json | 2 +- plugins/notifications-backend/CHANGELOG.md | 17 + plugins/notifications-backend/package.json | 2 +- plugins/notifications-node/CHANGELOG.md | 12 + plugins/notifications-node/package.json | 2 +- plugins/org-react/CHANGELOG.md | 11 + plugins/org-react/package.json | 2 +- plugins/org/CHANGELOG.md | 13 + plugins/org/package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- plugins/permission-backend/CHANGELOG.md | 13 + plugins/permission-backend/package.json | 2 +- plugins/permission-common/CHANGELOG.md | 10 + plugins/permission-common/package.json | 2 +- plugins/permission-node/CHANGELOG.md | 13 + plugins/permission-node/package.json | 2 +- plugins/permission-react/CHANGELOG.md | 9 + plugins/permission-react/package.json | 2 +- plugins/proxy-backend/CHANGELOG.md | 10 + plugins/proxy-backend/package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- plugins/scaffolder-backend/CHANGELOG.md | 32 + plugins/scaffolder-backend/package.json | 2 +- plugins/scaffolder-common/CHANGELOG.md | 9 + plugins/scaffolder-common/package.json | 2 +- .../scaffolder-node-test-utils/CHANGELOG.md | 10 + .../scaffolder-node-test-utils/package.json | 2 +- plugins/scaffolder-node/CHANGELOG.md | 13 + plugins/scaffolder-node/package.json | 2 +- plugins/scaffolder-react/CHANGELOG.md | 16 + plugins/scaffolder-react/package.json | 2 +- plugins/scaffolder/CHANGELOG.md | 22 + plugins/scaffolder/package.json | 2 +- .../CHANGELOG.md | 18 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- plugins/search-backend-module-pg/CHANGELOG.md | 11 + plugins/search-backend-module-pg/package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 18 + .../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-common/CHANGELOG.md | 8 + plugins/search-common/package.json | 2 +- plugins/search-react/CHANGELOG.md | 14 + plugins/search-react/package.json | 2 +- plugins/search/CHANGELOG.md | 17 + plugins/search/package.json | 2 +- plugins/signals-backend/CHANGELOG.md | 13 + plugins/signals-backend/package.json | 2 +- plugins/signals-node/CHANGELOG.md | 12 + plugins/signals-node/package.json | 2 +- .../techdocs-addons-test-utils/CHANGELOG.md | 15 + .../techdocs-addons-test-utils/package.json | 2 +- plugins/techdocs-backend/CHANGELOG.md | 19 + plugins/techdocs-backend/package.json | 2 +- plugins/techdocs-common/CHANGELOG.md | 7 + plugins/techdocs-common/package.json | 2 +- plugins/techdocs-node/CHANGELOG.md | 17 + plugins/techdocs-node/package.json | 2 +- plugins/techdocs/CHANGELOG.md | 24 + plugins/techdocs/package.json | 2 +- plugins/user-settings-backend/CHANGELOG.md | 14 + plugins/user-settings-backend/package.json | 2 +- plugins/user-settings/CHANGELOG.md | 18 + plugins/user-settings/package.json | 2 +- yarn.lock | 58 +- 307 files changed, 6459 insertions(+), 158 deletions(-) create mode 100644 docs/releases/v1.30.0-next.1-changelog.md create mode 100644 plugins/techdocs-common/CHANGELOG.md diff --git a/.changeset/pre.json b/.changeset/pre.json index 7da5b582e1..92a9550739 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -186,10 +186,13 @@ "@backstage/plugin-techdocs-react": "1.2.6", "@backstage/plugin-user-settings": "0.8.9", "@backstage/plugin-user-settings-backend": "0.2.21", - "@backstage/plugin-user-settings-common": "0.0.1" + "@backstage/plugin-user-settings-common": "0.0.1", + "@backstage/plugin-techdocs-common": "0.0.0" }, "changesets": [ + "big-eagles-grab", "blue-pumas-cheer", + "breezy-jeans-tie", "bright-trainers-brake", "chilly-trains-sleep", "cool-insects-remember", @@ -197,12 +200,16 @@ "dry-squids-tap", "dull-ghosts-double", "early-trees-dance", + "eighty-emus-leave", "eighty-mirrors-flow", + "few-wasps-hug", "flat-plums-grow", "forty-ties-agree", "forty-ties-disagree", "friendly-feet-refuse", "gentle-dryers-smile", + "good-steaks-report", + "green-planets-reflect", "grumpy-owls-suffer", "heavy-numbers-love", "hip-hairs-exist", @@ -210,33 +217,53 @@ "light-pianos-exercise", "little-bulldogs-guess", "little-suns-fly", + "mean-apricots-perform", "mighty-dolls-retire", + "mighty-geckos-kiss", "modern-parrots-protect", + "neat-bears-divide", "neat-gifts-join", "new-scissors-try", "nice-peas-retire", "nine-cherries-decide", "nine-glasses-nail", + "nine-seahorses-relate", "ninety-icons-smile", + "odd-books-share", + "olive-books-sort", + "orange-gifts-protect", "pink-gorillas-brake", "plenty-tools-exist", + "quick-roses-juggle", + "rare-foxes-compete", + "red-radios-promise", + "renovate-f04beb1", "rich-mugs-dress", "selfish-bees-think", + "seven-eggs-admire", + "shaggy-dodos-applaud", "six-rats-kick", "slow-toes-jog", "small-spoons-shout", "soft-gorillas-refuse", + "spicy-lies-listen", + "spicy-planets-provide", "spotty-planets-accept", "strange-papayas-beg", "strong-otters-compete", "stupid-dots-relate", + "sweet-oranges-buy", "swift-kings-sparkle", + "tall-snakes-fix", + "thick-hotels-know", "thirty-paws-hope", "tiny-oranges-pretend", "tough-lies-repair", "violet-jokes-wave", "wicked-bobcats-teach", "wild-eggs-exist", - "witty-bears-behave" + "witty-bears-behave", + "young-games-visit", + "young-peaches-shake" ] } diff --git a/docs/releases/v1.30.0-next.1-changelog.md b/docs/releases/v1.30.0-next.1-changelog.md new file mode 100644 index 0000000000..2f7153fe5c --- /dev/null +++ b/docs/releases/v1.30.0-next.1-changelog.md @@ -0,0 +1,4063 @@ +# Release v1.30.0-next.1 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.30.0-next.1](https://backstage.github.io/upgrade-helper/?to=1.30.0-next.1) + +## @backstage/core-app-api@1.14.2-next.0 + +# @backstage/core-app-api + +## 1.14.1-next.0 + +### Patch Changes + +- 9a46a81: The request to delete the session cookie when running the app in protected mode is now done with a plain `fetch` rather than `FetchApi`. This fixes a bug where the app would immediately try to sign-in again when removing the cookie during logout. +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## 1.14.0 + +### Minor Changes + +- d3c39fc: Allow for the disabling of external routes through config, which was rendered impossible after the introduction of default targets. + + ```yaml + app: + routes: + bindings: + # This has the effect of removing the button for registering new + # catalog entities in the scaffolder template list view + scaffolder.registerComponent: false + ``` + +### Patch Changes + +- db2e2d5: Updated config schema to support app.routes.bindings +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## 1.13.1-next.1 + +### Patch Changes + +- db2e2d5: Updated config schema to support app.routes.bindings +- Updated dependencies + - @backstage/core-plugin-api@1.9.3 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## 1.13.0-next.0 + +### Minor Changes + +- d3c39fc: Allow for the disabling of external routes through config, which was rendered impossible after the introduction of default targets. + + ```yaml + app: + routes: + bindings: + # This has the effect of removing the button for registering new + # catalog entities in the scaffolder template list view + scaffolder.registerComponent: false + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.9.3 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## 1.12.6 + +### Patch Changes + +- 35fbe09: Added support for configuration of route bindings through static configuration, and default targets for external route refs. + + In addition to configuring route bindings through code, it is now also possible to configure route bindings under the `app.routes.bindings` key, for example: + + ```yaml + app: + routes: + bindings: + catalog.createComponent: catalog-import.importPage + ``` + + Each key in the route binding object is of the form `<plugin-id>.<externalRouteName>`, where the route name is key used in the `externalRoutes` object passed to `createPlugin`. The value is of the same form, but with the name taken from the plugin `routes` option instead. + + The equivalent of the above configuration in code is the following: + + ```ts + const app = createApp({ + // ... + bindRoutes({ bind }) { + bind(catalogPlugin.externalRoutes, { + createComponent: catalogImportPlugin.routes.importPage, + }); + }, + }); + ``` + +- Updated dependencies + - @backstage/core-plugin-api@1.9.3 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## 1.12.6-next.0 + +### Patch Changes + +- 35fbe09: Added support for configuration of route bindings through static configuration, and default targets for external route refs. + + In addition to configuring route bindings through code, it is now also possible to configure route bindings under the `app.routes.bindings` key, for example: + + ```yaml + app: + routes: + bindings: + catalog.createComponent: catalog-import.importPage + ``` + + Each key in the route binding object is of the form `<plugin-id>.<externalRouteName>`, where the route name is key used in the `externalRoutes` object passed to `createPlugin`. The value is of the same form, but with the name taken from the plugin `routes` option instead. + + The equivalent of the above configuration in code is the following: + + ```ts + const app = createApp({ + // ... + bindRoutes({ bind }) { + bind(catalogPlugin.externalRoutes, { + createComponent: catalogImportPlugin.routes.importPage, + }); + }, + }); + ``` + +- Updated dependencies + - @backstage/core-plugin-api@1.9.3-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## 1.12.5 + +### Patch Changes + +- 1bed9a3: The Backstage identity session expiration check will no longer fall back to using the provider expiration. This was introduced to smooth out the rollout of Backstage release 1.18, and is no longer needed. + +## 1.12.4 + +### Patch Changes + +- c884b9a: The app is now aware of if it is being served from the `app-backend` with a separate public and protected bundles. When in protected mode the app will now continuously refresh the session cookie, as well as clear the cookie if the user signs out. +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.2 + - @backstage/version-bridge@1.0.8 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 1.12.4-next.0 + +### Patch Changes + +- c884b9a: The app is now aware of if it is being served from the `app-backend` with a separate public and protected bundles. When in protected mode the app will now continuously refresh the session cookie, as well as clear the cookie if the user signs out. +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## 1.12.3 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-plugin-api@1.9.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## 1.12.2 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-plugin-api@1.9.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## 1.12.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## 1.12.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## 1.12.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## 1.12.0 + +### Minor Changes + +- f919be9: Added a utility API for VMware Cloud auth; the API ref is available in the + `@backstage/core-plugin-api` and `@backstage/frontend-plugin-api` packages, the + implementation is in `@backstage/core-app-api` and a factory has been added to + `@backstage/app-defaults`. + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 7da67ce: Change `defaultScopes` for Bitbucket auth from invalid `team` to `account`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.0 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## 1.12.0-next.1 + +### Minor Changes + +- f919be9: Added a utility API for VMware Cloud auth; the API ref is available in the + `@backstage/core-plugin-api` and `@backstage/frontend-plugin-api` packages, the + implementation is in `@backstage/core-app-api` and a factory has been added to + `@backstage/app-defaults`. + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/core-plugin-api@1.9.0-next.1 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## 1.11.4-next.0 + +### Patch Changes + +- 7da67ce: Change `defaultScopes` for Bitbucket auth from invalid `team` to `account`. +- Updated dependencies + - @backstage/core-plugin-api@1.8.3-next.0 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## 1.11.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.8.2 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## 1.11.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.8.2-next.0 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## 1.11.2 + +### Patch Changes + +- 3e358b0: Added deprecation warning for React Router v6 beta, please make sure you have migrated your apps to use React Router v6 stable as support for the beta version will be removed. See the [migration tutorial](https://backstage.io/docs/tutorials/react-router-stable-migration) for more information. +- 0cbb03b: Fixing regular expression ReDoS with zod packages. Upgrading to latest. ref: <https://security.snyk.io/vuln/SNYK-JS-ZOD-5925617> +- Updated dependencies + - @backstage/core-plugin-api@1.8.1 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## 1.11.2-next.1 + +### Patch Changes + +- 3e358b0dff: Added deprecation warning for React Router v6 beta, please make sure you have migrated your apps to use React Router v6 stable as support for the beta version will be removed. See the [migration tutorial](https://backstage.io/docs/tutorials/react-router-stable-migration) for more information. +- Updated dependencies + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## 1.11.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.8.1-next.0 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## 1.11.1 + +### Patch Changes + +- 6c2b872153: Add official support for React 18. +- 89d13e5618: Add current and default scopes when refreshing session +- 9ab0572217: Add component data `core.type` marker for `AppRouter` and `FlatRoutes`. +- Updated dependencies + - @backstage/core-plugin-api@1.8.0 + - @backstage/version-bridge@1.0.7 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + +## 1.11.1-next.0 + +### Patch Changes + +- 6c2b872153: Add official support for React 18. +- 89d13e5618: Add current and default scopes when refreshing session +- 9ab0572217: Add component data `core.type` marker for `AppRouter` and `FlatRoutes`. +- Updated dependencies + - @backstage/core-plugin-api@1.8.0-next.0 + - @backstage/version-bridge@1.0.7-next.0 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + +## 1.11.0 + +### Minor Changes + +- c9d9bfeca2: URL encode some well known unsafe characters in `RouteResolver` (and therefore `useRouteRef`) + +### Patch Changes + +- 29e4d8b76b: Fixed bug in `AppRouter` to determine the correct `signOutTargetUrl` if `app.baseUrl` contains a `basePath` +- acca17e91a: Wrap entire app in `<Suspense>`, enabling support for using translations outside plugins. +- 1a0616fa10: Add missing resource and template app icons +- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. +- f95af4e540: Updated dependency `@testing-library/dom` to `^9.0.0`. +- f1b349cfba: Fixed a bug in `TranslationApi` implementation where in some cases it wouldn't notify subscribers of language changes. +- Updated dependencies + - @backstage/core-plugin-api@1.7.0 + - @backstage/version-bridge@1.0.6 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + +## 1.11.0-next.2 + +### Minor Changes + +- c9d9bfeca2: URL encode some well known unsafe characters in `RouteResolver` (and therefore `useRouteRef`) + +### Patch Changes + +- acca17e91a: Wrap entire app in `<Suspense>`, enabling support for using translations outside plugins. +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.1 + - @backstage/config@1.1.1-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.5 + +## 1.10.1-next.1 + +### Patch Changes + +- 1a0616fa10: Add missing resource and template app icons +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/config@1.1.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.5 + +## 1.10.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/config@1.1.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.5 + +## 1.10.0 + +### Minor Changes + +- 18619f793c94: Fixed two bugs in how the `OAuth2Session` type represents the underlying data. The `expiresAt` and `backstageIdentity` are now both optional, since that's what they are in practice. This is not considered a breaking change since it was effectively a bug in the modelling of the state that this type represents, and the type was not used in any other external contract. +- 18619f793c94: The `OAuth` class which is used by all OAuth providers will now consider both the session expiration of both the Backstage identity as well as the upstream identity provider, and refresh the session with either of them is about to expire. +- 6e30769cc627: Introduced experimental support for internationalization. + +### Patch Changes + +- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. +- 9fe827b380e1: Internal refactor +- 8cec7664e146: Removed `@types/node` dependency +- Updated dependencies + - @backstage/config@1.1.0 + - @backstage/core-plugin-api@1.6.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.5 + +## 1.10.0-next.3 + +### Patch Changes + +- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. +- 9fe827b380e1: Internal refactor +- Updated dependencies + - @backstage/config@1.1.0-next.2 + - @backstage/core-plugin-api@1.6.0-next.3 + - @backstage/types@1.1.1-next.0 + - @backstage/version-bridge@1.0.5-next.0 + +## 1.10.0-next.2 + +### Minor Changes + +- 6e30769cc627: Introduced experimental support for internationalization. + +### Patch Changes + +- 8cec7664e146: Removed `@types/node` dependency +- Updated dependencies + - @backstage/core-plugin-api@1.6.0-next.2 + - @backstage/config@1.1.0-next.1 + - @backstage/types@1.1.0 + - @backstage/version-bridge@1.0.4 + +## 1.10.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.0-next.0 + - @backstage/core-plugin-api@1.6.0-next.1 + - @backstage/types@1.1.0 + - @backstage/version-bridge@1.0.4 + +## 1.10.0-next.0 + +### Minor Changes + +- 18619f793c94: Fixed two bugs in how the `OAuth2Session` type represents the underlying data. The `expiresAt` and `backstageIdentity` are now both optional, since that's what they are in practice. This is not considered a breaking change since it was effectively a bug in the modelling of the state that this type represents, and the type was not used in any other external contract. +- 18619f793c94: The `OAuth` class which is used by all OAuth providers will now consider both the session expiration of both the Backstage identity as well as the upstream identity provider, and refresh the session with either of them is about to expire. + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.6.0-next.0 + - @backstage/config@1.0.8 + - @backstage/types@1.1.0 + - @backstage/version-bridge@1.0.4 + +## 1.9.1 + +### Patch Changes + +- 9ae4e7e63836: Fixed a bug that could cause `navigate` analytics events to be misattributed to the plugin mounted on the root route (e.g. the `home` plugin at `/`) when the route that was navigated to wasn't associated with a routable extension. +- Updated dependencies + - @backstage/core-plugin-api@1.5.3 + - @backstage/config@1.0.8 + - @backstage/types@1.1.0 + - @backstage/version-bridge@1.0.4 + +## 1.9.1-next.0 + +### Patch Changes + +- 9ae4e7e63836: Fixed a bug that could cause `navigate` analytics events to be misattributed to the plugin mounted on the root route (e.g. the `home` plugin at `/`) when the route that was navigated to wasn't associated with a routable extension. +- Updated dependencies + - @backstage/core-plugin-api@1.5.3 + - @backstage/config@1.0.8 + - @backstage/types@1.1.0 + - @backstage/version-bridge@1.0.4 + +## 1.9.0 + +### Minor Changes + +- a77ddf7ccd71: add login in popup options to config popup width and height + +### Patch Changes + +- 8174cf4c0edf: Fixing MUI / Material UI references +- Updated dependencies + - @backstage/core-plugin-api@1.5.3 + - @backstage/config@1.0.8 + - @backstage/types@1.1.0 + - @backstage/version-bridge@1.0.4 + +## 1.8.2-next.1 + +### Patch Changes + +- 8174cf4c0edf: Fixing MUI / Material UI references +- Updated dependencies + - @backstage/core-plugin-api@1.5.3-next.1 + - @backstage/config@1.0.8 + - @backstage/types@1.1.0 + - @backstage/version-bridge@1.0.4 + +## 1.8.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.5.3-next.0 + - @backstage/config@1.0.8 + +## 1.8.1 + +### Patch Changes + +- 12adfbc8fe2d: Fixed a bug that prevented accurate plugin and route data from being applied to `navigate` analytics events when users visited pages constructed with `<EntityLayout>`, `<TabbedLayout>`, and similar components that are used to gather one or more routable extensions under a given path. +- ac677bc30ae0: Expose discovery.endpoints configuration to use FrontendHostDiscovery +- 74b216ee4e50: Add `PropsWithChildren` to usages of `ComponentType`, in preparation for React 18 where the children are no longer implicit. +- Updated dependencies + - @backstage/core-plugin-api@1.5.2 + - @backstage/types@1.1.0 + - @backstage/config@1.0.8 + - @backstage/version-bridge@1.0.4 + +## 1.8.1-next.0 + +### Patch Changes + +- 74b216ee4e50: Add `PropsWithChildren` to usages of `ComponentType`, in preparation for React 18 where the children are no longer implicit. +- Updated dependencies + - @backstage/core-plugin-api@1.5.2-next.0 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.4 + +## 1.8.0 + +### Minor Changes + +- c89437db899: The analytics' `navigate` event will now include the route parameters as attributes of the navigate event + +### Patch Changes + +- b645d70034a: Fixed a bug in the Azure auth provider which prevented getting access tokens with multiple scopes for one resource +- 42d817e76ab: Added `FrontendHostDiscovery` for config driven discovery implementation +- Updated dependencies + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.4 + +## 1.8.0-next.1 + +### Minor Changes + +- c89437db899: The analytics' `navigate` event will now include the route parameters as attributes of the navigate event + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.5.1 + - @backstage/config@1.0.7 + +## 1.7.1-next.0 + +### Patch Changes + +- 42d817e76ab: Added `FrontendHostDiscovery` for config driven discovery implementation +- Updated dependencies + - @backstage/core-plugin-api@1.5.1 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.4 + +## 1.7.0 + +### Minor Changes + +- 7908d72e033: Introduce a new global config parameter, `enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. +- c15e0cedbe1: The `AuthConnector` interface now supports specifying a set of scopes when + refreshing a session. The `DefaultAuthConnector` implementation passes the + `scope` query parameter to the auth-backend plugin appropriately. The + `RefreshingAuthSessionManager` passes any scopes in its `GetSessionRequest` + appropriately. + +### Patch Changes + +- 1e4f5e91b8e: Bump `zod` and `zod-to-json-schema` dependencies. +- e0c6e8b9c3c: Update peer dependencies +- Updated dependencies + - @backstage/core-plugin-api@1.5.1 + - @backstage/version-bridge@1.0.4 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + +## 1.7.0-next.3 + +### Minor Changes + +- c15e0cedbe1: The `AuthConnector` interface now supports specifying a set of scopes when + refreshing a session. The `DefaultAuthConnector` implementation passes the + `scope` query parameter to the auth-backend plugin appropriately. The + `RefreshingAuthSessionManager` passes any scopes in its `GetSessionRequest` + appropriately. + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1-next.1 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.4-next.0 + +## 1.7.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.5.1-next.1 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.4-next.0 + +## 1.7.0-next.1 + +### Patch Changes + +- 1e4f5e91b8e: Bump `zod` and `zod-to-json-schema` dependencies. +- e0c6e8b9c3c: Update peer dependencies +- Updated dependencies + - @backstage/core-plugin-api@1.5.1-next.0 + - @backstage/version-bridge@1.0.4-next.0 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + +## 1.7.0-next.0 + +### Minor Changes + +- 7908d72e033: Introduce a new global config parameter, `enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.5.0 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + +## 1.6.0 + +### Minor Changes + +- 456eaa8cf83: `OAuth2` now gets ID tokens from a session with the `openid` scope explicitly + requested. + + This should not be considered a breaking change, because spec-compliant OIDC + providers will already be returning ID tokens if and only if the `openid` scope + is granted. + + This change makes the dependence explicit, and removes the burden on + OAuth2-based providers which require an ID token (e.g. this is done by various + default [auth handlers](https://backstage.io/docs/auth/identity-resolver/#authhandler)) to add + `openid` to their default scopes. _That_ could carry another indirect benefit: + by removing `openid` from the default scopes for a provider, grants for + resource-specific access tokens can avoid requesting excess ID token-related + scopes. + +### Patch Changes + +- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.5.0 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + +## 1.6.0-next.2 + +### Minor Changes + +- 456eaa8cf83: `OAuth2` now gets ID tokens from a session with the `openid` scope explicitly + requested. + + This should not be considered a breaking change, because spec-compliant OIDC + providers will already be returning ID tokens if and only if the `openid` scope + is granted. + + This change makes the dependence explicit, and removes the burden on + OAuth2-based providers which require an ID token (e.g. this is done by various + default [auth handlers](https://backstage.io/docs/auth/identity-resolver/#authhandler)) to add + `openid` to their default scopes. _That_ could carry another indirect benefit: + by removing `openid` from the default scopes for a provider, grants for + resource-specific access tokens can avoid requesting excess ID token-related + scopes. + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.5.0-next.2 + - @backstage/config@1.0.7-next.0 + +## 1.5.1-next.1 + +### Patch Changes + +- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.1 + - @backstage/config@1.0.7-next.0 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + +## 1.5.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + +## 1.5.0 + +### Minor Changes + +- db10b6ef65: Added a Bitbucket Server Auth Provider and added its API to the app defaults + +### Patch Changes + +- dff4d8ddb1: Fixed an issue where an explicit port the frontend base URL could break the app. +- Updated dependencies + - @backstage/core-plugin-api@1.4.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + +## 1.4.1-next.0 + +### Patch Changes + +- dff4d8ddb1: Fixed an issue where an explicit port the frontend base URL could break the app. +- Updated dependencies + - @backstage/config@1.0.6 + - @backstage/core-plugin-api@1.3.0 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + +## 1.4.0 + +### Minor Changes + +- bca8e8b393: Allow defining application level feature flags. See [Feature Flags documentation](https://backstage.io/docs/plugins/feature-flags#in-the-application) for reference. + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.3.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + +## 1.4.0-next.1 + +### Minor Changes + +- bca8e8b393: Allow defining application level feature flags. See [Feature Flags documentation](https://backstage.io/docs/plugins/feature-flags#in-the-application) for reference. + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.3.0-next.1 + - @backstage/config@1.0.6-next.0 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + +## 1.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.6-next.0 + - @backstage/core-plugin-api@1.2.1-next.0 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + +## 1.3.0 + +### Minor Changes + +- e0d9c9559a: Added a new `AppRouter` component and `app.createRoot()` method that replaces `app.getRouter()` and `app.getProvider()`, which are now deprecated. The new `AppRouter` component is a drop-in replacement for the old router component, while the new `app.createRoot()` method is used instead of the old provider component. + + An old app setup might look like this: + + ```tsx + const app = createApp(/* ... */); + + const AppProvider = app.getProvider(); + const AppRouter = app.getRouter(); + + const routes = ...; + + const App = () => ( + <AppProvider> + <AlertDisplay /> + <OAuthRequestDialog /> + <AppRouter> + <Root>{routes}</Root> + </AppRouter> + </AppProvider> + ); + + export default App; + ``` + + With these new APIs, the setup now looks like this: + + ```tsx + import { AppRouter } from '@backstage/core-app-api'; + + const app = createApp(/* ... */); + + const routes = ...; + + export default app.createRoot( + <> + <AlertDisplay /> + <OAuthRequestDialog /> + <AppRouter> + <Root>{routes}</Root> + </AppRouter> + </>, + ); + ``` + + Note that `app.createRoot()` accepts a React element, rather than a component. + +### Patch Changes + +- d3fea4ae0a: Internal fixes to avoid implicit usage of globals +- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries +- b4b5b02315: Tweak feature flag registration so that it happens immediately before the first rendering of the app, rather than just after. +- 6870b43dd1: Fix for the automatic rewriting of base URLs. +- 203271b746: Prevent duplicate feature flag components from rendering in the settings when using <FeatureFlagged /> components +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- c3fa90e184: Updated dependency `zen-observable` to `^0.10.0`. +- 8015ff1258: Tweaked wording to use inclusive terminology +- 653d7912ac: Made `WebStorage` notify its subscribers when `localStorage` values change in other tabs/windows +- 63310e3987: Apps will now rewrite the `app.baseUrl` configuration to match the current `location.origin`. The `backend.baseUrl` will also be rewritten in the same way when the `app.baseUrl` and `backend.baseUrl` have matching origins. This will reduce the need for separate frontend builds for different environments. +- Updated dependencies + - @backstage/core-plugin-api@1.2.0 + - @backstage/version-bridge@1.0.3 + - @backstage/types@1.0.2 + - @backstage/config@1.0.5 + +## 1.3.0-next.4 + +### Minor Changes + +- e0d9c9559a: Added a new `AppRouter` component and `app.createRoot()` method that replaces `app.getRouter()` and `app.getProvider()`, which are now deprecated. The new `AppRouter` component is a drop-in replacement for the old router component, while the new `app.createRoot()` method is used instead of the old provider component. + + An old app setup might look like this: + + ```tsx + const app = createApp(/* ... */); + + const AppProvider = app.getProvider(); + const AppRouter = app.getRouter(); + + const routes = ...; + + const App = () => ( + <AppProvider> + <AlertDisplay /> + <OAuthRequestDialog /> + <AppRouter> + <Root>{routes}</Root> + </AppRouter> + </AppProvider> + ); + + export default App; + ``` + + With these new APIs, the setup now looks like this: + + ```tsx + import { AppRouter } from '@backstage/core-app-api'; + + const app = createApp(/* ... */); + + const routes = ...; + + export default app.createRoot( + <> + <AlertDisplay /> + <OAuthRequestDialog /> + <AppRouter> + <Root>{routes}</Root> + </AppRouter> + </>, + ); + ``` + + Note that `app.createRoot()` accepts a React element, rather than a component. + +### Patch Changes + +- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries +- Updated dependencies + - @backstage/config@1.0.5-next.1 + - @backstage/core-plugin-api@1.2.0-next.2 + - @backstage/types@1.0.2-next.1 + - @backstage/version-bridge@1.0.3-next.0 + +## 1.2.1-next.3 + +### Patch Changes + +- 6870b43dd1: Fix for the automatic rewriting of base URLs. +- 653d7912ac: Made `WebStorage` notify its subscribers when `localStorage` values change in other tabs/windows +- Updated dependencies + - @backstage/config@1.0.5-next.1 + - @backstage/core-plugin-api@1.2.0-next.2 + - @backstage/types@1.0.2-next.1 + - @backstage/version-bridge@1.0.3-next.0 + +## 1.2.1-next.2 + +### Patch Changes + +- b4b5b02315: Tweak feature flag registration so that it happens immediately before the first rendering of the app, rather than just after. +- 203271b746: Prevent duplicate feature flag components from rendering in the settings when using <FeatureFlagged /> components +- 8015ff1258: Tweaked wording to use inclusive terminology +- 63310e3987: Apps will now rewrite the `app.baseUrl` configuration to match the current `location.origin`. The `backend.baseUrl` will also be rewritten in the same way when the `app.baseUrl` and `backend.baseUrl` have matching origins. This will reduce the need for separate frontend builds for different environments. +- Updated dependencies + - @backstage/core-plugin-api@1.2.0-next.2 + - @backstage/config@1.0.5-next.1 + - @backstage/types@1.0.2-next.1 + - @backstage/version-bridge@1.0.3-next.0 + +## 1.2.1-next.1 + +### Patch Changes + +- d3fea4ae0a: Internal fixes to avoid implicit usage of globals +- c3fa90e184: Updated dependency `zen-observable` to `^0.10.0`. +- Updated dependencies + - @backstage/version-bridge@1.0.3-next.0 + - @backstage/core-plugin-api@1.1.1-next.1 + - @backstage/types@1.0.2-next.1 + - @backstage/config@1.0.5-next.1 + +## 1.2.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/types@1.0.2-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/version-bridge@1.0.2 + +## 1.2.0 + +### Minor Changes + +- 9b737e5f2e: Updated the React Router wiring to make use of the new `basename` property of the router components in React Router v6 stable. To implement this, a new optional `basename` property has been added to the `Router` app component, which can be forwarded to the concrete router implementation in order to support this new behavior. This is done by default in any app that does not have a `Router` component override. +- 127fcad26d: Deprecated the `homepage` config as the component that used it - `HomepageTimer` - has been removed and replaced by the `HeaderWorldClock` in the home plugin + +### Patch Changes + +- Updated dependencies + - @backstage/version-bridge@1.0.2 + - @backstage/core-plugin-api@1.1.0 + - @backstage/types@1.0.1 + - @backstage/config@1.0.4 + +## 1.2.0-next.0 + +### Minor Changes + +- 9b737e5f2e: Updated the React Router wiring to make use of the new `basename` property of the router components in React Router v6 stable. To implement this, a new optional `basename` property has been added to the `Router` app component, which can be forwarded to the concrete router implementation in order to support this new behavior. This is done by default in any app that does not have a `Router` component override. +- 127fcad26d: Deprecated the `homepage` config as the component that used it - `HomepageTimer` - has been removed and replaced by the `HeaderWorldClock` in the home plugin + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/types@1.0.1-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/version-bridge@1.0.1 + +## 1.1.1 + +### Patch Changes + +- 27e6404aba: Fixed a bug where gathered index routes would fail to bind routable extensions. This would typically show up when placing a routable extension in the entity page overview tab. +- Updated dependencies + - @backstage/core-plugin-api@1.0.7 + - @backstage/config@1.0.3 + - @backstage/types@1.0.0 + - @backstage/version-bridge@1.0.1 + +## 1.1.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.3-next.2 + - @backstage/core-plugin-api@1.0.7-next.2 + - @backstage/types@1.0.0 + - @backstage/version-bridge@1.0.1 + +## 1.1.1-next.1 + +### Patch Changes + +- 27e6404aba: Fixed a bug where gathered index routes would fail to bind routable extensions. This would typically show up when placing a routable extension in the entity page overview tab. +- Updated dependencies + - @backstage/core-plugin-api@1.0.7-next.1 + - @backstage/config@1.0.3-next.1 + - @backstage/types@1.0.0 + - @backstage/version-bridge@1.0.1 + +## 1.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.3-next.0 + - @backstage/core-plugin-api@1.0.7-next.0 + - @backstage/types@1.0.0 + - @backstage/version-bridge@1.0.1 + +## 1.1.0 + +### Minor Changes + +- a448fea691: Updated the routing system to be compatible with React Router v6 stable. + +### Patch Changes + +- 817f3196f6: Updated React Router dependencies to be peer dependencies. + +- f9ec4e46e3: When using React Router v6 stable, it is now possible for components within the `Route` element tree to have `path` props, although they will be ignored. + +- 7d47def9c4: Removed dependency on `@types/jest`. + +- 744fea158b: Added `getSystemIcons()` function to the `AppContext` available through `useApp` that will pull a list of all the icons that have been registered in the App. + +- 667d917488: Updated dependency `msw` to `^0.47.0`. + +- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. + +- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. + +- 8448b53dd6: Clarify that the `WebStorage` observable returns `JsonValue` items. + +- 70299c99d5: Updated `FlatRoutes` to be compatible with React Router v6 stable. + +- e9d40ebf54: If you'd like to send analytics events to multiple implementations, you may now + do so using the `MultipleAnalyticsApi` implementation provided by this package. + + ```tsx + import { MultipleAnalyticsApi } from '@backstage/core-app-api'; + import { + analyticsApiRef, + configApiRef, + storageApiRef, + identityApiRef, + } from '@internal/backstage/core-plugin-api'; + import { CustomAnalyticsApi } from '@internal/analytics'; + import { VendorAnalyticsApi } from '@vendor/analytics'; + + createApiFactory({ + api: analyticsApiRef, + deps: { configApi: configApiRef, identityApi: identityApiRef, storageApi: storageApiRef }, + factory: ({ configApi, identityApi, storageApi }) => + MultipleAnalyticsApi.fromApis([ + VendorAnalyticsApi.fromConfig(configApi, { identityApi }), + CustomAnalyticsApi.fromConfig(configApi, { identityApi, storageApi }), + ]), + }), + ``` + +- Updated dependencies + - @backstage/core-plugin-api@1.0.6 + - @backstage/config@1.0.2 + +## 1.1.0-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/config@1.0.2-next.0 + - @backstage/core-plugin-api@1.0.6-next.3 + +## 1.1.0-next.2 + +### Patch Changes + +- f9ec4e46e3: When using React Router v6 stable, it is now possible for components within the `Route` element tree to have `path` props, although they will be ignored. + +- 667d917488: Updated dependency `msw` to `^0.47.0`. + +- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. + +- e9d40ebf54: If you'd like to send analytics events to multiple implementations, you may now + do so using the `MultipleAnalyticsApi` implementation provided by this package. + + ```tsx + import { MultipleAnalyticsApi } from '@backstage/core-app-api'; + import { + analyticsApiRef, + configApiRef, + storageApiRef, + identityApiRef, + } from '@internal/backstage/core-plugin-api'; + import { CustomAnalyticsApi } from '@internal/analytics'; + import { VendorAnalyticsApi } from '@vendor/analytics'; + + createApiFactory({ + api: analyticsApiRef, + deps: { configApi: configApiRef, identityApi: identityApiRef, storageApi: storageApiRef }, + factory: ({ configApi, identityApi, storageApi }) => + MultipleAnalyticsApi.fromApis([ + VendorAnalyticsApi.fromConfig(configApi, { identityApi }), + CustomAnalyticsApi.fromConfig(configApi, { identityApi, storageApi }), + ]), + }), + ``` + +- Updated dependencies + - @backstage/core-plugin-api@1.0.6-next.2 + +## 1.1.0-next.1 + +### Minor Changes + +- a448fea691: Updated the routing system to be compatible with React Router v6 stable. + +### Patch Changes + +- 817f3196f6: Updated React Router dependencies to be peer dependencies. +- 70299c99d5: Updated `FlatRoutes` to be compatible with React Router v6 stable. +- Updated dependencies + - @backstage/core-plugin-api@1.0.6-next.1 + +## 1.0.6-next.0 + +### Patch Changes + +- 744fea158b: Added `getSystemIcons()` function to the `AppContext` available through `useApp` that will pull a list of all the icons that have been registered in the App. +- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.6-next.0 + +## 1.0.5 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5 + +## 1.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + +## 1.0.4 + +### Patch Changes + +- 881fc75a75: Internal tweak removing usage of explicit type parameters for the `BackstagePlugin` type. +- 8fe2357101: The `signOut` method of the `IdentityApi` will now navigate the user back to the base URL of the app as indicated by the `app.baseUrl` config. +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.4 + +## 1.0.4-next.1 + +### Patch Changes + +- 881fc75a75: Internal tweak removing usage of explicit type parameters for the `BackstagePlugin` type. +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.4-next.0 + +## 1.0.4-next.0 + +### Patch Changes + +- 8fe2357101: The `signOut` method of the `IdentityApi` will now navigate the user back to the base URL of the app as indicated by the `app.baseUrl` config. + +## 1.0.3 + +### Patch Changes + +- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. +- 19781483a2: Handle URLs as the first argument to `fetchApi`, when using the `plugin:` protocol +- Updated dependencies + - @backstage/core-plugin-api@1.0.3 + +## 1.0.3-next.0 + +### Patch Changes + +- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.3-next.0 + +## 1.0.2 + +### Patch Changes + +- 1fae1f57c9: Fix SAML session schema to no longer require the (deprecated) id, to unbreak session data storage. +- Updated dependencies + - @backstage/core-plugin-api@1.0.2 + - @backstage/config@1.0.1 + +## 1.0.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.1-next.0 + - @backstage/core-plugin-api@1.0.2-next.1 + +## 1.0.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.2-next.0 + +## 1.0.1 + +### Patch Changes + +- 7c7919777e: build(deps-dev): bump `@testing-library/react-hooks` from 7.0.2 to 8.0.0 +- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 +- 3ff2bfb66e: Refactored the route collection logic to prepare for future changes and avoid duplicate element tree traversal for the analytics context. +- a7bb762dab: fixed empty body issue for POST requests using FetchAPI with 'plugin://' prefix +- 230ad0826f: Bump to using `@types/node` v16 +- c47509e1a0: Implemented changes suggested by Deepsource.io including multiple double non-null assertion operators and unexpected awaits for non-promise values. +- Updated dependencies + - @backstage/core-plugin-api@1.0.1 + - @backstage/version-bridge@1.0.1 + +## 1.0.1-next.1 + +### Patch Changes + +- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 +- 3ff2bfb66e: Refactored the route collection logic to prepare for future changes and avoid duplicate element tree traversal for the analytics context. +- 230ad0826f: Bump to using `@types/node` v16 +- Updated dependencies + - @backstage/core-plugin-api@1.0.1-next.0 + +## 1.0.1-next.0 + +### Patch Changes + +- a7bb762dab: fixed empty body issue for POST requests using FetchAPI with 'plugin://' prefix +- c47509e1a0: Implemented changes suggested by Deepsource.io including multiple double non-null assertion operators and unexpected awaits for non-promise values. + +## 1.0.0 + +### Major Changes + +- b58c70c223: This package has been promoted to v1.0! To understand how this change affects the package, please check out our [versioning policy](https://backstage.io/docs/overview/versioning-policy). + +### Patch Changes + +- a422d7ce5e: chore(deps): bump `@testing-library/react` from 11.2.6 to 12.1.3 +- f24ef7864e: Minor typo fixes +- Updated dependencies + - @backstage/core-plugin-api@1.0.0 + - @backstage/version-bridge@1.0.0 + - @backstage/config@1.0.0 + - @backstage/types@1.0.0 + +## 0.6.0 + +### Minor Changes + +- bb2bb36651: **BREAKING**: Removed the deprecated `get` method from `StorageAPI` and its implementations, this method has been replaced by the `snapshot` method. The return value from snapshot no longer includes `newValue` which has been replaced by `value`. For getting notified when a value changes, use \`observe# @backstage/core-app-api. +- f3cce3dcf7: **BREAKING**: Removed export of `GithubSession` and `SamlSession` which are only used internally. +- af5eaa87f4: **BREAKING**: Removed deprecated `auth0AuthApiRef`, `oauth2ApiRef`, `samlAuthApiRef` and `oidcAuthApiRef` as these APIs are too generic to be useful. Instructions for how to migrate can be found at <https://backstage.io/docs/api/deprecations#generic-auth-api-refs>. +- dbf84eee55: **BREAKING**: Removed the deprecated `GithubAuth.normalizeScopes` method. + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@0.8.0 + +## 0.5.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@0.7.0 + +## 0.5.3 + +### Patch Changes + +- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5 +- c77c5c7eb6: Added `backstage.role` to `package.json` +- Updated dependencies + - @backstage/core-plugin-api@0.6.1 + - @backstage/config@0.1.14 + - @backstage/types@0.1.2 + - @backstage/version-bridge@0.1.2 + +## 0.5.2 + +### Patch Changes + +- 40775bd263: Switched out the `GithubAuth` implementation to use the common `OAuth2` implementation. This relies on the simultaneous change in `@backstage/plugin-auth-backend` that enabled access token storage in cookies rather than the current solution that's based on `LocalStorage`. + + > **NOTE:** Make sure you upgrade the `auth-backend` deployment before or at the same time as you deploy this change. + +## 0.5.2-next.0 + +### Patch Changes + +- 40775bd263: Switched out the `GithubAuth` implementation to use the common `OAuth2` implementation. This relies on the simultaneous change in `@backstage/plugin-auth-backend` that enabled access token storage in cookies rather than the current solution that's based on `LocalStorage`. + + > **NOTE:** Make sure you upgrade the `auth-backend` deployment before or at the same time as you deploy this change. + +## 0.5.1 + +### Patch Changes + +- f959c22787: Asynchronous methods on the identity API can now reliably be called at any time, including early in the bootstrap process or prior to successful sign-in. + + Previously in such situations, a `Tried to access IdentityApi before app was loaded` error would be thrown. Now, those methods will wait and resolve eventually (as soon as a concrete identity API is provided). + +## 0.5.0 + +### Minor Changes + +- ceebe25391: Removed deprecated `SignInResult` type, which was replaced with the new `onSignInSuccess` callback. + +### Patch Changes + +- fb565073ec: Add an `allowUrl` callback option to `FetchMiddlewares.injectIdentityAuth` +- f050eec2c0: Added validation during the application startup that detects if there are any plugins present that have not had their required external routes bound. Failing the validation will cause a hard crash as it is a programmer error. It lets you detect early on that there are dangling routes, rather than having them cause an error later on. +- Updated dependencies + - @backstage/core-plugin-api@0.6.0 + - @backstage/config@0.1.13 + +## 0.5.0-next.0 + +### Minor Changes + +- ceebe25391: Removed deprecated `SignInResult` type, which was replaced with the new `onSignInSuccess` callback. + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@0.6.0-next.0 + - @backstage/config@0.1.13-next.0 + +## 0.4.0 + +### Minor Changes + +- e2eb92c109: Removed previously deprecated `ApiRegistry` export. + +### Patch Changes + +- 34442cd5cf: Fixed an issue where valid SAML and GitHub sessions would be considered invalid and not be stored. + + Deprecated the `SamlSession` and `GithubSession` types. + +- 784d8078ab: Removed direct and transitive Material UI dependencies. + +- Updated dependencies + - @backstage/config@0.1.12 + - @backstage/core-plugin-api@0.5.0 + +## 0.3.1 + +### Patch Changes + +- 4ce51ab0f1: Internal refactor of the `react-use` imports to use `react-use/lib/*` instead. +- Updated dependencies + - @backstage/core-plugin-api@0.4.1 + - @backstage/core-components@0.8.3 + +## 0.3.0 + +### Minor Changes + +- a195284c7b: Updated `WebStorageApi` to reflect the `StorageApi` changes in `@backstage/core-plugin-api`. +- b3605da81c: - Removed deprecated definition `createApp` from `@backstage/core-app-api` which has been replaced by `@backstage/app-defaults#createApp` + - Removed deprecated type `BackstagePluginWithAnyOutput` + - Removed deprecated constructors for `GithubAuth`, `OAuth2`, and `SamlAuth` as the `create` method should be used instead +- 68f8b10ccd: - Removed deprecation configuration option `theme` from `AppTheme` of the `AppThemeApi` + - Removed reference to `theme` in the `app-defaults` default `AppTheme` + - Removed logic in `AppThemeProvider` that creates `ThemeProvider` from `appTheme.theme` + +### Patch Changes + +- 7927005152: Add `FetchApi` and related `fetchApiRef` which implement fetch, with an added Backstage token header when available. +- 518ddc00bc: Schema-validate local storage cached session info on load +- Updated dependencies + - @backstage/app-defaults@0.1.3 + - @backstage/core-plugin-api@0.4.0 + - @backstage/core-components@0.8.2 + +## 0.2.1 + +### Patch Changes + +- c11ce4f552: Deprecated `Auth0Auth`, pointing to using `OAuth2` directly instead. +- 9d6503e86c: Switched out usage of deprecated `OAuthRequestApi` types from `@backstage/core-plugin-api`. +- Updated dependencies + - @backstage/core-plugin-api@0.3.1 + - @backstage/core-components@0.8.1 + +## 0.2.0 + +### Minor Changes + +- a036b65c2f: **BREAKING CHANGE** + + The app `SignInPage` component has been updated to switch out the `onResult` callback for a new `onSignInSuccess` callback. This is an immediate breaking change without any deprecation period, as it was deemed to be the way of making this change that had the lowest impact. + + The new `onSignInSuccess` callback directly accepts an implementation of an `IdentityApi`, rather than a `SignInResult`. The `SignInPage` from `@backstage/core-component` has been updated to fit this new API, and as long as you pass on `props` directly you should not see any breakage. + + However, if you implement your own custom `SignInPage`, then this will be a breaking change and you need to migrate over to using the new callback. While doing so you can take advantage of the `UserIdentity.fromLegacy` helper from `@backstage/core-components` to make the migration simpler by still using the `SignInResult` type. This helper is also deprecated though and is only provided for immediate migration. Long-term it will be necessary to build the `IdentityApi` using for example `UserIdentity.create` instead. + + The following is an example of how you can migrate existing usage immediately using `UserIdentity.fromLegacy`: + + ```ts + onResult(signInResult); + // becomes + onSignInSuccess(UserIdentity.fromLegacy(signInResult)); + ``` + + The following is an example of how implement the new `onSignInSuccess` callback of the `SignInPage` using `UserIdentity.create`: + + ```ts + const identityResponse = await authApi.getBackstageIdentity(); + // Profile is optional and will be removed, but allows the + // synchronous getProfile method of the IdentityApi to be used. + const profile = await authApi.getProfile(); + onSignInSuccess( + UserIdentity.create({ + identity: identityResponse.identity, + authApi, + profile, + }), + ); + ``` + +### Patch Changes + +- cd450844f6: Moved React dependencies to `peerDependencies` and allow both React v16 and v17 to be used. +- dcd1a0c3f4: Minor improvement to the API reports, by not unpacking arguments directly +- Updated dependencies + - @backstage/core-components@0.8.0 + - @backstage/core-plugin-api@0.3.0 + - @backstage/app-defaults@0.1.2 + - @backstage/version-bridge@0.1.1 + +## 0.1.24 + +### Patch Changes + +- 0e7f256034: Fixed a bug where `useRouteRef` would fail in situations where relative navigation was needed and the app was is mounted on a sub-path. This would typically show up as a failure to navigate to a tab on an entity page. +- Updated dependencies + - @backstage/core-components@0.7.6 + - @backstage/theme@0.2.14 + - @backstage/core-plugin-api@0.2.2 + +## 0.1.23 + +### Patch Changes + +- bab752e2b3: Change default port of backend from 7000 to 7007. + + This is due to the AirPlay Receiver process occupying port 7000 and preventing local Backstage instances on MacOS to start. + + You can change the port back to 7000 or any other value by providing an `app-config.yaml` with the following values: + + backend: + listen: 0.0.0.0:7123 + baseUrl: http://localhost:7123 + + More information can be found here: <https://backstage.io/docs/conf/writing> + +- 000190de69: The `ApiRegistry` from `@backstage/core-app-api` class has been deprecated and will be removed in a future release. To replace it, we have introduced two new helpers that are exported from `@backstage/test-utils`, namely `TestApiProvider` and `TestApiRegistry`. + + These two new helpers are more tailored for writing tests and development setups, as they allow for partial implementations of each of the APIs. + + When migrating existing code it is typically best to prefer usage of `TestApiProvider` when possible, so for example the following code: + + ```tsx + render( + <ApiProvider + apis={ApiRegistry.from([ + [identityApiRef, mockIdentityApi as unknown as IdentityApi] + ])} + > + {...} + </ApiProvider> + ) + ``` + + Would be migrated to this: + + ```tsx + render( + <TestApiProvider apis={[[identityApiRef, mockIdentityApi]]}> + {...} + </TestApiProvider> + ) + ``` + + In cases where the `ApiProvider` is used in a more standalone way, for example to reuse a set of APIs across multiple tests, the `TestApiRegistry` can be used instead. Note that the `TestApiRegistry` only has a single static factory method, `.from()`, and it is slightly different from the existing `.from()` method on `ApiRegistry` in that it doesn't require the API pairs to be wrapped in an outer array. + + Usage that looks like this: + + ```ts + const apis = ApiRegistry.with( + identityApiRef, + mockIdentityApi as unknown as IdentityApi, + ).with(configApiRef, new ConfigReader({})); + ``` + + OR like this: + + ```ts + const apis = ApiRegistry.from([ + [identityApiRef, mockIdentityApi as unknown as IdentityApi], + [configApiRef, new ConfigReader({})], + ]); + ``` + + Would be migrated to this: + + ```ts + const apis = TestApiRegistry.from( + [identityApiRef, mockIdentityApi], + [configApiRef, new ConfigReader({})], + ); + ``` + + If your app is still using the `ApiRegistry` to construct the `apis` for `createApp`, we recommend that you move over to use the new method of supplying API factories instead, using `createApiFactory`. + +- Updated dependencies + - @backstage/core-plugin-api@0.2.1 + - @backstage/core-components@0.7.5 + +## 0.1.22 + +### Patch Changes + +- Reverted the `createApp` TypeScript type to match the one before version `0.1.21`, as it was an accidental breaking change. + +## 0.1.21 + +### Patch Changes + +- 0b1de52732: Migrated to using new `ErrorApiError` and `ErrorApiErrorContext` names. + +- ecd1fcb80a: Deprecated the `BackstagePluginWithAnyOutput` type. + +- 32bfbafb0f: Start exporting and marking several types as public to address errors in the API report. + +- 014cbf8cb9: The `createApp` function from `@backstage/core-app-api` has been deprecated, with two new options being provided as a replacement. + + The first and most commonly used one is `createApp` from the new `@backstage/app-defaults` package, which behaves just like the existing `createApp`. In the future this method is likely to be expanded to add more APIs and other pieces into the default setup, for example the Utility APIs from `@backstage/integration-react`. + + The other option that we now provide is to use `createSpecializedApp` from `@backstage/core-app-api`. This is a more low-level API where you need to provide a full set of options, including your own `components`, `icons`, `defaultApis`, and `themes`. The `createSpecializedApp` way of creating an app is particularly useful if you are not using `@backstage/core-components` or Material UI, as it allows you to avoid those dependencies completely. + +- 475edb5bc5: move the BehaviorSubject init into the constructor + +- Updated dependencies + - @backstage/core-components@0.7.4 + - @backstage/core-plugin-api@0.2.0 + - @backstage/app-defaults@0.1.1 + +## 0.1.20 + +### Patch Changes + +- 78c512ce8f: I have added default icons for the catalog, scaffolder, techdocs, and search. +- 8b4284cd5c: Improve API documentation for @backstage/core-plugin-api +- Updated dependencies + - @backstage/core-components@0.7.3 + - @backstage/theme@0.2.13 + - @backstage/core-plugin-api@0.1.13 + +## 0.1.19 + +### Patch Changes + +- 10615525f3: Switch to use the json and observable types from `@backstage/types` +- 41c49884d2: Start using the new `@backstage/types` package. Initially, this means using the `Observable` and `Json*` types from there. The types also remain in their old places but deprecated, and will be removed in a future release. +- 925a967f36: Replace usage of test-utils-core with test-utils +- 6b615e92c8: Api cleanup, adding `@public` where necessary and tweaking some comments +- Updated dependencies + - @backstage/config@0.1.11 + - @backstage/theme@0.2.12 + - @backstage/core-components@0.7.2 + - @backstage/core-plugin-api@0.1.12 + +## 0.1.18 + +### Patch Changes + +- 202f322927: Atlassian auth provider + + - AtlassianAuth added to core-app-api + - Atlassian provider added to plugin-auth-backend + - Updated user-settings with Atlassian connection + +- 36e67d2f24: Internal updates to apply more strict checks to throw errors. + +- Updated dependencies + - @backstage/core-components@0.7.1 + - @backstage/core-plugin-api@0.1.11 + +## 0.1.17 + +### Patch Changes + +- 75bc878221: Internal refactor to avoid importing all of `@material-ui/core`. +- Updated dependencies + - @backstage/core-components@0.7.0 + - @backstage/theme@0.2.11 + +## 0.1.16 + +### Patch Changes + +- d9fd798cc8: The Core App API now automatically instruments all route location changes using + the new Analytics API. Each location change triggers a `navigate` event, which + is an analogue of a "pageview" event in traditional web analytics systems. In + addition to the path, these events provide plugin-level metadata via the + analytics context, which can be useful for analyzing plugin usage: + + ```json + { + "action": "navigate", + "subject": "/the-path/navigated/to?with=params#and-hashes", + "context": { + "extension": "App", + "pluginId": "id-of-plugin-that-exported-the-route", + "routeRef": "associated-route-ref-id" + } + } + ``` + + These events can be identified and handled by checking for the action + `navigate` and the extension `App`. + +- 4c3eea7788: Bitbucket Cloud authentication - based on the existing GitHub authentication + changes around BB apis and updated scope. + + - BitbucketAuth added to core-app-api. + - Bitbucket provider added to plugin-auth-backend. + - Cosmetic entry for Bitbucket connection in user-settings Authentication Providers tab. + +- d6ad46eb22: Stop calling connector.removeSession in StaticAuthSessionManager, instead just discarding the + session locally. + +- Updated dependencies + - @backstage/core-components@0.6.1 + - @backstage/core-plugin-api@0.1.10 + +## 0.1.15 + +### Patch Changes + +- 0c4ee1876f: Enables late registration of plugins into the application by updating ApiHolder when additional plugins have been added in. +- Updated dependencies + - @backstage/core-plugin-api@0.1.9 + - @backstage/core-components@0.6.0 + +## 0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.5.0 + - @backstage/config@0.1.10 + +## 0.1.13 + +### Patch Changes + +- 671015f132: Switch to using utilities from \`@backstage/version-bridge'. +- bd1981d609: Allow users to specify their own AppThemeProvider +- Updated dependencies + - @backstage/core-components@0.4.2 + - @backstage/core-plugin-api@0.1.8 + +## 0.1.12 + +### Patch Changes + +- 841666a19: Removed deprecated internal functions. +- Updated dependencies + - @backstage/core-components@0.4.1 + - @backstage/config@0.1.9 + - @backstage/core-plugin-api@0.1.7 + +## 0.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.4.0 + +## 0.1.10 + +### Patch Changes + +- cfcb486aa: Add system icons for the built-in entity types and use them in the entity list of the `catalog-import` plugin. + +- 392b36fa1: Added support for using authenticating via GitHub Apps in addition to GitHub OAuth Apps. It used to be possible to use GitHub Apps, but they did not handle session refresh correctly. + + Note that GitHub Apps handle OAuth scope at the app installation level, meaning that the `scope` parameter for `getAccessToken` has no effect. When calling `getAccessToken` in open source plugins, one should still include the appropriate scope, but also document in the plugin README what scopes are required in the case of GitHub Apps. + + In addition, the `authHandler` and `signInResolver` options have been implemented for the GitHub provider in the auth backend. + +- Updated dependencies + - @backstage/core-components@0.3.3 + - @backstage/config@0.1.8 + +## 0.1.9 + +### Patch Changes + +- 72a31c29a: Add support for additional app origins +- Updated dependencies + - @backstage/config@0.1.7 + - @backstage/core-components@0.3.2 + - @backstage/theme@0.2.10 + +## 0.1.8 + +### Patch Changes + +- 362657623: Add support for serving the app with a base path other than `/`, which is enabled by including the path in `app.baseUrl`. +- 56c773909: Switched `@types/react` dependency to request `*` rather than a specific version. +- Updated dependencies + - @backstage/core-components@0.3.1 + - @backstage/core-plugin-api@0.1.6 + +## 0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.3.0 + - @backstage/config@0.1.6 + - @backstage/core-plugin-api@0.1.5 + +## 0.1.6 + +### Patch Changes + +- 9d40fcb1e: - Bumping `material-ui/core` version to at least `4.12.2` as they made some breaking changes in later versions which broke `Pagination` of the `Table`. + - Switching out `material-table` to `@material-table/core` for support for the later versions of `material-ui/core` + - This causes a minor API change to `@backstage/core-components` as the interface for `Table` re-exports the `prop` from the underlying `Table` components. + - `onChangeRowsPerPage` has been renamed to `onRowsPerPageChange` + - `onChangePage` has been renamed to `onPageChange` + - Migration guide is here: <https://material-table-core.com/docs/breaking-changes> +- Updated dependencies + - @backstage/core-components@0.2.0 + - @backstage/core-plugin-api@0.1.4 + - @backstage/theme@0.2.9 + +## 0.1.5 + +### Patch Changes + +- ea249c6e6: Fix a bug in `FlatRoutes` that prevented outlets from working with the root route, as well as matching root routes too broadly. +- Updated dependencies + - @backstage/core-components@0.1.6 + +## 0.1.4 + +### Patch Changes + +- 62abffee4: Reintroduce export of `defaultConfigLoader`. +- Updated dependencies + - @backstage/core-components@0.1.4 + +## 0.1.3 + +### Patch Changes + +- dc3e7ce68: Introducing new UnhandledErrorForwarder installed by default. For catching unhandled promise rejections, you can override the API to align with general error handling. +- 5f4339b8c: Adding `FeatureFlag` component and treating `FeatureFlags` as first class citizens to composability API +- Updated dependencies + - @backstage/core-plugin-api@0.1.3 + +## 0.1.2 + +### Patch Changes + +- 9bca2a252: Fixes a type bug where supplying all app icons to `createApp` was required, rather than just a partial list. + +- 75b8537ce: This change adds automatic error boundaries around extensions. + + This means that all exposed parts of a plugin are wrapped in a general error boundary component, that is plugin aware. The default design for the error box is borrowed from `@backstage/errors`. To override the default "fallback", one must provide a component named `ErrorBoundaryFallback` to `createApp`, like so: + + ```ts + const app = createApp({ + components: { + ErrorBoundaryFallback: props => { + // a custom fallback component + return ( + <> + <h1>Oops.</h1> + <h2> + The plugin {props.plugin.getId()} failed with{' '} + {props.error.message} + </h2> + <button onClick={props.resetError}>Try again</button> + </> + ); + }, + }, + }); + ``` + + The props here include: + + - `error`. An `Error` object or something that inherits it that represents the error that was thrown from any inner component. + - `resetError`. A callback that will simply attempt to mount the children of the error boundary again. + - `plugin`. A `BackstagePlugin` that can be used to look up info to be presented in the error message. For instance, you may want to keep a map of your internal plugins and team names or slack channels and present these when an error occurs. Typically, you'll do that by getting the plugin ID with `plugin.getId()`. + +- da8cba44f: Deprecate and disable the extension creation methods, which were added to this package by mistake and should only exist within `@backstage/core-plugin-api`. + +- 9bca2a252: Update `createApp` options to allow plugins with unknown output types in order to improve forwards and backwards compatibility. + +- Updated dependencies [e47336ea4] + +- Updated dependencies [75b8537ce] + +- Updated dependencies [da8cba44f] + - @backstage/core-components@0.1.2 + - @backstage/core-plugin-api@0.1.2 + +## 0.1.1 + +### Patch Changes + +- e7c5e4b30: Update installation instructions in README. +- Updated dependencies [031ccd45f] +- Updated dependencies [e7c5e4b30] + - @backstage/core-plugin-api@0.1.1 + - @backstage/core-components@0.1.1 + - @backstage/theme@0.2.8 + +## @backstage/config-loader@1.9.0-next.1 + +### Minor Changes + +- 274428f: Add configuration key to File and Remote `ConfigSource`s that enables configuration of parsing logic. Previously limited to yaml, these `ConfigSource`s now allow for a multitude of parsing options (e.g. JSON). + +### Patch Changes + +- 1edd6c2: The `env` option of `ConfigSources.default` now correctly allows undefined members. +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-notifications-backend-module-email@0.2.0-next.1 + +### Minor Changes + +- def53a7: **BREAKING** Following `NotificationTemplateRenderer` methods now return a Promise and **must** be awaited: `getSubject`, `getText` and `getHtml`. + + Required changes and example usage: + + ```diff + import { notificationsEmailTemplateExtensionPoint } from '@backstage/plugin-notifications-backend-module-email'; + import { Notification } from '@backstage/plugin-notifications-common'; + +import { getNotificationSubject, getNotificationTextContent, getNotificationHtmlContent } from 'my-notification-processing-library` + export const notificationsModuleEmailDecorator = createBackendModule({ + pluginId: 'notifications', + moduleId: 'email.templates', + register(reg) { + reg.registerInit({ + deps: { + emailTemplates: notificationsEmailTemplateExtensionPoint, + }, + async init({ emailTemplates }) { + emailTemplates.setTemplateRenderer({ + - getSubject(notification) { + + async getSubject(notification) { + - return `New notification from ${notification.source}`; + + const subject = await getNotificationSubject(notification); + + return `New notification from ${subject}`; + }, + - getText(notification) { + + async getText(notification) { + - return notification.content; + + const text = await getNotificationTextContent(notification); + + return text; + }, + - getHtml(notification) { + + async getHtml(notification) { + - return `<p>${notification.content}</p>`; + + const html = await getNotificationHtmlContent(notification); + + return html; + }, + }); + }, + }); + }, + }); + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration-aws-node@0.1.12 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.4-next.1 + +## @backstage/plugin-techdocs-common@0.1.0-next.0 + +### Minor Changes + +- 4698e1f: Initial release of the techdocs-common package. + +## @backstage/app-defaults@1.5.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + +## @backstage/backend-app-api@0.8.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.9.0-next.1 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/backend-common@0.23.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.9.0-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/backend-defaults@0.4.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.9.0-next.1 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-app-api@0.8.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + +## @backstage/backend-dynamic-feature-service@0.2.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.9.0-next.1 + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-catalog-backend@1.24.1-next.1 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-app-api@0.8.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-app-node@0.1.23-next.1 + - @backstage/plugin-search-backend-node@1.2.28-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + - @backstage/plugin-events-backend@0.3.10-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + +## @backstage/backend-openapi-utils@0.1.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/errors@1.2.4 + +## @backstage/backend-plugin-api@0.7.1-next.1 + +### Patch Changes + +- f011d1b: fix typo in `getPluginRequestToken` comments +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/backend-tasks@0.5.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/backend-test-utils@0.4.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-app-api@0.8.1-next.1 + - @backstage/backend-defaults@0.4.2-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + +## @backstage/cli@0.27.0-next.1 + +### Patch Changes + +- e6e7d86: Switched the target from `'ES2022'` to `'es2022'` for better compatibility with older versions of `swc`. +- Updated dependencies + - @backstage/config-loader@1.9.0-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/eslint-plugin@0.1.8 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/core-compat-api@0.2.8-next.1 + +### Patch Changes + +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-plugin-api@1.9.3 + - @backstage/version-bridge@1.0.8 + +## @backstage/create-app@0.5.18-next.1 + +### Patch Changes + +- 6c1081c: Updated dockerfile and `app-config.production.yaml` to make it easier to get started with example data +- Updated dependencies + - @backstage/cli-common@0.1.14 + +## @backstage/dev-utils@1.0.37-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/app-defaults@1.5.10-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + +## @backstage/frontend-app-api@0.7.5-next.1 + +### Patch Changes + +- 3be9aeb: Added support for v2 extensions, which declare their inputs and outputs without using a data map. +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/frontend-plugin-api@0.6.8-next.1 + +### Patch Changes + +- 3be9aeb: Extensions have been changed to be declared with an array of inputs and outputs, rather than a map of named data refs. This change was made to reduce confusion around the role of the input and output names, as well as enable more powerful APIs for overriding extensions. + + An extension that was previously declared like this: + + ```tsx + const exampleExtension = createExtension({ + name: 'example', + inputs: { + items: createExtensionInput({ + element: coreExtensionData.reactElement, + }), + }, + output: { + element: coreExtensionData.reactElement, + }, + factory({ inputs }) { + return { + element: ( + <div> + Example + {inputs.items.map(item => { + return <div>{item.output.element}</div>; + })} + </div> + ), + }; + }, + }); + ``` + + Should be migrated to the following: + + ```tsx + const exampleExtension = createExtension({ + name: 'example', + inputs: { + items: createExtensionInput([coreExtensionData.reactElement]), + }, + output: [coreExtensionData.reactElement], + factory({ inputs }) { + return [ + coreExtensionData.reactElement( + <div> + Example + {inputs.items.map(item => { + return <div>{item.get(coreExtensionData.reactElement)}</div>; + })} + </div>, + ), + ]; + }, + }); + ``` + +- 3fb421d: Added support to be able to define `zod` config schema in Blueprints, with built in schema merging from the Blueprint and the extension instances. + +- 6349099: Added config input type to the extensions + +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/frontend-test-utils@0.1.12-next.1 + +### Patch Changes + +- 3be9aeb: Added support for v2 extensions, which declare their inputs and outputs without using a data map. +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/frontend-app-api@0.7.5-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/test-utils@1.5.10-next.1 + - @backstage/types@1.1.1 + +## @backstage/repo-tools@0.9.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.9.0-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/errors@1.2.4 + +## @techdocs/cli@1.8.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.9-next.1 + - @backstage/backend-defaults@0.4.2-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## @backstage/test-utils@1.5.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + +## @backstage/plugin-api-docs@0.11.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/plugin-catalog@1.21.2-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-app-backend@0.3.72-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.9.0-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-app-node@0.1.23-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-app-node@0.1.23-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.9.0-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + +## @backstage/plugin-app-visualizer@0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-auth-backend@0.22.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.1.6-next.1 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.2.4-next.1 + - @backstage/plugin-auth-backend-module-bitbucket-provider@0.1.6-next.1 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.1.18-next.1 + - @backstage/plugin-auth-backend-module-onelogin-provider@0.1.4-next.1 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.15-next.1 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.18-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.1.20-next.1 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.20-next.1 + - @backstage/plugin-auth-backend-module-google-provider@0.1.20-next.1 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.2.4-next.1 + - @backstage/plugin-auth-backend-module-oidc-provider@0.2.4-next.1 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.16-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.1.6-next.1 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.16-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.2.4-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.15-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-backend@0.22.10-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.1.6-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.1.6-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.18-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.1.20-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.1.20-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-auth-backend-module-google-provider@0.1.20-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-auth-backend-module-guest-provider@0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.1.18-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.2.4-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.2.4-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-backend@0.22.10-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-auth-backend-module-okta-provider@0.0.16-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.1.4-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.1.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.2.4-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-auth-node@0.4.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog@1.21.2-next.1 + +### Patch Changes + +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/plugin-search-react@1.7.14-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/plugin-scaffolder-common@1.5.5-next.0 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend@1.24.1-next.1 + +### Patch Changes + +- 51240ee: Preserve default `allowedLocationTypes` when `setAllowedLocationTypes()` of `CatalogLocationsExtensionPoint` is not called. +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-search-backend-module-catalog@0.1.29-next.1 + - @backstage/backend-openapi-utils@0.1.16-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.9-next.1 + +## @backstage/plugin-catalog-backend-module-aws@0.3.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-kubernetes-common@0.8.2-next.0 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-azure@0.1.43-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/config@1.2.0 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.2.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/backend-openapi-utils@0.1.16-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.2.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.22-next.0 + - @backstage/plugin-events-node@0.3.9-next.1 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.37-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-gcp@0.1.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-kubernetes-common@0.8.2-next.0 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.40-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-github@0.6.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.24.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.9-next.1 + +## @backstage/plugin-catalog-backend-module-github-org@0.1.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-catalog-backend-module-github@0.6.6-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.9-next.1 + +## @backstage/plugin-catalog-backend-module-gitlab@0.3.22-next.1 + +### Patch Changes + +- c7b14ed: Adds new optional `excludeRepos` configuration option to the Gitlab catalog provider. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.9-next.1 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.0.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-gitlab@0.3.22-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.4.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-catalog-backend@1.24.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-events-node@0.3.9-next.1 + +## @backstage/plugin-catalog-backend-module-ldap@0.7.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend-module-logs@0.0.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.24.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + +## @backstage/plugin-catalog-backend-module-msgraph@0.5.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.41-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.24.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.1.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-scaffolder-common@1.5.5-next.0 + - @backstage/catalog-model@1.5.0 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.4.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.4-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-catalog-common@1.0.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/catalog-model@1.5.0 + +## @backstage/plugin-catalog-graph@0.4.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-import@0.12.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + +## @backstage/plugin-catalog-node@1.12.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-react@1.12.3-next.1 + +### Patch Changes + +- 7ca331c: Correct `EntityDisplayName`'s icon alignment with the text. +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/plugin-catalog-unprocessed-entities-common@0.0.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + +## @backstage/plugin-devtools@0.1.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/plugin-devtools-common@0.1.12-next.0 + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + +## @backstage/plugin-devtools-backend@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.9.0-next.1 + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-devtools-common@0.1.12-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-devtools-common@0.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-events-backend@0.3.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.9-next.1 + +## @backstage/plugin-events-backend-module-aws-sqs@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.9-next.1 + +## @backstage/plugin-events-backend-module-azure@0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + +## @backstage/plugin-events-backend-module-gerrit@0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + +## @backstage/plugin-events-backend-module-github@0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.9-next.1 + +## @backstage/plugin-events-backend-module-gitlab@0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.9-next.1 + +## @backstage/plugin-events-backend-test-utils@0.1.33-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.9-next.1 + +## @backstage/plugin-events-node@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + +## @backstage/plugin-home@0.7.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-home-react@0.1.16-next.0 + +## @backstage/plugin-kubernetes@0.11.13-next.1 + +### Patch Changes + +- e6c15cc: Adds support for Backstage's new frontend system, available via the `/alpha` sub-path export. +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/plugin-kubernetes-common@0.8.2-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-kubernetes-react@0.4.2-next.1 + +## @backstage/plugin-kubernetes-backend@0.18.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-kubernetes-common@0.8.2-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + - @backstage/plugin-kubernetes-node@0.1.17-next.1 + +## @backstage/plugin-kubernetes-cluster@0.0.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/plugin-kubernetes-common@0.8.2-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-kubernetes-react@0.4.2-next.1 + +## @backstage/plugin-kubernetes-common@0.8.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-kubernetes-node@0.1.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-kubernetes-common@0.8.2-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-kubernetes-react@0.4.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-common@0.8.2-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-notifications-backend@0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.4-next.1 + - @backstage/plugin-signals-node@0.1.9-next.1 + +## @backstage/plugin-notifications-node@0.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-signals-node@0.1.9-next.1 + +## @backstage/plugin-org@0.6.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-org-react@0.1.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-permission-backend@0.5.47-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.1.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-permission-common@0.8.1-next.0 + +### Patch Changes + +- 137fa34: Add the MetadataResponseSerializedRule type from @backstage/plugin-permission-node, since this type might be used in frontend code. +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-permission-node@0.8.1-next.1 + +### Patch Changes + +- 5cd9878: The MetadataResponseSerializedRule type has been moved to @backstage/plugin-permission-common, and should be imported from there going forward. To avoid an immediate breaking change, this type is still re-exported from this package, but is marked as deprecated and will be removed in a future release. +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @backstage/plugin-permission-react@0.4.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-proxy-backend@0.5.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder@1.23.1-next.1 + +### Patch Changes + +- 896a22d: Fix helper text margin for scaffolder EntityNamePicker and EntityTagsPicker when using outlined text field +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/plugin-scaffolder-react@1.11.0-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/plugin-scaffolder-common@1.5.5-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend@1.23.1-next.1 + +### Patch Changes + +- ef87e06: Fix scaffolder action `catalog:write` to write to directories that don't already exist +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-github@0.4.1-next.1 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.13-next.1 + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.13-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-scaffolder-common@1.5.5-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.13-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + - @backstage/plugin-bitbucket-cloud-common@0.2.22-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.21-next.1 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.15-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.13-next.1 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.15-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.4.5-next.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + +## @backstage/plugin-scaffolder-backend-module-azure@0.1.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.13-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.13-next.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-bitbucket-cloud-common@0.2.22-next.0 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.13-next.1 + +### Patch Changes + +- e3b64be: Added examples for publish:bitbucketServer action and improve its test cases +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.47-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.1.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.1.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.1.13-next.1 + +### Patch Changes + +- 24de005: Added test cases for publish:gitea examples +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + +## @backstage/plugin-scaffolder-backend-module-github@0.4.1-next.1 + +### Patch Changes + +- d21d307: Added examples for github:environment:create action and improve its test cases +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.4.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.0.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.4-next.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.40-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.1.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.3.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + - @backstage/plugin-scaffolder-node-test-utils@0.1.10-next.1 + +## @backstage/plugin-scaffolder-common@1.5.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-node@0.4.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-scaffolder-common@1.5.5-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-node-test-utils@0.1.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.1 + - @backstage/backend-test-utils@0.4.5-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + +## @backstage/plugin-scaffolder-react@1.11.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/plugin-scaffolder-common@1.5.5-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/plugin-search@1.4.15-next.1 + +### Patch Changes + +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/plugin-search-react@1.7.14-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/plugin-search-backend@1.5.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/backend-defaults@0.4.2-next.1 + - @backstage/plugin-search-backend-node@1.2.28-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/backend-openapi-utils@0.1.16-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-search-backend-module-catalog@0.1.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-search-backend-node@1.2.28-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-search-backend-module-elasticsearch@1.5.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-backend-node@1.2.28-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-search-backend-module-explore@0.1.29-next.1 + +### Patch Changes + +- 93fc1a0: Updated dependency `@backstage-community/plugin-explore-common` to `^0.0.4`. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-search-backend-node@1.2.28-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/config@1.2.0 + +## @backstage/plugin-search-backend-module-pg@0.5.33-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-search-backend-node@1.2.28-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-search-backend-node@1.2.28-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/config@1.2.0 + +## @backstage/plugin-search-backend-module-techdocs@0.1.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.9-next.1 + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-search-backend-node@1.2.28-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-search-backend-node@1.2.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-search-common@1.2.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-search-react@1.7.14-next.1 + +### Patch Changes + +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/plugin-signals-backend@0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + - @backstage/plugin-signals-node@0.1.9-next.1 + +## @backstage/plugin-signals-node@0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + +## @backstage/plugin-techdocs@1.10.8-next.1 + +### Patch Changes + +- 69bd940: Use annotation constants from new techdocs-common package. +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/plugin-techdocs-common@0.1.0-next.0 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/plugin-search-react@1.7.14-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.37-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.8-next.1 + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/plugin-search-react@1.7.14-next.1 + - @backstage/plugin-catalog@1.21.2-next.1 + - @backstage/test-utils@1.5.10-next.1 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + +## @backstage/plugin-techdocs-backend@1.10.10-next.1 + +### Patch Changes + +- 69bd940: Use annotation constants from new techdocs-common package. +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.9-next.1 + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-techdocs-common@0.1.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.28-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-techdocs-node@1.12.9-next.1 + +### Patch Changes + +- 69bd940: Use annotation constants from new techdocs-common package. +- 949083d: Update `patchMkdocsYmlPrebuild` to modify `repo_url` and `edit_uri` independently. +- Updated dependencies + - @backstage/plugin-techdocs-common@0.1.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-user-settings@0.8.11-next.1 + +### Patch Changes + +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.4 + - @backstage/plugin-user-settings-common@0.0.1 + +## @backstage/plugin-user-settings-backend@0.2.22-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + - @backstage/plugin-signals-node@0.1.9-next.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.100-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.8-next.1 + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-app-api@0.7.5-next.1 + - @backstage/plugin-kubernetes@0.11.13-next.1 + - @backstage/cli@0.27.0-next.1 + - @backstage/plugin-scaffolder@1.23.1-next.1 + - @backstage/plugin-user-settings@0.8.11-next.1 + - @backstage/plugin-search-react@1.7.14-next.1 + - @backstage/plugin-catalog@1.21.2-next.1 + - @backstage/plugin-search@1.4.15-next.1 + - @backstage/plugin-api-docs@0.11.8-next.1 + - @backstage/plugin-catalog-graph@0.4.8-next.1 + - @backstage/plugin-catalog-import@0.12.2-next.1 + - @backstage/plugin-home@0.7.9-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.14-next.1 + - @backstage/plugin-org@0.6.28-next.1 + - @backstage/plugin-scaffolder-react@1.11.0-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/plugin-devtools@0.1.17-next.1 + - @backstage/app-defaults@1.5.10-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.7-next.0 + - @backstage/plugin-notifications@0.2.4-next.0 + - @backstage/plugin-signals@0.0.9-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.13-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + +## example-app-next@0.0.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.8-next.1 + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-app-api@0.7.5-next.1 + - @backstage/plugin-kubernetes@0.11.13-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/cli@0.27.0-next.1 + - @backstage/plugin-scaffolder@1.23.1-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/plugin-user-settings@0.8.11-next.1 + - @backstage/plugin-search-react@1.7.14-next.1 + - @backstage/plugin-catalog@1.21.2-next.1 + - @backstage/plugin-search@1.4.15-next.1 + - @backstage/plugin-api-docs@0.11.8-next.1 + - @backstage/plugin-catalog-graph@0.4.8-next.1 + - @backstage/plugin-catalog-import@0.12.2-next.1 + - @backstage/plugin-home@0.7.9-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.14-next.1 + - @backstage/plugin-org@0.6.28-next.1 + - @backstage/plugin-scaffolder-react@1.11.0-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/plugin-app-visualizer@0.1.9-next.1 + - @backstage/app-defaults@1.5.10-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.7-next.0 + - @backstage/plugin-notifications@0.2.4-next.0 + - @backstage/plugin-signals@0.0.9-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.13-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + +## app-next-example-plugin@0.0.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-components@0.14.10-next.0 + +## example-backend@0.0.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-github@0.4.1-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.1.20-next.1 + - @backstage/plugin-techdocs-backend@1.10.10-next.1 + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-catalog-backend@1.24.1-next.1 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/plugin-search-backend-module-explore@0.1.29-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-scaffolder-backend@1.23.1-next.1 + - @backstage/plugin-auth-backend@0.22.10-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.28-next.1 + - @backstage/backend-defaults@0.4.2-next.1 + - @backstage/plugin-app-backend@0.3.72-next.1 + - @backstage/plugin-devtools-backend@0.3.9-next.1 + - @backstage/plugin-proxy-backend@0.5.4-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.10-next.1 + - @backstage/plugin-kubernetes-backend@0.18.4-next.1 + - @backstage/plugin-permission-backend@0.5.47-next.1 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.20-next.1 + - @backstage/plugin-search-backend@1.5.15-next.1 + - @backstage/plugin-search-backend-module-catalog@0.1.29-next.1 + - @backstage/plugin-search-backend-node@1.2.28-next.1 + - @backstage/plugin-catalog-backend-module-openapi@0.1.41-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.1.9-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.2.6-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.21-next.1 + - @backstage/plugin-notifications-backend@0.3.4-next.1 + - @backstage/plugin-signals-backend@0.1.9-next.1 + +## example-backend-legacy@0.2.101-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-backend@1.10.10-next.1 + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-catalog-backend@1.24.1-next.1 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/plugin-search-backend-module-explore@0.1.29-next.1 + - @backstage/plugin-scaffolder-backend@1.23.1-next.1 + - @backstage/plugin-auth-backend@0.22.10-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.28-next.1 + - example-app@0.2.100-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-app-backend@0.3.72-next.1 + - @backstage/plugin-devtools-backend@0.3.9-next.1 + - @backstage/plugin-proxy-backend@0.5.4-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.10-next.1 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-kubernetes-backend@0.18.4-next.1 + - @backstage/plugin-permission-backend@0.5.47-next.1 + - @backstage/plugin-search-backend@1.5.15-next.1 + - @backstage/plugin-search-backend-module-catalog@0.1.29-next.1 + - @backstage/plugin-search-backend-node@1.2.28-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-auth-node@0.4.18-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.21-next.1 + - @backstage/plugin-events-backend@0.3.10-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.24-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.4.5-next.1 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.40-next.1 + - @backstage/plugin-search-backend-module-elasticsearch@1.5.4-next.1 + - @backstage/plugin-search-backend-module-pg@0.5.33-next.1 + - @backstage/plugin-signals-backend@0.1.9-next.1 + - @backstage/plugin-signals-node@0.1.9-next.1 + +## e2e-test@0.2.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.18-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + +## techdocs-cli-embedded-app@0.2.99-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.8-next.1 + - @backstage/cli@0.27.0-next.1 + - @backstage/plugin-catalog@1.21.2-next.1 + - @backstage/test-utils@1.5.10-next.1 + - @backstage/app-defaults@1.5.10-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + +## @internal/plugin-todo-list-backend@1.0.30-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.1 + +## @internal/plugin-todo-list-common@1.0.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 diff --git a/package.json b/package.json index 73d0ca5b19..0e93bd349c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "root", - "version": "1.30.0-next.0", + "version": "1.30.0-next.1", "private": true, "repository": { "type": "git", diff --git a/packages/app-defaults/CHANGELOG.md b/packages/app-defaults/CHANGELOG.md index a045f9a4f9..ef2ecbce78 100644 --- a/packages/app-defaults/CHANGELOG.md +++ b/packages/app-defaults/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/app-defaults +## 1.5.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + ## 1.5.9-next.0 ### Patch Changes diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json index 2389c2cddc..6bed796754 100644 --- a/packages/app-defaults/package.json +++ b/packages/app-defaults/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/app-defaults", - "version": "1.5.9-next.0", + "version": "1.5.10-next.1", "description": "Provides the default wiring of a Backstage App", "backstage": { "role": "web-library" diff --git a/packages/app-next-example-plugin/CHANGELOG.md b/packages/app-next-example-plugin/CHANGELOG.md index f05b81642f..13cd327ef1 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.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-components@0.14.10-next.0 + ## 0.0.14-next.0 ### Patch Changes diff --git a/packages/app-next-example-plugin/package.json b/packages/app-next-example-plugin/package.json index d397883063..64be34d516 100644 --- a/packages/app-next-example-plugin/package.json +++ b/packages/app-next-example-plugin/package.json @@ -1,6 +1,6 @@ { "name": "app-next-example-plugin", - "version": "0.0.14-next.0", + "version": "0.0.14-next.1", "description": "Backstage internal example plugin", "backstage": { "role": "frontend-plugin", diff --git a/packages/app-next/CHANGELOG.md b/packages/app-next/CHANGELOG.md index 794484d2ce..fe43f310b7 100644 --- a/packages/app-next/CHANGELOG.md +++ b/packages/app-next/CHANGELOG.md @@ -1,5 +1,48 @@ # example-app-next +## 0.0.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.8-next.1 + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-app-api@0.7.5-next.1 + - @backstage/plugin-kubernetes@0.11.13-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/cli@0.27.0-next.1 + - @backstage/plugin-scaffolder@1.23.1-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/plugin-user-settings@0.8.11-next.1 + - @backstage/plugin-search-react@1.7.14-next.1 + - @backstage/plugin-catalog@1.21.2-next.1 + - @backstage/plugin-search@1.4.15-next.1 + - @backstage/plugin-api-docs@0.11.8-next.1 + - @backstage/plugin-catalog-graph@0.4.8-next.1 + - @backstage/plugin-catalog-import@0.12.2-next.1 + - @backstage/plugin-home@0.7.9-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.14-next.1 + - @backstage/plugin-org@0.6.28-next.1 + - @backstage/plugin-scaffolder-react@1.11.0-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/plugin-app-visualizer@0.1.9-next.1 + - @backstage/app-defaults@1.5.10-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.7-next.0 + - @backstage/plugin-notifications@0.2.4-next.0 + - @backstage/plugin-signals@0.0.9-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.13-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + ## 0.0.14-next.0 ### Patch Changes diff --git a/packages/app-next/package.json b/packages/app-next/package.json index b4b9f69c51..e64eb438e6 100644 --- a/packages/app-next/package.json +++ b/packages/app-next/package.json @@ -1,6 +1,6 @@ { "name": "example-app-next", - "version": "0.0.14-next.0", + "version": "0.0.14-next.1", "private": true, "repository": { "type": "git", diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index 4ba5430905..78bff3c88e 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,46 @@ # example-app +## 0.2.100-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.8-next.1 + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-app-api@0.7.5-next.1 + - @backstage/plugin-kubernetes@0.11.13-next.1 + - @backstage/cli@0.27.0-next.1 + - @backstage/plugin-scaffolder@1.23.1-next.1 + - @backstage/plugin-user-settings@0.8.11-next.1 + - @backstage/plugin-search-react@1.7.14-next.1 + - @backstage/plugin-catalog@1.21.2-next.1 + - @backstage/plugin-search@1.4.15-next.1 + - @backstage/plugin-api-docs@0.11.8-next.1 + - @backstage/plugin-catalog-graph@0.4.8-next.1 + - @backstage/plugin-catalog-import@0.12.2-next.1 + - @backstage/plugin-home@0.7.9-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.14-next.1 + - @backstage/plugin-org@0.6.28-next.1 + - @backstage/plugin-scaffolder-react@1.11.0-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/plugin-devtools@0.1.17-next.1 + - @backstage/app-defaults@1.5.10-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.7-next.0 + - @backstage/plugin-notifications@0.2.4-next.0 + - @backstage/plugin-signals@0.0.9-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.13-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + ## 0.2.100-next.0 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index 0468a2f7a8..0ab80dc42e 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "example-app", - "version": "0.2.100-next.0", + "version": "0.2.100-next.1", "backstage": { "role": "frontend" }, diff --git a/packages/backend-app-api/CHANGELOG.md b/packages/backend-app-api/CHANGELOG.md index 94ab9afb6f..cbbb9e949e 100644 --- a/packages/backend-app-api/CHANGELOG.md +++ b/packages/backend-app-api/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/backend-app-api +## 0.8.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.9.0-next.1 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.8.1-next.0 ### Patch Changes diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index 9372b837e0..adfd2476a2 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-app-api", - "version": "0.8.1-next.0", + "version": "0.8.1-next.1", "description": "Core API used by Backstage backend apps", "backstage": { "role": "node-library" diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md index 01499c5d92..2bd24bc8d5 100644 --- a/packages/backend-common/CHANGELOG.md +++ b/packages/backend-common/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/backend-common +## 0.23.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.9.0-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.23.4-next.0 ### Patch Changes diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 4ace5e950a..04353fc04c 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-common", - "version": "0.23.4-next.0", + "version": "0.23.4-next.1", "description": "Common functionality library for Backstage backends", "backstage": { "role": "node-library" diff --git a/packages/backend-defaults/CHANGELOG.md b/packages/backend-defaults/CHANGELOG.md index a8cc588f1e..387c9d197e 100644 --- a/packages/backend-defaults/CHANGELOG.md +++ b/packages/backend-defaults/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/backend-defaults +## 0.4.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.9.0-next.1 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-app-api@0.8.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + ## 0.4.2-next.0 ### Patch Changes diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index 9c04507003..7114e7090a 100644 --- a/packages/backend-defaults/package.json +++ b/packages/backend-defaults/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-defaults", - "version": "0.4.2-next.0", + "version": "0.4.2-next.1", "description": "Backend defaults used by Backstage backend apps", "backstage": { "role": "node-library" diff --git a/packages/backend-dynamic-feature-service/CHANGELOG.md b/packages/backend-dynamic-feature-service/CHANGELOG.md index ade7a7c0ec..ede70bfbca 100644 --- a/packages/backend-dynamic-feature-service/CHANGELOG.md +++ b/packages/backend-dynamic-feature-service/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/backend-dynamic-feature-service +## 0.2.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.9.0-next.1 + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-catalog-backend@1.24.1-next.1 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-app-api@0.8.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-app-node@0.1.23-next.1 + - @backstage/plugin-search-backend-node@1.2.28-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + - @backstage/plugin-events-backend@0.3.10-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + ## 0.2.16-next.0 ### Patch Changes diff --git a/packages/backend-dynamic-feature-service/package.json b/packages/backend-dynamic-feature-service/package.json index cc7a8b390b..1282d39d6c 100644 --- a/packages/backend-dynamic-feature-service/package.json +++ b/packages/backend-dynamic-feature-service/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-dynamic-feature-service", "description": "Backstage dynamic feature service", - "version": "0.2.16-next.0", + "version": "0.2.16-next.1", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-legacy/CHANGELOG.md b/packages/backend-legacy/CHANGELOG.md index 5acae66b6a..f036362cd2 100644 --- a/packages/backend-legacy/CHANGELOG.md +++ b/packages/backend-legacy/CHANGELOG.md @@ -1,5 +1,47 @@ # example-backend-legacy +## 0.2.101-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-backend@1.10.10-next.1 + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-catalog-backend@1.24.1-next.1 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/plugin-search-backend-module-explore@0.1.29-next.1 + - @backstage/plugin-scaffolder-backend@1.23.1-next.1 + - @backstage/plugin-auth-backend@0.22.10-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.28-next.1 + - example-app@0.2.100-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-app-backend@0.3.72-next.1 + - @backstage/plugin-devtools-backend@0.3.9-next.1 + - @backstage/plugin-proxy-backend@0.5.4-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.10-next.1 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-kubernetes-backend@0.18.4-next.1 + - @backstage/plugin-permission-backend@0.5.47-next.1 + - @backstage/plugin-search-backend@1.5.15-next.1 + - @backstage/plugin-search-backend-module-catalog@0.1.29-next.1 + - @backstage/plugin-search-backend-node@1.2.28-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-auth-node@0.4.18-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.21-next.1 + - @backstage/plugin-events-backend@0.3.10-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.24-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.4.5-next.1 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.40-next.1 + - @backstage/plugin-search-backend-module-elasticsearch@1.5.4-next.1 + - @backstage/plugin-search-backend-module-pg@0.5.33-next.1 + - @backstage/plugin-signals-backend@0.1.9-next.1 + - @backstage/plugin-signals-node@0.1.9-next.1 + ## 0.2.101-next.0 ### Patch Changes diff --git a/packages/backend-legacy/package.json b/packages/backend-legacy/package.json index 8b07afca38..3f59103f4c 100644 --- a/packages/backend-legacy/package.json +++ b/packages/backend-legacy/package.json @@ -1,6 +1,6 @@ { "name": "example-backend-legacy", - "version": "0.2.101-next.0", + "version": "0.2.101-next.1", "backstage": { "role": "backend" }, diff --git a/packages/backend-openapi-utils/CHANGELOG.md b/packages/backend-openapi-utils/CHANGELOG.md index 1056cc4cc1..37bb91f625 100644 --- a/packages/backend-openapi-utils/CHANGELOG.md +++ b/packages/backend-openapi-utils/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/backend-openapi-utils +## 0.1.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/errors@1.2.4 + ## 0.1.16-next.0 ### Patch Changes diff --git a/packages/backend-openapi-utils/package.json b/packages/backend-openapi-utils/package.json index 7b7778f9fe..ccf49f2be7 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.16-next.0", + "version": "0.1.16-next.1", "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 9dd2e2587c..9f5ced6b18 100644 --- a/packages/backend-plugin-api/CHANGELOG.md +++ b/packages/backend-plugin-api/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/backend-plugin-api +## 0.7.1-next.1 + +### Patch Changes + +- f011d1b: fix typo in `getPluginRequestToken` comments +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.7.1-next.0 ### Patch Changes diff --git a/packages/backend-plugin-api/package.json b/packages/backend-plugin-api/package.json index 4bad9325f1..267fdf6a01 100644 --- a/packages/backend-plugin-api/package.json +++ b/packages/backend-plugin-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-plugin-api", - "version": "0.7.1-next.0", + "version": "0.7.1-next.1", "description": "Core API used by Backstage backend plugins", "backstage": { "role": "node-library" diff --git a/packages/backend-tasks/CHANGELOG.md b/packages/backend-tasks/CHANGELOG.md index 929a38084c..2313e04748 100644 --- a/packages/backend-tasks/CHANGELOG.md +++ b/packages/backend-tasks/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/backend-tasks +## 0.5.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.5.28-next.0 ### Patch Changes diff --git a/packages/backend-tasks/package.json b/packages/backend-tasks/package.json index 51e8c4611e..a6c88c2be4 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.28-next.0", + "version": "0.5.28-next.1", "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 72672bba7f..288bc2fd1d 100644 --- a/packages/backend-test-utils/CHANGELOG.md +++ b/packages/backend-test-utils/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/backend-test-utils +## 0.4.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-app-api@0.8.1-next.1 + - @backstage/backend-defaults@0.4.2-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + ## 0.4.5-next.0 ### Patch Changes diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index e562b89c84..bb0786b02c 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-test-utils", - "version": "0.4.5-next.0", + "version": "0.4.5-next.1", "description": "Test helpers library for Backstage backends", "backstage": { "role": "node-library" diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index 6110ab5f99..0c58a76dd1 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,42 @@ # example-backend +## 0.0.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-github@0.4.1-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.1.20-next.1 + - @backstage/plugin-techdocs-backend@1.10.10-next.1 + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-catalog-backend@1.24.1-next.1 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/plugin-search-backend-module-explore@0.1.29-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-scaffolder-backend@1.23.1-next.1 + - @backstage/plugin-auth-backend@0.22.10-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.28-next.1 + - @backstage/backend-defaults@0.4.2-next.1 + - @backstage/plugin-app-backend@0.3.72-next.1 + - @backstage/plugin-devtools-backend@0.3.9-next.1 + - @backstage/plugin-proxy-backend@0.5.4-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.10-next.1 + - @backstage/plugin-kubernetes-backend@0.18.4-next.1 + - @backstage/plugin-permission-backend@0.5.47-next.1 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.20-next.1 + - @backstage/plugin-search-backend@1.5.15-next.1 + - @backstage/plugin-search-backend-module-catalog@0.1.29-next.1 + - @backstage/plugin-search-backend-node@1.2.28-next.1 + - @backstage/plugin-catalog-backend-module-openapi@0.1.41-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.1.9-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.2.6-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.21-next.1 + - @backstage/plugin-notifications-backend@0.3.4-next.1 + - @backstage/plugin-signals-backend@0.1.9-next.1 + ## 0.0.29-next.0 ### Patch Changes diff --git a/packages/backend/package.json b/packages/backend/package.json index 27c378e339..91c63d7553 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.0.29-next.0", + "version": "0.0.29-next.1", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index cbeb8493eb..4098230493 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/cli +## 0.27.0-next.1 + +### Patch Changes + +- e6e7d86: Switched the target from `'ES2022'` to `'es2022'` for better compatibility with older versions of `swc`. +- Updated dependencies + - @backstage/config-loader@1.9.0-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/eslint-plugin@0.1.8 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + ## 0.27.0-next.0 ### Minor Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 0c999b8b9c..0b746fbaf8 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/cli", - "version": "0.27.0-next.0", + "version": "0.27.0-next.1", "description": "CLI for developing Backstage plugins and apps", "backstage": { "role": "cli" diff --git a/packages/config-loader/CHANGELOG.md b/packages/config-loader/CHANGELOG.md index f19fa29e29..a026e7549d 100644 --- a/packages/config-loader/CHANGELOG.md +++ b/packages/config-loader/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/config-loader +## 1.9.0-next.1 + +### Minor Changes + +- 274428f: Add configuration key to File and Remote `ConfigSource`s that enables configuration of parsing logic. Previously limited to yaml, these `ConfigSource`s now allow for a multitude of parsing options (e.g. JSON). + +### Patch Changes + +- 1edd6c2: The `env` option of `ConfigSources.default` now correctly allows undefined members. +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 1.8.2-next.0 ### Patch Changes diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json index 16ff3e4f0b..08589bfca4 100644 --- a/packages/config-loader/package.json +++ b/packages/config-loader/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/config-loader", - "version": "1.8.2-next.0", + "version": "1.9.0-next.1", "description": "Config loading functionality used by Backstage backend, and CLI", "backstage": { "role": "node-library" diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json index 0f78b11f98..6a107e0a87 100644 --- a/packages/core-app-api/package.json +++ b/packages/core-app-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-app-api", "description": "Core app API used by Backstage apps", - "version": "1.14.1-next.0", + "version": "1.14.2-next.0", "publishConfig": { "access": "public" }, diff --git a/packages/core-compat-api/CHANGELOG.md b/packages/core-compat-api/CHANGELOG.md index 43acba43f0..587d78242b 100644 --- a/packages/core-compat-api/CHANGELOG.md +++ b/packages/core-compat-api/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/core-compat-api +## 0.2.8-next.1 + +### Patch Changes + +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-plugin-api@1.9.3 + - @backstage/version-bridge@1.0.8 + ## 0.2.8-next.0 ### Patch Changes diff --git a/packages/core-compat-api/package.json b/packages/core-compat-api/package.json index dd954f3318..a76f7878dd 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.2.8-next.0", + "version": "0.2.8-next.1", "backstage": { "role": "web-library" }, diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index dea7ecb237..24176ccf48 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/create-app +## 0.5.18-next.1 + +### Patch Changes + +- 6c1081c: Updated dockerfile and `app-config.production.yaml` to make it easier to get started with example data +- Updated dependencies + - @backstage/cli-common@0.1.14 + ## 0.5.18-next.0 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index b566cb53b1..848b6640e7 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.18-next.0", + "version": "0.5.18-next.1", "publishConfig": { "access": "public" }, diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index e6d6bf3ae4..30aeba5a08 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/dev-utils +## 1.0.37-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/app-defaults@1.5.10-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + ## 1.0.36-next.0 ### Patch Changes diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index 72d35cd29c..f3f835b015 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/dev-utils", - "version": "1.0.36-next.0", + "version": "1.0.37-next.1", "description": "Utilities for developing Backstage plugins.", "backstage": { "role": "web-library" diff --git a/packages/e2e-test/CHANGELOG.md b/packages/e2e-test/CHANGELOG.md index 3e346fdac8..f3294c82e0 100644 --- a/packages/e2e-test/CHANGELOG.md +++ b/packages/e2e-test/CHANGELOG.md @@ -1,5 +1,14 @@ # e2e-test +## 0.2.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.18-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + ## 0.2.19-next.0 ### Patch Changes diff --git a/packages/e2e-test/package.json b/packages/e2e-test/package.json index 47fbd2ef1e..22424cac2f 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.19-next.0", + "version": "0.2.19-next.1", "private": true, "backstage": { "role": "cli" diff --git a/packages/frontend-app-api/CHANGELOG.md b/packages/frontend-app-api/CHANGELOG.md index 0c7526d65e..8593bb38e5 100644 --- a/packages/frontend-app-api/CHANGELOG.md +++ b/packages/frontend-app-api/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/frontend-app-api +## 0.7.5-next.1 + +### Patch Changes + +- 3be9aeb: Added support for v2 extensions, which declare their inputs and outputs without using a data map. +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 0.7.4-next.0 ### Patch Changes diff --git a/packages/frontend-app-api/package.json b/packages/frontend-app-api/package.json index 83127290f4..11059214c2 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.7.4-next.0", + "version": "0.7.5-next.1", "backstage": { "role": "web-library" }, diff --git a/packages/frontend-plugin-api/CHANGELOG.md b/packages/frontend-plugin-api/CHANGELOG.md index 607883d5e0..40961b558f 100644 --- a/packages/frontend-plugin-api/CHANGELOG.md +++ b/packages/frontend-plugin-api/CHANGELOG.md @@ -1,5 +1,71 @@ # @backstage/frontend-plugin-api +## 0.6.8-next.1 + +### Patch Changes + +- 3be9aeb: Extensions have been changed to be declared with an array of inputs and outputs, rather than a map of named data refs. This change was made to reduce confusion around the role of the input and output names, as well as enable more powerful APIs for overriding extensions. + + An extension that was previously declared like this: + + ```tsx + const exampleExtension = createExtension({ + name: 'example', + inputs: { + items: createExtensionInput({ + element: coreExtensionData.reactElement, + }), + }, + output: { + element: coreExtensionData.reactElement, + }, + factory({ inputs }) { + return { + element: ( + <div> + Example + {inputs.items.map(item => { + return <div>{item.output.element}</div>; + })} + </div> + ), + }; + }, + }); + ``` + + Should be migrated to the following: + + ```tsx + const exampleExtension = createExtension({ + name: 'example', + inputs: { + items: createExtensionInput([coreExtensionData.reactElement]), + }, + output: [coreExtensionData.reactElement], + factory({ inputs }) { + return [ + coreExtensionData.reactElement( + <div> + Example + {inputs.items.map(item => { + return <div>{item.get(coreExtensionData.reactElement)}</div>; + })} + </div>, + ), + ]; + }, + }); + ``` + +- 3fb421d: Added support to be able to define `zod` config schema in Blueprints, with built in schema merging from the Blueprint and the extension instances. +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 0.6.8-next.0 ### Patch Changes diff --git a/packages/frontend-plugin-api/package.json b/packages/frontend-plugin-api/package.json index 0206fece7e..5ee4667c3a 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.6.8-next.0", + "version": "0.6.8-next.1", "backstage": { "role": "web-library" }, diff --git a/packages/frontend-test-utils/CHANGELOG.md b/packages/frontend-test-utils/CHANGELOG.md index 89deed057e..8f770b7b31 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.12-next.1 + +### Patch Changes + +- 3be9aeb: Added support for v2 extensions, which declare their inputs and outputs without using a data map. +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/frontend-app-api@0.7.5-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/test-utils@1.5.10-next.1 + - @backstage/types@1.1.1 + ## 0.1.11-next.0 ### Patch Changes diff --git a/packages/frontend-test-utils/package.json b/packages/frontend-test-utils/package.json index 1d0b00132b..218a6fa4c4 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.11-next.0", + "version": "0.1.12-next.1", "backstage": { "role": "web-library" }, diff --git a/packages/repo-tools/CHANGELOG.md b/packages/repo-tools/CHANGELOG.md index 7f90cb37e9..35c7f35836 100644 --- a/packages/repo-tools/CHANGELOG.md +++ b/packages/repo-tools/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/repo-tools +## 0.9.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.9.0-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/errors@1.2.4 + ## 0.9.5-next.0 ### Patch Changes diff --git a/packages/repo-tools/package.json b/packages/repo-tools/package.json index f314dcc580..7e03d78758 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.9.5-next.0", + "version": "0.9.5-next.1", "publishConfig": { "access": "public" }, diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md index 727cd20533..af755dd888 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.99-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.8-next.1 + - @backstage/cli@0.27.0-next.1 + - @backstage/plugin-catalog@1.21.2-next.1 + - @backstage/test-utils@1.5.10-next.1 + - @backstage/app-defaults@1.5.10-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + ## 0.2.99-next.0 ### Patch Changes diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json index 13aa5a1855..bbe4ef9aed 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.99-next.0", + "version": "0.2.99-next.1", "private": true, "backstage": { "role": "frontend" diff --git a/packages/techdocs-cli/CHANGELOG.md b/packages/techdocs-cli/CHANGELOG.md index 74fe37f0b1..d6d5128e4d 100644 --- a/packages/techdocs-cli/CHANGELOG.md +++ b/packages/techdocs-cli/CHANGELOG.md @@ -1,5 +1,16 @@ # @techdocs/cli +## 1.8.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.9-next.1 + - @backstage/backend-defaults@0.4.2-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + ## 1.8.17-next.0 ### Patch Changes diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index 98eea44657..fc28ab1458 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.17-next.0", + "version": "1.8.17-next.1", "publishConfig": { "access": "public" }, diff --git a/packages/test-utils/CHANGELOG.md b/packages/test-utils/CHANGELOG.md index 951efa799d..6684b8b4b5 100644 --- a/packages/test-utils/CHANGELOG.md +++ b/packages/test-utils/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/test-utils +## 1.5.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + ## 1.5.9-next.0 ### Patch Changes diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index dac4827938..32a69da9df 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/test-utils", - "version": "1.5.9-next.0", + "version": "1.5.10-next.1", "description": "Utilities to test Backstage plugins and apps.", "backstage": { "role": "web-library" diff --git a/plugins/api-docs/CHANGELOG.md b/plugins/api-docs/CHANGELOG.md index 80b23769a0..f649d4e0b8 100644 --- a/plugins/api-docs/CHANGELOG.md +++ b/plugins/api-docs/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-api-docs +## 0.11.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/plugin-catalog@1.21.2-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + ## 0.11.8-next.0 ### Patch Changes diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index c448b1dd9b..4f88e8874a 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-api-docs", - "version": "0.11.8-next.0", + "version": "0.11.8-next.1", "description": "A Backstage plugin that helps represent API entities in the frontend", "backstage": { "role": "frontend-plugin", diff --git a/plugins/app-backend/CHANGELOG.md b/plugins/app-backend/CHANGELOG.md index bb73548da8..c0a59fca0e 100644 --- a/plugins/app-backend/CHANGELOG.md +++ b/plugins/app-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-app-backend +## 0.3.72-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.9.0-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-app-node@0.1.23-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.3.72-next.0 ### Patch Changes diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json index fcd9cd34b9..7ca6b7924d 100644 --- a/plugins/app-backend/package.json +++ b/plugins/app-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-app-backend", - "version": "0.3.72-next.0", + "version": "0.3.72-next.1", "description": "A Backstage backend plugin that serves the Backstage frontend app", "backstage": { "role": "backend-plugin", diff --git a/plugins/app-node/CHANGELOG.md b/plugins/app-node/CHANGELOG.md index af94c02d84..efd406fc95 100644 --- a/plugins/app-node/CHANGELOG.md +++ b/plugins/app-node/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-app-node +## 0.1.23-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.9.0-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + ## 0.1.23-next.0 ### Patch Changes diff --git a/plugins/app-node/package.json b/plugins/app-node/package.json index c8e4074899..3d02ac0388 100644 --- a/plugins/app-node/package.json +++ b/plugins/app-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-app-node", - "version": "0.1.23-next.0", + "version": "0.1.23-next.1", "description": "Node.js library for the app plugin", "backstage": { "role": "node-library", diff --git a/plugins/app-visualizer/CHANGELOG.md b/plugins/app-visualizer/CHANGELOG.md index 4db02d9234..0a676a49cf 100644 --- a/plugins/app-visualizer/CHANGELOG.md +++ b/plugins/app-visualizer/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-app-visualizer +## 0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + ## 0.1.9-next.0 ### Patch Changes diff --git a/plugins/app-visualizer/package.json b/plugins/app-visualizer/package.json index a156ceef2e..784848a573 100644 --- a/plugins/app-visualizer/package.json +++ b/plugins/app-visualizer/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-app-visualizer", - "version": "0.1.9-next.0", + "version": "0.1.9-next.1", "description": "Visualizes the Backstage app structure", "backstage": { "role": "frontend-plugin", diff --git a/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md b/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md index a683d8199b..74b7d191c4 100644 --- a/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-atlassian-provider +## 0.2.4-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.2.4-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-atlassian-provider/package.json b/plugins/auth-backend-module-atlassian-provider/package.json index dc638ba86f..c6416f1cfc 100644 --- a/plugins/auth-backend-module-atlassian-provider/package.json +++ b/plugins/auth-backend-module-atlassian-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-atlassian-provider", - "version": "0.2.4-next.0", + "version": "0.2.4-next.1", "description": "The atlassian-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md b/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md index 45e5d75611..bf64404405 100644 --- a/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-auth-backend-module-aws-alb-provider +## 0.1.15-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-backend@0.22.10-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.1.15-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-aws-alb-provider/package.json b/plugins/auth-backend-module-aws-alb-provider/package.json index 25e43952e4..c7a03d7177 100644 --- a/plugins/auth-backend-module-aws-alb-provider/package.json +++ b/plugins/auth-backend-module-aws-alb-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-aws-alb-provider", - "version": "0.1.15-next.0", + "version": "0.1.15-next.1", "description": "The aws-alb provider module for the Backstage auth backend.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md b/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md index 88898de862..cfc576d6e1 100644 --- a/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-azure-easyauth-provider +## 0.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.1.6-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-azure-easyauth-provider/package.json b/plugins/auth-backend-module-azure-easyauth-provider/package.json index 5a94dd320a..521318cb37 100644 --- a/plugins/auth-backend-module-azure-easyauth-provider/package.json +++ b/plugins/auth-backend-module-azure-easyauth-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-azure-easyauth-provider", - "version": "0.1.6-next.0", + "version": "0.1.6-next.1", "description": "The azure-easyauth-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md b/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md index 60a7ecc458..87da903953 100644 --- a/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-bitbucket-provider +## 0.1.6-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.1.6-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-bitbucket-provider/package.json b/plugins/auth-backend-module-bitbucket-provider/package.json index 159069ad4f..912f0c99a7 100644 --- a/plugins/auth-backend-module-bitbucket-provider/package.json +++ b/plugins/auth-backend-module-bitbucket-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-bitbucket-provider", - "version": "0.1.6-next.0", + "version": "0.1.6-next.1", "description": "The bitbucket-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md b/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md index 8000a1da90..f1423273d7 100644 --- a/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-auth-backend-module-cloudflare-access-provider +## 0.1.6-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.1.6-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-cloudflare-access-provider/package.json b/plugins/auth-backend-module-cloudflare-access-provider/package.json index bed6fc8094..e33a50c25d 100644 --- a/plugins/auth-backend-module-cloudflare-access-provider/package.json +++ b/plugins/auth-backend-module-cloudflare-access-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-cloudflare-access-provider", - "version": "0.1.6-next.0", + "version": "0.1.6-next.1", "description": "The cloudflare-access-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md b/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md index 0e3949cfdc..6d000cede5 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.18-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.2.18-next.0 ### 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 b106675e14..098416f347 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/package.json +++ b/plugins/auth-backend-module-gcp-iap-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-gcp-iap-provider", - "version": "0.2.18-next.0", + "version": "0.2.18-next.1", "description": "A GCP IAP auth provider module for the Backstage auth backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-github-provider/CHANGELOG.md b/plugins/auth-backend-module-github-provider/CHANGELOG.md index 8f2d91ce6f..cb68d5ab5c 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.20-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.1.20-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-github-provider/package.json b/plugins/auth-backend-module-github-provider/package.json index a986d04852..13504d3a2f 100644 --- a/plugins/auth-backend-module-github-provider/package.json +++ b/plugins/auth-backend-module-github-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-github-provider", - "version": "0.1.20-next.0", + "version": "0.1.20-next.1", "description": "The github-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md b/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md index 15265dcca3..4bf32bad63 100644 --- a/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-gitlab-provider +## 0.1.20-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.1.20-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-gitlab-provider/package.json b/plugins/auth-backend-module-gitlab-provider/package.json index be77920597..c77669aaac 100644 --- a/plugins/auth-backend-module-gitlab-provider/package.json +++ b/plugins/auth-backend-module-gitlab-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-gitlab-provider", - "version": "0.1.20-next.0", + "version": "0.1.20-next.1", "description": "The gitlab-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-google-provider/CHANGELOG.md b/plugins/auth-backend-module-google-provider/CHANGELOG.md index eaeed7dbca..08739b52cf 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.20-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.1.20-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-google-provider/package.json b/plugins/auth-backend-module-google-provider/package.json index 524d1f3d90..209a422980 100644 --- a/plugins/auth-backend-module-google-provider/package.json +++ b/plugins/auth-backend-module-google-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-google-provider", - "version": "0.1.20-next.0", + "version": "0.1.20-next.1", "description": "A Google auth provider module for the Backstage auth backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-guest-provider/CHANGELOG.md b/plugins/auth-backend-module-guest-provider/CHANGELOG.md index 7382ea2c19..94904ce214 100644 --- a/plugins/auth-backend-module-guest-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-guest-provider/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-auth-backend-module-guest-provider +## 0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.1.9-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-guest-provider/package.json b/plugins/auth-backend-module-guest-provider/package.json index db19f2e37b..9ddc9f5877 100644 --- a/plugins/auth-backend-module-guest-provider/package.json +++ b/plugins/auth-backend-module-guest-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-guest-provider", - "version": "0.1.9-next.0", + "version": "0.1.9-next.1", "description": "The guest-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md b/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md index b2d8d704d5..4e640b0b73 100644 --- a/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-microsoft-provider +## 0.1.18-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.1.18-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-microsoft-provider/package.json b/plugins/auth-backend-module-microsoft-provider/package.json index bb2f82dc68..eab709c3a3 100644 --- a/plugins/auth-backend-module-microsoft-provider/package.json +++ b/plugins/auth-backend-module-microsoft-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-microsoft-provider", - "version": "0.1.18-next.0", + "version": "0.1.18-next.1", "description": "The microsoft-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md b/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md index 4090d62d57..066695c188 100644 --- a/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-oauth2-provider +## 0.2.4-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.2.4-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-oauth2-provider/package.json b/plugins/auth-backend-module-oauth2-provider/package.json index 962362ce87..b475437611 100644 --- a/plugins/auth-backend-module-oauth2-provider/package.json +++ b/plugins/auth-backend-module-oauth2-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-oauth2-provider", - "version": "0.2.4-next.0", + "version": "0.2.4-next.1", "description": "The oauth2-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md b/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md index 33fd2b18d4..acad1b96a8 100644 --- a/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-oauth2-proxy-provider +## 0.1.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.1.16-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-oauth2-proxy-provider/package.json b/plugins/auth-backend-module-oauth2-proxy-provider/package.json index e07da7f6d4..ff6d31ebee 100644 --- a/plugins/auth-backend-module-oauth2-proxy-provider/package.json +++ b/plugins/auth-backend-module-oauth2-proxy-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-oauth2-proxy-provider", - "version": "0.1.16-next.0", + "version": "0.1.16-next.1", "description": "The oauth2-proxy-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-oidc-provider/CHANGELOG.md b/plugins/auth-backend-module-oidc-provider/CHANGELOG.md index b8702dd3e4..b0686455b5 100644 --- a/plugins/auth-backend-module-oidc-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oidc-provider/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-auth-backend-module-oidc-provider +## 0.2.4-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-backend@0.22.10-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.2.4-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-oidc-provider/package.json b/plugins/auth-backend-module-oidc-provider/package.json index 89ef91181c..90fd9c4b63 100644 --- a/plugins/auth-backend-module-oidc-provider/package.json +++ b/plugins/auth-backend-module-oidc-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-oidc-provider", - "version": "0.2.4-next.0", + "version": "0.2.4-next.1", "description": "The oidc-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-okta-provider/CHANGELOG.md b/plugins/auth-backend-module-okta-provider/CHANGELOG.md index 3f3ecdbffa..12266f8aba 100644 --- a/plugins/auth-backend-module-okta-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-okta-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-okta-provider +## 0.0.16-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.0.16-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-okta-provider/package.json b/plugins/auth-backend-module-okta-provider/package.json index 18cb4ce208..a2460cc5f3 100644 --- a/plugins/auth-backend-module-okta-provider/package.json +++ b/plugins/auth-backend-module-okta-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-okta-provider", - "version": "0.0.16-next.0", + "version": "0.0.16-next.1", "description": "The okta-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md b/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md index cbaa2f2ad6..b2ab669eca 100644 --- a/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-onelogin-provider +## 0.1.4-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.1.4-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-onelogin-provider/package.json b/plugins/auth-backend-module-onelogin-provider/package.json index 750fe96aab..c299519e45 100644 --- a/plugins/auth-backend-module-onelogin-provider/package.json +++ b/plugins/auth-backend-module-onelogin-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-onelogin-provider", - "version": "0.1.4-next.0", + "version": "0.1.4-next.1", "description": "The onelogin-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md b/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md index f0c914c43a..3dcce4d28f 100644 --- a/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-pinniped-provider +## 0.1.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.1.17-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-pinniped-provider/package.json b/plugins/auth-backend-module-pinniped-provider/package.json index 73496380af..a33c321292 100644 --- a/plugins/auth-backend-module-pinniped-provider/package.json +++ b/plugins/auth-backend-module-pinniped-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-pinniped-provider", - "version": "0.1.17-next.0", + "version": "0.1.17-next.1", "description": "The pinniped-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md b/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md index aa61e780c5..cc50745204 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.2.4-next.1 + +### Patch Changes + +- c8f1cae: Add `signIn` to authentication provider configuration schema +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.2.4-next.0 ### Patch Changes diff --git a/plugins/auth-backend-module-vmware-cloud-provider/package.json b/plugins/auth-backend-module-vmware-cloud-provider/package.json index f75891634b..8fcf5fb2a4 100644 --- a/plugins/auth-backend-module-vmware-cloud-provider/package.json +++ b/plugins/auth-backend-module-vmware-cloud-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-vmware-cloud-provider", - "version": "0.2.4-next.0", + "version": "0.2.4-next.1", "description": "The vmware-cloud-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md index 2b74787a53..d17fdabb26 100644 --- a/plugins/auth-backend/CHANGELOG.md +++ b/plugins/auth-backend/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-auth-backend +## 0.22.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.1.6-next.1 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.2.4-next.1 + - @backstage/plugin-auth-backend-module-bitbucket-provider@0.1.6-next.1 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.1.18-next.1 + - @backstage/plugin-auth-backend-module-onelogin-provider@0.1.4-next.1 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.15-next.1 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.18-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.1.20-next.1 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.20-next.1 + - @backstage/plugin-auth-backend-module-google-provider@0.1.20-next.1 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.2.4-next.1 + - @backstage/plugin-auth-backend-module-oidc-provider@0.2.4-next.1 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.16-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.1.6-next.1 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.16-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.22.10-next.0 ### Patch Changes diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index 57591313f4..086e5de7c5 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend", - "version": "0.22.10-next.0", + "version": "0.22.10-next.1", "description": "A Backstage backend plugin that handles authentication", "backstage": { "role": "backend-plugin", diff --git a/plugins/auth-node/CHANGELOG.md b/plugins/auth-node/CHANGELOG.md index 021d89b518..e8b2a4f4b9 100644 --- a/plugins/auth-node/CHANGELOG.md +++ b/plugins/auth-node/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-auth-node +## 0.4.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.4.18-next.0 ### Patch Changes diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index 114491c06e..3ce4490790 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.18-next.0", + "version": "0.4.18-next.1", "backstage": { "role": "node-library", "pluginId": "auth", diff --git a/plugins/catalog-backend-module-aws/CHANGELOG.md b/plugins/catalog-backend-module-aws/CHANGELOG.md index 22a372051e..705712aac6 100644 --- a/plugins/catalog-backend-module-aws/CHANGELOG.md +++ b/plugins/catalog-backend-module-aws/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-catalog-backend-module-aws +## 0.3.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-kubernetes-common@0.8.2-next.0 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.3.18-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-aws/package.json b/plugins/catalog-backend-module-aws/package.json index eeb26b2e1c..96c57eb821 100644 --- a/plugins/catalog-backend-module-aws/package.json +++ b/plugins/catalog-backend-module-aws/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-aws", - "version": "0.3.18-next.0", + "version": "0.3.18-next.1", "description": "A Backstage catalog backend module that helps integrate towards AWS", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-azure/CHANGELOG.md b/plugins/catalog-backend-module-azure/CHANGELOG.md index 1706dc02bf..d7b4c90862 100644 --- a/plugins/catalog-backend-module-azure/CHANGELOG.md +++ b/plugins/catalog-backend-module-azure/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-azure +## 0.1.43-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/config@1.2.0 + ## 0.1.43-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-azure/package.json b/plugins/catalog-backend-module-azure/package.json index 5fdd95140d..02f4094131 100644 --- a/plugins/catalog-backend-module-azure/package.json +++ b/plugins/catalog-backend-module-azure/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-azure", - "version": "0.1.43-next.0", + "version": "0.1.43-next.1", "description": "A Backstage catalog backend module that helps integrate towards Azure", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md b/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md index afdd92803f..17b20064ba 100644 --- a/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-backstage-openapi +## 0.2.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/backend-openapi-utils@0.1.16-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.2.6-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-backstage-openapi/package.json b/plugins/catalog-backend-module-backstage-openapi/package.json index 6da2d92d5f..d854bbd8e5 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.2.6-next.0", + "version": "0.2.6-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "catalog", diff --git a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md index 2c01eb8857..58c54afce9 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-catalog-backend-module-bitbucket-cloud +## 0.2.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.22-next.0 + - @backstage/plugin-events-node@0.3.9-next.1 + ## 0.2.10-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-cloud/package.json b/plugins/catalog-backend-module-bitbucket-cloud/package.json index 234bfea5c5..03ae26f4c2 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/package.json +++ b/plugins/catalog-backend-module-bitbucket-cloud/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-cloud", - "version": "0.2.10-next.0", + "version": "0.2.10-next.1", "description": "A Backstage catalog backend module that helps integrate towards Bitbucket Cloud", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md index 7f47be269c..762d73c1b6 100644 --- a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-bitbucket-server +## 0.1.37-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.1.37-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-server/package.json b/plugins/catalog-backend-module-bitbucket-server/package.json index 45d8c5cd33..7f35ea702c 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.37-next.0", + "version": "0.1.37-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "catalog", diff --git a/plugins/catalog-backend-module-gcp/CHANGELOG.md b/plugins/catalog-backend-module-gcp/CHANGELOG.md index ca2d4412b2..0a5ed326fd 100644 --- a/plugins/catalog-backend-module-gcp/CHANGELOG.md +++ b/plugins/catalog-backend-module-gcp/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-gcp +## 0.1.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-kubernetes-common@0.8.2-next.0 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + ## 0.1.24-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-gcp/package.json b/plugins/catalog-backend-module-gcp/package.json index 442c7540e3..9abc3da395 100644 --- a/plugins/catalog-backend-module-gcp/package.json +++ b/plugins/catalog-backend-module-gcp/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gcp", - "version": "0.1.24-next.0", + "version": "0.1.24-next.1", "description": "A Backstage catalog backend module that helps integrate towards GCP", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-gerrit/CHANGELOG.md b/plugins/catalog-backend-module-gerrit/CHANGELOG.md index 63dcfa9562..78f6172a3d 100644 --- a/plugins/catalog-backend-module-gerrit/CHANGELOG.md +++ b/plugins/catalog-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-gerrit +## 0.1.40-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.1.40-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-gerrit/package.json b/plugins/catalog-backend-module-gerrit/package.json index 61f2ac8dfd..abec87fab7 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.40-next.0", + "version": "0.1.40-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "catalog", diff --git a/plugins/catalog-backend-module-github-org/CHANGELOG.md b/plugins/catalog-backend-module-github-org/CHANGELOG.md index 72c80a97cd..f0f37b1c03 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.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-catalog-backend-module-github@0.6.6-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.9-next.1 + ## 0.1.18-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-github-org/package.json b/plugins/catalog-backend-module-github-org/package.json index 9a363613de..562b20401a 100644 --- a/plugins/catalog-backend-module-github-org/package.json +++ b/plugins/catalog-backend-module-github-org/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-github-org", - "version": "0.1.18-next.0", + "version": "0.1.18-next.1", "description": "The github-org backend module for the catalog plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-github/CHANGELOG.md b/plugins/catalog-backend-module-github/CHANGELOG.md index 12e2d70eb1..e42812d75d 100644 --- a/plugins/catalog-backend-module-github/CHANGELOG.md +++ b/plugins/catalog-backend-module-github/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-catalog-backend-module-github +## 0.6.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.24.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.9-next.1 + ## 0.6.6-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-github/package.json b/plugins/catalog-backend-module-github/package.json index aa1f750aef..ca2042f214 100644 --- a/plugins/catalog-backend-module-github/package.json +++ b/plugins/catalog-backend-module-github/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-github", - "version": "0.6.6-next.0", + "version": "0.6.6-next.1", "description": "A Backstage catalog backend module that helps integrate towards GitHub", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md b/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md index 8d1c8871ae..33ce83336c 100644 --- a/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md +++ b/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-catalog-backend-module-gitlab-org +## 0.0.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-gitlab@0.3.22-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + ## 0.0.6-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-gitlab-org/package.json b/plugins/catalog-backend-module-gitlab-org/package.json index 16c492d849..79c43d6529 100644 --- a/plugins/catalog-backend-module-gitlab-org/package.json +++ b/plugins/catalog-backend-module-gitlab-org/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gitlab-org", - "version": "0.0.6-next.0", + "version": "0.0.6-next.1", "description": "The gitlab-org backend module for the catalog plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-gitlab/CHANGELOG.md b/plugins/catalog-backend-module-gitlab/CHANGELOG.md index c4e8f25903..2b8cffa0d6 100644 --- a/plugins/catalog-backend-module-gitlab/CHANGELOG.md +++ b/plugins/catalog-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-catalog-backend-module-gitlab +## 0.3.22-next.1 + +### Patch Changes + +- c7b14ed: Adds new optional `excludeRepos` configuration option to the Gitlab catalog provider. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.9-next.1 + ## 0.3.22-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-gitlab/package.json b/plugins/catalog-backend-module-gitlab/package.json index ad5b8e88bd..8cc2b6ac3a 100644 --- a/plugins/catalog-backend-module-gitlab/package.json +++ b/plugins/catalog-backend-module-gitlab/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gitlab", - "version": "0.3.22-next.0", + "version": "0.3.22-next.1", "description": "A Backstage catalog backend module that helps integrate towards GitLab", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md index c2b3835940..d43ff7902d 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md +++ b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-catalog-backend-module-incremental-ingestion +## 0.4.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-catalog-backend@1.24.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-events-node@0.3.9-next.1 + ## 0.4.28-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-incremental-ingestion/package.json b/plugins/catalog-backend-module-incremental-ingestion/package.json index cabacc7bd6..8d3d25188d 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/package.json +++ b/plugins/catalog-backend-module-incremental-ingestion/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-incremental-ingestion", - "version": "0.4.28-next.0", + "version": "0.4.28-next.1", "description": "An entity provider for streaming large asset sources into the catalog", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-ldap/CHANGELOG.md b/plugins/catalog-backend-module-ldap/CHANGELOG.md index 1253404d2d..a93f095557 100644 --- a/plugins/catalog-backend-module-ldap/CHANGELOG.md +++ b/plugins/catalog-backend-module-ldap/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-ldap +## 0.7.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.7.1-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-ldap/package.json b/plugins/catalog-backend-module-ldap/package.json index e5f67d59c6..efda8a6b40 100644 --- a/plugins/catalog-backend-module-ldap/package.json +++ b/plugins/catalog-backend-module-ldap/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-ldap", - "version": "0.7.1-next.0", + "version": "0.7.1-next.1", "description": "A Backstage catalog backend module that helps integrate towards LDAP", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-logs/CHANGELOG.md b/plugins/catalog-backend-module-logs/CHANGELOG.md index 83053dcf6b..a62e7d7984 100644 --- a/plugins/catalog-backend-module-logs/CHANGELOG.md +++ b/plugins/catalog-backend-module-logs/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-catalog-backend-module-logs +## 0.0.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.24.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + ## 0.0.2-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-logs/package.json b/plugins/catalog-backend-module-logs/package.json index 0c4a78dfa4..2cf01d9e2c 100644 --- a/plugins/catalog-backend-module-logs/package.json +++ b/plugins/catalog-backend-module-logs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-logs", - "version": "0.0.2-next.0", + "version": "0.0.2-next.1", "description": "A module that subscribes to catalog releated events and logs them.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-msgraph/CHANGELOG.md b/plugins/catalog-backend-module-msgraph/CHANGELOG.md index d9b8da87d2..86bf7e2e45 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.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + ## 0.5.31-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json index 087d4c4a82..fc0502201b 100644 --- a/plugins/catalog-backend-module-msgraph/package.json +++ b/plugins/catalog-backend-module-msgraph/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-msgraph", - "version": "0.5.31-next.0", + "version": "0.5.31-next.1", "description": "A Backstage catalog backend module that helps integrate towards Microsoft Graph", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-openapi/CHANGELOG.md b/plugins/catalog-backend-module-openapi/CHANGELOG.md index 46d8c1319b..8daf794314 100644 --- a/plugins/catalog-backend-module-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-openapi/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-backend-module-openapi +## 0.1.41-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.24.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + ## 0.1.41-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-openapi/package.json b/plugins/catalog-backend-module-openapi/package.json index 1cd250d884..c6147804f9 100644 --- a/plugins/catalog-backend-module-openapi/package.json +++ b/plugins/catalog-backend-module-openapi/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-openapi", - "version": "0.1.41-next.0", + "version": "0.1.41-next.1", "description": "A Backstage catalog backend module that helps with OpenAPI specifications", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-puppetdb/CHANGELOG.md b/plugins/catalog-backend-module-puppetdb/CHANGELOG.md index d85ad0ecf2..924e0a9df0 100644 --- a/plugins/catalog-backend-module-puppetdb/CHANGELOG.md +++ b/plugins/catalog-backend-module-puppetdb/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-puppetdb +## 0.1.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.1.29-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-puppetdb/package.json b/plugins/catalog-backend-module-puppetdb/package.json index dadba558a5..ad76a864d3 100644 --- a/plugins/catalog-backend-module-puppetdb/package.json +++ b/plugins/catalog-backend-module-puppetdb/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-puppetdb", - "version": "0.1.29-next.0", + "version": "0.1.29-next.1", "description": "A Backstage catalog backend module that helps integrate towards PuppetDB", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md b/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md index 1ec7c01c6a..262105e62a 100644 --- a/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md +++ b/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-catalog-backend-module-scaffolder-entity-model +## 0.1.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-scaffolder-common@1.5.5-next.0 + - @backstage/catalog-model@1.5.0 + ## 0.1.21-next.0 ### 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 09dfa63a91..0b3b1a9534 100644 --- a/plugins/catalog-backend-module-scaffolder-entity-model/package.json +++ b/plugins/catalog-backend-module-scaffolder-entity-model/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-scaffolder-entity-model", - "version": "0.1.21-next.0", + "version": "0.1.21-next.1", "description": "Adds support for the scaffolder specific entity model (e.g. the Template kind) to the catalog backend plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-unprocessed/CHANGELOG.md b/plugins/catalog-backend-module-unprocessed/CHANGELOG.md index 2abd4e32a3..435637c3d8 100644 --- a/plugins/catalog-backend-module-unprocessed/CHANGELOG.md +++ b/plugins/catalog-backend-module-unprocessed/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-unprocessed +## 0.4.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.4-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.4.10-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-unprocessed/package.json b/plugins/catalog-backend-module-unprocessed/package.json index b01fddef04..a1078106eb 100644 --- a/plugins/catalog-backend-module-unprocessed/package.json +++ b/plugins/catalog-backend-module-unprocessed/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-unprocessed", - "version": "0.4.10-next.0", + "version": "0.4.10-next.1", "description": "Backstage Catalog module to view unprocessed entities", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md index 796611fa90..826f0c5897 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-catalog-backend +## 1.24.1-next.1 + +### Patch Changes + +- 51240ee: Preserve default `allowedLocationTypes` when `setAllowedLocationTypes()` of `CatalogLocationsExtensionPoint` is not called. +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-search-backend-module-catalog@0.1.29-next.1 + - @backstage/backend-openapi-utils@0.1.16-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.9-next.1 + ## 1.24.1-next.0 ### Patch Changes diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 0c1983d1e2..c78d5dc578 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend", - "version": "1.24.1-next.0", + "version": "1.24.1-next.1", "description": "The Backstage backend plugin that provides the Backstage catalog", "backstage": { "role": "backend-plugin", diff --git a/plugins/catalog-common/CHANGELOG.md b/plugins/catalog-common/CHANGELOG.md index e2859fcc83..615bcc538e 100644 --- a/plugins/catalog-common/CHANGELOG.md +++ b/plugins/catalog-common/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-catalog-common +## 1.0.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/catalog-model@1.5.0 + ## 1.0.25 ### Patch Changes diff --git a/plugins/catalog-common/package.json b/plugins/catalog-common/package.json index 865dc02f4c..167c1b0a91 100644 --- a/plugins/catalog-common/package.json +++ b/plugins/catalog-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-common", - "version": "1.0.25", + "version": "1.0.26-next.0", "description": "Common functionalities for the catalog plugin", "backstage": { "role": "common-library", diff --git a/plugins/catalog-graph/CHANGELOG.md b/plugins/catalog-graph/CHANGELOG.md index 5995074b53..566420808c 100644 --- a/plugins/catalog-graph/CHANGELOG.md +++ b/plugins/catalog-graph/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-graph +## 0.4.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + ## 0.4.8-next.0 ### Patch Changes diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json index 51ed923a01..35508194a6 100644 --- a/plugins/catalog-graph/package.json +++ b/plugins/catalog-graph/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-graph", - "version": "0.4.8-next.0", + "version": "0.4.8-next.1", "backstage": { "role": "frontend-plugin", "pluginId": "catalog-graph", diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md index 484676f245..43e132823a 100644 --- a/plugins/catalog-import/CHANGELOG.md +++ b/plugins/catalog-import/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-catalog-import +## 0.12.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + ## 0.12.2-next.0 ### Patch Changes diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index dfc07ddb43..397d3c92d9 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-import", - "version": "0.12.2-next.0", + "version": "0.12.2-next.1", "description": "A Backstage plugin the helps you import entities into your catalog", "backstage": { "role": "frontend-plugin", diff --git a/plugins/catalog-node/CHANGELOG.md b/plugins/catalog-node/CHANGELOG.md index 3d1dbe07ba..f276e0a93e 100644 --- a/plugins/catalog-node/CHANGELOG.md +++ b/plugins/catalog-node/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-node +## 1.12.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 1.12.5-next.0 ### Patch Changes diff --git a/plugins/catalog-node/package.json b/plugins/catalog-node/package.json index 04a942f7b3..3e755330e3 100644 --- a/plugins/catalog-node/package.json +++ b/plugins/catalog-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-node", - "version": "1.12.5-next.0", + "version": "1.12.5-next.1", "description": "The plugin-catalog-node module for @backstage/plugin-catalog-backend", "backstage": { "role": "node-library", diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md index 982d3db031..38c15e8957 100644 --- a/plugins/catalog-react/CHANGELOG.md +++ b/plugins/catalog-react/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-catalog-react +## 1.12.3-next.1 + +### Patch Changes + +- 7ca331c: Correct `EntityDisplayName`'s icon alignment with the text. +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 1.12.3-next.0 ### Patch Changes diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index dc5a80d4b7..fdbd942529 100644 --- a/plugins/catalog-react/package.json +++ b/plugins/catalog-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-react", - "version": "1.12.3-next.0", + "version": "1.12.3-next.1", "description": "A frontend library that helps other Backstage plugins interact with the catalog", "backstage": { "role": "web-library", diff --git a/plugins/catalog-unprocessed-entities-common/CHANGELOG.md b/plugins/catalog-unprocessed-entities-common/CHANGELOG.md index ca38c923bd..e3dc87146f 100644 --- a/plugins/catalog-unprocessed-entities-common/CHANGELOG.md +++ b/plugins/catalog-unprocessed-entities-common/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-catalog-unprocessed-entities-common +## 0.0.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + ## 0.0.3 ### Patch Changes diff --git a/plugins/catalog-unprocessed-entities-common/package.json b/plugins/catalog-unprocessed-entities-common/package.json index 990f75bbea..8bded795b4 100644 --- a/plugins/catalog-unprocessed-entities-common/package.json +++ b/plugins/catalog-unprocessed-entities-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-unprocessed-entities-common", - "version": "0.0.3", + "version": "0.0.4-next.0", "description": "Common functionalities for the catalog-unprocessed-entities plugin", "backstage": { "role": "common-library", diff --git a/plugins/catalog/CHANGELOG.md b/plugins/catalog/CHANGELOG.md index e0b947b965..0a229ff17a 100644 --- a/plugins/catalog/CHANGELOG.md +++ b/plugins/catalog/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-catalog +## 1.21.2-next.1 + +### Patch Changes + +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/plugin-search-react@1.7.14-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/plugin-scaffolder-common@1.5.5-next.0 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/types@1.1.1 + ## 1.21.2-next.0 ### Patch Changes diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index 64f6b0d201..e747170032 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog", - "version": "1.21.2-next.0", + "version": "1.21.2-next.1", "description": "The Backstage plugin for browsing the Backstage catalog", "backstage": { "role": "frontend-plugin", diff --git a/plugins/devtools-backend/CHANGELOG.md b/plugins/devtools-backend/CHANGELOG.md index d415b1bf65..323385dc82 100644 --- a/plugins/devtools-backend/CHANGELOG.md +++ b/plugins/devtools-backend/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-devtools-backend +## 0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.9.0-next.1 + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-devtools-common@0.1.12-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.3.9-next.0 ### Patch Changes diff --git a/plugins/devtools-backend/package.json b/plugins/devtools-backend/package.json index 1fe3330698..f2f39dea9a 100644 --- a/plugins/devtools-backend/package.json +++ b/plugins/devtools-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-devtools-backend", - "version": "0.3.9-next.0", + "version": "0.3.9-next.1", "backstage": { "role": "backend-plugin", "pluginId": "devtools", diff --git a/plugins/devtools-common/CHANGELOG.md b/plugins/devtools-common/CHANGELOG.md index 37923e3fc7..09e8a85edb 100644 --- a/plugins/devtools-common/CHANGELOG.md +++ b/plugins/devtools-common/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-devtools-common +## 0.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/types@1.1.1 + ## 0.1.11 ### Patch Changes diff --git a/plugins/devtools-common/package.json b/plugins/devtools-common/package.json index f476580ac0..be1fab2967 100644 --- a/plugins/devtools-common/package.json +++ b/plugins/devtools-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-devtools-common", - "version": "0.1.11", + "version": "0.1.12-next.0", "description": "Common functionalities for the devtools plugin", "backstage": { "role": "common-library", diff --git a/plugins/devtools/CHANGELOG.md b/plugins/devtools/CHANGELOG.md index b7db4a95bc..496ff5cf52 100644 --- a/plugins/devtools/CHANGELOG.md +++ b/plugins/devtools/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-devtools +## 0.1.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/plugin-devtools-common@0.1.12-next.0 + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + ## 0.1.17-next.0 ### Patch Changes diff --git a/plugins/devtools/package.json b/plugins/devtools/package.json index 2827110d4a..a6956161c6 100644 --- a/plugins/devtools/package.json +++ b/plugins/devtools/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-devtools", - "version": "0.1.17-next.0", + "version": "0.1.17-next.1", "backstage": { "role": "frontend-plugin", "pluginId": "devtools", diff --git a/plugins/events-backend-module-aws-sqs/CHANGELOG.md b/plugins/events-backend-module-aws-sqs/CHANGELOG.md index 5e954c38ca..53a4e8a3fa 100644 --- a/plugins/events-backend-module-aws-sqs/CHANGELOG.md +++ b/plugins/events-backend-module-aws-sqs/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-events-backend-module-aws-sqs +## 0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.9-next.1 + ## 0.3.9-next.0 ### Patch Changes diff --git a/plugins/events-backend-module-aws-sqs/package.json b/plugins/events-backend-module-aws-sqs/package.json index 0135594bd6..0a4ef481ff 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.3.9-next.0", + "version": "0.3.9-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-azure/CHANGELOG.md b/plugins/events-backend-module-azure/CHANGELOG.md index 27060d63e4..0c13627d71 100644 --- a/plugins/events-backend-module-azure/CHANGELOG.md +++ b/plugins/events-backend-module-azure/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-events-backend-module-azure +## 0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + ## 0.2.9-next.0 ### Patch Changes diff --git a/plugins/events-backend-module-azure/package.json b/plugins/events-backend-module-azure/package.json index eacae60bc2..c24b8743ac 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.2.9-next.0", + "version": "0.2.9-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md index a411dcecaa..0c333e1d8f 100644 --- a/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-events-backend-module-bitbucket-cloud +## 0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + ## 0.2.9-next.0 ### Patch Changes diff --git a/plugins/events-backend-module-bitbucket-cloud/package.json b/plugins/events-backend-module-bitbucket-cloud/package.json index 084b3cb512..87fb26f2e5 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.2.9-next.0", + "version": "0.2.9-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-gerrit/CHANGELOG.md b/plugins/events-backend-module-gerrit/CHANGELOG.md index 3cc3f4f3bf..2cd77d9933 100644 --- a/plugins/events-backend-module-gerrit/CHANGELOG.md +++ b/plugins/events-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-events-backend-module-gerrit +## 0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + ## 0.2.9-next.0 ### Patch Changes diff --git a/plugins/events-backend-module-gerrit/package.json b/plugins/events-backend-module-gerrit/package.json index 99a1cba796..43fd0446eb 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.2.9-next.0", + "version": "0.2.9-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-github/CHANGELOG.md b/plugins/events-backend-module-github/CHANGELOG.md index 3ba0e5de31..068b54c0b0 100644 --- a/plugins/events-backend-module-github/CHANGELOG.md +++ b/plugins/events-backend-module-github/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-events-backend-module-github +## 0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.9-next.1 + ## 0.2.9-next.0 ### Patch Changes diff --git a/plugins/events-backend-module-github/package.json b/plugins/events-backend-module-github/package.json index bad39f8080..57516356ea 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.2.9-next.0", + "version": "0.2.9-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-gitlab/CHANGELOG.md b/plugins/events-backend-module-gitlab/CHANGELOG.md index 39fd274342..b717e5886d 100644 --- a/plugins/events-backend-module-gitlab/CHANGELOG.md +++ b/plugins/events-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-events-backend-module-gitlab +## 0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.9-next.1 + ## 0.2.9-next.0 ### Patch Changes diff --git a/plugins/events-backend-module-gitlab/package.json b/plugins/events-backend-module-gitlab/package.json index f2d76a5193..34643977cb 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.2.9-next.0", + "version": "0.2.9-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-test-utils/CHANGELOG.md b/plugins/events-backend-test-utils/CHANGELOG.md index be1e0f023c..33ad7e0318 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.33-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.9-next.1 + ## 0.1.33-next.0 ### Patch Changes diff --git a/plugins/events-backend-test-utils/package.json b/plugins/events-backend-test-utils/package.json index f6914c81c5..a20f4fa7c7 100644 --- a/plugins/events-backend-test-utils/package.json +++ b/plugins/events-backend-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-test-utils", - "version": "0.1.33-next.0", + "version": "0.1.33-next.1", "description": "The plugin-events-backend-test-utils for @backstage/plugin-events-node", "backstage": { "role": "node-library", diff --git a/plugins/events-backend/CHANGELOG.md b/plugins/events-backend/CHANGELOG.md index 6a6a17c13f..1bbf2359e4 100644 --- a/plugins/events-backend/CHANGELOG.md +++ b/plugins/events-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-events-backend +## 0.3.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.9-next.1 + ## 0.3.10-next.0 ### Patch Changes diff --git a/plugins/events-backend/package.json b/plugins/events-backend/package.json index accb240c22..e563551d5b 100644 --- a/plugins/events-backend/package.json +++ b/plugins/events-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend", - "version": "0.3.10-next.0", + "version": "0.3.10-next.1", "backstage": { "role": "backend-plugin", "pluginId": "events", diff --git a/plugins/events-node/CHANGELOG.md b/plugins/events-node/CHANGELOG.md index a3dfd8682d..a01292b23e 100644 --- a/plugins/events-node/CHANGELOG.md +++ b/plugins/events-node/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-events-node +## 0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + ## 0.3.9-next.0 ### Patch Changes diff --git a/plugins/events-node/package.json b/plugins/events-node/package.json index 7387294d24..7943aadc8f 100644 --- a/plugins/events-node/package.json +++ b/plugins/events-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-node", - "version": "0.3.9-next.0", + "version": "0.3.9-next.1", "description": "The plugin-events-node module for @backstage/plugin-events-backend", "backstage": { "role": "node-library", diff --git a/plugins/example-todo-list-backend/CHANGELOG.md b/plugins/example-todo-list-backend/CHANGELOG.md index 3d3c9fd1bb..cff91b2e5c 100644 --- a/plugins/example-todo-list-backend/CHANGELOG.md +++ b/plugins/example-todo-list-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @internal/plugin-todo-list-backend +## 1.0.30-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 1.0.30-next.0 ### Patch Changes diff --git a/plugins/example-todo-list-backend/package.json b/plugins/example-todo-list-backend/package.json index 1ea02728de..2e84c6c2b7 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.30-next.0", + "version": "1.0.30-next.1", "backstage": { "role": "backend-plugin", "pluginId": "todo-list", diff --git a/plugins/example-todo-list-common/CHANGELOG.md b/plugins/example-todo-list-common/CHANGELOG.md index e30cb653df..f780b14906 100644 --- a/plugins/example-todo-list-common/CHANGELOG.md +++ b/plugins/example-todo-list-common/CHANGELOG.md @@ -1,5 +1,12 @@ # @internal/plugin-todo-list-common +## 1.0.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + ## 1.0.20 ### Patch Changes diff --git a/plugins/example-todo-list-common/package.json b/plugins/example-todo-list-common/package.json index efccce611f..6071032963 100644 --- a/plugins/example-todo-list-common/package.json +++ b/plugins/example-todo-list-common/package.json @@ -1,6 +1,6 @@ { "name": "@internal/plugin-todo-list-common", - "version": "1.0.20", + "version": "1.0.21-next.0", "backstage": { "role": "common-library", "pluginId": "todo-list", diff --git a/plugins/home/CHANGELOG.md b/plugins/home/CHANGELOG.md index 75c786c4de..2cd0a184fd 100644 --- a/plugins/home/CHANGELOG.md +++ b/plugins/home/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-home +## 0.7.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-home-react@0.1.16-next.0 + ## 0.7.8-next.0 ### Patch Changes diff --git a/plugins/home/package.json b/plugins/home/package.json index d2f0c43a11..792f7a1525 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-home", - "version": "0.7.8-next.0", + "version": "0.7.9-next.1", "description": "A Backstage plugin that helps you build a home page", "backstage": { "role": "frontend-plugin", diff --git a/plugins/kubernetes-backend/CHANGELOG.md b/plugins/kubernetes-backend/CHANGELOG.md index d749d8579e..c286d49164 100644 --- a/plugins/kubernetes-backend/CHANGELOG.md +++ b/plugins/kubernetes-backend/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-kubernetes-backend +## 0.18.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-kubernetes-common@0.8.2-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + - @backstage/plugin-kubernetes-node@0.1.17-next.1 + ## 0.18.4-next.0 ### Patch Changes diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index eb135d4f0f..71154e0712 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-backend", - "version": "0.18.4-next.0", + "version": "0.18.4-next.1", "description": "A Backstage backend plugin that integrates towards Kubernetes", "backstage": { "role": "backend-plugin", diff --git a/plugins/kubernetes-cluster/CHANGELOG.md b/plugins/kubernetes-cluster/CHANGELOG.md index cd5b6772de..cab3826e64 100644 --- a/plugins/kubernetes-cluster/CHANGELOG.md +++ b/plugins/kubernetes-cluster/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-kubernetes-cluster +## 0.0.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/plugin-kubernetes-common@0.8.2-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-kubernetes-react@0.4.2-next.1 + ## 0.0.14-next.0 ### Patch Changes diff --git a/plugins/kubernetes-cluster/package.json b/plugins/kubernetes-cluster/package.json index 5549c8dcc5..f2b1feb906 100644 --- a/plugins/kubernetes-cluster/package.json +++ b/plugins/kubernetes-cluster/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-cluster", - "version": "0.0.14-next.0", + "version": "0.0.14-next.1", "description": "A Backstage plugin that shows details of Kubernetes clusters", "backstage": { "role": "frontend-plugin", diff --git a/plugins/kubernetes-common/CHANGELOG.md b/plugins/kubernetes-common/CHANGELOG.md index a9cabafdd0..9ff6547ad4 100644 --- a/plugins/kubernetes-common/CHANGELOG.md +++ b/plugins/kubernetes-common/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-kubernetes-common +## 0.8.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/types@1.1.1 + ## 0.8.1 ### Patch Changes diff --git a/plugins/kubernetes-common/package.json b/plugins/kubernetes-common/package.json index db94d165e4..7ac04abea5 100644 --- a/plugins/kubernetes-common/package.json +++ b/plugins/kubernetes-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-common", - "version": "0.8.1", + "version": "0.8.2-next.0", "description": "Common functionalities for kubernetes, to be shared between kubernetes and kubernetes-backend plugin", "backstage": { "role": "common-library", diff --git a/plugins/kubernetes-node/CHANGELOG.md b/plugins/kubernetes-node/CHANGELOG.md index 58c458da9c..6e738ab3aa 100644 --- a/plugins/kubernetes-node/CHANGELOG.md +++ b/plugins/kubernetes-node/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-kubernetes-node +## 0.1.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-kubernetes-common@0.8.2-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/types@1.1.1 + ## 0.1.17-next.0 ### Patch Changes diff --git a/plugins/kubernetes-node/package.json b/plugins/kubernetes-node/package.json index 6d1d6d73f8..7597206bd0 100644 --- a/plugins/kubernetes-node/package.json +++ b/plugins/kubernetes-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-node", - "version": "0.1.17-next.0", + "version": "0.1.17-next.1", "description": "Node.js library for the kubernetes plugin", "backstage": { "role": "node-library", diff --git a/plugins/kubernetes-react/CHANGELOG.md b/plugins/kubernetes-react/CHANGELOG.md index c84b5c01e3..8859563287 100644 --- a/plugins/kubernetes-react/CHANGELOG.md +++ b/plugins/kubernetes-react/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-kubernetes-react +## 0.4.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-common@0.8.2-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.4.2-next.0 ### Patch Changes diff --git a/plugins/kubernetes-react/package.json b/plugins/kubernetes-react/package.json index 2f4ddd7415..094fdaa5e2 100644 --- a/plugins/kubernetes-react/package.json +++ b/plugins/kubernetes-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-react", - "version": "0.4.2-next.0", + "version": "0.4.2-next.1", "description": "Web library for the kubernetes-react plugin", "backstage": { "role": "web-library", diff --git a/plugins/kubernetes/CHANGELOG.md b/plugins/kubernetes/CHANGELOG.md index 26fbfffbdb..384f6574bc 100644 --- a/plugins/kubernetes/CHANGELOG.md +++ b/plugins/kubernetes/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-kubernetes +## 0.11.13-next.1 + +### Patch Changes + +- e6c15cc: Adds support for Backstage's new frontend system, available via the `/alpha` sub-path export. +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/plugin-kubernetes-common@0.8.2-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-kubernetes-react@0.4.2-next.1 + ## 0.11.13-next.0 ### Patch Changes diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index d44d175211..d711c5bdb5 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes", - "version": "0.11.13-next.0", + "version": "0.11.13-next.1", "description": "A Backstage plugin that integrates towards Kubernetes", "backstage": { "role": "frontend-plugin", diff --git a/plugins/notifications-backend-module-email/CHANGELOG.md b/plugins/notifications-backend-module-email/CHANGELOG.md index f13ba48616..1a9e5ad4bc 100644 --- a/plugins/notifications-backend-module-email/CHANGELOG.md +++ b/plugins/notifications-backend-module-email/CHANGELOG.md @@ -1,5 +1,65 @@ # @backstage/plugin-notifications-backend-module-email +## 0.2.0-next.1 + +### Minor Changes + +- def53a7: **BREAKING** Following `NotificationTemplateRenderer` methods now return a Promise and **must** be awaited: `getSubject`, `getText` and `getHtml`. + + Required changes and example usage: + + ```diff + import { notificationsEmailTemplateExtensionPoint } from '@backstage/plugin-notifications-backend-module-email'; + import { Notification } from '@backstage/plugin-notifications-common'; + +import { getNotificationSubject, getNotificationTextContent, getNotificationHtmlContent } from 'my-notification-processing-library` + export const notificationsModuleEmailDecorator = createBackendModule({ + pluginId: 'notifications', + moduleId: 'email.templates', + register(reg) { + reg.registerInit({ + deps: { + emailTemplates: notificationsEmailTemplateExtensionPoint, + }, + async init({ emailTemplates }) { + emailTemplates.setTemplateRenderer({ + - getSubject(notification) { + + async getSubject(notification) { + - return `New notification from ${notification.source}`; + + const subject = await getNotificationSubject(notification); + + return `New notification from ${subject}`; + }, + - getText(notification) { + + async getText(notification) { + - return notification.content; + + const text = await getNotificationTextContent(notification); + + return text; + }, + - getHtml(notification) { + + async getHtml(notification) { + - return `<p>${notification.content}</p>`; + + const html = await getNotificationHtmlContent(notification); + + return html; + }, + }); + }, + }); + }, + }); + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration-aws-node@0.1.12 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.4-next.1 + ## 0.1.4-next.0 ### Patch Changes diff --git a/plugins/notifications-backend-module-email/package.json b/plugins/notifications-backend-module-email/package.json index c024e6ad50..425186fcad 100644 --- a/plugins/notifications-backend-module-email/package.json +++ b/plugins/notifications-backend-module-email/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications-backend-module-email", - "version": "0.1.4-next.0", + "version": "0.2.0-next.1", "description": "The email backend module for the notifications plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/notifications-backend/CHANGELOG.md b/plugins/notifications-backend/CHANGELOG.md index ef654d213c..9afeff1a51 100644 --- a/plugins/notifications-backend/CHANGELOG.md +++ b/plugins/notifications-backend/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-notifications-backend +## 0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.4-next.1 + - @backstage/plugin-signals-node@0.1.9-next.1 + ## 0.3.4-next.0 ### Patch Changes diff --git a/plugins/notifications-backend/package.json b/plugins/notifications-backend/package.json index b59ae301f2..5916b18116 100644 --- a/plugins/notifications-backend/package.json +++ b/plugins/notifications-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications-backend", - "version": "0.3.4-next.0", + "version": "0.3.4-next.1", "backstage": { "role": "backend-plugin", "pluginId": "notifications", diff --git a/plugins/notifications-node/CHANGELOG.md b/plugins/notifications-node/CHANGELOG.md index 4344467104..6907885ce7 100644 --- a/plugins/notifications-node/CHANGELOG.md +++ b/plugins/notifications-node/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-notifications-node +## 0.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-signals-node@0.1.9-next.1 + ## 0.2.4-next.0 ### Patch Changes diff --git a/plugins/notifications-node/package.json b/plugins/notifications-node/package.json index b71e5d954f..e3b61e2734 100644 --- a/plugins/notifications-node/package.json +++ b/plugins/notifications-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications-node", - "version": "0.2.4-next.0", + "version": "0.2.4-next.1", "description": "Node.js library for the notifications plugin", "backstage": { "role": "node-library", diff --git a/plugins/org-react/CHANGELOG.md b/plugins/org-react/CHANGELOG.md index 9d0c722d80..e5994b4ec4 100644 --- a/plugins/org-react/CHANGELOG.md +++ b/plugins/org-react/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-org-react +## 0.1.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + ## 0.1.27-next.0 ### Patch Changes diff --git a/plugins/org-react/package.json b/plugins/org-react/package.json index 65d600b96f..3dca7e029b 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.27-next.0", + "version": "0.1.27-next.1", "backstage": { "role": "web-library", "pluginId": "org", diff --git a/plugins/org/CHANGELOG.md b/plugins/org/CHANGELOG.md index 130a62d56d..69d6b3fc0f 100644 --- a/plugins/org/CHANGELOG.md +++ b/plugins/org/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-org +## 0.6.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + ## 0.6.28-next.0 ### Patch Changes diff --git a/plugins/org/package.json b/plugins/org/package.json index a3ed608aeb..72ea35013d 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-org", - "version": "0.6.28-next.0", + "version": "0.6.28-next.1", "description": "A Backstage plugin that helps you create entity pages for your organization", "backstage": { "role": "frontend-plugin", diff --git a/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md b/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md index c2e00cf839..559697105d 100644 --- a/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md +++ b/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-permission-backend-module-allow-all-policy +## 0.1.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.1.20-next.0 ### 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 85becb2b60..fb40f025ce 100644 --- a/plugins/permission-backend-module-policy-allow-all/package.json +++ b/plugins/permission-backend-module-policy-allow-all/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-backend-module-allow-all-policy", - "version": "0.1.20-next.0", + "version": "0.1.20-next.1", "description": "Allow all policy backend module for the permission plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/permission-backend/CHANGELOG.md b/plugins/permission-backend/CHANGELOG.md index c5e9b7675f..9f0f3cf8ac 100644 --- a/plugins/permission-backend/CHANGELOG.md +++ b/plugins/permission-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-permission-backend +## 0.5.47-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.5.47-next.0 ### Patch Changes diff --git a/plugins/permission-backend/package.json b/plugins/permission-backend/package.json index 11ad9538be..100bde718f 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.47-next.0", + "version": "0.5.47-next.1", "backstage": { "role": "backend-plugin", "pluginId": "permission", diff --git a/plugins/permission-common/CHANGELOG.md b/plugins/permission-common/CHANGELOG.md index 92a33afea2..9194c9cae6 100644 --- a/plugins/permission-common/CHANGELOG.md +++ b/plugins/permission-common/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-permission-common +## 0.8.1-next.0 + +### Patch Changes + +- 137fa34: Add the MetadataResponseSerializedRule type from @backstage/plugin-permission-node, since this type might be used in frontend code. +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.8.0 ### Minor Changes diff --git a/plugins/permission-common/package.json b/plugins/permission-common/package.json index 585fc00531..323dea5638 100644 --- a/plugins/permission-common/package.json +++ b/plugins/permission-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-common", - "version": "0.8.0", + "version": "0.8.1-next.0", "description": "Isomorphic types and client for Backstage permissions and authorization", "backstage": { "role": "common-library", diff --git a/plugins/permission-node/CHANGELOG.md b/plugins/permission-node/CHANGELOG.md index 31d2f9145e..3e29fe0c2a 100644 --- a/plugins/permission-node/CHANGELOG.md +++ b/plugins/permission-node/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-permission-node +## 0.8.1-next.1 + +### Patch Changes + +- 5cd9878: The MetadataResponseSerializedRule type has been moved to @backstage/plugin-permission-common, and should be imported from there going forward. To avoid an immediate breaking change, this type is still re-exported from this package, but is marked as deprecated and will be removed in a future release. +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.18-next.1 + ## 0.8.1-next.0 ### Patch Changes diff --git a/plugins/permission-node/package.json b/plugins/permission-node/package.json index 630391f373..4e024a3f10 100644 --- a/plugins/permission-node/package.json +++ b/plugins/permission-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-node", - "version": "0.8.1-next.0", + "version": "0.8.1-next.1", "description": "Common permission and authorization utilities for backend plugins", "backstage": { "role": "node-library", diff --git a/plugins/permission-react/CHANGELOG.md b/plugins/permission-react/CHANGELOG.md index 2b19b7e849..8b2e8e3250 100644 --- a/plugins/permission-react/CHANGELOG.md +++ b/plugins/permission-react/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-permission-react +## 0.4.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + ## 0.4.24 ### Patch Changes diff --git a/plugins/permission-react/package.json b/plugins/permission-react/package.json index c119be8eb9..8bd566a34c 100644 --- a/plugins/permission-react/package.json +++ b/plugins/permission-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-react", - "version": "0.4.24", + "version": "0.4.25-next.0", "backstage": { "role": "web-library", "pluginId": "permission", diff --git a/plugins/proxy-backend/CHANGELOG.md b/plugins/proxy-backend/CHANGELOG.md index d906b17327..bfec70e942 100644 --- a/plugins/proxy-backend/CHANGELOG.md +++ b/plugins/proxy-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-proxy-backend +## 0.5.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + ## 0.5.4-next.0 ### Patch Changes diff --git a/plugins/proxy-backend/package.json b/plugins/proxy-backend/package.json index ec3594f985..ad4627b907 100644 --- a/plugins/proxy-backend/package.json +++ b/plugins/proxy-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-proxy-backend", - "version": "0.5.4-next.0", + "version": "0.5.4-next.1", "description": "A Backstage backend plugin that helps you set up proxy endpoints in the backend", "backstage": { "role": "backend-plugin", diff --git a/plugins/scaffolder-backend-module-azure/CHANGELOG.md b/plugins/scaffolder-backend-module-azure/CHANGELOG.md index bb5b2644ae..fe925ffb7d 100644 --- a/plugins/scaffolder-backend-module-azure/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-azure/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-scaffolder-backend-module-azure +## 0.1.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + ## 0.1.15-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-azure/package.json b/plugins/scaffolder-backend-module-azure/package.json index c2b7a39e0c..19470655e6 100644 --- a/plugins/scaffolder-backend-module-azure/package.json +++ b/plugins/scaffolder-backend-module-azure/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-azure", - "version": "0.1.15-next.0", + "version": "0.1.15-next.1", "description": "The azure module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md index 04236c2a4b..0d52996a88 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder-backend-module-bitbucket-cloud +## 0.1.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-bitbucket-cloud-common@0.2.22-next.0 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + ## 0.1.13-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/package.json b/plugins/scaffolder-backend-module-bitbucket-cloud/package.json index 39080241a0..f5bbd2df63 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/package.json +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud", - "version": "0.1.13-next.0", + "version": "0.1.13-next.1", "description": "The Bitbucket Cloud module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md b/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md index 93801a3012..7d4b793d10 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder-backend-module-bitbucket-server +## 0.1.13-next.1 + +### Patch Changes + +- e3b64be: Added examples for publish:bitbucketServer action and improve its test cases +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + ## 0.1.13-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-bitbucket-server/package.json b/plugins/scaffolder-backend-module-bitbucket-server/package.json index b995ef57da..c4c00f96e7 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/package.json +++ b/plugins/scaffolder-backend-module-bitbucket-server/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-bitbucket-server", - "version": "0.1.13-next.0", + "version": "0.1.13-next.1", "description": "The Bitbucket Server module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md b/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md index b905cc33e1..8ab0a80df0 100644 --- a/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-backend-module-bitbucket +## 0.2.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.13-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.13-next.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + ## 0.2.13-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-bitbucket/package.json b/plugins/scaffolder-backend-module-bitbucket/package.json index a853f795af..584f61b502 100644 --- a/plugins/scaffolder-backend-module-bitbucket/package.json +++ b/plugins/scaffolder-backend-module-bitbucket/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-bitbucket", - "version": "0.2.13-next.0", + "version": "0.2.13-next.1", "description": "The bitbucket module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md b/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md index 29677250a5..9c9b493c1d 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.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + ## 0.2.24-next.0 ### 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 39fb5f49b9..5b54e3841d 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/package.json +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown", - "version": "0.2.24-next.0", + "version": "0.2.24-next.1", "description": "The confluence-to-markdown module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md index 865478ea2b..71ce038f43 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-backend-module-cookiecutter +## 0.2.47-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + ## 0.2.47-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-cookiecutter/package.json b/plugins/scaffolder-backend-module-cookiecutter/package.json index 2f21b89244..ec1899099b 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/package.json +++ b/plugins/scaffolder-backend-module-cookiecutter/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-cookiecutter", - "version": "0.2.47-next.0", + "version": "0.2.47-next.1", "description": "A module for the scaffolder backend that lets you template projects using cookiecutter", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-gcp/CHANGELOG.md b/plugins/scaffolder-backend-module-gcp/CHANGELOG.md index 05843ee288..551141df6c 100644 --- a/plugins/scaffolder-backend-module-gcp/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gcp/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-scaffolder-backend-module-gcp +## 0.1.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + ## 0.1.1-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gcp/package.json b/plugins/scaffolder-backend-module-gcp/package.json index f6355e93f4..1c2feb106a 100644 --- a/plugins/scaffolder-backend-module-gcp/package.json +++ b/plugins/scaffolder-backend-module-gcp/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gcp", - "version": "0.1.1-next.0", + "version": "0.1.1-next.1", "description": "The GCP Bucket module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md b/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md index d95047ba64..6827109801 100644 --- a/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-scaffolder-backend-module-gerrit +## 0.1.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + ## 0.1.15-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gerrit/package.json b/plugins/scaffolder-backend-module-gerrit/package.json index 4be6e4c56c..68bdd36f44 100644 --- a/plugins/scaffolder-backend-module-gerrit/package.json +++ b/plugins/scaffolder-backend-module-gerrit/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gerrit", - "version": "0.1.15-next.0", + "version": "0.1.15-next.1", "description": "The gerrit module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-gitea/CHANGELOG.md b/plugins/scaffolder-backend-module-gitea/CHANGELOG.md index 6bc250f801..983d3cebb0 100644 --- a/plugins/scaffolder-backend-module-gitea/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gitea/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder-backend-module-gitea +## 0.1.13-next.1 + +### Patch Changes + +- 24de005: Added test cases for publish:gitea examples +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + ## 0.1.13-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gitea/package.json b/plugins/scaffolder-backend-module-gitea/package.json index 22b6ab700f..432daf6c8b 100644 --- a/plugins/scaffolder-backend-module-gitea/package.json +++ b/plugins/scaffolder-backend-module-gitea/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gitea", - "version": "0.1.13-next.0", + "version": "0.1.13-next.1", "description": "The gitea module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-github/CHANGELOG.md b/plugins/scaffolder-backend-module-github/CHANGELOG.md index 0399be8de3..d39143c7c4 100644 --- a/plugins/scaffolder-backend-module-github/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-github/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-backend-module-github +## 0.4.1-next.1 + +### Patch Changes + +- d21d307: Added examples for github:environment:create action and improve its test cases +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + ## 0.4.1-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-github/package.json b/plugins/scaffolder-backend-module-github/package.json index a43469d7e5..68a0475622 100644 --- a/plugins/scaffolder-backend-module-github/package.json +++ b/plugins/scaffolder-backend-module-github/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-github", - "version": "0.4.1-next.0", + "version": "0.4.1-next.1", "description": "The github module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md b/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md index 41df7c2a60..c0099a16c6 100644 --- a/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder-backend-module-gitlab +## 0.4.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + ## 0.4.5-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gitlab/package.json b/plugins/scaffolder-backend-module-gitlab/package.json index e4705e6206..410a6111f5 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.4.5-next.0", + "version": "0.4.5-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "scaffolder", diff --git a/plugins/scaffolder-backend-module-notifications/CHANGELOG.md b/plugins/scaffolder-backend-module-notifications/CHANGELOG.md index f51473dd0c..31f8197923 100644 --- a/plugins/scaffolder-backend-module-notifications/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-notifications/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-scaffolder-backend-module-notifications +## 0.0.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.4-next.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + ## 0.0.6-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-notifications/package.json b/plugins/scaffolder-backend-module-notifications/package.json index 15fe158651..c4a10f6a92 100644 --- a/plugins/scaffolder-backend-module-notifications/package.json +++ b/plugins/scaffolder-backend-module-notifications/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-notifications", - "version": "0.0.6-next.0", + "version": "0.0.6-next.1", "description": "The notifications backend module for the scaffolder plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-rails/CHANGELOG.md b/plugins/scaffolder-backend-module-rails/CHANGELOG.md index f9ce2e1e6b..ff68b1d78c 100644 --- a/plugins/scaffolder-backend-module-rails/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-rails/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-backend-module-rails +## 0.4.40-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + ## 0.4.40-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-rails/package.json b/plugins/scaffolder-backend-module-rails/package.json index a2e2a215dd..38088ccfc8 100644 --- a/plugins/scaffolder-backend-module-rails/package.json +++ b/plugins/scaffolder-backend-module-rails/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-rails", - "version": "0.4.40-next.0", + "version": "0.4.40-next.1", "description": "A module for the scaffolder backend that lets you template projects using Rails", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-sentry/CHANGELOG.md b/plugins/scaffolder-backend-module-sentry/CHANGELOG.md index 0dd4fb6c5b..7515c6494b 100644 --- a/plugins/scaffolder-backend-module-sentry/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-sentry/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-scaffolder-backend-module-sentry +## 0.1.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + ## 0.1.31-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-sentry/package.json b/plugins/scaffolder-backend-module-sentry/package.json index 3eb11dc3e9..069f310dcc 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.31-next.0", + "version": "0.1.31-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "scaffolder", diff --git a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md index 3c9fe7db6b..069390e33f 100644 --- a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-scaffolder-backend-module-yeoman +## 0.3.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + - @backstage/plugin-scaffolder-node-test-utils@0.1.10-next.1 + ## 0.3.7-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-yeoman/package.json b/plugins/scaffolder-backend-module-yeoman/package.json index 29f4d7c1aa..a820392630 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.3.7-next.0", + "version": "0.3.7-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "scaffolder", diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md index 8496dbf17b..b1bb14c6a7 100644 --- a/plugins/scaffolder-backend/CHANGELOG.md +++ b/plugins/scaffolder-backend/CHANGELOG.md @@ -1,5 +1,37 @@ # @backstage/plugin-scaffolder-backend +## 1.23.1-next.1 + +### Patch Changes + +- ef87e06: Fix scaffolder action `catalog:write` to write to directories that don't already exist +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-github@0.4.1-next.1 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.13-next.1 + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.13-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-scaffolder-common@1.5.5-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.13-next.1 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + - @backstage/plugin-bitbucket-cloud-common@0.2.22-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.21-next.1 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.15-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.13-next.1 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.15-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.4.5-next.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + ## 1.23.1-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index af67447fed..8f304690f6 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend", - "version": "1.23.1-next.0", + "version": "1.23.1-next.1", "description": "The Backstage backend plugin that helps you create new things", "backstage": { "role": "backend-plugin", diff --git a/plugins/scaffolder-common/CHANGELOG.md b/plugins/scaffolder-common/CHANGELOG.md index 914faf70f3..6c2b31d18b 100644 --- a/plugins/scaffolder-common/CHANGELOG.md +++ b/plugins/scaffolder-common/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-scaffolder-common +## 1.5.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/types@1.1.1 + ## 1.5.4 ### Patch Changes diff --git a/plugins/scaffolder-common/package.json b/plugins/scaffolder-common/package.json index d86f0d67c0..e37ee5462c 100644 --- a/plugins/scaffolder-common/package.json +++ b/plugins/scaffolder-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-common", - "version": "1.5.4", + "version": "1.5.5-next.0", "description": "Common functionalities for the scaffolder, to be shared between scaffolder and scaffolder-backend plugin", "backstage": { "role": "common-library", diff --git a/plugins/scaffolder-node-test-utils/CHANGELOG.md b/plugins/scaffolder-node-test-utils/CHANGELOG.md index 9eb166062e..d49e076730 100644 --- a/plugins/scaffolder-node-test-utils/CHANGELOG.md +++ b/plugins/scaffolder-node-test-utils/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-scaffolder-node-test-utils +## 0.1.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.1 + - @backstage/backend-test-utils@0.4.5-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.9-next.1 + ## 0.1.10-next.0 ### Patch Changes diff --git a/plugins/scaffolder-node-test-utils/package.json b/plugins/scaffolder-node-test-utils/package.json index ef31d541f4..f3ee13fcbe 100644 --- a/plugins/scaffolder-node-test-utils/package.json +++ b/plugins/scaffolder-node-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-node-test-utils", - "version": "0.1.10-next.0", + "version": "0.1.10-next.1", "backstage": { "role": "node-library", "pluginId": "scaffolder", diff --git a/plugins/scaffolder-node/CHANGELOG.md b/plugins/scaffolder-node/CHANGELOG.md index db361e0120..3dc6b6b952 100644 --- a/plugins/scaffolder-node/CHANGELOG.md +++ b/plugins/scaffolder-node/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-node +## 0.4.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-scaffolder-common@1.5.5-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.4.9-next.0 ### Patch Changes diff --git a/plugins/scaffolder-node/package.json b/plugins/scaffolder-node/package.json index 2cb7198631..544c40d5b7 100644 --- a/plugins/scaffolder-node/package.json +++ b/plugins/scaffolder-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-node", - "version": "0.4.9-next.0", + "version": "0.4.9-next.1", "description": "The plugin-scaffolder-node module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "node-library", diff --git a/plugins/scaffolder-react/CHANGELOG.md b/plugins/scaffolder-react/CHANGELOG.md index f23a0e2425..ab664aecb3 100644 --- a/plugins/scaffolder-react/CHANGELOG.md +++ b/plugins/scaffolder-react/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-scaffolder-react +## 1.11.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/plugin-scaffolder-common@1.5.5-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 1.11.0-next.0 ### Minor Changes diff --git a/plugins/scaffolder-react/package.json b/plugins/scaffolder-react/package.json index 7c16c11c1a..d4bdd70081 100644 --- a/plugins/scaffolder-react/package.json +++ b/plugins/scaffolder-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-react", - "version": "1.11.0-next.0", + "version": "1.11.0-next.1", "description": "A frontend library that helps other Backstage plugins interact with the Scaffolder", "backstage": { "role": "web-library", diff --git a/plugins/scaffolder/CHANGELOG.md b/plugins/scaffolder/CHANGELOG.md index e012f99928..8bb5dc093d 100644 --- a/plugins/scaffolder/CHANGELOG.md +++ b/plugins/scaffolder/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-scaffolder +## 1.23.1-next.1 + +### Patch Changes + +- 896a22d: Fix helper text margin for scaffolder EntityNamePicker and EntityTagsPicker when using outlined text field +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/plugin-scaffolder-react@1.11.0-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/plugin-scaffolder-common@1.5.5-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/types@1.1.1 + ## 1.23.1-next.0 ### Patch Changes diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index ed1bb10e7a..5d0b842be6 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder", - "version": "1.23.1-next.0", + "version": "1.23.1-next.1", "description": "The Backstage plugin that helps you create new things", "backstage": { "role": "frontend-plugin", diff --git a/plugins/search-backend-module-catalog/CHANGELOG.md b/plugins/search-backend-module-catalog/CHANGELOG.md index 1c6f7205f3..14b950872a 100644 --- a/plugins/search-backend-module-catalog/CHANGELOG.md +++ b/plugins/search-backend-module-catalog/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-search-backend-module-catalog +## 0.1.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-search-backend-node@1.2.28-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.1.29-next.0 ### Patch Changes diff --git a/plugins/search-backend-module-catalog/package.json b/plugins/search-backend-module-catalog/package.json index 972a8b66d2..9914ab599e 100644 --- a/plugins/search-backend-module-catalog/package.json +++ b/plugins/search-backend-module-catalog/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-catalog", - "version": "0.1.29-next.0", + "version": "0.1.29-next.1", "description": "A module for the search backend that exports catalog modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-elasticsearch/CHANGELOG.md b/plugins/search-backend-module-elasticsearch/CHANGELOG.md index a78362a926..d851114cc3 100644 --- a/plugins/search-backend-module-elasticsearch/CHANGELOG.md +++ b/plugins/search-backend-module-elasticsearch/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-search-backend-module-elasticsearch +## 1.5.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-backend-node@1.2.28-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/config@1.2.0 + ## 1.5.4-next.0 ### Patch Changes diff --git a/plugins/search-backend-module-elasticsearch/package.json b/plugins/search-backend-module-elasticsearch/package.json index 4107811cfd..56a1dcd6e2 100644 --- a/plugins/search-backend-module-elasticsearch/package.json +++ b/plugins/search-backend-module-elasticsearch/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-elasticsearch", - "version": "1.5.4-next.0", + "version": "1.5.4-next.1", "description": "A module for the search backend that implements search using ElasticSearch", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-explore/CHANGELOG.md b/plugins/search-backend-module-explore/CHANGELOG.md index e14dd6c6c0..344969254c 100644 --- a/plugins/search-backend-module-explore/CHANGELOG.md +++ b/plugins/search-backend-module-explore/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-search-backend-module-explore +## 0.1.29-next.1 + +### Patch Changes + +- 93fc1a0: Updated dependency `@backstage-community/plugin-explore-common` to `^0.0.4`. +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-search-backend-node@1.2.28-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/config@1.2.0 + ## 0.1.29-next.0 ### Patch Changes diff --git a/plugins/search-backend-module-explore/package.json b/plugins/search-backend-module-explore/package.json index a4411d558c..7827067c8a 100644 --- a/plugins/search-backend-module-explore/package.json +++ b/plugins/search-backend-module-explore/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-explore", - "version": "0.1.29-next.0", + "version": "0.1.29-next.1", "description": "A module for the search backend that exports explore modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-pg/CHANGELOG.md b/plugins/search-backend-module-pg/CHANGELOG.md index b2fa9b818e..03a33c2081 100644 --- a/plugins/search-backend-module-pg/CHANGELOG.md +++ b/plugins/search-backend-module-pg/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-search-backend-module-pg +## 0.5.33-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-search-backend-node@1.2.28-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/config@1.2.0 + ## 0.5.33-next.0 ### Patch Changes diff --git a/plugins/search-backend-module-pg/package.json b/plugins/search-backend-module-pg/package.json index 9679c5ddec..62b5309b06 100644 --- a/plugins/search-backend-module-pg/package.json +++ b/plugins/search-backend-module-pg/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-pg", - "version": "0.5.33-next.0", + "version": "0.5.33-next.1", "description": "A module for the search backend that implements search using PostgreSQL", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md b/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md index ba1143e663..a3c64851bb 100644 --- a/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md +++ b/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-search-backend-module-stack-overflow-collator +## 0.1.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-search-backend-node@1.2.28-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/config@1.2.0 + ## 0.1.16-next.0 ### 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 0fd6425e45..7f66d093d8 100644 --- a/plugins/search-backend-module-stack-overflow-collator/package.json +++ b/plugins/search-backend-module-stack-overflow-collator/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-stack-overflow-collator", - "version": "0.1.16-next.0", + "version": "0.1.16-next.1", "description": "A module for the search backend that exports stack overflow modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-techdocs/CHANGELOG.md b/plugins/search-backend-module-techdocs/CHANGELOG.md index 26137e8eef..9f5b9e41da 100644 --- a/plugins/search-backend-module-techdocs/CHANGELOG.md +++ b/plugins/search-backend-module-techdocs/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-search-backend-module-techdocs +## 0.1.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.9-next.1 + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-node@1.12.5-next.1 + - @backstage/plugin-search-backend-node@1.2.28-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + ## 0.1.28-next.0 ### Patch Changes diff --git a/plugins/search-backend-module-techdocs/package.json b/plugins/search-backend-module-techdocs/package.json index 52f5d7252b..ec703cf38e 100644 --- a/plugins/search-backend-module-techdocs/package.json +++ b/plugins/search-backend-module-techdocs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-techdocs", - "version": "0.1.28-next.0", + "version": "0.1.28-next.1", "description": "A module for the search backend that exports techdocs modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-node/CHANGELOG.md b/plugins/search-backend-node/CHANGELOG.md index 05d6d3dba2..9597076338 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.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/backend-tasks@0.5.28-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 1.2.28-next.0 ### Patch Changes diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index f00a58b584..710de9cd67 100644 --- a/plugins/search-backend-node/package.json +++ b/plugins/search-backend-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-node", - "version": "1.2.28-next.0", + "version": "1.2.28-next.1", "description": "A library for Backstage backend plugins that want to interact with the search backend plugin", "backstage": { "role": "node-library", diff --git a/plugins/search-backend/CHANGELOG.md b/plugins/search-backend/CHANGELOG.md index 018e049523..16e4c8ae4f 100644 --- a/plugins/search-backend/CHANGELOG.md +++ b/plugins/search-backend/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-search-backend +## 1.5.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-permission-node@0.8.1-next.1 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/backend-defaults@0.4.2-next.1 + - @backstage/plugin-search-backend-node@1.2.28-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/backend-openapi-utils@0.1.16-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 1.5.15-next.0 ### Patch Changes diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index 502bfd674e..8962162af6 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend", - "version": "1.5.15-next.0", + "version": "1.5.15-next.1", "description": "The Backstage backend plugin that provides your backstage app with search", "backstage": { "role": "backend-plugin", diff --git a/plugins/search-common/CHANGELOG.md b/plugins/search-common/CHANGELOG.md index 5b163eab0d..dc76382d5c 100644 --- a/plugins/search-common/CHANGELOG.md +++ b/plugins/search-common/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-search-common +## 1.2.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/types@1.1.1 + ## 1.2.13 ### Patch Changes diff --git a/plugins/search-common/package.json b/plugins/search-common/package.json index 8d0f4e9585..f569388c48 100644 --- a/plugins/search-common/package.json +++ b/plugins/search-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-common", - "version": "1.2.13", + "version": "1.2.14-next.0", "description": "Common functionalities for Search, to be shared between various search-enabled plugins", "backstage": { "role": "common-library", diff --git a/plugins/search-react/CHANGELOG.md b/plugins/search-react/CHANGELOG.md index f90428a139..f3c5688145 100644 --- a/plugins/search-react/CHANGELOG.md +++ b/plugins/search-react/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-search-react +## 1.7.14-next.1 + +### Patch Changes + +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 1.7.14-next.0 ### Patch Changes diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index 4cf1e476e8..4fa50cca10 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.14-next.0", + "version": "1.7.14-next.1", "backstage": { "role": "web-library", "pluginId": "search", diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md index 2c85c5bcf0..5e04d7a198 100644 --- a/plugins/search/CHANGELOG.md +++ b/plugins/search/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-search +## 1.4.15-next.1 + +### Patch Changes + +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/plugin-search-react@1.7.14-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 1.4.15-next.0 ### Patch Changes diff --git a/plugins/search/package.json b/plugins/search/package.json index d1aa27716a..a4a5ea3593 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search", - "version": "1.4.15-next.0", + "version": "1.4.15-next.1", "description": "The Backstage plugin that provides your backstage app with search", "backstage": { "role": "frontend-plugin", diff --git a/plugins/signals-backend/CHANGELOG.md b/plugins/signals-backend/CHANGELOG.md index 844d2cc185..d95a9d74a3 100644 --- a/plugins/signals-backend/CHANGELOG.md +++ b/plugins/signals-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-signals-backend +## 0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + - @backstage/plugin-signals-node@0.1.9-next.1 + ## 0.1.9-next.0 ### Patch Changes diff --git a/plugins/signals-backend/package.json b/plugins/signals-backend/package.json index f88e8825cd..6e4a17d612 100644 --- a/plugins/signals-backend/package.json +++ b/plugins/signals-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals-backend", - "version": "0.1.9-next.0", + "version": "0.1.9-next.1", "backstage": { "role": "backend-plugin", "pluginId": "signals", diff --git a/plugins/signals-node/CHANGELOG.md b/plugins/signals-node/CHANGELOG.md index 769800350a..ac1b4d835d 100644 --- a/plugins/signals-node/CHANGELOG.md +++ b/plugins/signals-node/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-signals-node +## 0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + - @backstage/plugin-events-node@0.3.9-next.1 + ## 0.1.9-next.0 ### Patch Changes diff --git a/plugins/signals-node/package.json b/plugins/signals-node/package.json index e4a4000120..7b98587482 100644 --- a/plugins/signals-node/package.json +++ b/plugins/signals-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals-node", - "version": "0.1.9-next.0", + "version": "0.1.9-next.1", "description": "Node.js library for the signals plugin", "backstage": { "role": "node-library", diff --git a/plugins/techdocs-addons-test-utils/CHANGELOG.md b/plugins/techdocs-addons-test-utils/CHANGELOG.md index 844ee41d30..728f9e073d 100644 --- a/plugins/techdocs-addons-test-utils/CHANGELOG.md +++ b/plugins/techdocs-addons-test-utils/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-techdocs-addons-test-utils +## 1.0.37-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.8-next.1 + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/plugin-search-react@1.7.14-next.1 + - @backstage/plugin-catalog@1.21.2-next.1 + - @backstage/test-utils@1.5.10-next.1 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + ## 1.0.36-next.0 ### Patch Changes diff --git a/plugins/techdocs-addons-test-utils/package.json b/plugins/techdocs-addons-test-utils/package.json index 6310ad03b8..a13624e2d8 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.36-next.0", + "version": "1.0.37-next.1", "backstage": { "role": "web-library", "pluginId": "techdocs-addons", diff --git a/plugins/techdocs-backend/CHANGELOG.md b/plugins/techdocs-backend/CHANGELOG.md index 44ab26cb79..cc0383d7f4 100644 --- a/plugins/techdocs-backend/CHANGELOG.md +++ b/plugins/techdocs-backend/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-techdocs-backend +## 1.10.10-next.1 + +### Patch Changes + +- 69bd940: Use annotation constants from new techdocs-common package. +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.9-next.1 + - @backstage/plugin-permission-common@0.8.1-next.0 + - @backstage/plugin-techdocs-common@0.1.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.28-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 1.10.10-next.0 ### Patch Changes diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index 2b4f23b342..f12a32a1ec 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-backend", - "version": "1.10.10-next.0", + "version": "1.10.10-next.1", "description": "The Backstage backend plugin that renders technical documentation for your components", "backstage": { "role": "backend-plugin", diff --git a/plugins/techdocs-common/CHANGELOG.md b/plugins/techdocs-common/CHANGELOG.md new file mode 100644 index 0000000000..e6d454e557 --- /dev/null +++ b/plugins/techdocs-common/CHANGELOG.md @@ -0,0 +1,7 @@ +# @backstage/plugin-techdocs-common + +## 0.1.0-next.0 + +### Minor Changes + +- 4698e1f: Initial release of the techdocs-common package. diff --git a/plugins/techdocs-common/package.json b/plugins/techdocs-common/package.json index 3e9eebbd23..e8d2692c0f 100644 --- a/plugins/techdocs-common/package.json +++ b/plugins/techdocs-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-common", - "version": "0.0.0", + "version": "0.1.0-next.0", "description": "Common functionality for TechDocs", "backstage": { "role": "common-library", diff --git a/plugins/techdocs-node/CHANGELOG.md b/plugins/techdocs-node/CHANGELOG.md index 6fb8d7bd8d..40c203014e 100644 --- a/plugins/techdocs-node/CHANGELOG.md +++ b/plugins/techdocs-node/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-techdocs-node +## 1.12.9-next.1 + +### Patch Changes + +- 69bd940: Use annotation constants from new techdocs-common package. +- 949083d: Update `patchMkdocsYmlPrebuild` to modify `repo_url` and `edit_uri` independently. +- Updated dependencies + - @backstage/plugin-techdocs-common@0.1.0-next.0 + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 1.12.9-next.0 ### Patch Changes diff --git a/plugins/techdocs-node/package.json b/plugins/techdocs-node/package.json index 16cf0d9155..8553169546 100644 --- a/plugins/techdocs-node/package.json +++ b/plugins/techdocs-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-node", - "version": "1.12.9-next.0", + "version": "1.12.9-next.1", "description": "Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", "backstage": { "role": "node-library", diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index f2e16e331c..0318bf45aa 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-techdocs +## 1.10.8-next.1 + +### Patch Changes + +- 69bd940: Use annotation constants from new techdocs-common package. +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/plugin-techdocs-common@0.1.0-next.0 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/plugin-search-react@1.7.14-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + ## 1.10.8-next.0 ### Patch Changes diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 3558590938..c08dd92f09 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs", - "version": "1.10.8-next.0", + "version": "1.10.8-next.1", "description": "The Backstage plugin that renders technical documentation for your components", "backstage": { "role": "frontend-plugin", diff --git a/plugins/user-settings-backend/CHANGELOG.md b/plugins/user-settings-backend/CHANGELOG.md index 05f426e57f..9101a22bef 100644 --- a/plugins/user-settings-backend/CHANGELOG.md +++ b/plugins/user-settings-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-user-settings-backend +## 0.2.22-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.18-next.1 + - @backstage/plugin-signals-node@0.1.9-next.1 + - @backstage/plugin-user-settings-common@0.0.1 + ## 0.2.22-next.0 ### Patch Changes diff --git a/plugins/user-settings-backend/package.json b/plugins/user-settings-backend/package.json index 1c28f1e90c..244209a267 100644 --- a/plugins/user-settings-backend/package.json +++ b/plugins/user-settings-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-user-settings-backend", - "version": "0.2.22-next.0", + "version": "0.2.22-next.1", "description": "The Backstage backend plugin to manage user settings", "backstage": { "role": "backend-plugin", diff --git a/plugins/user-settings/CHANGELOG.md b/plugins/user-settings/CHANGELOG.md index 84598558ee..dafa984b09 100644 --- a/plugins/user-settings/CHANGELOG.md +++ b/plugins/user-settings/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-user-settings +## 0.8.11-next.1 + +### Patch Changes + +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.4 + - @backstage/plugin-user-settings-common@0.0.1 + ## 0.8.10-next.0 ### Patch Changes diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index 7534c275d1..b229e625b6 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-user-settings", - "version": "0.8.10-next.0", + "version": "0.8.11-next.1", "description": "A Backstage plugin that provides a settings page", "backstage": { "role": "frontend-plugin", diff --git a/yarn.lock b/yarn.lock index 13c930cc5a..ab91486c9b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5720,7 +5720,18 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-common@^1.0.20, @backstage/plugin-catalog-common@^1.0.25, @backstage/plugin-catalog-common@workspace:^, @backstage/plugin-catalog-common@workspace:plugins/catalog-common": +"@backstage/plugin-catalog-common@npm:^1.0.20, @backstage/plugin-catalog-common@npm:^1.0.25": + version: 1.0.25 + resolution: "@backstage/plugin-catalog-common@npm:1.0.25" + dependencies: + "@backstage/catalog-model": ^1.5.0 + "@backstage/plugin-permission-common": ^0.8.0 + "@backstage/plugin-search-common": ^1.2.13 + checksum: 37078811a78423accc078ae43d1572de6e74e0daff6b03a3d6f30d3ce37e71d30f60ac90aea5cf442ca0d2123259b267b37b966e29aa4f2dba08845d562d0e68 + languageName: node + linkType: hard + +"@backstage/plugin-catalog-common@workspace:^, @backstage/plugin-catalog-common@workspace:plugins/catalog-common": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-common@workspace:plugins/catalog-common" dependencies: @@ -6711,7 +6722,21 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-permission-common@^0.8.0, @backstage/plugin-permission-common@workspace:^, @backstage/plugin-permission-common@workspace:plugins/permission-common": +"@backstage/plugin-permission-common@npm:^0.8.0": + version: 0.8.0 + resolution: "@backstage/plugin-permission-common@npm:0.8.0" + dependencies: + "@backstage/config": ^1.2.0 + "@backstage/errors": ^1.2.4 + "@backstage/types": ^1.1.1 + cross-fetch: ^4.0.0 + uuid: ^9.0.0 + zod: ^3.22.4 + checksum: 03d706cf764d65319fd32156438b6f826568c7d51e79fc6e7cd951b023017a1e07c7380f2babec7efd2ed96f441485ee68072d06fb5e42a1bf7aba7cd1f6ce6f + languageName: node + linkType: hard + +"@backstage/plugin-permission-common@workspace:^, @backstage/plugin-permission-common@workspace:plugins/permission-common": version: 0.0.0-use.local resolution: "@backstage/plugin-permission-common@workspace:plugins/permission-common" dependencies: @@ -6750,7 +6775,24 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-permission-react@^0.4.24, @backstage/plugin-permission-react@workspace:^, @backstage/plugin-permission-react@workspace:plugins/permission-react": +"@backstage/plugin-permission-react@npm:^0.4.24": + version: 0.4.24 + resolution: "@backstage/plugin-permission-react@npm:0.4.24" + dependencies: + "@backstage/config": ^1.2.0 + "@backstage/core-plugin-api": ^1.9.3 + "@backstage/plugin-permission-common": ^0.8.0 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + swr: ^2.0.0 + 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 + checksum: 6fa895f4a25f7f08642f64a9b4b41e5f3adfbf3c3f1ede9e1abc7bb08f532d9d0c9baf9f08b472fff54803a2c2aaeff2306b5e6d1514193a2407af4b12433d3a + languageName: node + linkType: hard + +"@backstage/plugin-permission-react@workspace:^, @backstage/plugin-permission-react@workspace:plugins/permission-react": version: 0.0.0-use.local resolution: "@backstage/plugin-permission-react@workspace:plugins/permission-react" dependencies: @@ -7526,6 +7568,16 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-search-common@npm:^1.2.13": + version: 1.2.13 + resolution: "@backstage/plugin-search-common@npm:1.2.13" + dependencies: + "@backstage/plugin-permission-common": ^0.8.0 + "@backstage/types": ^1.1.1 + checksum: 0c7b7b791b648e874081b845488f636791754bc4da1a4780b49e7281cc6294bcad0a9feab9fd7dd5f6a583b5fce372e704f440ad7bc33ab828ebd2afc5344504 + languageName: node + linkType: hard + "@backstage/plugin-search-common@workspace:^, @backstage/plugin-search-common@workspace:plugins/search-common": version: 0.0.0-use.local resolution: "@backstage/plugin-search-common@workspace:plugins/search-common" From 211cfb63b4eecc0b2d9846267e6b069b39a2b9c6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 13:12:29 +0000 Subject: [PATCH 486/510] Update dependency @backstage-community/plugin-stackstorm to v0.1.17 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/yarn.lock b/yarn.lock index 13c930cc5a..38b07e745e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3412,11 +3412,11 @@ __metadata: linkType: hard "@backstage-community/plugin-stackstorm@npm:^0.1.16": - version: 0.1.16 - resolution: "@backstage-community/plugin-stackstorm@npm:0.1.16" + version: 0.1.17 + resolution: "@backstage-community/plugin-stackstorm@npm:0.1.17" dependencies: - "@backstage/core-components": ^0.14.4 - "@backstage/core-plugin-api": ^1.9.2 + "@backstage/core-components": ^0.14.9 + "@backstage/core-plugin-api": ^1.9.3 "@backstage/errors": ^1.2.4 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -3426,7 +3426,7 @@ __metadata: 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 - checksum: 2fd7d290cd98ad09b16862a5dee3302796942e85818abf9c4a9102038a4fb83e86ceee39d901e59bb7fb7c60df7797524f8c6a5cfee1a4a0ea59edcbb4de5a0a + checksum: 3fa2b45da036e4001a9e034a8841b58877d0b4189d244806b3b1808d3c2a34bb4ab4acbcff629edda47d03b2941c51743dd84f7352ed0d700988aaee946b65f3 languageName: node linkType: hard From 87165f6b100532ea7a8d5d26bc367a58b6f523c7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 13:42:03 +0000 Subject: [PATCH 487/510] Update dependency @changesets/cli to v2.27.7 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 66 +++++++++++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/yarn.lock b/yarn.lock index dd1c6d9e3a..71ca5f58c7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8224,12 +8224,12 @@ __metadata: languageName: node linkType: hard -"@changesets/apply-release-plan@npm:^7.0.3": - version: 7.0.3 - resolution: "@changesets/apply-release-plan@npm:7.0.3" +"@changesets/apply-release-plan@npm:^7.0.4": + version: 7.0.4 + resolution: "@changesets/apply-release-plan@npm:7.0.4" dependencies: "@babel/runtime": ^7.20.1 - "@changesets/config": ^3.0.1 + "@changesets/config": ^3.0.2 "@changesets/get-version-range-type": ^0.4.0 "@changesets/git": ^3.0.0 "@changesets/should-skip-package": ^0.1.0 @@ -8242,22 +8242,22 @@ __metadata: prettier: ^2.7.1 resolve-from: ^5.0.0 semver: ^7.5.3 - checksum: 622b1ed7652b072b28bee431d5407ce686cff058caa3db9353848cd1177dc535d352711f6e5f9f819a7331235e72279f7e0f34955da67681c50d051ec30f476a + checksum: 5a61a8794fd4762e9270ffec474dc7c5d420c1d0479c5316a12e5264589882ccfb3ec08af6c0ebd07de2bf26ae880ad2f65e8f16d5886745aecf48cb11f625f5 languageName: node linkType: hard -"@changesets/assemble-release-plan@npm:^6.0.2": - version: 6.0.2 - resolution: "@changesets/assemble-release-plan@npm:6.0.2" +"@changesets/assemble-release-plan@npm:^6.0.3": + version: 6.0.3 + resolution: "@changesets/assemble-release-plan@npm:6.0.3" dependencies: "@babel/runtime": ^7.20.1 "@changesets/errors": ^0.2.0 - "@changesets/get-dependents-graph": ^2.1.0 + "@changesets/get-dependents-graph": ^2.1.1 "@changesets/should-skip-package": ^0.1.0 "@changesets/types": ^6.0.0 "@manypkg/get-packages": ^1.1.3 semver: ^7.5.3 - checksum: 90019a9bd22ad1368f23f1335d1b7eea5a55b1ed8b9141c9cc2fdab99bda85f9cb3886062a33c078cfb6f08f1a6f165aedbb1d1ce2a63c15ce0bfa7a7c365854 + checksum: ae0ac29a44640fc6c0d3782c134adad3f0af80903ecb8bf663f0bf5f569586c9620980100737a05639f1a7252f145942ae62fa25d0757e89b5d6311abf899cd5 languageName: node linkType: hard @@ -8271,17 +8271,17 @@ __metadata: linkType: hard "@changesets/cli@npm:^2.14.0": - version: 2.27.6 - resolution: "@changesets/cli@npm:2.27.6" + version: 2.27.7 + resolution: "@changesets/cli@npm:2.27.7" dependencies: "@babel/runtime": ^7.20.1 - "@changesets/apply-release-plan": ^7.0.3 - "@changesets/assemble-release-plan": ^6.0.2 + "@changesets/apply-release-plan": ^7.0.4 + "@changesets/assemble-release-plan": ^6.0.3 "@changesets/changelog-git": ^0.2.0 - "@changesets/config": ^3.0.1 + "@changesets/config": ^3.0.2 "@changesets/errors": ^0.2.0 - "@changesets/get-dependents-graph": ^2.1.0 - "@changesets/get-release-plan": ^4.0.2 + "@changesets/get-dependents-graph": ^2.1.1 + "@changesets/get-release-plan": ^4.0.3 "@changesets/git": ^3.0.0 "@changesets/logger": ^0.1.0 "@changesets/pre": ^2.0.0 @@ -8308,22 +8308,22 @@ __metadata: term-size: ^2.1.0 bin: changeset: bin.js - checksum: efb3c7b569debb2bb0baae2d7bafee4ae19d3c7f0023ea97fa0b6518198c85ba16c2a66609561c9dd0f0601c3390d5933b00e3ad3cb962b4b0e7fcb4de929dfa + checksum: f518121a516ce8186dfc71dcca2f4be5fea28fe29a54b038aa787964bb4d4f1e866840d6d765776db33f7723d1a850ee4a38ed726f302a26e2e56a5e2b9422e8 languageName: node linkType: hard -"@changesets/config@npm:^3.0.1": - version: 3.0.1 - resolution: "@changesets/config@npm:3.0.1" +"@changesets/config@npm:^3.0.2": + version: 3.0.2 + resolution: "@changesets/config@npm:3.0.2" dependencies: "@changesets/errors": ^0.2.0 - "@changesets/get-dependents-graph": ^2.1.0 + "@changesets/get-dependents-graph": ^2.1.1 "@changesets/logger": ^0.1.0 "@changesets/types": ^6.0.0 "@manypkg/get-packages": ^1.1.3 fs-extra: ^7.0.1 micromatch: ^4.0.2 - checksum: 588a8139f721e2917c9bad842e3a933a8a5216b6a73c6a203ddcb834c274f873eaa780b32b42f89a477159e898ad3c1c93ca0ac28a07401b7b3f56185672a6a8 + checksum: 4160e59f74c1f36a2d3d011868f83c46410553f9fc164a83dde46ec7e37f13ba983526b9c299de3cd3f317e5e42808a991959931c9d34f2913f3e8d4c515cd12 languageName: node linkType: hard @@ -8336,31 +8336,31 @@ __metadata: languageName: node linkType: hard -"@changesets/get-dependents-graph@npm:^2.1.0": - version: 2.1.0 - resolution: "@changesets/get-dependents-graph@npm:2.1.0" +"@changesets/get-dependents-graph@npm:^2.1.1": + version: 2.1.1 + resolution: "@changesets/get-dependents-graph@npm:2.1.1" dependencies: "@changesets/types": ^6.0.0 "@manypkg/get-packages": ^1.1.3 chalk: ^2.1.0 fs-extra: ^7.0.1 semver: ^7.5.3 - checksum: 1cd9c0f145a20d735ab9e1d615c5bdf52179cd2fc9b8555649d74979d8dbc915f9e85af4e20f7b71da76d3d860cd2090cee4c6ecccac4f5bf42ae11bb245471d + checksum: e427603a3cad3690deec86a5831f15766dc32dc0819532e3ad70fbda027317bb46bb207c6a3bc947daf00e5e8229a01dd67aa3ec7248aa11f87611a7ecd74097 languageName: node linkType: hard -"@changesets/get-release-plan@npm:^4.0.2": - version: 4.0.2 - resolution: "@changesets/get-release-plan@npm:4.0.2" +"@changesets/get-release-plan@npm:^4.0.3": + version: 4.0.3 + resolution: "@changesets/get-release-plan@npm:4.0.3" dependencies: "@babel/runtime": ^7.20.1 - "@changesets/assemble-release-plan": ^6.0.2 - "@changesets/config": ^3.0.1 + "@changesets/assemble-release-plan": ^6.0.3 + "@changesets/config": ^3.0.2 "@changesets/pre": ^2.0.0 "@changesets/read": ^0.6.0 "@changesets/types": ^6.0.0 "@manypkg/get-packages": ^1.1.3 - checksum: 651814230890bf7605f4094332e4842505eb060092fbe65d9c8fa1a44f724ce0086890b8437f2fa96aedfa11c88e622e133d700847dea4c92141c2fbb486460f + checksum: baf01eb124f95df729e1798c23e4ac1996acd74e0d22336492e4a0fd68f3a19c97197337fdcb58d47d0b580ca38e0b0888cbacaa1c99d7c173c3cecb859ab4cc languageName: node linkType: hard From 1a1132c9bb7742e5aade21a9bb3d956d917c45ef Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Tue, 30 Jul 2024 19:15:01 +0200 Subject: [PATCH 488/510] chore: fixing config loading for additional config paths Signed-off-by: blam <ben@blam.sh> --- packages/cli/src/lib/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/lib/config.ts b/packages/cli/src/lib/config.ts index 49cce1f1ed..aab16a8670 100644 --- a/packages/cli/src/lib/config.ts +++ b/packages/cli/src/lib/config.ts @@ -70,7 +70,7 @@ export async function loadCliConfig(options: Options) { : undefined, watch: Boolean(options.watch), rootDir: paths.targetRoot, - argv: options.args, + argv: options.args.flatMap(t => ['--config', paths.resolveTarget(t)]), }); const appConfigs = await new Promise<AppConfig[]>((resolve, reject) => { From b2d97fd5cea4d3e59a292143d2596a71c3676c44 Mon Sep 17 00:00:00 2001 From: blam <ben@blam.sh> Date: Tue, 30 Jul 2024 19:16:45 +0200 Subject: [PATCH 489/510] chore: changeset Signed-off-by: blam <ben@blam.sh> --- .changeset/cool-schools-vanish.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/cool-schools-vanish.md diff --git a/.changeset/cool-schools-vanish.md b/.changeset/cool-schools-vanish.md new file mode 100644 index 0000000000..9b2ded5248 --- /dev/null +++ b/.changeset/cool-schools-vanish.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Fixing loading of additional config files with new `ConfigSources` From dd0ce5a890307a7b4092757e10a9665bb8f7f8c7 Mon Sep 17 00:00:00 2001 From: Alex Lorenzi <alorenzi@spotify.com> Date: Tue, 30 Jul 2024 14:52:09 -0400 Subject: [PATCH 490/510] The header size calculation weren't taking into account cases where the value was a CSS variable. This could lead to situation where the outputted property was invalid. This update resolves the CSS property and then tries to calculate again using that value Signed-off-by: Alex Lorenzi <alorenzi@spotify.com> --- .../transformers/styles/rules/typeset.ts | 30 ++-- .../transformers/styles/transformer.test.ts | 48 ------- .../transformers/styles/transformer.test.tsx | 135 ++++++++++++++++++ 3 files changed, 156 insertions(+), 57 deletions(-) delete mode 100644 plugins/techdocs/src/reader/transformers/styles/transformer.test.ts create mode 100644 plugins/techdocs/src/reader/transformers/styles/transformer.test.tsx diff --git a/plugins/techdocs/src/reader/transformers/styles/rules/typeset.ts b/plugins/techdocs/src/reader/transformers/styles/rules/typeset.ts index cc7ba6bace..c682008a4d 100644 --- a/plugins/techdocs/src/reader/transformers/styles/rules/typeset.ts +++ b/plugins/techdocs/src/reader/transformers/styles/rules/typeset.ts @@ -30,6 +30,8 @@ type TypographyHeadings = Pick< type TypographyHeadingsKeys = keyof TypographyHeadings; const headings: TypographyHeadingsKeys[] = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']; +const relativeLengthUnit: RegExp = /(em)|(rem)/gi; +const cssVariable: RegExp = /var\(|\)/gi; export default ({ theme }: RuleOptions) => ` /*================== Typeset ==================*/ @@ -43,17 +45,27 @@ ${headings.reduce<string>((style, heading) => { (theme.typography as BackstageTypography).htmlFontSize ?? 16; const styles = theme.typography[heading]; const { lineHeight, fontFamily, fontWeight, fontSize } = styles; - const calculate = (value: typeof fontSize) => { - let factor: number | string = 1; + const calculate = (value: typeof fontSize): string | undefined => { if (typeof value === 'number') { - // convert px to rem - // 60% of the size defined because it is too big - factor = (value / htmlFontSize) * 0.6; + // Convert px to rem and apply 60% factor + return calculate(`${(value / htmlFontSize) * 0.6}rem`); + } else if (typeof value === 'string') { + if (value.match(cssVariable)) { + // Resolve css variable and calculate recursively + const resolvedValue = window + .getComputedStyle(document.body) + .getPropertyValue(value.replaceAll(cssVariable, '')); + if (resolvedValue !== '') { + return calculate(resolvedValue); + } + } else if (value.match(relativeLengthUnit)) { + // Use relative size as factor + const factor = value.replace(relativeLengthUnit, ''); + return `calc(${factor} * var(--md-typeset-font-size))`; + } } - if (typeof value === 'string') { - factor = value.replace('rem', ''); - } - return `calc(${factor} * var(--md-typeset-font-size))`; + // Value is not a number, relative length unit, or CSS variable, return as is + return value; }; return style.concat(` .md-typeset ${heading} { diff --git a/plugins/techdocs/src/reader/transformers/styles/transformer.test.ts b/plugins/techdocs/src/reader/transformers/styles/transformer.test.ts deleted file mode 100644 index 90244e96ad..0000000000 --- a/plugins/techdocs/src/reader/transformers/styles/transformer.test.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 { renderHook } from '@testing-library/react'; -import { useStylesTransformer } from './transformer'; - -describe('Transformers > Styles', () => { - it('should return a function that injects all styles into a given dom element', () => { - const { result } = renderHook(() => useStylesTransformer()); - - const dom = document.createElement('html'); - dom.innerHTML = '<head></head>'; - result.current(dom); // calling styles transformer - - const style = dom.querySelector('head > style'); - expect(style).toHaveTextContent( - '/*================== Variables ==================*/', - ); - expect(style).toHaveTextContent( - '/*================== Reset ==================*/', - ); - expect(style).toHaveTextContent( - '/*================== Layout ==================*/', - ); - expect(style).toHaveTextContent( - '/*================== Typeset ==================*/', - ); - expect(style).toHaveTextContent( - '/*================== Animations ==================*/', - ); - expect(style).toHaveTextContent( - '/*================== Extensions ==================*/', - ); - }); -}); diff --git a/plugins/techdocs/src/reader/transformers/styles/transformer.test.tsx b/plugins/techdocs/src/reader/transformers/styles/transformer.test.tsx new file mode 100644 index 0000000000..464bb834ea --- /dev/null +++ b/plugins/techdocs/src/reader/transformers/styles/transformer.test.tsx @@ -0,0 +1,135 @@ +/* + * 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 { renderHook } from '@testing-library/react'; +import { useStylesTransformer } from './transformer'; +import { createTheme, ThemeProvider } from '@material-ui/core/styles'; +import React from 'react'; + +describe('Transformers > Styles', () => { + it('should return a function that injects all styles into a given dom element', () => { + const { result } = renderHook(() => useStylesTransformer()); + + const dom = document.createElement('html'); + dom.innerHTML = '<head></head>'; + result.current(dom); // calling styles transformer + + const style = dom.querySelector('head > style'); + + expect(style).toHaveTextContent( + '/*================== Variables ==================*/', + ); + expect(style).toHaveTextContent( + '/*================== Reset ==================*/', + ); + expect(style).toHaveTextContent( + '/*================== Layout ==================*/', + ); + expect(style).toHaveTextContent( + '/*================== Typeset ==================*/', + ); + expect(style).toHaveTextContent( + '/*================== Animations ==================*/', + ); + expect(style).toHaveTextContent( + '/*================== Extensions ==================*/', + ); + }); + + it('should use relative header sizes as the factor the md-typeset variable', () => { + const theme = createTheme({ + typography: { + h1: { + fontSize: '20rem', + }, + }, + }); + const wrapper = ({ children }: { children: React.ReactNode }) => ( + <ThemeProvider theme={theme}>{children}</ThemeProvider> + ); + const { result } = renderHook(() => useStylesTransformer(), { wrapper }); + + const dom = document.createElement('html'); + dom.innerHTML = `<head></head>`; + result.current(dom); // calling styles transformer + + const style = dom.querySelector('head > style'); + expect(style).not.toBeNull(); + + const h1 = style!.textContent?.match(/\.md-typeset h1 {.*?}/s); + expect(h1).toHaveLength(1); + expect(h1![0]).toContain( + 'font-size: calc(20 * var(--md-typeset-font-size));', + ); + }); + + it('should resolve header sizes that are variables', () => { + document.body.style.setProperty('--font-size-h1', '20rem'); + const theme = createTheme({ + typography: { + h1: { + fontSize: 'var(--font-size-h1)', + }, + }, + }); + const wrapper = ({ children }: { children: React.ReactNode }) => ( + <ThemeProvider theme={theme}>{children}</ThemeProvider> + ); + const { result } = renderHook(() => useStylesTransformer(), { wrapper }); + + const dom = document.createElement('html'); + dom.innerHTML = `<head></head>`; + result.current(dom); // calling styles transformer + + const style = dom.querySelector('head > style'); + expect(style).not.toBeNull(); + + const h1 = style!.textContent?.match(/\.md-typeset h1 {.*?}/s); + expect(h1).toHaveLength(1); + expect(h1![0]).toContain( + 'font-size: calc(20 * var(--md-typeset-font-size));', + ); + }); + + it('should convert pixel header sizes to REM and reduce by 60%', () => { + const theme = createTheme({ + typography: { + htmlFontSize: 16, + h1: { + fontSize: 100, + }, + }, + }); + const wrapper = ({ children }: { children: React.ReactNode }) => ( + <ThemeProvider theme={theme}>{children}</ThemeProvider> + ); + const { result } = renderHook(() => useStylesTransformer(), { wrapper }); + + const dom = document.createElement('html'); + dom.innerHTML = `<head></head>`; + result.current(dom); // calling styles transformer + + const style = dom.querySelector('head > style'); + expect(style).not.toBeNull(); + + const h1 = style!.textContent?.match(/\.md-typeset h1 {.*?}/s); + expect(h1).toHaveLength(1); + expect(h1![0]).toContain( + // 100px / 16px * 0.6 = 3.75rem + 'font-size: calc(3.75 * var(--md-typeset-font-size));', + ); + }); +}); From bdc547132ac0133cc9711105be8fbd7b2306fa0c Mon Sep 17 00:00:00 2001 From: Alex Lorenzi <alorenzi@spotify.com> Date: Tue, 30 Jul 2024 15:03:31 -0400 Subject: [PATCH 491/510] Added changeset Signed-off-by: Alex Lorenzi <alorenzi@spotify.com> --- .changeset/wise-spiders-walk.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/wise-spiders-walk.md diff --git a/.changeset/wise-spiders-walk.md b/.changeset/wise-spiders-walk.md new file mode 100644 index 0000000000..65793041c5 --- /dev/null +++ b/.changeset/wise-spiders-walk.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Fixed issue where header styles were incorrectly generated when themes used CSS variables to define font size. From 69ae4c030996629ea40af19d46901567a9362734 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 20:04:59 +0000 Subject: [PATCH 492/510] fix(deps): update aws-sdk-js-v3 monorepo Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 1929 ++++++++++++++++++++++++++--------------------------- 1 file changed, 962 insertions(+), 967 deletions(-) diff --git a/yarn.lock b/yarn.lock index dd1c6d9e3a..bc630737a6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -489,674 +489,677 @@ __metadata: linkType: hard "@aws-sdk/client-codecommit@npm:^3.350.0": - version: 3.600.0 - resolution: "@aws-sdk/client-codecommit@npm:3.600.0" + version: 3.621.0 + resolution: "@aws-sdk/client-codecommit@npm:3.621.0" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.600.0 - "@aws-sdk/client-sts": 3.600.0 - "@aws-sdk/core": 3.598.0 - "@aws-sdk/credential-provider-node": 3.600.0 - "@aws-sdk/middleware-host-header": 3.598.0 - "@aws-sdk/middleware-logger": 3.598.0 - "@aws-sdk/middleware-recursion-detection": 3.598.0 - "@aws-sdk/middleware-user-agent": 3.598.0 - "@aws-sdk/region-config-resolver": 3.598.0 - "@aws-sdk/types": 3.598.0 - "@aws-sdk/util-endpoints": 3.598.0 - "@aws-sdk/util-user-agent-browser": 3.598.0 - "@aws-sdk/util-user-agent-node": 3.598.0 - "@smithy/config-resolver": ^3.0.2 - "@smithy/core": ^2.2.1 - "@smithy/fetch-http-handler": ^3.0.2 - "@smithy/hash-node": ^3.0.1 - "@smithy/invalid-dependency": ^3.0.1 - "@smithy/middleware-content-length": ^3.0.1 - "@smithy/middleware-endpoint": ^3.0.2 - "@smithy/middleware-retry": ^3.0.4 - "@smithy/middleware-serde": ^3.0.1 - "@smithy/middleware-stack": ^3.0.1 - "@smithy/node-config-provider": ^3.1.1 - "@smithy/node-http-handler": ^3.0.1 - "@smithy/protocol-http": ^4.0.1 - "@smithy/smithy-client": ^3.1.2 - "@smithy/types": ^3.1.0 - "@smithy/url-parser": ^3.0.1 + "@aws-sdk/client-sso-oidc": 3.621.0 + "@aws-sdk/client-sts": 3.621.0 + "@aws-sdk/core": 3.621.0 + "@aws-sdk/credential-provider-node": 3.621.0 + "@aws-sdk/middleware-host-header": 3.620.0 + "@aws-sdk/middleware-logger": 3.609.0 + "@aws-sdk/middleware-recursion-detection": 3.620.0 + "@aws-sdk/middleware-user-agent": 3.620.0 + "@aws-sdk/region-config-resolver": 3.614.0 + "@aws-sdk/types": 3.609.0 + "@aws-sdk/util-endpoints": 3.614.0 + "@aws-sdk/util-user-agent-browser": 3.609.0 + "@aws-sdk/util-user-agent-node": 3.614.0 + "@smithy/config-resolver": ^3.0.5 + "@smithy/core": ^2.3.1 + "@smithy/fetch-http-handler": ^3.2.4 + "@smithy/hash-node": ^3.0.3 + "@smithy/invalid-dependency": ^3.0.3 + "@smithy/middleware-content-length": ^3.0.5 + "@smithy/middleware-endpoint": ^3.1.0 + "@smithy/middleware-retry": ^3.0.13 + "@smithy/middleware-serde": ^3.0.3 + "@smithy/middleware-stack": ^3.0.3 + "@smithy/node-config-provider": ^3.1.4 + "@smithy/node-http-handler": ^3.1.4 + "@smithy/protocol-http": ^4.1.0 + "@smithy/smithy-client": ^3.1.11 + "@smithy/types": ^3.3.0 + "@smithy/url-parser": ^3.0.3 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.4 - "@smithy/util-defaults-mode-node": ^3.0.4 - "@smithy/util-endpoints": ^2.0.2 - "@smithy/util-middleware": ^3.0.1 - "@smithy/util-retry": ^3.0.1 + "@smithy/util-defaults-mode-browser": ^3.0.13 + "@smithy/util-defaults-mode-node": ^3.0.13 + "@smithy/util-endpoints": ^2.0.5 + "@smithy/util-middleware": ^3.0.3 + "@smithy/util-retry": ^3.0.3 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 uuid: ^9.0.1 - checksum: 1a8197ffcf74b27a4b6159d8b4923db0f5c27b3d5daacb321ef956c49b0250800ce904c1c03264c67366c14244a8ba7a067849700b382979da19f7bc4c20a3fd + checksum: be8a5ebbe178f7d81c44a34f7e1ee54b8f7d3912c92de570855be4612cf60a02444957373eb9d9abfbf606f9998fc34acf020a2fb1d7be1e0e77be6c30388408 languageName: node linkType: hard -"@aws-sdk/client-cognito-identity@npm:3.600.0": - version: 3.600.0 - resolution: "@aws-sdk/client-cognito-identity@npm:3.600.0" +"@aws-sdk/client-cognito-identity@npm:3.621.0": + version: 3.621.0 + resolution: "@aws-sdk/client-cognito-identity@npm:3.621.0" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.600.0 - "@aws-sdk/client-sts": 3.600.0 - "@aws-sdk/core": 3.598.0 - "@aws-sdk/credential-provider-node": 3.600.0 - "@aws-sdk/middleware-host-header": 3.598.0 - "@aws-sdk/middleware-logger": 3.598.0 - "@aws-sdk/middleware-recursion-detection": 3.598.0 - "@aws-sdk/middleware-user-agent": 3.598.0 - "@aws-sdk/region-config-resolver": 3.598.0 - "@aws-sdk/types": 3.598.0 - "@aws-sdk/util-endpoints": 3.598.0 - "@aws-sdk/util-user-agent-browser": 3.598.0 - "@aws-sdk/util-user-agent-node": 3.598.0 - "@smithy/config-resolver": ^3.0.2 - "@smithy/core": ^2.2.1 - "@smithy/fetch-http-handler": ^3.0.2 - "@smithy/hash-node": ^3.0.1 - "@smithy/invalid-dependency": ^3.0.1 - "@smithy/middleware-content-length": ^3.0.1 - "@smithy/middleware-endpoint": ^3.0.2 - "@smithy/middleware-retry": ^3.0.4 - "@smithy/middleware-serde": ^3.0.1 - "@smithy/middleware-stack": ^3.0.1 - "@smithy/node-config-provider": ^3.1.1 - "@smithy/node-http-handler": ^3.0.1 - "@smithy/protocol-http": ^4.0.1 - "@smithy/smithy-client": ^3.1.2 - "@smithy/types": ^3.1.0 - "@smithy/url-parser": ^3.0.1 + "@aws-sdk/client-sso-oidc": 3.621.0 + "@aws-sdk/client-sts": 3.621.0 + "@aws-sdk/core": 3.621.0 + "@aws-sdk/credential-provider-node": 3.621.0 + "@aws-sdk/middleware-host-header": 3.620.0 + "@aws-sdk/middleware-logger": 3.609.0 + "@aws-sdk/middleware-recursion-detection": 3.620.0 + "@aws-sdk/middleware-user-agent": 3.620.0 + "@aws-sdk/region-config-resolver": 3.614.0 + "@aws-sdk/types": 3.609.0 + "@aws-sdk/util-endpoints": 3.614.0 + "@aws-sdk/util-user-agent-browser": 3.609.0 + "@aws-sdk/util-user-agent-node": 3.614.0 + "@smithy/config-resolver": ^3.0.5 + "@smithy/core": ^2.3.1 + "@smithy/fetch-http-handler": ^3.2.4 + "@smithy/hash-node": ^3.0.3 + "@smithy/invalid-dependency": ^3.0.3 + "@smithy/middleware-content-length": ^3.0.5 + "@smithy/middleware-endpoint": ^3.1.0 + "@smithy/middleware-retry": ^3.0.13 + "@smithy/middleware-serde": ^3.0.3 + "@smithy/middleware-stack": ^3.0.3 + "@smithy/node-config-provider": ^3.1.4 + "@smithy/node-http-handler": ^3.1.4 + "@smithy/protocol-http": ^4.1.0 + "@smithy/smithy-client": ^3.1.11 + "@smithy/types": ^3.3.0 + "@smithy/url-parser": ^3.0.3 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.4 - "@smithy/util-defaults-mode-node": ^3.0.4 - "@smithy/util-endpoints": ^2.0.2 - "@smithy/util-middleware": ^3.0.1 - "@smithy/util-retry": ^3.0.1 + "@smithy/util-defaults-mode-browser": ^3.0.13 + "@smithy/util-defaults-mode-node": ^3.0.13 + "@smithy/util-endpoints": ^2.0.5 + "@smithy/util-middleware": ^3.0.3 + "@smithy/util-retry": ^3.0.3 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: ad01c387061da6d46767e209f3d422281e6af97d60ed61af687980990c7600ecbd88e2f430d975f029648d4475bf84234f710f4099edd2d61f90fef3444ee4a0 + checksum: 227fb03620396c3d5f9ca36fd463fc2e3e2e04909f5dea59b90e25a89d110d3a869e89e870237b808b494156bba06fb966406d2dc192a8ad6a072b7abdd4d81c languageName: node linkType: hard "@aws-sdk/client-eks@npm:^3.350.0": - version: 3.605.0 - resolution: "@aws-sdk/client-eks@npm:3.605.0" + version: 3.621.0 + resolution: "@aws-sdk/client-eks@npm:3.621.0" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.600.0 - "@aws-sdk/client-sts": 3.600.0 - "@aws-sdk/core": 3.598.0 - "@aws-sdk/credential-provider-node": 3.600.0 - "@aws-sdk/middleware-host-header": 3.598.0 - "@aws-sdk/middleware-logger": 3.598.0 - "@aws-sdk/middleware-recursion-detection": 3.598.0 - "@aws-sdk/middleware-user-agent": 3.598.0 - "@aws-sdk/region-config-resolver": 3.598.0 - "@aws-sdk/types": 3.598.0 - "@aws-sdk/util-endpoints": 3.598.0 - "@aws-sdk/util-user-agent-browser": 3.598.0 - "@aws-sdk/util-user-agent-node": 3.598.0 - "@smithy/config-resolver": ^3.0.2 - "@smithy/core": ^2.2.1 - "@smithy/fetch-http-handler": ^3.0.2 - "@smithy/hash-node": ^3.0.1 - "@smithy/invalid-dependency": ^3.0.1 - "@smithy/middleware-content-length": ^3.0.1 - "@smithy/middleware-endpoint": ^3.0.2 - "@smithy/middleware-retry": ^3.0.4 - "@smithy/middleware-serde": ^3.0.1 - "@smithy/middleware-stack": ^3.0.1 - "@smithy/node-config-provider": ^3.1.1 - "@smithy/node-http-handler": ^3.0.1 - "@smithy/protocol-http": ^4.0.1 - "@smithy/smithy-client": ^3.1.2 - "@smithy/types": ^3.1.0 - "@smithy/url-parser": ^3.0.1 + "@aws-sdk/client-sso-oidc": 3.621.0 + "@aws-sdk/client-sts": 3.621.0 + "@aws-sdk/core": 3.621.0 + "@aws-sdk/credential-provider-node": 3.621.0 + "@aws-sdk/middleware-host-header": 3.620.0 + "@aws-sdk/middleware-logger": 3.609.0 + "@aws-sdk/middleware-recursion-detection": 3.620.0 + "@aws-sdk/middleware-user-agent": 3.620.0 + "@aws-sdk/region-config-resolver": 3.614.0 + "@aws-sdk/types": 3.609.0 + "@aws-sdk/util-endpoints": 3.614.0 + "@aws-sdk/util-user-agent-browser": 3.609.0 + "@aws-sdk/util-user-agent-node": 3.614.0 + "@smithy/config-resolver": ^3.0.5 + "@smithy/core": ^2.3.1 + "@smithy/fetch-http-handler": ^3.2.4 + "@smithy/hash-node": ^3.0.3 + "@smithy/invalid-dependency": ^3.0.3 + "@smithy/middleware-content-length": ^3.0.5 + "@smithy/middleware-endpoint": ^3.1.0 + "@smithy/middleware-retry": ^3.0.13 + "@smithy/middleware-serde": ^3.0.3 + "@smithy/middleware-stack": ^3.0.3 + "@smithy/node-config-provider": ^3.1.4 + "@smithy/node-http-handler": ^3.1.4 + "@smithy/protocol-http": ^4.1.0 + "@smithy/smithy-client": ^3.1.11 + "@smithy/types": ^3.3.0 + "@smithy/url-parser": ^3.0.3 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.4 - "@smithy/util-defaults-mode-node": ^3.0.4 - "@smithy/util-endpoints": ^2.0.2 - "@smithy/util-middleware": ^3.0.1 - "@smithy/util-retry": ^3.0.1 + "@smithy/util-defaults-mode-browser": ^3.0.13 + "@smithy/util-defaults-mode-node": ^3.0.13 + "@smithy/util-endpoints": ^2.0.5 + "@smithy/util-middleware": ^3.0.3 + "@smithy/util-retry": ^3.0.3 "@smithy/util-utf8": ^3.0.0 - "@smithy/util-waiter": ^3.0.1 + "@smithy/util-waiter": ^3.1.2 tslib: ^2.6.2 uuid: ^9.0.1 - checksum: 6cd87756d631fd18b12d21a89a938612ba17446cdc1de06c3c3a0ee488ffd8c9de4af3d27567524eb0e17155d423394e374002cb5a45d4376df6d82255abe870 + checksum: a69d67d1d6c447e541baebc06f2e5e4ac6532933422a0af2850c916075986c555d1e3ba9f397c1c35e95efd770642b5985d6f2c73d38cd566c4425fecc0dc2fa languageName: node linkType: hard "@aws-sdk/client-organizations@npm:^3.350.0": - version: 3.600.0 - resolution: "@aws-sdk/client-organizations@npm:3.600.0" + version: 3.621.0 + resolution: "@aws-sdk/client-organizations@npm:3.621.0" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.600.0 - "@aws-sdk/client-sts": 3.600.0 - "@aws-sdk/core": 3.598.0 - "@aws-sdk/credential-provider-node": 3.600.0 - "@aws-sdk/middleware-host-header": 3.598.0 - "@aws-sdk/middleware-logger": 3.598.0 - "@aws-sdk/middleware-recursion-detection": 3.598.0 - "@aws-sdk/middleware-user-agent": 3.598.0 - "@aws-sdk/region-config-resolver": 3.598.0 - "@aws-sdk/types": 3.598.0 - "@aws-sdk/util-endpoints": 3.598.0 - "@aws-sdk/util-user-agent-browser": 3.598.0 - "@aws-sdk/util-user-agent-node": 3.598.0 - "@smithy/config-resolver": ^3.0.2 - "@smithy/core": ^2.2.1 - "@smithy/fetch-http-handler": ^3.0.2 - "@smithy/hash-node": ^3.0.1 - "@smithy/invalid-dependency": ^3.0.1 - "@smithy/middleware-content-length": ^3.0.1 - "@smithy/middleware-endpoint": ^3.0.2 - "@smithy/middleware-retry": ^3.0.4 - "@smithy/middleware-serde": ^3.0.1 - "@smithy/middleware-stack": ^3.0.1 - "@smithy/node-config-provider": ^3.1.1 - "@smithy/node-http-handler": ^3.0.1 - "@smithy/protocol-http": ^4.0.1 - "@smithy/smithy-client": ^3.1.2 - "@smithy/types": ^3.1.0 - "@smithy/url-parser": ^3.0.1 + "@aws-sdk/client-sso-oidc": 3.621.0 + "@aws-sdk/client-sts": 3.621.0 + "@aws-sdk/core": 3.621.0 + "@aws-sdk/credential-provider-node": 3.621.0 + "@aws-sdk/middleware-host-header": 3.620.0 + "@aws-sdk/middleware-logger": 3.609.0 + "@aws-sdk/middleware-recursion-detection": 3.620.0 + "@aws-sdk/middleware-user-agent": 3.620.0 + "@aws-sdk/region-config-resolver": 3.614.0 + "@aws-sdk/types": 3.609.0 + "@aws-sdk/util-endpoints": 3.614.0 + "@aws-sdk/util-user-agent-browser": 3.609.0 + "@aws-sdk/util-user-agent-node": 3.614.0 + "@smithy/config-resolver": ^3.0.5 + "@smithy/core": ^2.3.1 + "@smithy/fetch-http-handler": ^3.2.4 + "@smithy/hash-node": ^3.0.3 + "@smithy/invalid-dependency": ^3.0.3 + "@smithy/middleware-content-length": ^3.0.5 + "@smithy/middleware-endpoint": ^3.1.0 + "@smithy/middleware-retry": ^3.0.13 + "@smithy/middleware-serde": ^3.0.3 + "@smithy/middleware-stack": ^3.0.3 + "@smithy/node-config-provider": ^3.1.4 + "@smithy/node-http-handler": ^3.1.4 + "@smithy/protocol-http": ^4.1.0 + "@smithy/smithy-client": ^3.1.11 + "@smithy/types": ^3.3.0 + "@smithy/url-parser": ^3.0.3 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.4 - "@smithy/util-defaults-mode-node": ^3.0.4 - "@smithy/util-endpoints": ^2.0.2 - "@smithy/util-middleware": ^3.0.1 - "@smithy/util-retry": ^3.0.1 + "@smithy/util-defaults-mode-browser": ^3.0.13 + "@smithy/util-defaults-mode-node": ^3.0.13 + "@smithy/util-endpoints": ^2.0.5 + "@smithy/util-middleware": ^3.0.3 + "@smithy/util-retry": ^3.0.3 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: b403a51e298fec8ec93553ac8a22a452408b0634b3a01d6c61ce271d7af69b1cef8907a9dce31fad79fa2cfc01fd6912d848e9b656b7a16f973e986b00bd727c + checksum: 28db7d0490cc93a512cc2299afa67ce01d60f2f07ec4a59f9e826c86ef0769164ac103128c0c8617ea86f0a4d2a7be2468803aace84e054e1db7a00c871f7783 languageName: node linkType: hard "@aws-sdk/client-s3@npm:^3.350.0": - version: 3.600.0 - resolution: "@aws-sdk/client-s3@npm:3.600.0" + version: 3.621.0 + resolution: "@aws-sdk/client-s3@npm:3.621.0" dependencies: "@aws-crypto/sha1-browser": 5.2.0 "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.600.0 - "@aws-sdk/client-sts": 3.600.0 - "@aws-sdk/core": 3.598.0 - "@aws-sdk/credential-provider-node": 3.600.0 - "@aws-sdk/middleware-bucket-endpoint": 3.598.0 - "@aws-sdk/middleware-expect-continue": 3.598.0 - "@aws-sdk/middleware-flexible-checksums": 3.598.0 - "@aws-sdk/middleware-host-header": 3.598.0 - "@aws-sdk/middleware-location-constraint": 3.598.0 - "@aws-sdk/middleware-logger": 3.598.0 - "@aws-sdk/middleware-recursion-detection": 3.598.0 - "@aws-sdk/middleware-sdk-s3": 3.598.0 - "@aws-sdk/middleware-signing": 3.598.0 - "@aws-sdk/middleware-ssec": 3.598.0 - "@aws-sdk/middleware-user-agent": 3.598.0 - "@aws-sdk/region-config-resolver": 3.598.0 - "@aws-sdk/signature-v4-multi-region": 3.598.0 - "@aws-sdk/types": 3.598.0 - "@aws-sdk/util-endpoints": 3.598.0 - "@aws-sdk/util-user-agent-browser": 3.598.0 - "@aws-sdk/util-user-agent-node": 3.598.0 - "@aws-sdk/xml-builder": 3.598.0 - "@smithy/config-resolver": ^3.0.2 - "@smithy/core": ^2.2.1 - "@smithy/eventstream-serde-browser": ^3.0.2 - "@smithy/eventstream-serde-config-resolver": ^3.0.1 - "@smithy/eventstream-serde-node": ^3.0.2 - "@smithy/fetch-http-handler": ^3.0.2 - "@smithy/hash-blob-browser": ^3.1.0 - "@smithy/hash-node": ^3.0.1 - "@smithy/hash-stream-node": ^3.1.0 - "@smithy/invalid-dependency": ^3.0.1 - "@smithy/md5-js": ^3.0.1 - "@smithy/middleware-content-length": ^3.0.1 - "@smithy/middleware-endpoint": ^3.0.2 - "@smithy/middleware-retry": ^3.0.4 - "@smithy/middleware-serde": ^3.0.1 - "@smithy/middleware-stack": ^3.0.1 - "@smithy/node-config-provider": ^3.1.1 - "@smithy/node-http-handler": ^3.0.1 - "@smithy/protocol-http": ^4.0.1 - "@smithy/smithy-client": ^3.1.2 - "@smithy/types": ^3.1.0 - "@smithy/url-parser": ^3.0.1 + "@aws-sdk/client-sso-oidc": 3.621.0 + "@aws-sdk/client-sts": 3.621.0 + "@aws-sdk/core": 3.621.0 + "@aws-sdk/credential-provider-node": 3.621.0 + "@aws-sdk/middleware-bucket-endpoint": 3.620.0 + "@aws-sdk/middleware-expect-continue": 3.620.0 + "@aws-sdk/middleware-flexible-checksums": 3.620.0 + "@aws-sdk/middleware-host-header": 3.620.0 + "@aws-sdk/middleware-location-constraint": 3.609.0 + "@aws-sdk/middleware-logger": 3.609.0 + "@aws-sdk/middleware-recursion-detection": 3.620.0 + "@aws-sdk/middleware-sdk-s3": 3.621.0 + "@aws-sdk/middleware-signing": 3.620.0 + "@aws-sdk/middleware-ssec": 3.609.0 + "@aws-sdk/middleware-user-agent": 3.620.0 + "@aws-sdk/region-config-resolver": 3.614.0 + "@aws-sdk/signature-v4-multi-region": 3.621.0 + "@aws-sdk/types": 3.609.0 + "@aws-sdk/util-endpoints": 3.614.0 + "@aws-sdk/util-user-agent-browser": 3.609.0 + "@aws-sdk/util-user-agent-node": 3.614.0 + "@aws-sdk/xml-builder": 3.609.0 + "@smithy/config-resolver": ^3.0.5 + "@smithy/core": ^2.3.1 + "@smithy/eventstream-serde-browser": ^3.0.5 + "@smithy/eventstream-serde-config-resolver": ^3.0.3 + "@smithy/eventstream-serde-node": ^3.0.4 + "@smithy/fetch-http-handler": ^3.2.4 + "@smithy/hash-blob-browser": ^3.1.2 + "@smithy/hash-node": ^3.0.3 + "@smithy/hash-stream-node": ^3.1.2 + "@smithy/invalid-dependency": ^3.0.3 + "@smithy/md5-js": ^3.0.3 + "@smithy/middleware-content-length": ^3.0.5 + "@smithy/middleware-endpoint": ^3.1.0 + "@smithy/middleware-retry": ^3.0.13 + "@smithy/middleware-serde": ^3.0.3 + "@smithy/middleware-stack": ^3.0.3 + "@smithy/node-config-provider": ^3.1.4 + "@smithy/node-http-handler": ^3.1.4 + "@smithy/protocol-http": ^4.1.0 + "@smithy/smithy-client": ^3.1.11 + "@smithy/types": ^3.3.0 + "@smithy/url-parser": ^3.0.3 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.4 - "@smithy/util-defaults-mode-node": ^3.0.4 - "@smithy/util-endpoints": ^2.0.2 - "@smithy/util-retry": ^3.0.1 - "@smithy/util-stream": ^3.0.2 + "@smithy/util-defaults-mode-browser": ^3.0.13 + "@smithy/util-defaults-mode-node": ^3.0.13 + "@smithy/util-endpoints": ^2.0.5 + "@smithy/util-retry": ^3.0.3 + "@smithy/util-stream": ^3.1.3 "@smithy/util-utf8": ^3.0.0 - "@smithy/util-waiter": ^3.0.1 + "@smithy/util-waiter": ^3.1.2 tslib: ^2.6.2 - checksum: be9940ac1a9bff2e8efbf6f0ac782b0bcd66ab229639dc46d60aa71e041b3ef16a327e37c92397691a16c982cf5e529ab2ffd60351a9d9730bf4947bb391ced4 + checksum: 120bfaa142a61a8dbc2f82d6fe5e36cb2ec0acdb12390795d15326dfad4f67b0d2e95515afb04da34b3f686fef0368f7a79a20c85735b28df654cbc5bdb1f04c languageName: node linkType: hard "@aws-sdk/client-ses@npm:^3.550.0": - version: 3.600.0 - resolution: "@aws-sdk/client-ses@npm:3.600.0" + version: 3.621.0 + resolution: "@aws-sdk/client-ses@npm:3.621.0" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.600.0 - "@aws-sdk/client-sts": 3.600.0 - "@aws-sdk/core": 3.598.0 - "@aws-sdk/credential-provider-node": 3.600.0 - "@aws-sdk/middleware-host-header": 3.598.0 - "@aws-sdk/middleware-logger": 3.598.0 - "@aws-sdk/middleware-recursion-detection": 3.598.0 - "@aws-sdk/middleware-user-agent": 3.598.0 - "@aws-sdk/region-config-resolver": 3.598.0 - "@aws-sdk/types": 3.598.0 - "@aws-sdk/util-endpoints": 3.598.0 - "@aws-sdk/util-user-agent-browser": 3.598.0 - "@aws-sdk/util-user-agent-node": 3.598.0 - "@smithy/config-resolver": ^3.0.2 - "@smithy/core": ^2.2.1 - "@smithy/fetch-http-handler": ^3.0.2 - "@smithy/hash-node": ^3.0.1 - "@smithy/invalid-dependency": ^3.0.1 - "@smithy/middleware-content-length": ^3.0.1 - "@smithy/middleware-endpoint": ^3.0.2 - "@smithy/middleware-retry": ^3.0.4 - "@smithy/middleware-serde": ^3.0.1 - "@smithy/middleware-stack": ^3.0.1 - "@smithy/node-config-provider": ^3.1.1 - "@smithy/node-http-handler": ^3.0.1 - "@smithy/protocol-http": ^4.0.1 - "@smithy/smithy-client": ^3.1.2 - "@smithy/types": ^3.1.0 - "@smithy/url-parser": ^3.0.1 + "@aws-sdk/client-sso-oidc": 3.621.0 + "@aws-sdk/client-sts": 3.621.0 + "@aws-sdk/core": 3.621.0 + "@aws-sdk/credential-provider-node": 3.621.0 + "@aws-sdk/middleware-host-header": 3.620.0 + "@aws-sdk/middleware-logger": 3.609.0 + "@aws-sdk/middleware-recursion-detection": 3.620.0 + "@aws-sdk/middleware-user-agent": 3.620.0 + "@aws-sdk/region-config-resolver": 3.614.0 + "@aws-sdk/types": 3.609.0 + "@aws-sdk/util-endpoints": 3.614.0 + "@aws-sdk/util-user-agent-browser": 3.609.0 + "@aws-sdk/util-user-agent-node": 3.614.0 + "@smithy/config-resolver": ^3.0.5 + "@smithy/core": ^2.3.1 + "@smithy/fetch-http-handler": ^3.2.4 + "@smithy/hash-node": ^3.0.3 + "@smithy/invalid-dependency": ^3.0.3 + "@smithy/middleware-content-length": ^3.0.5 + "@smithy/middleware-endpoint": ^3.1.0 + "@smithy/middleware-retry": ^3.0.13 + "@smithy/middleware-serde": ^3.0.3 + "@smithy/middleware-stack": ^3.0.3 + "@smithy/node-config-provider": ^3.1.4 + "@smithy/node-http-handler": ^3.1.4 + "@smithy/protocol-http": ^4.1.0 + "@smithy/smithy-client": ^3.1.11 + "@smithy/types": ^3.3.0 + "@smithy/url-parser": ^3.0.3 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.4 - "@smithy/util-defaults-mode-node": ^3.0.4 - "@smithy/util-endpoints": ^2.0.2 - "@smithy/util-middleware": ^3.0.1 - "@smithy/util-retry": ^3.0.1 + "@smithy/util-defaults-mode-browser": ^3.0.13 + "@smithy/util-defaults-mode-node": ^3.0.13 + "@smithy/util-endpoints": ^2.0.5 + "@smithy/util-middleware": ^3.0.3 + "@smithy/util-retry": ^3.0.3 "@smithy/util-utf8": ^3.0.0 - "@smithy/util-waiter": ^3.0.1 + "@smithy/util-waiter": ^3.1.2 tslib: ^2.6.2 - checksum: f0c042db4e20b8165f7da42ba2026ee6c32944c10c6a3508c021efbc0a3474fd0ef888367db47f54dc89a6bbad482858b0c816f6d3ec4ac84bfc156d315b2381 + checksum: 40de6b66fc6ac93eae26906cfb77b9a9d4bfd1a990e68f5bdc1a7024a624397e470149c1054e904c181b87b09e1a9d1ec4308dc206ffdfa5740113c0a199b5eb languageName: node linkType: hard "@aws-sdk/client-sqs@npm:^3.350.0": - version: 3.600.0 - resolution: "@aws-sdk/client-sqs@npm:3.600.0" + version: 3.621.0 + resolution: "@aws-sdk/client-sqs@npm:3.621.0" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.600.0 - "@aws-sdk/client-sts": 3.600.0 - "@aws-sdk/core": 3.598.0 - "@aws-sdk/credential-provider-node": 3.600.0 - "@aws-sdk/middleware-host-header": 3.598.0 - "@aws-sdk/middleware-logger": 3.598.0 - "@aws-sdk/middleware-recursion-detection": 3.598.0 - "@aws-sdk/middleware-sdk-sqs": 3.598.0 - "@aws-sdk/middleware-user-agent": 3.598.0 - "@aws-sdk/region-config-resolver": 3.598.0 - "@aws-sdk/types": 3.598.0 - "@aws-sdk/util-endpoints": 3.598.0 - "@aws-sdk/util-user-agent-browser": 3.598.0 - "@aws-sdk/util-user-agent-node": 3.598.0 - "@smithy/config-resolver": ^3.0.2 - "@smithy/core": ^2.2.1 - "@smithy/fetch-http-handler": ^3.0.2 - "@smithy/hash-node": ^3.0.1 - "@smithy/invalid-dependency": ^3.0.1 - "@smithy/md5-js": ^3.0.1 - "@smithy/middleware-content-length": ^3.0.1 - "@smithy/middleware-endpoint": ^3.0.2 - "@smithy/middleware-retry": ^3.0.4 - "@smithy/middleware-serde": ^3.0.1 - "@smithy/middleware-stack": ^3.0.1 - "@smithy/node-config-provider": ^3.1.1 - "@smithy/node-http-handler": ^3.0.1 - "@smithy/protocol-http": ^4.0.1 - "@smithy/smithy-client": ^3.1.2 - "@smithy/types": ^3.1.0 - "@smithy/url-parser": ^3.0.1 + "@aws-sdk/client-sso-oidc": 3.621.0 + "@aws-sdk/client-sts": 3.621.0 + "@aws-sdk/core": 3.621.0 + "@aws-sdk/credential-provider-node": 3.621.0 + "@aws-sdk/middleware-host-header": 3.620.0 + "@aws-sdk/middleware-logger": 3.609.0 + "@aws-sdk/middleware-recursion-detection": 3.620.0 + "@aws-sdk/middleware-sdk-sqs": 3.621.0 + "@aws-sdk/middleware-user-agent": 3.620.0 + "@aws-sdk/region-config-resolver": 3.614.0 + "@aws-sdk/types": 3.609.0 + "@aws-sdk/util-endpoints": 3.614.0 + "@aws-sdk/util-user-agent-browser": 3.609.0 + "@aws-sdk/util-user-agent-node": 3.614.0 + "@smithy/config-resolver": ^3.0.5 + "@smithy/core": ^2.3.1 + "@smithy/fetch-http-handler": ^3.2.4 + "@smithy/hash-node": ^3.0.3 + "@smithy/invalid-dependency": ^3.0.3 + "@smithy/md5-js": ^3.0.3 + "@smithy/middleware-content-length": ^3.0.5 + "@smithy/middleware-endpoint": ^3.1.0 + "@smithy/middleware-retry": ^3.0.13 + "@smithy/middleware-serde": ^3.0.3 + "@smithy/middleware-stack": ^3.0.3 + "@smithy/node-config-provider": ^3.1.4 + "@smithy/node-http-handler": ^3.1.4 + "@smithy/protocol-http": ^4.1.0 + "@smithy/smithy-client": ^3.1.11 + "@smithy/types": ^3.3.0 + "@smithy/url-parser": ^3.0.3 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.4 - "@smithy/util-defaults-mode-node": ^3.0.4 - "@smithy/util-endpoints": ^2.0.2 - "@smithy/util-middleware": ^3.0.1 - "@smithy/util-retry": ^3.0.1 + "@smithy/util-defaults-mode-browser": ^3.0.13 + "@smithy/util-defaults-mode-node": ^3.0.13 + "@smithy/util-endpoints": ^2.0.5 + "@smithy/util-middleware": ^3.0.3 + "@smithy/util-retry": ^3.0.3 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: e0ec11d0d89539ae1964cc2f0655af7367c0c43153ab16fe9542e303cd1b69c5f0e9f3d912c52ff7bbfc5f557733d52e187e72563f0bfed3a21ed6249ae37c8a + checksum: 293d3164570623e6228fc9e14c803b20e7ca5e562ce470f6f8ee3adf2b9a4cffd886ab69859d60afa1cf46f2df8cd9e0190a081335c1c2be21fee0739f21ce9f languageName: node linkType: hard -"@aws-sdk/client-sso-oidc@npm:3.600.0": - version: 3.600.0 - resolution: "@aws-sdk/client-sso-oidc@npm:3.600.0" +"@aws-sdk/client-sso-oidc@npm:3.621.0": + version: 3.621.0 + resolution: "@aws-sdk/client-sso-oidc@npm:3.621.0" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sts": 3.600.0 - "@aws-sdk/core": 3.598.0 - "@aws-sdk/credential-provider-node": 3.600.0 - "@aws-sdk/middleware-host-header": 3.598.0 - "@aws-sdk/middleware-logger": 3.598.0 - "@aws-sdk/middleware-recursion-detection": 3.598.0 - "@aws-sdk/middleware-user-agent": 3.598.0 - "@aws-sdk/region-config-resolver": 3.598.0 - "@aws-sdk/types": 3.598.0 - "@aws-sdk/util-endpoints": 3.598.0 - "@aws-sdk/util-user-agent-browser": 3.598.0 - "@aws-sdk/util-user-agent-node": 3.598.0 - "@smithy/config-resolver": ^3.0.2 - "@smithy/core": ^2.2.1 - "@smithy/fetch-http-handler": ^3.0.2 - "@smithy/hash-node": ^3.0.1 - "@smithy/invalid-dependency": ^3.0.1 - "@smithy/middleware-content-length": ^3.0.1 - "@smithy/middleware-endpoint": ^3.0.2 - "@smithy/middleware-retry": ^3.0.4 - "@smithy/middleware-serde": ^3.0.1 - "@smithy/middleware-stack": ^3.0.1 - "@smithy/node-config-provider": ^3.1.1 - "@smithy/node-http-handler": ^3.0.1 - "@smithy/protocol-http": ^4.0.1 - "@smithy/smithy-client": ^3.1.2 - "@smithy/types": ^3.1.0 - "@smithy/url-parser": ^3.0.1 + "@aws-sdk/core": 3.621.0 + "@aws-sdk/credential-provider-node": 3.621.0 + "@aws-sdk/middleware-host-header": 3.620.0 + "@aws-sdk/middleware-logger": 3.609.0 + "@aws-sdk/middleware-recursion-detection": 3.620.0 + "@aws-sdk/middleware-user-agent": 3.620.0 + "@aws-sdk/region-config-resolver": 3.614.0 + "@aws-sdk/types": 3.609.0 + "@aws-sdk/util-endpoints": 3.614.0 + "@aws-sdk/util-user-agent-browser": 3.609.0 + "@aws-sdk/util-user-agent-node": 3.614.0 + "@smithy/config-resolver": ^3.0.5 + "@smithy/core": ^2.3.1 + "@smithy/fetch-http-handler": ^3.2.4 + "@smithy/hash-node": ^3.0.3 + "@smithy/invalid-dependency": ^3.0.3 + "@smithy/middleware-content-length": ^3.0.5 + "@smithy/middleware-endpoint": ^3.1.0 + "@smithy/middleware-retry": ^3.0.13 + "@smithy/middleware-serde": ^3.0.3 + "@smithy/middleware-stack": ^3.0.3 + "@smithy/node-config-provider": ^3.1.4 + "@smithy/node-http-handler": ^3.1.4 + "@smithy/protocol-http": ^4.1.0 + "@smithy/smithy-client": ^3.1.11 + "@smithy/types": ^3.3.0 + "@smithy/url-parser": ^3.0.3 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.4 - "@smithy/util-defaults-mode-node": ^3.0.4 - "@smithy/util-endpoints": ^2.0.2 - "@smithy/util-middleware": ^3.0.1 - "@smithy/util-retry": ^3.0.1 + "@smithy/util-defaults-mode-browser": ^3.0.13 + "@smithy/util-defaults-mode-node": ^3.0.13 + "@smithy/util-endpoints": ^2.0.5 + "@smithy/util-middleware": ^3.0.3 + "@smithy/util-retry": ^3.0.3 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: ef7a40ce69de30b25a8a7a5ee035f17e87edc1060c128b3b50f30f19b681aaa7b99b564ffc348cd74fe0e1079bd46087a6784674266d743c45564bcd4d5221b3 - languageName: node - linkType: hard - -"@aws-sdk/client-sso@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/client-sso@npm:3.598.0" - dependencies: - "@aws-crypto/sha256-browser": 5.2.0 - "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/core": 3.598.0 - "@aws-sdk/middleware-host-header": 3.598.0 - "@aws-sdk/middleware-logger": 3.598.0 - "@aws-sdk/middleware-recursion-detection": 3.598.0 - "@aws-sdk/middleware-user-agent": 3.598.0 - "@aws-sdk/region-config-resolver": 3.598.0 - "@aws-sdk/types": 3.598.0 - "@aws-sdk/util-endpoints": 3.598.0 - "@aws-sdk/util-user-agent-browser": 3.598.0 - "@aws-sdk/util-user-agent-node": 3.598.0 - "@smithy/config-resolver": ^3.0.2 - "@smithy/core": ^2.2.1 - "@smithy/fetch-http-handler": ^3.0.2 - "@smithy/hash-node": ^3.0.1 - "@smithy/invalid-dependency": ^3.0.1 - "@smithy/middleware-content-length": ^3.0.1 - "@smithy/middleware-endpoint": ^3.0.2 - "@smithy/middleware-retry": ^3.0.4 - "@smithy/middleware-serde": ^3.0.1 - "@smithy/middleware-stack": ^3.0.1 - "@smithy/node-config-provider": ^3.1.1 - "@smithy/node-http-handler": ^3.0.1 - "@smithy/protocol-http": ^4.0.1 - "@smithy/smithy-client": ^3.1.2 - "@smithy/types": ^3.1.0 - "@smithy/url-parser": ^3.0.1 - "@smithy/util-base64": ^3.0.0 - "@smithy/util-body-length-browser": ^3.0.0 - "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.4 - "@smithy/util-defaults-mode-node": ^3.0.4 - "@smithy/util-endpoints": ^2.0.2 - "@smithy/util-middleware": ^3.0.1 - "@smithy/util-retry": ^3.0.1 - "@smithy/util-utf8": ^3.0.0 - tslib: ^2.6.2 - checksum: b570f54643ac0ab0f300bf074e77c2fbba70206a11d2aed1f6ecd361027f2f6a1d62719627e905bcb44dd73d481a29ef5a70878c676386afe2a133f479a445d4 - languageName: node - linkType: hard - -"@aws-sdk/client-sts@npm:3.600.0, @aws-sdk/client-sts@npm:^3.350.0": - version: 3.600.0 - resolution: "@aws-sdk/client-sts@npm:3.600.0" - dependencies: - "@aws-crypto/sha256-browser": 5.2.0 - "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.600.0 - "@aws-sdk/core": 3.598.0 - "@aws-sdk/credential-provider-node": 3.600.0 - "@aws-sdk/middleware-host-header": 3.598.0 - "@aws-sdk/middleware-logger": 3.598.0 - "@aws-sdk/middleware-recursion-detection": 3.598.0 - "@aws-sdk/middleware-user-agent": 3.598.0 - "@aws-sdk/region-config-resolver": 3.598.0 - "@aws-sdk/types": 3.598.0 - "@aws-sdk/util-endpoints": 3.598.0 - "@aws-sdk/util-user-agent-browser": 3.598.0 - "@aws-sdk/util-user-agent-node": 3.598.0 - "@smithy/config-resolver": ^3.0.2 - "@smithy/core": ^2.2.1 - "@smithy/fetch-http-handler": ^3.0.2 - "@smithy/hash-node": ^3.0.1 - "@smithy/invalid-dependency": ^3.0.1 - "@smithy/middleware-content-length": ^3.0.1 - "@smithy/middleware-endpoint": ^3.0.2 - "@smithy/middleware-retry": ^3.0.4 - "@smithy/middleware-serde": ^3.0.1 - "@smithy/middleware-stack": ^3.0.1 - "@smithy/node-config-provider": ^3.1.1 - "@smithy/node-http-handler": ^3.0.1 - "@smithy/protocol-http": ^4.0.1 - "@smithy/smithy-client": ^3.1.2 - "@smithy/types": ^3.1.0 - "@smithy/url-parser": ^3.0.1 - "@smithy/util-base64": ^3.0.0 - "@smithy/util-body-length-browser": ^3.0.0 - "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.4 - "@smithy/util-defaults-mode-node": ^3.0.4 - "@smithy/util-endpoints": ^2.0.2 - "@smithy/util-middleware": ^3.0.1 - "@smithy/util-retry": ^3.0.1 - "@smithy/util-utf8": ^3.0.0 - tslib: ^2.6.2 - checksum: 47d6d145d481c8dc285b68baccf36ab76b92ed1fbf5a58a0900bbe913a7caf3eddc84414428b013e58c91242e7ffd5a55b0620217dc295c75c2729ccb89b9ae8 - languageName: node - linkType: hard - -"@aws-sdk/core@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/core@npm:3.598.0" - dependencies: - "@smithy/core": ^2.2.1 - "@smithy/protocol-http": ^4.0.1 - "@smithy/signature-v4": ^3.1.0 - "@smithy/smithy-client": ^3.1.2 - "@smithy/types": ^3.1.0 - fast-xml-parser: 4.2.5 - tslib: ^2.6.2 - checksum: e58944a6571808b53d21f012b9671ffec597d2a826a9c0f1fbcbe160189a3c47f5b4671ac92b7437c349f19b8a8df7e12255c57795ab0224c318ed69a0d23229 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-cognito-identity@npm:3.600.0": - version: 3.600.0 - resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.600.0" - dependencies: - "@aws-sdk/client-cognito-identity": 3.600.0 - "@aws-sdk/types": 3.598.0 - "@smithy/property-provider": ^3.1.1 - "@smithy/types": ^3.1.0 - tslib: ^2.6.2 - checksum: 9e7e325fde26192fbd7f542ad0ff69d193b5edb65b0361cdeb13f538b1b563de999e82da34493921351ea599643c4884bd17fdc16eba423d3343e681f346072f - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-env@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/credential-provider-env@npm:3.598.0" - dependencies: - "@aws-sdk/types": 3.598.0 - "@smithy/property-provider": ^3.1.1 - "@smithy/types": ^3.1.0 - tslib: ^2.6.2 - checksum: 517f06dd47b7aa4c8d5a9fe82698150237c28c46ed9f82cd1d92d1453690b9d6139b65519d92dea611d319c4418fe4540e7d52c03d3897e7e471731fb0156afb - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-http@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/credential-provider-http@npm:3.598.0" - dependencies: - "@aws-sdk/types": 3.598.0 - "@smithy/fetch-http-handler": ^3.0.2 - "@smithy/node-http-handler": ^3.0.1 - "@smithy/property-provider": ^3.1.1 - "@smithy/protocol-http": ^4.0.1 - "@smithy/smithy-client": ^3.1.2 - "@smithy/types": ^3.1.0 - "@smithy/util-stream": ^3.0.2 - tslib: ^2.6.2 - checksum: e2f6208491a6e58b7ac7368c2247dee55080be740511ded01cc3454920ef29d0b7712930571651a8d0ec2aea4e0a107c7d5dd6ecd01bd4de3c264c54e32959b3 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-ini@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/credential-provider-ini@npm:3.598.0" - dependencies: - "@aws-sdk/credential-provider-env": 3.598.0 - "@aws-sdk/credential-provider-http": 3.598.0 - "@aws-sdk/credential-provider-process": 3.598.0 - "@aws-sdk/credential-provider-sso": 3.598.0 - "@aws-sdk/credential-provider-web-identity": 3.598.0 - "@aws-sdk/types": 3.598.0 - "@smithy/credential-provider-imds": ^3.1.1 - "@smithy/property-provider": ^3.1.1 - "@smithy/shared-ini-file-loader": ^3.1.1 - "@smithy/types": ^3.1.0 - tslib: ^2.6.2 peerDependencies: - "@aws-sdk/client-sts": ^3.598.0 - checksum: 9fab1e9c312e20150c96daf15e0347b79f0589cc44eb299c15e80c7d5380e8966805fa8893d3c906f99b7eb3c0f872f0795415f75921204580a30d869dd87f54 + "@aws-sdk/client-sts": ^3.621.0 + checksum: 12aa50a56f2498a9202b877b0b789fa95c038707b648dc3c9e93976c209ed3d4518868279707ee8fe12f42858eba7181098bdbf68556341c9017bd5e31f89135 languageName: node linkType: hard -"@aws-sdk/credential-provider-node@npm:3.600.0, @aws-sdk/credential-provider-node@npm:^3.350.0": - version: 3.600.0 - resolution: "@aws-sdk/credential-provider-node@npm:3.600.0" +"@aws-sdk/client-sso@npm:3.621.0": + version: 3.621.0 + resolution: "@aws-sdk/client-sso@npm:3.621.0" dependencies: - "@aws-sdk/credential-provider-env": 3.598.0 - "@aws-sdk/credential-provider-http": 3.598.0 - "@aws-sdk/credential-provider-ini": 3.598.0 - "@aws-sdk/credential-provider-process": 3.598.0 - "@aws-sdk/credential-provider-sso": 3.598.0 - "@aws-sdk/credential-provider-web-identity": 3.598.0 - "@aws-sdk/types": 3.598.0 - "@smithy/credential-provider-imds": ^3.1.1 - "@smithy/property-provider": ^3.1.1 - "@smithy/shared-ini-file-loader": ^3.1.1 - "@smithy/types": ^3.1.0 + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.621.0 + "@aws-sdk/middleware-host-header": 3.620.0 + "@aws-sdk/middleware-logger": 3.609.0 + "@aws-sdk/middleware-recursion-detection": 3.620.0 + "@aws-sdk/middleware-user-agent": 3.620.0 + "@aws-sdk/region-config-resolver": 3.614.0 + "@aws-sdk/types": 3.609.0 + "@aws-sdk/util-endpoints": 3.614.0 + "@aws-sdk/util-user-agent-browser": 3.609.0 + "@aws-sdk/util-user-agent-node": 3.614.0 + "@smithy/config-resolver": ^3.0.5 + "@smithy/core": ^2.3.1 + "@smithy/fetch-http-handler": ^3.2.4 + "@smithy/hash-node": ^3.0.3 + "@smithy/invalid-dependency": ^3.0.3 + "@smithy/middleware-content-length": ^3.0.5 + "@smithy/middleware-endpoint": ^3.1.0 + "@smithy/middleware-retry": ^3.0.13 + "@smithy/middleware-serde": ^3.0.3 + "@smithy/middleware-stack": ^3.0.3 + "@smithy/node-config-provider": ^3.1.4 + "@smithy/node-http-handler": ^3.1.4 + "@smithy/protocol-http": ^4.1.0 + "@smithy/smithy-client": ^3.1.11 + "@smithy/types": ^3.3.0 + "@smithy/url-parser": ^3.0.3 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.13 + "@smithy/util-defaults-mode-node": ^3.0.13 + "@smithy/util-endpoints": ^2.0.5 + "@smithy/util-middleware": ^3.0.3 + "@smithy/util-retry": ^3.0.3 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 480c7c36a8558667a25617e6f7f2292b4362b0e894bc204ce62f565dc8e8cc46c713dc04621321336ce715b493590b3b854b33dc6d5123ed39a17643158d94fc + checksum: fe72875685c07b9cf42b7fcde06502d42a5398161b37de87c5360f10a0d28cf7b32fc95f5eecdf782cff04c8109bd7a20d9644bfacc78e3521b6a7670ed76b40 languageName: node linkType: hard -"@aws-sdk/credential-provider-process@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/credential-provider-process@npm:3.598.0" +"@aws-sdk/client-sts@npm:3.621.0, @aws-sdk/client-sts@npm:^3.350.0": + version: 3.621.0 + resolution: "@aws-sdk/client-sts@npm:3.621.0" dependencies: - "@aws-sdk/types": 3.598.0 - "@smithy/property-provider": ^3.1.1 - "@smithy/shared-ini-file-loader": ^3.1.1 - "@smithy/types": ^3.1.0 + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/client-sso-oidc": 3.621.0 + "@aws-sdk/core": 3.621.0 + "@aws-sdk/credential-provider-node": 3.621.0 + "@aws-sdk/middleware-host-header": 3.620.0 + "@aws-sdk/middleware-logger": 3.609.0 + "@aws-sdk/middleware-recursion-detection": 3.620.0 + "@aws-sdk/middleware-user-agent": 3.620.0 + "@aws-sdk/region-config-resolver": 3.614.0 + "@aws-sdk/types": 3.609.0 + "@aws-sdk/util-endpoints": 3.614.0 + "@aws-sdk/util-user-agent-browser": 3.609.0 + "@aws-sdk/util-user-agent-node": 3.614.0 + "@smithy/config-resolver": ^3.0.5 + "@smithy/core": ^2.3.1 + "@smithy/fetch-http-handler": ^3.2.4 + "@smithy/hash-node": ^3.0.3 + "@smithy/invalid-dependency": ^3.0.3 + "@smithy/middleware-content-length": ^3.0.5 + "@smithy/middleware-endpoint": ^3.1.0 + "@smithy/middleware-retry": ^3.0.13 + "@smithy/middleware-serde": ^3.0.3 + "@smithy/middleware-stack": ^3.0.3 + "@smithy/node-config-provider": ^3.1.4 + "@smithy/node-http-handler": ^3.1.4 + "@smithy/protocol-http": ^4.1.0 + "@smithy/smithy-client": ^3.1.11 + "@smithy/types": ^3.3.0 + "@smithy/url-parser": ^3.0.3 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.13 + "@smithy/util-defaults-mode-node": ^3.0.13 + "@smithy/util-endpoints": ^2.0.5 + "@smithy/util-middleware": ^3.0.3 + "@smithy/util-retry": ^3.0.3 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: cd1f0dbbc38b137a0e9c2cfa9bb9e55eed1da5166e13576295205d276ab313e9d4a2f97a566d576abc85c6f4e9e84ad676ca5c32f90de17e027d6a1372fb00e6 + checksum: 35f543e1c4b419dc598489b4ce4dfbce22ad726ffe8f807876de13c0e8b5db10684835f7b95841e988d4f16aeb921935133e5775d35b47186c18cced6715a82a languageName: node linkType: hard -"@aws-sdk/credential-provider-sso@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/credential-provider-sso@npm:3.598.0" +"@aws-sdk/core@npm:3.621.0": + version: 3.621.0 + resolution: "@aws-sdk/core@npm:3.621.0" dependencies: - "@aws-sdk/client-sso": 3.598.0 - "@aws-sdk/token-providers": 3.598.0 - "@aws-sdk/types": 3.598.0 - "@smithy/property-provider": ^3.1.1 - "@smithy/shared-ini-file-loader": ^3.1.1 - "@smithy/types": ^3.1.0 + "@smithy/core": ^2.3.1 + "@smithy/node-config-provider": ^3.1.4 + "@smithy/protocol-http": ^4.1.0 + "@smithy/signature-v4": ^4.1.0 + "@smithy/smithy-client": ^3.1.11 + "@smithy/types": ^3.3.0 + "@smithy/util-middleware": ^3.0.3 + fast-xml-parser: 4.4.1 tslib: ^2.6.2 - checksum: 16828609b9ac17772eecd89deb9ac9b98a1decad42ca1f8cf6a57e6873eeb3563db00bfb67684cbb08108d5ee6b8f98ec23047d7f6750cb67c1342cd8b96ac1c + checksum: 789409227f2aa0f3c735e0f1bebf1d900b359e589bad50324e2fbec20ddb30435e1dcf9132501dad7aaf793829530980d1670257208c5e407c78be5f831e796d languageName: node linkType: hard -"@aws-sdk/credential-provider-web-identity@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/credential-provider-web-identity@npm:3.598.0" +"@aws-sdk/credential-provider-cognito-identity@npm:3.621.0": + version: 3.621.0 + resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.621.0" dependencies: - "@aws-sdk/types": 3.598.0 - "@smithy/property-provider": ^3.1.1 - "@smithy/types": ^3.1.0 + "@aws-sdk/client-cognito-identity": 3.621.0 + "@aws-sdk/types": 3.609.0 + "@smithy/property-provider": ^3.1.3 + "@smithy/types": ^3.3.0 + tslib: ^2.6.2 + checksum: e8a913d61ac4e772e07cd1a6144ef8680e630894c2192aed81d06f36fb9607c4de3b95386155d52f050b99d8b4d78ceb69eb7fa0987d339631765cc1dc8c9588 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-env@npm:3.620.1": + version: 3.620.1 + resolution: "@aws-sdk/credential-provider-env@npm:3.620.1" + dependencies: + "@aws-sdk/types": 3.609.0 + "@smithy/property-provider": ^3.1.3 + "@smithy/types": ^3.3.0 + tslib: ^2.6.2 + checksum: 3e05eeb6c6490e7759d03b7b688ef321d5e6c97929f21226e912b01aa926815312043febd505e8b43b54010b5ae2717559aba6deeea93bda7d6cf0d8a0b9fc76 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-http@npm:3.621.0": + version: 3.621.0 + resolution: "@aws-sdk/credential-provider-http@npm:3.621.0" + dependencies: + "@aws-sdk/types": 3.609.0 + "@smithy/fetch-http-handler": ^3.2.4 + "@smithy/node-http-handler": ^3.1.4 + "@smithy/property-provider": ^3.1.3 + "@smithy/protocol-http": ^4.1.0 + "@smithy/smithy-client": ^3.1.11 + "@smithy/types": ^3.3.0 + "@smithy/util-stream": ^3.1.3 + tslib: ^2.6.2 + checksum: bc45dfe7d0a6868978d71fa73731784af1839f822c09ef13b5a08ad74fa57c008dd874dd1765317df61ab022f9470bf509df38a70dd0aa5262d1d2234cc5eda2 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-ini@npm:3.621.0": + version: 3.621.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.621.0" + dependencies: + "@aws-sdk/credential-provider-env": 3.620.1 + "@aws-sdk/credential-provider-http": 3.621.0 + "@aws-sdk/credential-provider-process": 3.620.1 + "@aws-sdk/credential-provider-sso": 3.621.0 + "@aws-sdk/credential-provider-web-identity": 3.621.0 + "@aws-sdk/types": 3.609.0 + "@smithy/credential-provider-imds": ^3.2.0 + "@smithy/property-provider": ^3.1.3 + "@smithy/shared-ini-file-loader": ^3.1.4 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 peerDependencies: - "@aws-sdk/client-sts": ^3.598.0 - checksum: e62352ae7f408ae8969d22fd42a502ec078536952be1253f184bf96c57f3c88589fd431762b2300b494159df4eb4af975358645772ac36f2cc722c86a88ff85e + "@aws-sdk/client-sts": ^3.621.0 + checksum: a3db43adfbdb2ea1d6d80b1ca6789e48b729fce2499039f99721f504322cba325e4b48ed842bd26ae6f49ca771e5817016b75cda31cf247fd3e2bd0ac235b332 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-node@npm:3.621.0, @aws-sdk/credential-provider-node@npm:^3.350.0": + version: 3.621.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.621.0" + dependencies: + "@aws-sdk/credential-provider-env": 3.620.1 + "@aws-sdk/credential-provider-http": 3.621.0 + "@aws-sdk/credential-provider-ini": 3.621.0 + "@aws-sdk/credential-provider-process": 3.620.1 + "@aws-sdk/credential-provider-sso": 3.621.0 + "@aws-sdk/credential-provider-web-identity": 3.621.0 + "@aws-sdk/types": 3.609.0 + "@smithy/credential-provider-imds": ^3.2.0 + "@smithy/property-provider": ^3.1.3 + "@smithy/shared-ini-file-loader": ^3.1.4 + "@smithy/types": ^3.3.0 + tslib: ^2.6.2 + checksum: aada1f0624caee0e00b9ba287e66120031c8f5095acbcd80723b2ab6b5e4bffcd662665fffe62b7f2091bfb89d33ea13212a82893318005699914f13fbed70c3 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-process@npm:3.620.1": + version: 3.620.1 + resolution: "@aws-sdk/credential-provider-process@npm:3.620.1" + dependencies: + "@aws-sdk/types": 3.609.0 + "@smithy/property-provider": ^3.1.3 + "@smithy/shared-ini-file-loader": ^3.1.4 + "@smithy/types": ^3.3.0 + tslib: ^2.6.2 + checksum: 1fd6d3abf35ccfaed0882ee74e4d876e8c6cfe8d8b23c574dfe98364b2a2f3226d97fe35e2d48b88dd514906595cbb5fa1e0066d989a9582f73f92117796168f + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-sso@npm:3.621.0": + version: 3.621.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.621.0" + dependencies: + "@aws-sdk/client-sso": 3.621.0 + "@aws-sdk/token-providers": 3.614.0 + "@aws-sdk/types": 3.609.0 + "@smithy/property-provider": ^3.1.3 + "@smithy/shared-ini-file-loader": ^3.1.4 + "@smithy/types": ^3.3.0 + tslib: ^2.6.2 + checksum: 4602308a0bf74bda9dd7b92caf02868b855935deb703a8894d052c81864ef9c9359408ec84569f71527c1b204577940ebe1a9f6cbba8de677471eb590d91c3ba + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-web-identity@npm:3.621.0": + version: 3.621.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.621.0" + dependencies: + "@aws-sdk/types": 3.609.0 + "@smithy/property-provider": ^3.1.3 + "@smithy/types": ^3.3.0 + tslib: ^2.6.2 + peerDependencies: + "@aws-sdk/client-sts": ^3.621.0 + checksum: b1157e83b81c21f384ad95d29c646149124136c38e6395265ff8d9f5f6afec1e3e2b70c1f0be165c440058802c3871f3766c5e7ba44705ced447de221f4d04df languageName: node linkType: hard "@aws-sdk/credential-providers@npm:^3.350.0": - version: 3.600.0 - resolution: "@aws-sdk/credential-providers@npm:3.600.0" + version: 3.621.0 + resolution: "@aws-sdk/credential-providers@npm:3.621.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.600.0 - "@aws-sdk/client-sso": 3.598.0 - "@aws-sdk/client-sts": 3.600.0 - "@aws-sdk/credential-provider-cognito-identity": 3.600.0 - "@aws-sdk/credential-provider-env": 3.598.0 - "@aws-sdk/credential-provider-http": 3.598.0 - "@aws-sdk/credential-provider-ini": 3.598.0 - "@aws-sdk/credential-provider-node": 3.600.0 - "@aws-sdk/credential-provider-process": 3.598.0 - "@aws-sdk/credential-provider-sso": 3.598.0 - "@aws-sdk/credential-provider-web-identity": 3.598.0 - "@aws-sdk/types": 3.598.0 - "@smithy/credential-provider-imds": ^3.1.1 - "@smithy/property-provider": ^3.1.1 - "@smithy/types": ^3.1.0 + "@aws-sdk/client-cognito-identity": 3.621.0 + "@aws-sdk/client-sso": 3.621.0 + "@aws-sdk/client-sts": 3.621.0 + "@aws-sdk/credential-provider-cognito-identity": 3.621.0 + "@aws-sdk/credential-provider-env": 3.620.1 + "@aws-sdk/credential-provider-http": 3.621.0 + "@aws-sdk/credential-provider-ini": 3.621.0 + "@aws-sdk/credential-provider-node": 3.621.0 + "@aws-sdk/credential-provider-process": 3.620.1 + "@aws-sdk/credential-provider-sso": 3.621.0 + "@aws-sdk/credential-provider-web-identity": 3.621.0 + "@aws-sdk/types": 3.609.0 + "@smithy/credential-provider-imds": ^3.2.0 + "@smithy/property-provider": ^3.1.3 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: d957d851a9d4aba30e941c12515ce08fda66cadf2623fa329a2f651e2229e901a7845b139cd15404c8a714985e9b358747f1a8aacf0951e9b05331c5ae92af7c + checksum: 152a8911ca52a0663e4552e720f73bef2d93088d7b9fc58da88cf2aac91ebc3b720ea8abc5d28228d1658888903bd737dbba88e7d5cc97e2a2c7fdc0e5243c6f languageName: node linkType: hard @@ -1182,34 +1185,34 @@ __metadata: linkType: hard "@aws-sdk/lib-storage@npm:^3.350.0": - version: 3.600.0 - resolution: "@aws-sdk/lib-storage@npm:3.600.0" + version: 3.621.0 + resolution: "@aws-sdk/lib-storage@npm:3.621.0" dependencies: - "@smithy/abort-controller": ^3.0.1 - "@smithy/middleware-endpoint": ^3.0.2 - "@smithy/smithy-client": ^3.1.2 + "@smithy/abort-controller": ^3.1.1 + "@smithy/middleware-endpoint": ^3.1.0 + "@smithy/smithy-client": ^3.1.11 buffer: 5.6.0 events: 3.3.0 stream-browserify: 3.0.0 tslib: ^2.6.2 peerDependencies: - "@aws-sdk/client-s3": ^3.600.0 - checksum: 3fc04712f61289ac47f9502f0f33351a50e581d7999398575e84713750c77261b20ef8ac4f0a68514737c9950b313a563752b6856f63acaff23d128a4b4a9f4b + "@aws-sdk/client-s3": ^3.621.0 + checksum: 6c84a1601bcbea53aabad52c2453afd3c577e3935eda4bb13a7d9d4b1405289a3f2f4747327fc30c5eeaf482a9a78d56dfb4453c4c892f876f491e677d0f6c95 languageName: node linkType: hard -"@aws-sdk/middleware-bucket-endpoint@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.598.0" +"@aws-sdk/middleware-bucket-endpoint@npm:3.620.0": + version: 3.620.0 + resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.620.0" dependencies: - "@aws-sdk/types": 3.598.0 + "@aws-sdk/types": 3.609.0 "@aws-sdk/util-arn-parser": 3.568.0 - "@smithy/node-config-provider": ^3.1.1 - "@smithy/protocol-http": ^4.0.1 - "@smithy/types": ^3.1.0 + "@smithy/node-config-provider": ^3.1.4 + "@smithy/protocol-http": ^4.1.0 + "@smithy/types": ^3.3.0 "@smithy/util-config-provider": ^3.0.0 tslib: ^2.6.2 - checksum: 45a4adc3427a70f7129675439c9396073dc418e9e5ede4acd0dc0620d76610e8adf3f1c863120f7714bc67053a194289ac55ce6814a79960c4746cbd45f7116f + checksum: a5539ad611d3a2f7709952bf735a075a9d18ed5e9c0abe4e268bca32775a2100f3e956a264f6afb0ad0b48600f5b1d3389ec0566cd2795e6ae2dbe5af322b56b languageName: node linkType: hard @@ -1226,108 +1229,110 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-expect-continue@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/middleware-expect-continue@npm:3.598.0" +"@aws-sdk/middleware-expect-continue@npm:3.620.0": + version: 3.620.0 + resolution: "@aws-sdk/middleware-expect-continue@npm:3.620.0" dependencies: - "@aws-sdk/types": 3.598.0 - "@smithy/protocol-http": ^4.0.1 - "@smithy/types": ^3.1.0 + "@aws-sdk/types": 3.609.0 + "@smithy/protocol-http": ^4.1.0 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 1038945711d48d661cbf21343fd78968240f43b18f5b7fade7e41a7bf5308a65f37859f2b349e5fb038dded0136e0ea734e38e52085178b6a546a6ac48c630e9 + checksum: 739af454854562342984ac5e3c1c3dca39205344f52eda5961dae80020595062eaae6da2f76bf48ad486d92041c2a2bd30f1dd67b8b20ae043897d1d27b1a6bb languageName: node linkType: hard -"@aws-sdk/middleware-flexible-checksums@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.598.0" +"@aws-sdk/middleware-flexible-checksums@npm:3.620.0": + version: 3.620.0 + resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.620.0" dependencies: "@aws-crypto/crc32": 5.2.0 "@aws-crypto/crc32c": 5.2.0 - "@aws-sdk/types": 3.598.0 + "@aws-sdk/types": 3.609.0 "@smithy/is-array-buffer": ^3.0.0 - "@smithy/protocol-http": ^4.0.1 - "@smithy/types": ^3.1.0 + "@smithy/protocol-http": ^4.1.0 + "@smithy/types": ^3.3.0 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 1311849976b0631055d2d79f991647a87cae742bba23a94f01d18164612ba303ff3bed629744ba58c04bfde371b69ad4eb29e266a7b022ea8529b9a7f6a18415 + checksum: 2fc70ffa826d94924c0dae92ed5250c85aade93cbc15a488df81683d8f32eb7660f546569b1c2d2e878db5c8da02a83a3a98c331c5bb3adca46362e667abcbed languageName: node linkType: hard -"@aws-sdk/middleware-host-header@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/middleware-host-header@npm:3.598.0" +"@aws-sdk/middleware-host-header@npm:3.620.0": + version: 3.620.0 + resolution: "@aws-sdk/middleware-host-header@npm:3.620.0" dependencies: - "@aws-sdk/types": 3.598.0 - "@smithy/protocol-http": ^4.0.1 - "@smithy/types": ^3.1.0 + "@aws-sdk/types": 3.609.0 + "@smithy/protocol-http": ^4.1.0 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: c505de5bf4f39051a55011b9b2da0b673bda668def00a9b3b4696a3146bfbf0e5509d3bde28ef238648158b863816ce85fbf5829228bb97450c826b7d24d40d0 + checksum: 829c2d230e5051704f45c5283c42bec657607f4e4b2dd251fda8a716be90f8c9dfd6e7d45892a9a558c35cb64711628b3d0f88b90fe8cd061382c70b473991ef languageName: node linkType: hard -"@aws-sdk/middleware-location-constraint@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/middleware-location-constraint@npm:3.598.0" +"@aws-sdk/middleware-location-constraint@npm:3.609.0": + version: 3.609.0 + resolution: "@aws-sdk/middleware-location-constraint@npm:3.609.0" dependencies: - "@aws-sdk/types": 3.598.0 - "@smithy/types": ^3.1.0 + "@aws-sdk/types": 3.609.0 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: ab1ae3ad3dc7fad76688c039136d602abe25ebd6b98b6fb61a86f02dbec4414a74334169d12581aae720fe9d372549e9b9dfb56ee87388602264b697db09ff9f + checksum: f7962cf0b382efdf56cd07f8c0279efead02365edd7a2c124be39551b51a8359ee0d6f0399fcbf679ead3d235e24d1765f79712cf88e06c0a5432bf2d0c317d8 languageName: node linkType: hard -"@aws-sdk/middleware-logger@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/middleware-logger@npm:3.598.0" +"@aws-sdk/middleware-logger@npm:3.609.0": + version: 3.609.0 + resolution: "@aws-sdk/middleware-logger@npm:3.609.0" dependencies: - "@aws-sdk/types": 3.598.0 - "@smithy/types": ^3.1.0 + "@aws-sdk/types": 3.609.0 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 8c90bf68b65fe82ae08bf0c665bfea335fef757f8be7ddac6f9059f9f149c9bebc68e034bc225d131d168a61d61a409936d4f4d260c4b2aa2251385238df765a + checksum: b6f67a2e9ba082c8aec9d45905ae45ea5a95896f1beecb0c2d7fecfe17dd8fad99513f43b11ed7fd6ca9ff7764a0fc1ce63af91b1baed92b36f7b4b5390be5c6 languageName: node linkType: hard -"@aws-sdk/middleware-recursion-detection@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/middleware-recursion-detection@npm:3.598.0" +"@aws-sdk/middleware-recursion-detection@npm:3.620.0": + version: 3.620.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.620.0" dependencies: - "@aws-sdk/types": 3.598.0 - "@smithy/protocol-http": ^4.0.1 - "@smithy/types": ^3.1.0 + "@aws-sdk/types": 3.609.0 + "@smithy/protocol-http": ^4.1.0 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 161247dbbc8aa31d77c8d4c9c55264c775b5f9996e58451574605435c4a0ff6b9fce28be6f133ddce9f93a24f08c7af6fde59ef93ecb2cc4cd170a4db72b4833 + checksum: 1dedbbab2f79d4c0b214ca183a45daf89e98f9a33b2a08dcd7d30e059c1bcc04a74499b49870300d5f0b827d660512582f96f857624d3feaaf194a7a92703cea languageName: node linkType: hard -"@aws-sdk/middleware-sdk-s3@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/middleware-sdk-s3@npm:3.598.0" +"@aws-sdk/middleware-sdk-s3@npm:3.621.0": + version: 3.621.0 + resolution: "@aws-sdk/middleware-sdk-s3@npm:3.621.0" dependencies: - "@aws-sdk/types": 3.598.0 + "@aws-sdk/types": 3.609.0 "@aws-sdk/util-arn-parser": 3.568.0 - "@smithy/node-config-provider": ^3.1.1 - "@smithy/protocol-http": ^4.0.1 - "@smithy/signature-v4": ^3.1.0 - "@smithy/smithy-client": ^3.1.2 - "@smithy/types": ^3.1.0 + "@smithy/node-config-provider": ^3.1.4 + "@smithy/protocol-http": ^4.1.0 + "@smithy/signature-v4": ^4.1.0 + "@smithy/smithy-client": ^3.1.11 + "@smithy/types": ^3.3.0 "@smithy/util-config-provider": ^3.0.0 + "@smithy/util-stream": ^3.1.3 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 2953ae0f2729ffc4ca68e51e8f3247d447004e5d3d787b333351f2972cc94b49f8379f3403d153c3c5940bda47e1930b0386b77c448ca81bc54bf40f7cb4111f + checksum: 2db38ad1575e9209f053474ff69731d0c0910304fc14dcdf22a09c06a849cbada0b18f36879d96e3020c0e050f80b02e47c45137da561a3f243cc080f6df4f3a languageName: node linkType: hard -"@aws-sdk/middleware-sdk-sqs@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.598.0" +"@aws-sdk/middleware-sdk-sqs@npm:3.621.0": + version: 3.621.0 + resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.621.0" dependencies: - "@aws-sdk/types": 3.598.0 - "@smithy/smithy-client": ^3.1.2 - "@smithy/types": ^3.1.0 + "@aws-sdk/types": 3.609.0 + "@smithy/smithy-client": ^3.1.11 + "@smithy/types": ^3.3.0 "@smithy/util-hex-encoding": ^3.0.0 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 5b31bc50ffb2973a1a5108ca0a9a2fbf3cc96a403fd06e58994eb9e98e5804cb8fd2d2db977214d92ce30a5a256b54df156b285f7a89e286e7d0ceb3d9f69414 + checksum: d0cad52b1ffbfc6078fd62865bb88b4ac3b3a06d883ad5ef0a419dfaefe11d33314892f862150801d57e8c277e3a1465f8e798a1176c1ad6090765faf325c1d0 languageName: node linkType: hard @@ -1341,42 +1346,42 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-signing@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/middleware-signing@npm:3.598.0" +"@aws-sdk/middleware-signing@npm:3.620.0": + version: 3.620.0 + resolution: "@aws-sdk/middleware-signing@npm:3.620.0" dependencies: - "@aws-sdk/types": 3.598.0 - "@smithy/property-provider": ^3.1.1 - "@smithy/protocol-http": ^4.0.1 - "@smithy/signature-v4": ^3.1.0 - "@smithy/types": ^3.1.0 - "@smithy/util-middleware": ^3.0.1 + "@aws-sdk/types": 3.609.0 + "@smithy/property-provider": ^3.1.3 + "@smithy/protocol-http": ^4.1.0 + "@smithy/signature-v4": ^4.1.0 + "@smithy/types": ^3.3.0 + "@smithy/util-middleware": ^3.0.3 tslib: ^2.6.2 - checksum: c952da22635dbca7b91c47e43df43a9f4826bbebc36e5851ce325e07f43451de015232145df32eed3190b23d3b051469bf4c381b94ab4eb367ca8f22de4a4670 + checksum: ef2365b282ccfe8dc29983b620ca6cd5f2e41f5f8d12b84d2e3cb73866535ba3f7383579e561ec5a3c422d3fefdfbb2f3461ae7806a9f87e4fe92fd10a929386 languageName: node linkType: hard -"@aws-sdk/middleware-ssec@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/middleware-ssec@npm:3.598.0" +"@aws-sdk/middleware-ssec@npm:3.609.0": + version: 3.609.0 + resolution: "@aws-sdk/middleware-ssec@npm:3.609.0" dependencies: - "@aws-sdk/types": 3.598.0 - "@smithy/types": ^3.1.0 + "@aws-sdk/types": 3.609.0 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 600afb96254d1085c402fec6c5b7f260ca64126104c4cf3ff6da9811c5cdf0dab5f34fadf68e449ec61f89a165479e1cfab8cd3135c720a2e7a678be4572c215 + checksum: 4b40627ed103159ef0db4cc6bdc2148d1a65b786f3d1c643d34bccc79b9d265495613dc9bb34d18d5ab9b21b5d31110e495ec2b077e6e2f7603a0493254180a2 languageName: node linkType: hard -"@aws-sdk/middleware-user-agent@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/middleware-user-agent@npm:3.598.0" +"@aws-sdk/middleware-user-agent@npm:3.620.0": + version: 3.620.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.620.0" dependencies: - "@aws-sdk/types": 3.598.0 - "@aws-sdk/util-endpoints": 3.598.0 - "@smithy/protocol-http": ^4.0.1 - "@smithy/types": ^3.1.0 + "@aws-sdk/types": 3.609.0 + "@aws-sdk/util-endpoints": 3.614.0 + "@smithy/protocol-http": ^4.1.0 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 11dcf64badadf8c6b3283b3cec4cb684467eaf57206782c68a9b758e6f7a4f1b632d5ed89bb6ffbc855bf6d3fb855f0a56858bda640a67c0812ced08cd19959f + checksum: 137a969b5c17ebf172aa1f5a393812c443425dd9833fdf786a3039af5b3197e7d17139659891858b268ff723d9f2c5fbc840e8ac6a7af4b1cb566a3d54746a51 languageName: node linkType: hard @@ -1424,31 +1429,31 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/region-config-resolver@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/region-config-resolver@npm:3.598.0" +"@aws-sdk/region-config-resolver@npm:3.614.0": + version: 3.614.0 + resolution: "@aws-sdk/region-config-resolver@npm:3.614.0" dependencies: - "@aws-sdk/types": 3.598.0 - "@smithy/node-config-provider": ^3.1.1 - "@smithy/types": ^3.1.0 + "@aws-sdk/types": 3.609.0 + "@smithy/node-config-provider": ^3.1.4 + "@smithy/types": ^3.3.0 "@smithy/util-config-provider": ^3.0.0 - "@smithy/util-middleware": ^3.0.1 + "@smithy/util-middleware": ^3.0.3 tslib: ^2.6.2 - checksum: 649115771cb6b77e793088f3ee6eec346c1379f9f5d0e925f71103ad55c5f4a1132fca7e859a6b75ff46ecd1cc165a4eb260227596e4a2871118e6918602a726 + checksum: dbaca50792c99685845b21dd4a53228613e0458ee517a21db941890ee521d91eff80704f08e9ee71b6f04e70fb86362c4823750bb0b3727240af68d78d8fa4be languageName: node linkType: hard -"@aws-sdk/signature-v4-multi-region@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/signature-v4-multi-region@npm:3.598.0" +"@aws-sdk/signature-v4-multi-region@npm:3.621.0": + version: 3.621.0 + resolution: "@aws-sdk/signature-v4-multi-region@npm:3.621.0" dependencies: - "@aws-sdk/middleware-sdk-s3": 3.598.0 - "@aws-sdk/types": 3.598.0 - "@smithy/protocol-http": ^4.0.1 - "@smithy/signature-v4": ^3.1.0 - "@smithy/types": ^3.1.0 + "@aws-sdk/middleware-sdk-s3": 3.621.0 + "@aws-sdk/types": 3.609.0 + "@smithy/protocol-http": ^4.1.0 + "@smithy/signature-v4": ^4.1.0 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 6e0aa7adfe98c452eaa269ea9dc68d2b914a3c5bdc00b5923c0a9003e54899b7d3b9ce14d305b5229200e658a18fdebb93977437f029e9a576c9fe9a3cded0b1 + checksum: 741c07e65341da4c807d55b0bc6f1ec0064190c6fceb7571b0796f6ec94cc156a6214c0f308a93ad364884adae48502d248d30bd0ef43e7a4542586f264982c4 languageName: node linkType: hard @@ -1468,18 +1473,18 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/token-providers@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/token-providers@npm:3.598.0" +"@aws-sdk/token-providers@npm:3.614.0": + version: 3.614.0 + resolution: "@aws-sdk/token-providers@npm:3.614.0" dependencies: - "@aws-sdk/types": 3.598.0 - "@smithy/property-provider": ^3.1.1 - "@smithy/shared-ini-file-loader": ^3.1.1 - "@smithy/types": ^3.1.0 + "@aws-sdk/types": 3.609.0 + "@smithy/property-provider": ^3.1.3 + "@smithy/shared-ini-file-loader": ^3.1.4 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 peerDependencies: - "@aws-sdk/client-sso-oidc": ^3.598.0 - checksum: 24197672226e1e953fa57ca10c6adae9c3f6b571fbf40f517609e028d8ea6ab45c3afd285bd999bc35c0690b3427be04d4af3f677ced6778b0a716e0dd4e5280 + "@aws-sdk/client-sso-oidc": ^3.614.0 + checksum: 2901b8428afc3b76ff1df9ac29a2698db6bf65d1d2afcd8424b9bf187313d2a3ca747c3b205afeb5c132068b5a5a94d84ce82710f775fa0cbb79499d7fea2d64 languageName: node linkType: hard @@ -1493,13 +1498,13 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/types@npm:3.598.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0": - version: 3.598.0 - resolution: "@aws-sdk/types@npm:3.598.0" +"@aws-sdk/types@npm:3.609.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0": + version: 3.609.0 + resolution: "@aws-sdk/types@npm:3.609.0" dependencies: - "@smithy/types": ^3.1.0 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 9b2bd50d6935422dd1046e6eaa48c4c774d06aa1374bf4600a3af2c7a52432b5e25ec111cf49976b07b03d7cb5f4fa6fd44b7ce8a67dd0b3a4cee4abaf9e6fa5 + checksum: 522768d08f104065b0ff6a37eddaa7803186014acee1c0011b3dbd3ef841e47ae694e58f608aeec8a39d22d644d759ade996fe51d18b880617778dc2dbbe1ede languageName: node linkType: hard @@ -1533,15 +1538,15 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-endpoints@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/util-endpoints@npm:3.598.0" +"@aws-sdk/util-endpoints@npm:3.614.0": + version: 3.614.0 + resolution: "@aws-sdk/util-endpoints@npm:3.614.0" dependencies: - "@aws-sdk/types": 3.598.0 - "@smithy/types": ^3.1.0 - "@smithy/util-endpoints": ^2.0.2 + "@aws-sdk/types": 3.609.0 + "@smithy/types": ^3.3.0 + "@smithy/util-endpoints": ^2.0.5 tslib: ^2.6.2 - checksum: 6fb92e8c99b6ce96cda21c9d1744a290c683bae8d82394c1b1fe7ed7d3cb0a18d4025b8863532680db3f550ad130e54d528c64a0a32f398f3c00c5ce2e043ecd + checksum: 9d9973ceee59bf30af85c7f4328083daea033a987ec396dcb89eb7649f470ceb19c6b96635e121f3557e726f7ec7453236c956cf43f22128883c277f17d2a13f languageName: node linkType: hard @@ -1593,32 +1598,32 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-user-agent-browser@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/util-user-agent-browser@npm:3.598.0" +"@aws-sdk/util-user-agent-browser@npm:3.609.0": + version: 3.609.0 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.609.0" dependencies: - "@aws-sdk/types": 3.598.0 - "@smithy/types": ^3.1.0 + "@aws-sdk/types": 3.609.0 + "@smithy/types": ^3.3.0 bowser: ^2.11.0 tslib: ^2.6.2 - checksum: c53afc0fe7a07838ad22ae1e9ed6834d56a69cb0ad623d4912deeaa715af479b64266965fce30e7210e576118f80ceb525f79f504dc459fe0294fd15e694752e + checksum: 75ba1ae74dd1001f47870766d92b66ac02a0a488efcf42c1a368962a7978a778d99536e880f07f7db1c2ca66cc9b1863fd3342957a22dcf78bf2f4398265a7a5 languageName: node linkType: hard -"@aws-sdk/util-user-agent-node@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/util-user-agent-node@npm:3.598.0" +"@aws-sdk/util-user-agent-node@npm:3.614.0": + version: 3.614.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.614.0" dependencies: - "@aws-sdk/types": 3.598.0 - "@smithy/node-config-provider": ^3.1.1 - "@smithy/types": ^3.1.0 + "@aws-sdk/types": 3.609.0 + "@smithy/node-config-provider": ^3.1.4 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 peerDependencies: aws-crt: ">=1.0.0" peerDependenciesMeta: aws-crt: optional: true - checksum: 1560fabf19b236cfbce42769e1ef7e46bdad881b8a4b0ce069401d9a6edd5e1b195f45cb2847abf9ef1453d2e69447e7a3dabc92b037d9a41fe58960538db1ae + checksum: 1f010080c2301fd836908963a235ef39e597d959e27461d15d4958fa582ab20795022f8cb7429c183c386f558a5c125cb254a0c4e844dbc6422169f4884be34a languageName: node linkType: hard @@ -1641,13 +1646,13 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/xml-builder@npm:3.598.0": - version: 3.598.0 - resolution: "@aws-sdk/xml-builder@npm:3.598.0" +"@aws-sdk/xml-builder@npm:3.609.0": + version: 3.609.0 + resolution: "@aws-sdk/xml-builder@npm:3.609.0" dependencies: - "@smithy/types": ^3.1.0 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 6b9fa385f749219d0a0654445e5deba54c7753d3e0da795dfc2bfdbaeb59fbfc8ef0e3f477c6aff6181a12a11ac87e3f84dedbbd1d1adb2c32941b149401abcf + checksum: 0e9c8b7786737ff50a6cf39f7ca9a758897c2db364718364b5dad45f50a33e65bd7801348fd033af60768a5be64b454c3a7e65222e13c70d145e8df6211ca33c languageName: node linkType: hard @@ -15230,13 +15235,13 @@ __metadata: languageName: node linkType: hard -"@smithy/abort-controller@npm:^3.0.1, @smithy/abort-controller@npm:^3.1.0": - version: 3.1.0 - resolution: "@smithy/abort-controller@npm:3.1.0" +"@smithy/abort-controller@npm:^3.1.1": + version: 3.1.1 + resolution: "@smithy/abort-controller@npm:3.1.1" dependencies: - "@smithy/types": ^3.2.0 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 78643bddda2bcb68e00bb95ae866741407236b92b1834796c0855710950386ae1e5e67d72fb42ec444e8a4dc4357a1527c4f331324a2fad156468f5a0cccf128 + checksum: 7b7497f49d58787cad858f8c5ea9931ccd44d39536db4abdd531a5abf37784469522e41d9ad1d541892caa0ed3bea750447809a0a18f4689a9543d672aa61d48 languageName: node linkType: hard @@ -15259,158 +15264,158 @@ __metadata: languageName: node linkType: hard -"@smithy/config-resolver@npm:^3.0.2, @smithy/config-resolver@npm:^3.0.3": - version: 3.0.3 - resolution: "@smithy/config-resolver@npm:3.0.3" +"@smithy/config-resolver@npm:^3.0.5": + version: 3.0.5 + resolution: "@smithy/config-resolver@npm:3.0.5" dependencies: - "@smithy/node-config-provider": ^3.1.2 - "@smithy/types": ^3.2.0 + "@smithy/node-config-provider": ^3.1.4 + "@smithy/types": ^3.3.0 "@smithy/util-config-provider": ^3.0.0 - "@smithy/util-middleware": ^3.0.2 + "@smithy/util-middleware": ^3.0.3 tslib: ^2.6.2 - checksum: 7a7baf23e64ed85d4229bfd320a3ea96087c57ce1b94638a89bab5f92dcc24ec22c11740d90f2fab38eb39eeb860463ae98b24598555c2b55a01bd79c20ef99b + checksum: 96895ae0622a229655fa08f009d29a20157043020125014e84cb5ca33a10171c9724c309491214c2422d9c4c6681e7f5ec5f7faa8f45e11250449cf07f3552ec languageName: node linkType: hard -"@smithy/core@npm:^2.2.1": - version: 2.2.3 - resolution: "@smithy/core@npm:2.2.3" +"@smithy/core@npm:^2.3.1": + version: 2.3.1 + resolution: "@smithy/core@npm:2.3.1" dependencies: - "@smithy/middleware-endpoint": ^3.0.3 - "@smithy/middleware-retry": ^3.0.6 - "@smithy/middleware-serde": ^3.0.2 - "@smithy/protocol-http": ^4.0.2 - "@smithy/smithy-client": ^3.1.4 - "@smithy/types": ^3.2.0 - "@smithy/util-middleware": ^3.0.2 + "@smithy/middleware-endpoint": ^3.1.0 + "@smithy/middleware-retry": ^3.0.13 + "@smithy/middleware-serde": ^3.0.3 + "@smithy/protocol-http": ^4.1.0 + "@smithy/smithy-client": ^3.1.11 + "@smithy/types": ^3.3.0 + "@smithy/util-middleware": ^3.0.3 tslib: ^2.6.2 - checksum: 6addaede7f4699c48d690872647bbc86efc5bf9adb088557cfd4263e629e6bd7d45a1de983824a7c5ff608ec2cd42d7c6f61854d3d33b8ded352df550789b34b + checksum: f191a36742a08c6898f4aaa43335bfb96cdca9a9099c0608fb0ef151917816b03ee1b27ef3720d89fba90d2d24fedfb47478f837d47c1c2e5ff8ceeb844ec7d6 languageName: node linkType: hard -"@smithy/credential-provider-imds@npm:^3.1.1, @smithy/credential-provider-imds@npm:^3.1.2": +"@smithy/credential-provider-imds@npm:^3.2.0": + version: 3.2.0 + resolution: "@smithy/credential-provider-imds@npm:3.2.0" + dependencies: + "@smithy/node-config-provider": ^3.1.4 + "@smithy/property-provider": ^3.1.3 + "@smithy/types": ^3.3.0 + "@smithy/url-parser": ^3.0.3 + tslib: ^2.6.2 + checksum: fc79919133008db91a83f2caf6eba11d704f34af5fa3dd1f7b8cc048214e805d9f20a3f302f5ed4862ee6b6c3bb28ff3a5d8c77d2f497d10f3be14915e59debe + languageName: node + linkType: hard + +"@smithy/eventstream-codec@npm:^3.1.2": version: 3.1.2 - resolution: "@smithy/credential-provider-imds@npm:3.1.2" - dependencies: - "@smithy/node-config-provider": ^3.1.2 - "@smithy/property-provider": ^3.1.2 - "@smithy/types": ^3.2.0 - "@smithy/url-parser": ^3.0.2 - tslib: ^2.6.2 - checksum: bf0ce9f7c510f5f7e05d08c2b1d861f133016457e3872bfc5e4ac9b22f26123adcf773a562189971e2ce97bdad2f576a4eefb764808df2ae1833e77be86358f2 - languageName: node - linkType: hard - -"@smithy/eventstream-codec@npm:^3.1.1": - version: 3.1.1 - resolution: "@smithy/eventstream-codec@npm:3.1.1" + resolution: "@smithy/eventstream-codec@npm:3.1.2" dependencies: "@aws-crypto/crc32": 5.2.0 - "@smithy/types": ^3.2.0 + "@smithy/types": ^3.3.0 "@smithy/util-hex-encoding": ^3.0.0 tslib: ^2.6.2 - checksum: fdc7a2bcf99f7c830ba24b5745877ec26556613423a025c6b122b167ef92a76a860f7dffe21f25667f12c2736a121f4e2064050dcf768406a60ce3ebc029e402 + checksum: b0c836acbf59b57a7e2ef948a54bd441d11b75d70f1c334723c27fce1ab0ff93ea9f936976b754272b5e90413b5a169c60b1df7ecfd7d061ebaae8d5cc067d94 languageName: node linkType: hard -"@smithy/eventstream-serde-browser@npm:^3.0.2": +"@smithy/eventstream-serde-browser@npm:^3.0.5": + version: 3.0.5 + resolution: "@smithy/eventstream-serde-browser@npm:3.0.5" + dependencies: + "@smithy/eventstream-serde-universal": ^3.0.4 + "@smithy/types": ^3.3.0 + tslib: ^2.6.2 + checksum: 14e8a2027745e7a1ad261068e792e4a660043ce53fefc5f564b38b841ba02d40992b38fbd2357e762f0a1ecb658df3bbf23cf5ef33c3ec2488d316be95b61b9e + languageName: node + linkType: hard + +"@smithy/eventstream-serde-config-resolver@npm:^3.0.3": version: 3.0.3 - resolution: "@smithy/eventstream-serde-browser@npm:3.0.3" + resolution: "@smithy/eventstream-serde-config-resolver@npm:3.0.3" dependencies: - "@smithy/eventstream-serde-universal": ^3.0.3 - "@smithy/types": ^3.2.0 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 3e41fb32f06dc266ab41185482e441068c1e84ac5637462fc107511a495a7338972f10568bb57970e22eef2d14e024f93e0991b30b54545bca5b5189add5d41e + checksum: c61780aa0ad8c479618d0b3fcb2b42f1f9a74dcf814dba08305107ed1f088f56aa1c346db9c72439ff18617f31b9c59c6895060e4c9765c81d759150a22674af languageName: node linkType: hard -"@smithy/eventstream-serde-config-resolver@npm:^3.0.1": - version: 3.0.2 - resolution: "@smithy/eventstream-serde-config-resolver@npm:3.0.2" +"@smithy/eventstream-serde-node@npm:^3.0.4": + version: 3.0.4 + resolution: "@smithy/eventstream-serde-node@npm:3.0.4" dependencies: - "@smithy/types": ^3.2.0 + "@smithy/eventstream-serde-universal": ^3.0.4 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 5c2113b6acc65df61f6fc844054c5a85825305e1d9f47987a5f350b603e304c8d90ad2c62cb7a098f10b7243c4f466fa413264821d261a3b69dc12c33fa976d4 + checksum: 0a75b184d95ab8c08efd93bf32c5fd9d735b5879df556599bd2ab78f23e3f77452e597bbdd42586c9bbedcc2b0b7683de4c816db739c19a2ebd62a34096ca86d languageName: node linkType: hard -"@smithy/eventstream-serde-node@npm:^3.0.2": - version: 3.0.3 - resolution: "@smithy/eventstream-serde-node@npm:3.0.3" +"@smithy/eventstream-serde-universal@npm:^3.0.4": + version: 3.0.4 + resolution: "@smithy/eventstream-serde-universal@npm:3.0.4" dependencies: - "@smithy/eventstream-serde-universal": ^3.0.3 - "@smithy/types": ^3.2.0 + "@smithy/eventstream-codec": ^3.1.2 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 29e2323b92a87302518ecfd75096e856c77a3d39ffa2680ff56e11c2c01b4434f56f86940e13c636e207af7cadf867f824f5c60249c53e1c27faa1cf932b6eb9 + checksum: 8463403ca4caf4ad48dba89b126f394439a289c9095ce6361c1f186c6021c1cd8ea402d1ce06b7284069c3415091ae4d802f66ded1b89e9da9d4c255b8402668 languageName: node linkType: hard -"@smithy/eventstream-serde-universal@npm:^3.0.3": - version: 3.0.3 - resolution: "@smithy/eventstream-serde-universal@npm:3.0.3" +"@smithy/fetch-http-handler@npm:^3.2.4": + version: 3.2.4 + resolution: "@smithy/fetch-http-handler@npm:3.2.4" dependencies: - "@smithy/eventstream-codec": ^3.1.1 - "@smithy/types": ^3.2.0 - tslib: ^2.6.2 - checksum: 6c0c3602e3e79bb0abe47f1d7b8c277f58879ab613cda99d80cf0e825653055f892daee313e6d40e5096932e004838e3c9f674e440b97921520257f80337bed8 - languageName: node - linkType: hard - -"@smithy/fetch-http-handler@npm:^3.0.2, @smithy/fetch-http-handler@npm:^3.1.0": - version: 3.1.0 - resolution: "@smithy/fetch-http-handler@npm:3.1.0" - dependencies: - "@smithy/protocol-http": ^4.0.2 - "@smithy/querystring-builder": ^3.0.2 - "@smithy/types": ^3.2.0 + "@smithy/protocol-http": ^4.1.0 + "@smithy/querystring-builder": ^3.0.3 + "@smithy/types": ^3.3.0 "@smithy/util-base64": ^3.0.0 tslib: ^2.6.2 - checksum: 7b9b928e8a094e41a9c7516aa2fcfd3bb88b0271737e1d4fa301973a49f577094fa967ba481a0cf6e5c977be6bb8b2898d868b3269a476cae2aaaed582277733 + checksum: 73df885c637c14353f449678a4e109aeb19945c5370a615793ca2a54a29746a78e725e324b01cfd86fc71f4afd6386da2758fccc49d247a623ecbe70f607cb74 languageName: node linkType: hard -"@smithy/hash-blob-browser@npm:^3.1.0": - version: 3.1.1 - resolution: "@smithy/hash-blob-browser@npm:3.1.1" +"@smithy/hash-blob-browser@npm:^3.1.2": + version: 3.1.2 + resolution: "@smithy/hash-blob-browser@npm:3.1.2" dependencies: "@smithy/chunked-blob-reader": ^3.0.0 "@smithy/chunked-blob-reader-native": ^3.0.0 - "@smithy/types": ^3.2.0 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 9a54f0b7d48d5a411c2e3361f8a946d71b75d54965bc3d2a0524d0fe01fc032c2ee2a4e105104daefa14e3e02f0e38b9e83faf0b40d3933a33b87d8b8b142c8f + checksum: 959ec975cd4b3d86e3d0288e24b460343795bc305ef38fc43f8485cd1440da4068d375c5d1dab73ae875f02e861f194512a7adf5afcd7395bbeb97897d8a809b languageName: node linkType: hard -"@smithy/hash-node@npm:^3.0.1": - version: 3.0.2 - resolution: "@smithy/hash-node@npm:3.0.2" +"@smithy/hash-node@npm:^3.0.3": + version: 3.0.3 + resolution: "@smithy/hash-node@npm:3.0.3" dependencies: - "@smithy/types": ^3.2.0 + "@smithy/types": ^3.3.0 "@smithy/util-buffer-from": ^3.0.0 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 2b7b678d429b9806a28f18472f8beec45f5a2e1d004b084cc4b591c1239565c46435b278c7f76be09790d6d6eabc617e7d0f3aef11c375721b78600506d62856 + checksum: 203a3581bec5373e63d42e03f62129022f03d17390e9358a4e25fc1d44c43962ea80ab5bcbb91605e3025e22136bed059665a3b16835f66316f43ed391df9548 languageName: node linkType: hard -"@smithy/hash-stream-node@npm:^3.1.0": - version: 3.1.1 - resolution: "@smithy/hash-stream-node@npm:3.1.1" +"@smithy/hash-stream-node@npm:^3.1.2": + version: 3.1.2 + resolution: "@smithy/hash-stream-node@npm:3.1.2" dependencies: - "@smithy/types": ^3.2.0 + "@smithy/types": ^3.3.0 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 21d4d8ffca488a1aa83d97eb418197ca4b9c25329ce2d67a5978cd4b74ee7e609ebcb510fce3a271ce240b5e421073cda516e23cde7d9fedbb682ee02d7b7c9f + checksum: e5284ef06548e301aa50bd06fe06bf3e2ed11ecd57f73d2d85c98cf26119c2cc0084b5b8be49d4127cb798c6011651d5361958eb6546c19b45fd6c94ea11ef47 languageName: node linkType: hard -"@smithy/invalid-dependency@npm:^3.0.1": - version: 3.0.2 - resolution: "@smithy/invalid-dependency@npm:3.0.2" +"@smithy/invalid-dependency@npm:^3.0.3": + version: 3.0.3 + resolution: "@smithy/invalid-dependency@npm:3.0.3" dependencies: - "@smithy/types": ^3.2.0 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 21f0f2669989d9b8ffdc86e80fa8d0a39b5ada187a21c61bc4405936a31fa054a59577fa8fde4de707de559cc3e08c80aaac0205aaacf0eaf3a2ff620fa12830 + checksum: 459b4ae4e47595e8a675ff2e8bfea7f58a41f77138416ea310c89e29312e08963a701cdc354324da9dd578a7995158b4421695365070d74b0276ddff7f701bba languageName: node linkType: hard @@ -15432,89 +15437,89 @@ __metadata: languageName: node linkType: hard -"@smithy/md5-js@npm:^3.0.1": - version: 3.0.2 - resolution: "@smithy/md5-js@npm:3.0.2" +"@smithy/md5-js@npm:^3.0.3": + version: 3.0.3 + resolution: "@smithy/md5-js@npm:3.0.3" dependencies: - "@smithy/types": ^3.2.0 + "@smithy/types": ^3.3.0 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: cc8857d043b53234ce280776ac7592ed6287c911d7ac45d3b9836adbf01b9e814a1f164b8a8c5b654bde14e8ce4baed17494b983d4cfee61584da623f9b794e5 + checksum: 52ef56439be4187cc65391f4252173ffad0ce5a2ce5f636d78e9cdfb517844889340156ddbdbbe86f63e7f7e0fc924fe6905749a1c833910784015133a467406 languageName: node linkType: hard -"@smithy/middleware-content-length@npm:^3.0.1": - version: 3.0.2 - resolution: "@smithy/middleware-content-length@npm:3.0.2" +"@smithy/middleware-content-length@npm:^3.0.5": + version: 3.0.5 + resolution: "@smithy/middleware-content-length@npm:3.0.5" dependencies: - "@smithy/protocol-http": ^4.0.2 - "@smithy/types": ^3.2.0 + "@smithy/protocol-http": ^4.1.0 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 67758207c3a26eb6d44fd922d178299418fc42a07937813364a17a76547bf736df75d279cb493fca9ac5c3897c0c8d24c6e124f3edc143c991a26b44521eb423 + checksum: 21c667530f5e64db300827dfe8aa5b18396d151ac489a3e634f882179fae5c0f84940e1f831f0bf7b4b6b9623283f4a516da92d89c13ba395aede8788b523cd3 languageName: node linkType: hard -"@smithy/middleware-endpoint@npm:^3.0.2, @smithy/middleware-endpoint@npm:^3.0.3": - version: 3.0.3 - resolution: "@smithy/middleware-endpoint@npm:3.0.3" +"@smithy/middleware-endpoint@npm:^3.1.0": + version: 3.1.0 + resolution: "@smithy/middleware-endpoint@npm:3.1.0" dependencies: - "@smithy/middleware-serde": ^3.0.2 - "@smithy/node-config-provider": ^3.1.2 - "@smithy/shared-ini-file-loader": ^3.1.2 - "@smithy/types": ^3.2.0 - "@smithy/url-parser": ^3.0.2 - "@smithy/util-middleware": ^3.0.2 + "@smithy/middleware-serde": ^3.0.3 + "@smithy/node-config-provider": ^3.1.4 + "@smithy/shared-ini-file-loader": ^3.1.4 + "@smithy/types": ^3.3.0 + "@smithy/url-parser": ^3.0.3 + "@smithy/util-middleware": ^3.0.3 tslib: ^2.6.2 - checksum: 15a37293aa590bd0c8ab59430e967f786500603bca92dbde655480c3b7c1812a8cbcd267ff31691c2d8ea596f7917769ef91fa4033e07ec9971bf252fc12ebcd + checksum: 3271b7c1ec5d01db63439757d198e921618a2f1d4827c64fc425163e7d1bc969049d8c8ce74f3a8c0b0dac5ea3466c154f38805c8d62fe19fb9bd6af72ca2d3c languageName: node linkType: hard -"@smithy/middleware-retry@npm:^3.0.4, @smithy/middleware-retry@npm:^3.0.6": - version: 3.0.6 - resolution: "@smithy/middleware-retry@npm:3.0.6" +"@smithy/middleware-retry@npm:^3.0.13": + version: 3.0.13 + resolution: "@smithy/middleware-retry@npm:3.0.13" dependencies: - "@smithy/node-config-provider": ^3.1.2 - "@smithy/protocol-http": ^4.0.2 - "@smithy/service-error-classification": ^3.0.2 - "@smithy/smithy-client": ^3.1.4 - "@smithy/types": ^3.2.0 - "@smithy/util-middleware": ^3.0.2 - "@smithy/util-retry": ^3.0.2 + "@smithy/node-config-provider": ^3.1.4 + "@smithy/protocol-http": ^4.1.0 + "@smithy/service-error-classification": ^3.0.3 + "@smithy/smithy-client": ^3.1.11 + "@smithy/types": ^3.3.0 + "@smithy/util-middleware": ^3.0.3 + "@smithy/util-retry": ^3.0.3 tslib: ^2.6.2 uuid: ^9.0.1 - checksum: c17ac5665e0dd2315e996c219b5aa2327c9270a49ca7dc64b8d81c80261f9d0098d3725641f2e4c87aac293c283d709fb062b5c7be6912e72f9042492a3e91d9 + checksum: 3aa98ae08633022dedc19a60b173289d4c8e04c94fe45a626499269f596de517a94b587272a578d554d1e91dc8cb19297e3d3c45da01829d520a6c730e77df36 languageName: node linkType: hard -"@smithy/middleware-serde@npm:^3.0.1, @smithy/middleware-serde@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/middleware-serde@npm:3.0.2" +"@smithy/middleware-serde@npm:^3.0.3": + version: 3.0.3 + resolution: "@smithy/middleware-serde@npm:3.0.3" dependencies: - "@smithy/types": ^3.2.0 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 16c933ecb8061ff9fcf49ecabcc54b6d56de0e02464e5dd995ac729ad06e70be7a341c329b0b7cc1b33c8dbaa31372e337130e9eb6aac4c2df63ce37cb36d54f + checksum: 6c633bb8957e078d480888bd33d5a8c269a483a1358c2b28c62daecfd442c711c509d9e69302e6b19fc298139ee67cdda63a604e7da0e4ef9005117d8e0897cc languageName: node linkType: hard -"@smithy/middleware-stack@npm:^3.0.1, @smithy/middleware-stack@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/middleware-stack@npm:3.0.2" +"@smithy/middleware-stack@npm:^3.0.3": + version: 3.0.3 + resolution: "@smithy/middleware-stack@npm:3.0.3" dependencies: - "@smithy/types": ^3.2.0 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 70ec59d020ae6d8c53aefecb039fb511cfa67a57ce00ba1e41d2c3da346265cc18bdf1e0724b0df10f1ef838807e151e93f6da6e886fafbac51d2ed962b795d1 + checksum: f4a450e2ebca0a8a3b4e1bbfad7d7e9c45edccbe1c984a22f2228092a526120748365e8964b478357249675d8bbc28fdaa8a4a19643a3c1d86bd74e1499327c5 languageName: node linkType: hard -"@smithy/node-config-provider@npm:^3.1.1, @smithy/node-config-provider@npm:^3.1.2": - version: 3.1.2 - resolution: "@smithy/node-config-provider@npm:3.1.2" +"@smithy/node-config-provider@npm:^3.1.4": + version: 3.1.4 + resolution: "@smithy/node-config-provider@npm:3.1.4" dependencies: - "@smithy/property-provider": ^3.1.2 - "@smithy/shared-ini-file-loader": ^3.1.2 - "@smithy/types": ^3.2.0 + "@smithy/property-provider": ^3.1.3 + "@smithy/shared-ini-file-loader": ^3.1.4 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 596e7a6b92fa68f6c172969bde6a04aadf35634f78a601351642b44bc271f3ad5444588a8c3dea8f7cdbe65a2d69e1c1d93291bf8d240736a035ac8db4e96ce3 + checksum: 7ea4e7cea93ab154ab89a9d6b2453c8f96b96db18883070d287bc5fa9cfd10091bb00006a15bb7e6ed25810fd1a133d458e45310a8eaa1727a55d4ce2be3ba09 languageName: node linkType: hard @@ -15531,26 +15536,26 @@ __metadata: languageName: node linkType: hard -"@smithy/node-http-handler@npm:^3.0.1, @smithy/node-http-handler@npm:^3.1.0": - version: 3.1.0 - resolution: "@smithy/node-http-handler@npm:3.1.0" +"@smithy/node-http-handler@npm:^3.1.4": + version: 3.1.4 + resolution: "@smithy/node-http-handler@npm:3.1.4" dependencies: - "@smithy/abort-controller": ^3.1.0 - "@smithy/protocol-http": ^4.0.2 - "@smithy/querystring-builder": ^3.0.2 - "@smithy/types": ^3.2.0 + "@smithy/abort-controller": ^3.1.1 + "@smithy/protocol-http": ^4.1.0 + "@smithy/querystring-builder": ^3.0.3 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 915cc2876cfe5b2330e868aa512930d4c126192d7695354dc2a88aab1c6639968ace36c1e8778c8a647a8b6f3f3faac2a14870607043cba972e05ee94491738a + checksum: 8f2f611bef99800b122b852103c3d1ff391b91077df191ca06676bd8c4e50d7e335bf2a311f90ff6a9fa0639a812216492e5e0ecee703e89eb05a4b253c8273c languageName: node linkType: hard -"@smithy/property-provider@npm:^3.1.1, @smithy/property-provider@npm:^3.1.2": - version: 3.1.2 - resolution: "@smithy/property-provider@npm:3.1.2" +"@smithy/property-provider@npm:^3.1.3": + version: 3.1.3 + resolution: "@smithy/property-provider@npm:3.1.3" dependencies: - "@smithy/types": ^3.2.0 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 9ec0cce2728dd4a0d327fef523ca5bddcba9a7750e6e5a614293d6ba4c12d6b86c32020689481a529b4797d07315fd84647f13ea0dbe91f1da7932c954b08421 + checksum: 37a3d92267a2a32c2cc17fd1f0ab2b336f75fb7807db88f6194efede9d6a66068658a7effb7773451404fca990924393dbbf3d57e2aca67ef2e489a85666e225 languageName: node linkType: hard @@ -15564,13 +15569,13 @@ __metadata: languageName: node linkType: hard -"@smithy/protocol-http@npm:^4.0.1, @smithy/protocol-http@npm:^4.0.2": - version: 4.0.2 - resolution: "@smithy/protocol-http@npm:4.0.2" +"@smithy/protocol-http@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/protocol-http@npm:4.1.0" dependencies: - "@smithy/types": ^3.2.0 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: e1b419e0324f20300c490491cbc32b9d151579a6ce11f708b76ed265ef3499d404d9c0e3443692984514a0f8042b456f5c7e1a62694d42c7dc9bc64bfcff0301 + checksum: fe4f97bc35075c6e6669c12ff90a4ab3dbe620b375298795d0c1104b30d04536cf002ea81f29983895c6042c7a30eecd1d2306d3ac90bf7910ec02929233f5ad languageName: node linkType: hard @@ -15585,72 +15590,73 @@ __metadata: languageName: node linkType: hard -"@smithy/querystring-builder@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/querystring-builder@npm:3.0.2" +"@smithy/querystring-builder@npm:^3.0.3": + version: 3.0.3 + resolution: "@smithy/querystring-builder@npm:3.0.3" dependencies: - "@smithy/types": ^3.2.0 + "@smithy/types": ^3.3.0 "@smithy/util-uri-escape": ^3.0.0 tslib: ^2.6.2 - checksum: c6f6fc8681879daed9c85b3fd2d81cbbf553addbdc1d6ab2660687d967af40eba0112e40cf1157bdd4c42784bc22977a3da9ed9dde674b7ede5e70720a0b38af + checksum: 5c46c620d87f9b4e67b8eb543667b0160fb05bbec01d62d45adb94305369dca9e82daba47d81e840fdc399fa47f9b5930ce668d65fe83ee278a1b27d59d0b5d3 languageName: node linkType: hard -"@smithy/querystring-parser@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/querystring-parser@npm:3.0.2" +"@smithy/querystring-parser@npm:^3.0.3": + version: 3.0.3 + resolution: "@smithy/querystring-parser@npm:3.0.3" dependencies: - "@smithy/types": ^3.2.0 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 7f18281e8d73c70dc020e1a8719a8322d88130c24e8c8cffa39ffe83e9f18d28bb9d420e6026ddb17d60ac950b0fb5b9465a4ba8493086e6186f60a9573b2ad8 + checksum: 1de11cbc4325578b243a0e3e89b46371f4705d3df41ea51b37e8efa655d3b75253180b0fca9ceed8b3955a2d458689f551cd24fd904d0f65647c62c6b08795bf languageName: node linkType: hard -"@smithy/service-error-classification@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/service-error-classification@npm:3.0.2" +"@smithy/service-error-classification@npm:^3.0.3": + version: 3.0.3 + resolution: "@smithy/service-error-classification@npm:3.0.3" dependencies: - "@smithy/types": ^3.2.0 - checksum: f7cfd6438286942ec1f7f059c4bdac517c64833fcbea27198880106c7e55d0c2083f0c8e22c8fe5a68f0d86e5bd33a78f644898b48008b2f14c0c13d46f0923c + "@smithy/types": ^3.3.0 + checksum: 5bef710f5698c929c97865cba41f36b0c59100b9a1c4478a2d47caeb5e3a1a18077b870b365efaa45c94666f2075bc8978f7a6e8b964afbba3a4e490eb6c13eb languageName: node linkType: hard -"@smithy/shared-ini-file-loader@npm:^3.1.1, @smithy/shared-ini-file-loader@npm:^3.1.2": - version: 3.1.2 - resolution: "@smithy/shared-ini-file-loader@npm:3.1.2" +"@smithy/shared-ini-file-loader@npm:^3.1.4": + version: 3.1.4 + resolution: "@smithy/shared-ini-file-loader@npm:3.1.4" dependencies: - "@smithy/types": ^3.2.0 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: bbb7ceaefdcbe4e43e5a65cf424e41f6a70e44fc9b05b7f8c968bd6134253e04af4455ad0fa91fda18f55695b7992c8bfc5281aa201be2a69f7733014fd84042 + checksum: c5321635f3be34e424009fc9045454a9ceec543ec20b3b9719bf3a48bbfc03b794f4545546e9c2dcb0a987de2ca5ff8999df9bf7c166c6fc7685c1fa1f068bc1 languageName: node linkType: hard -"@smithy/signature-v4@npm:^3.1.0": - version: 3.1.1 - resolution: "@smithy/signature-v4@npm:3.1.1" +"@smithy/signature-v4@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/signature-v4@npm:4.1.0" dependencies: "@smithy/is-array-buffer": ^3.0.0 - "@smithy/types": ^3.2.0 + "@smithy/protocol-http": ^4.1.0 + "@smithy/types": ^3.3.0 "@smithy/util-hex-encoding": ^3.0.0 - "@smithy/util-middleware": ^3.0.2 + "@smithy/util-middleware": ^3.0.3 "@smithy/util-uri-escape": ^3.0.0 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: f7eca9889ac4252e8fff76bf31a75bbc8afebc7ac690e3fddffadaccde64fd05305b6e22ad00f8d8da3bb3ca8739d310d6abe70350a4c12c996fb0335a8bd975 + checksum: 8c58bbc5b3f9eed092351f36dc0193ed2e43f916856dc95eadc65b42460a0c5f662016156034ef8a25419f95be8f6a15a7e85469358b77db236445919f66c77e languageName: node linkType: hard -"@smithy/smithy-client@npm:^3.1.2, @smithy/smithy-client@npm:^3.1.4": - version: 3.1.4 - resolution: "@smithy/smithy-client@npm:3.1.4" +"@smithy/smithy-client@npm:^3.1.11": + version: 3.1.11 + resolution: "@smithy/smithy-client@npm:3.1.11" dependencies: - "@smithy/middleware-endpoint": ^3.0.3 - "@smithy/middleware-stack": ^3.0.2 - "@smithy/protocol-http": ^4.0.2 - "@smithy/types": ^3.2.0 - "@smithy/util-stream": ^3.0.4 + "@smithy/middleware-endpoint": ^3.1.0 + "@smithy/middleware-stack": ^3.0.3 + "@smithy/protocol-http": ^4.1.0 + "@smithy/types": ^3.3.0 + "@smithy/util-stream": ^3.1.3 tslib: ^2.6.2 - checksum: be1ce3523d5b49d1c2fb75695201dcc3748583050675efc7910b0a8bc9444c781daf435bec711166e6d2f0238ed301187283362c33aa31aefd2c21b09fb305a5 + checksum: acbbd29f45d342845eebf9086fd37cbf5abc563c60f37f787be92e4922bf09594cd882a6f9dcec85073120580c030ad14a035fd10c120733ca402938d87c143b languageName: node linkType: hard @@ -15672,23 +15678,23 @@ __metadata: languageName: node linkType: hard -"@smithy/types@npm:^3.1.0, @smithy/types@npm:^3.2.0": - version: 3.2.0 - resolution: "@smithy/types@npm:3.2.0" +"@smithy/types@npm:^3.3.0": + version: 3.3.0 + resolution: "@smithy/types@npm:3.3.0" dependencies: tslib: ^2.6.2 - checksum: f07caa63cd2f1ed9a14612a9493fcc9c0aca974593e16c1328daecc7f36af2ece5e5e79c24212966180f88a183abf078bfbcd98cf362a8d8f95f3f8642d41389 + checksum: 29bb5f83c41e32f8d4094a2aba2d3dfbd763ab5943784a700f3fa22df0dcf0ccac1b1907f7a87fbb9f6f2269fcd4750524bcb48f892249e200ffe397c0981309 languageName: node linkType: hard -"@smithy/url-parser@npm:^3.0.1, @smithy/url-parser@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/url-parser@npm:3.0.2" +"@smithy/url-parser@npm:^3.0.3": + version: 3.0.3 + resolution: "@smithy/url-parser@npm:3.0.3" dependencies: - "@smithy/querystring-parser": ^3.0.2 - "@smithy/types": ^3.2.0 + "@smithy/querystring-parser": ^3.0.3 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: a0dac1ff3eac440d3dba7f2ad80eb3cfb46cf912ceb4a533b0bd87ad5b5f1e9b641ca9a247844129c33dc2901cbe753c89185b70c6d323b781b83451a738702e + checksum: 86b4bc8e6c176b56076c30233ca4cfeb98d162fe27a348ddfda5f163ce7d173b8e684aa26202bbf4e0b5695b0ad43c0cb40170ca6793652d0ea6edb00443c036 languageName: node linkType: hard @@ -15750,42 +15756,42 @@ __metadata: languageName: node linkType: hard -"@smithy/util-defaults-mode-browser@npm:^3.0.4": - version: 3.0.6 - resolution: "@smithy/util-defaults-mode-browser@npm:3.0.6" +"@smithy/util-defaults-mode-browser@npm:^3.0.13": + version: 3.0.13 + resolution: "@smithy/util-defaults-mode-browser@npm:3.0.13" dependencies: - "@smithy/property-provider": ^3.1.2 - "@smithy/smithy-client": ^3.1.4 - "@smithy/types": ^3.2.0 + "@smithy/property-provider": ^3.1.3 + "@smithy/smithy-client": ^3.1.11 + "@smithy/types": ^3.3.0 bowser: ^2.11.0 tslib: ^2.6.2 - checksum: 753e21d8b6c9cbfb874dd9468823bce7ebfa979da8972fb5c67a31333513cebe09072fcb9ae803219bf41775569c8277e49f83abd96041042d3c487d299c7a0a + checksum: 087c583d0b276df7369053b068217821c4474bf3d9de3111110ef81e8d895539f80b53a11ecaaae105ce2d24a78a52d958840b8a6c6d3e18696c45f27015a3f3 languageName: node linkType: hard -"@smithy/util-defaults-mode-node@npm:^3.0.4": - version: 3.0.6 - resolution: "@smithy/util-defaults-mode-node@npm:3.0.6" +"@smithy/util-defaults-mode-node@npm:^3.0.13": + version: 3.0.13 + resolution: "@smithy/util-defaults-mode-node@npm:3.0.13" dependencies: - "@smithy/config-resolver": ^3.0.3 - "@smithy/credential-provider-imds": ^3.1.2 - "@smithy/node-config-provider": ^3.1.2 - "@smithy/property-provider": ^3.1.2 - "@smithy/smithy-client": ^3.1.4 - "@smithy/types": ^3.2.0 + "@smithy/config-resolver": ^3.0.5 + "@smithy/credential-provider-imds": ^3.2.0 + "@smithy/node-config-provider": ^3.1.4 + "@smithy/property-provider": ^3.1.3 + "@smithy/smithy-client": ^3.1.11 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: d64efd2b5bd7b4b3b1a668725d34018bd8cae00b8a59991eadabf122e590ad153be4f9beda58b063b451d9f03371575c9a8e2806bcc0b7790e63fc9d839f5c95 + checksum: a56c9f06472bb42e4180fd424ec237a6ca170eef5d487d1a3806a8845cd9c0bef37b431b22a9340afee5ae26b6bca6c11647112ef73433ba949f8c671e2b2067 languageName: node linkType: hard -"@smithy/util-endpoints@npm:^2.0.2": - version: 2.0.3 - resolution: "@smithy/util-endpoints@npm:2.0.3" +"@smithy/util-endpoints@npm:^2.0.5": + version: 2.0.5 + resolution: "@smithy/util-endpoints@npm:2.0.5" dependencies: - "@smithy/node-config-provider": ^3.1.2 - "@smithy/types": ^3.2.0 + "@smithy/node-config-provider": ^3.1.4 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: f8b77a7f68bd99b73362b29a56e35270b509f76ed82c003e82dae1468f46c2c986060aea1fcb78f3d9346830f62c1c3f3e0aa4de856b8897ba183efabc22969d + checksum: bb2a96323f52beaf2820f4e5764c865cff3ac5bca0c0df6923bb4582b0f87faf1606110cd4e36005ac43f41e9673ebdca4bbb8b913880fc2a4e0ff3301250da8 languageName: node linkType: hard @@ -15798,40 +15804,40 @@ __metadata: languageName: node linkType: hard -"@smithy/util-middleware@npm:^3.0.1, @smithy/util-middleware@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/util-middleware@npm:3.0.2" +"@smithy/util-middleware@npm:^3.0.3": + version: 3.0.3 + resolution: "@smithy/util-middleware@npm:3.0.3" dependencies: - "@smithy/types": ^3.2.0 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 8a6183d3fd4a7c01787fbfd1dd901b1cdf0937f3c5e73646e8377b1e3322782e191cb7c1c9278e6c84d7462d4b0e70bcac9cfca52367728b3357914db96f90cc + checksum: f37f25d65595af5ff4c3f69fa7e66545ac1651f77979e15ffbc9047e18fc668dae90458ee76add85a49ea3729c49d317e40542d5430e81e2eafe8dcae2ddb3bc languageName: node linkType: hard -"@smithy/util-retry@npm:^3.0.1, @smithy/util-retry@npm:^3.0.2": - version: 3.0.2 - resolution: "@smithy/util-retry@npm:3.0.2" +"@smithy/util-retry@npm:^3.0.3": + version: 3.0.3 + resolution: "@smithy/util-retry@npm:3.0.3" dependencies: - "@smithy/service-error-classification": ^3.0.2 - "@smithy/types": ^3.2.0 + "@smithy/service-error-classification": ^3.0.3 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 68846a52a6c71658db40f54681afad8c9bdb4687dc3c12fd13c27cf9aa3b96c57469a4d5658d4caabc9c710d95f920c0a3faafc9503fb99fb6466f51072fe852 + checksum: c760595376154be67414083aa6f76094022df72987521469b124ef3ef5848c0536757dcd2006520580380db6a4d7b597a05569470c3151f71d5e678df63f4c13 languageName: node linkType: hard -"@smithy/util-stream@npm:^3.0.2, @smithy/util-stream@npm:^3.0.4": - version: 3.0.4 - resolution: "@smithy/util-stream@npm:3.0.4" +"@smithy/util-stream@npm:^3.1.3": + version: 3.1.3 + resolution: "@smithy/util-stream@npm:3.1.3" dependencies: - "@smithy/fetch-http-handler": ^3.1.0 - "@smithy/node-http-handler": ^3.1.0 - "@smithy/types": ^3.2.0 + "@smithy/fetch-http-handler": ^3.2.4 + "@smithy/node-http-handler": ^3.1.4 + "@smithy/types": ^3.3.0 "@smithy/util-base64": ^3.0.0 "@smithy/util-buffer-from": ^3.0.0 "@smithy/util-hex-encoding": ^3.0.0 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: ba4a785d30606e82cbf80e644be05fad7a1813e19226ec8893a91993e0c943bc222643ab9c70625f72ee760b4f4d1632e74af586e028e7d3dc8197b1927e580b + checksum: b663124c3b857b7744a0f2db47d091c570ff4fe4e8a8d254a7e1b8fed1d57fa4dc8fb12e496f7f607666ac5bc36d6f44a57ef3132bc882ff1d869b9bfdb5fc6e languageName: node linkType: hard @@ -15873,14 +15879,14 @@ __metadata: languageName: node linkType: hard -"@smithy/util-waiter@npm:^3.0.1": - version: 3.1.1 - resolution: "@smithy/util-waiter@npm:3.1.1" +"@smithy/util-waiter@npm:^3.1.2": + version: 3.1.2 + resolution: "@smithy/util-waiter@npm:3.1.2" dependencies: - "@smithy/abort-controller": ^3.1.0 - "@smithy/types": ^3.2.0 + "@smithy/abort-controller": ^3.1.1 + "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: dda2666bc0c91a158fdcd04eab41f01130b5d34a9d8a86ea5ed9a8d1c87829caf381fda34a0595bf4748e99365a36842afe12fbf045f532c55f0d14f49c6a448 + checksum: 35773b1bbbb215102555a55ce4de57cbd3e38f37546ca3e6748ce3856119019a613946b399c6d97981a0bad447ce9c41f87c276325ff4c0e5a2276ee4e9e384e languageName: node linkType: hard @@ -27495,25 +27501,14 @@ __metadata: languageName: node linkType: hard -"fast-xml-parser@npm:4.2.5": - version: 4.2.5 - resolution: "fast-xml-parser@npm:4.2.5" +"fast-xml-parser@npm:4.4.1, fast-xml-parser@npm:^4.3.0, fast-xml-parser@npm:^4.3.2": + version: 4.4.1 + resolution: "fast-xml-parser@npm:4.4.1" dependencies: strnum: ^1.0.5 bin: fxparser: src/cli/cli.js - checksum: d32b22005504eeb207249bf40dc82d0994b5bb9ca9dcc731d335a1f425e47fe085b3cace3cf9d32172dd1a5544193c49e8615ca95b4bf95a4a4920a226b06d80 - languageName: node - linkType: hard - -"fast-xml-parser@npm:^4.3.0, fast-xml-parser@npm:^4.3.2": - version: 4.4.0 - resolution: "fast-xml-parser@npm:4.4.0" - dependencies: - strnum: ^1.0.5 - bin: - fxparser: src/cli/cli.js - checksum: ad33a4b5165a0ffcb6e17ae78825bd4619a8298844a8a8408f2ea141a0d2d9439d18865dc5254162f09fe54d510ff18e5d5c0a190869cab21fc745ee66be816b + checksum: f440c01cd141b98789ae777503bcb6727393296094cc82924ae9f88a5b971baa4eec7e65306c7e07746534caa661fc83694ff437d9012dc84dee39dfbfaab947 languageName: node linkType: hard From 4a529c266ee260eae2c91a9328b48e9188bed9fd Mon Sep 17 00:00:00 2001 From: David Weber <david.weber.schenker@gmail.com> Date: Wed, 31 Jul 2024 01:32:54 +0200 Subject: [PATCH 493/510] feat: use `entityPresentationApi` for the node title and the icon Signed-off-by: David Weber <david.weber@w3tec.ch> Signed-off-by: David Weber <david.weber.schenker@gmail.com> --- .changeset/smooth-countries-relate.md | 5 ++++ .../DefaultRenderNode.test.tsx | 8 +++-- .../DefaultRenderNode.tsx | 30 +++++++------------ ...yKindIcon.test.tsx => EntityIcon.test.tsx} | 8 +++-- .../{EntityKindIcon.tsx => EntityIcon.tsx} | 14 ++++----- 5 files changed, 33 insertions(+), 32 deletions(-) create mode 100644 .changeset/smooth-countries-relate.md rename plugins/catalog-graph/src/components/EntityRelationsGraph/{EntityKindIcon.test.tsx => EntityIcon.test.tsx} (81%) rename plugins/catalog-graph/src/components/EntityRelationsGraph/{EntityKindIcon.tsx => EntityIcon.tsx} (69%) diff --git a/.changeset/smooth-countries-relate.md b/.changeset/smooth-countries-relate.md new file mode 100644 index 0000000000..5e86ee8ab5 --- /dev/null +++ b/.changeset/smooth-countries-relate.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-graph': patch +--- + +Use `entityPresentationApi` for the node title and the icon. diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/DefaultRenderNode.test.tsx b/plugins/catalog-graph/src/components/EntityRelationsGraph/DefaultRenderNode.test.tsx index 1f3d77e1ae..10aa62f946 100644 --- a/plugins/catalog-graph/src/components/EntityRelationsGraph/DefaultRenderNode.test.tsx +++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/DefaultRenderNode.test.tsx @@ -47,6 +47,7 @@ describe('<CustomNode />', () => { ); expect(screen.getByText('kind:namespace/name')).toBeInTheDocument(); + expect(screen.getByText('namespace/name')).toBeInTheDocument(); }); test('renders node, skips default namespace', async () => { @@ -73,7 +74,7 @@ describe('<CustomNode />', () => { </svg>, ); - expect(screen.getByText('kind:name')).toBeInTheDocument(); + expect(screen.getByText('name')).toBeInTheDocument(); }); test('renders node with onClick', async () => { @@ -102,8 +103,8 @@ describe('<CustomNode />', () => { </svg>, ); - expect(screen.getByText('kind:namespace/name')).toBeInTheDocument(); - await userEvent.click(screen.getByText('kind:namespace/name')); + expect(screen.getByText('namespace/name')).toBeInTheDocument(); + await userEvent.click(screen.getByText('namespace/name')); expect(onClick).toHaveBeenCalledTimes(1); }); @@ -134,5 +135,6 @@ describe('<CustomNode />', () => { ); expect(screen.getByText('Custom Title')).toBeInTheDocument(); + expect(screen.getByText('kind:namespace/name')).toBeInTheDocument(); }); }); diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/DefaultRenderNode.tsx b/plugins/catalog-graph/src/components/EntityRelationsGraph/DefaultRenderNode.tsx index d55f4c015b..bc3311d33f 100644 --- a/plugins/catalog-graph/src/components/EntityRelationsGraph/DefaultRenderNode.tsx +++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/DefaultRenderNode.tsx @@ -14,12 +14,12 @@ * limitations under the License. */ import { DependencyGraphTypes } from '@backstage/core-components'; -import { useApp } from '@backstage/core-plugin-api'; -import { humanizeEntityRef } from '@backstage/plugin-catalog-react'; +import { IconComponent } from '@backstage/core-plugin-api'; +import { useEntityPresentation } from '@backstage/plugin-catalog-react'; import { makeStyles } from '@material-ui/core/styles'; import classNames from 'classnames'; import React, { useLayoutEffect, useRef, useState } from 'react'; -import { EntityKindIcon } from './EntityKindIcon'; +import { EntityIcon } from './EntityIcon'; import { EntityNodeData } from './types'; import { DEFAULT_NAMESPACE } from '@backstage/catalog-model'; @@ -64,8 +64,10 @@ export function DefaultRenderNode({ const classes = useStyles(); const [width, setWidth] = useState(0); const [height, setHeight] = useState(0); - const app = useApp(); const idRef = useRef<SVGTextElement | null>(null); + const entityRefPresentationSnapshot = useEntityPresentation(entity, { + defaultNamespace: DEFAULT_NAMESPACE, + }); useLayoutEffect(() => { // set the width to the length of the ID @@ -82,25 +84,14 @@ export function DefaultRenderNode({ } }, [width, height]); - const { - kind, - metadata: { name, namespace = DEFAULT_NAMESPACE, title }, - } = entity; - - const hasKindIcon = app.getSystemIcon( - `kind:${kind.toLocaleLowerCase('en-US')}`, - ); + const hasKindIcon = !!entityRefPresentationSnapshot.Icon; const padding = 10; const iconSize = height; const paddedIconWidth = hasKindIcon ? iconSize + padding : 0; const paddedWidth = paddedIconWidth + width + padding * 2; const paddedHeight = height + padding * 2; - const displayTitle = - title ?? - (kind && name && namespace - ? humanizeEntityRef({ kind, name, namespace }) - : id); + const displayTitle = entityRefPresentationSnapshot.primaryTitle ?? id; return ( <g onClick={onClick} className={classNames(onClick && classes.clickable)}> @@ -115,8 +106,8 @@ export function DefaultRenderNode({ rx={10} /> {hasKindIcon && ( - <EntityKindIcon - kind={kind} + <EntityIcon + icon={entityRefPresentationSnapshot.Icon as IconComponent} y={padding} x={padding} width={iconSize} @@ -144,6 +135,7 @@ export function DefaultRenderNode({ > {displayTitle} </text> + <title>{entityRefPresentationSnapshot.entityRef} ); } diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityKindIcon.test.tsx b/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityIcon.test.tsx similarity index 81% rename from plugins/catalog-graph/src/components/EntityRelationsGraph/EntityKindIcon.test.tsx rename to plugins/catalog-graph/src/components/EntityRelationsGraph/EntityIcon.test.tsx index cc47c8850b..8683af9c1e 100644 --- a/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityKindIcon.test.tsx +++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityIcon.test.tsx @@ -16,12 +16,14 @@ import { renderInTestApp } from '@backstage/test-utils'; import React from 'react'; -import { EntityKindIcon } from './EntityKindIcon'; +import { EntityIcon } from './EntityIcon'; +import MuiMemoryIcon from '@material-ui/icons/Memory'; +import { IconComponent } from '@backstage/core-plugin-api'; describe('', () => { it('renders without exploding', async () => { const { baseElement } = await renderInTestApp( - , + , ); expect(baseElement.querySelector('svg')).toBeInTheDocument(); @@ -29,7 +31,7 @@ describe('', () => { it('renders without exploding for unknown kind', async () => { const { baseElement } = await renderInTestApp( - , + , ); expect(baseElement.querySelector('svg')).toBeInTheDocument(); diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityKindIcon.tsx b/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityIcon.tsx similarity index 69% rename from plugins/catalog-graph/src/components/EntityRelationsGraph/EntityKindIcon.tsx rename to plugins/catalog-graph/src/components/EntityRelationsGraph/EntityIcon.tsx index 7263e25eae..a46a8bcc9d 100644 --- a/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityKindIcon.tsx +++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityIcon.tsx @@ -13,23 +13,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { useApp } from '@backstage/core-plugin-api'; import React from 'react'; import SvgIcon from '@material-ui/core/SvgIcon'; +import { OverridableComponent } from '@material-ui/core/OverridableComponent'; +import { SvgIconTypeMap } from '@material-ui/core/SvgIcon/SvgIcon'; +import { IconComponent } from '@backstage/core-plugin-api'; -export function EntityKindIcon({ - kind, +export function EntityIcon({ + icon, ...props }: { - kind: string; + icon: IconComponent | undefined; x?: number; y?: number; width?: number; height?: number; className?: string; }) { - const app = useApp(); - const Icon = - app.getSystemIcon(`kind:${kind.toLocaleLowerCase('en-US')}`) ?? SvgIcon; + const Icon = (icon as OverridableComponent) ?? SvgIcon; return ; } From 3d9891d2242f3a09bf113a0250d979c379a48c08 Mon Sep 17 00:00:00 2001 From: Alex Lorenzi <671432+alexlorenzi@users.noreply.github.com> Date: Tue, 30 Jul 2024 20:01:37 -0400 Subject: [PATCH 494/510] Update plugins/techdocs/src/reader/transformers/styles/transformer.test.tsx Signed-off-by: Alex Lorenzi <671432+alexlorenzi@users.noreply.github.com> --- .../src/reader/transformers/styles/transformer.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/techdocs/src/reader/transformers/styles/transformer.test.tsx b/plugins/techdocs/src/reader/transformers/styles/transformer.test.tsx index 464bb834ea..b55e372212 100644 --- a/plugins/techdocs/src/reader/transformers/styles/transformer.test.tsx +++ b/plugins/techdocs/src/reader/transformers/styles/transformer.test.tsx @@ -49,7 +49,7 @@ describe('Transformers > Styles', () => { ); }); - it('should use relative header sizes as the factor the md-typeset variable', () => { + it('should use headers relative font-size value as the factor for the md-typeset variable', () => { const theme = createTheme({ typography: { h1: { From adabb40edbd82cdc5d8b156e26cc399763dae860 Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Wed, 31 Jul 2024 08:51:52 +0300 Subject: [PATCH 495/510] feat(cli): allow setting license for new command This allows using custom licenses for new plugins when using the backstage-cli new command Signed-off-by: Heikki Hellgren --- .changeset/two-emus-work.md | 5 +++++ packages/cli/cli-report.md | 1 + packages/cli/src/commands/create-plugin/createPlugin.ts | 6 ++++-- packages/cli/src/commands/index.ts | 4 ++++ packages/cli/src/commands/new/new.ts | 3 +++ packages/cli/src/lib/new/factories/backendModule.test.ts | 1 + packages/cli/src/lib/new/factories/backendModule.ts | 1 + packages/cli/src/lib/new/factories/backendPlugin.test.ts | 1 + packages/cli/src/lib/new/factories/backendPlugin.ts | 1 + packages/cli/src/lib/new/factories/frontendPlugin.test.ts | 2 ++ packages/cli/src/lib/new/factories/frontendPlugin.ts | 1 + .../cli/src/lib/new/factories/nodeLibraryPackage.test.ts | 2 ++ packages/cli/src/lib/new/factories/nodeLibraryPackage.ts | 1 + packages/cli/src/lib/new/factories/pluginCommon.test.ts | 1 + packages/cli/src/lib/new/factories/pluginCommon.ts | 1 + packages/cli/src/lib/new/factories/pluginNode.test.ts | 1 + packages/cli/src/lib/new/factories/pluginNode.ts | 1 + packages/cli/src/lib/new/factories/pluginWeb.test.ts | 1 + packages/cli/src/lib/new/factories/pluginWeb.ts | 1 + packages/cli/src/lib/new/factories/scaffolderModule.test.ts | 1 + packages/cli/src/lib/new/factories/scaffolderModule.ts | 1 + .../cli/src/lib/new/factories/webLibraryPackage.test.ts | 2 ++ packages/cli/src/lib/new/factories/webLibraryPackage.ts | 1 + packages/cli/src/lib/new/types.ts | 2 ++ .../cli/templates/default-backend-module/package.json.hbs | 2 +- .../cli/templates/default-backend-plugin/package.json.hbs | 2 +- .../default-common-plugin-package/package.json.hbs | 2 +- .../templates/default-node-plugin-package/package.json.hbs | 2 +- packages/cli/templates/default-plugin/package.json.hbs | 2 +- .../templates/default-react-plugin-package/package.json.hbs | 2 +- .../cli/templates/node-library-package/package.json.hbs | 2 +- packages/cli/templates/scaffolder-module/package.json.hbs | 2 +- packages/cli/templates/web-library-package/package.json.hbs | 2 +- 33 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 .changeset/two-emus-work.md diff --git a/.changeset/two-emus-work.md b/.changeset/two-emus-work.md new file mode 100644 index 0000000000..3c60086043 --- /dev/null +++ b/.changeset/two-emus-work.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +New command now supports setting package license diff --git a/packages/cli/cli-report.md b/packages/cli/cli-report.md index 01b0f7ddec..10f3e088c1 100644 --- a/packages/cli/cli-report.md +++ b/packages/cli/cli-report.md @@ -194,6 +194,7 @@ Options: --scope --npm-registry --baseVersion + --license --no-private -h, --help ``` diff --git a/packages/cli/src/commands/create-plugin/createPlugin.ts b/packages/cli/src/commands/create-plugin/createPlugin.ts index 7fcb0aef1a..f8d7e54e97 100644 --- a/packages/cli/src/commands/create-plugin/createPlugin.ts +++ b/packages/cli/src/commands/create-plugin/createPlugin.ts @@ -19,16 +19,16 @@ import { promisify } from 'util'; import chalk from 'chalk'; import inquirer, { Answers, Question } from 'inquirer'; import { exec as execCb } from 'child_process'; -import { resolve as resolvePath, join as joinPath } from 'path'; +import { join as joinPath, resolve as resolvePath } from 'path'; import camelCase from 'lodash/camelCase'; import upperFirst from 'lodash/upperFirst'; import os from 'os'; import { OptionValues } from 'commander'; import { assertError } from '@backstage/errors'; import { - parseOwnerIds, addCodeownersEntry, getCodeownersFilePath, + parseOwnerIds, } from '../../lib/codeowners'; import { paths } from '../../lib/paths'; import { Task, templatingTask } from '../../lib/tasks'; @@ -266,6 +266,7 @@ export default async (opts: OptionValues) => { const { version: pluginVersion } = isMonoRepo ? await fs.readJson(paths.resolveTargetRoot('lerna.json')) : { version: '0.1.0' }; + const license = opts.license ?? 'Apache-2.0'; let lockfile: Lockfile | undefined; try { @@ -299,6 +300,7 @@ export default async (opts: OptionValues) => { name, privatePackage, npmRegistry, + license, }, createPackageVersionProvider(lockfile), isMonoRepo, diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index 25a3a4e26c..6881c933db 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -254,6 +254,10 @@ export function registerCommands(program: Command) { '--baseVersion ', 'The version to use for any new packages (default: 0.1.0)', ) + .option( + '--license ', + 'The license to use for any new packages (default: Apache-2.0)', + ) .option('--no-private', 'Do not mark new packages as private') .action(lazy(() => import('./new/new').then(m => m.default))); diff --git a/packages/cli/src/commands/new/new.ts b/packages/cli/src/commands/new/new.ts index 61e27af3c5..2733b0be9b 100644 --- a/packages/cli/src/commands/new/new.ts +++ b/packages/cli/src/commands/new/new.ts @@ -70,11 +70,14 @@ export default async (opts: OptionValues) => { return dir; } + const license = opts.license ?? 'Apache-2.0'; + let modified = false; try { await factory.create(options, { isMonoRepo: await isMonoRepo(), defaultVersion, + license, scope: opts.scope?.replace(/^@/, ''), npmRegistry: opts.npmRegistry, private: Boolean(opts.private), diff --git a/packages/cli/src/lib/new/factories/backendModule.test.ts b/packages/cli/src/lib/new/factories/backendModule.test.ts index 2d6a4c9c83..59b5403239 100644 --- a/packages/cli/src/lib/new/factories/backendModule.test.ts +++ b/packages/cli/src/lib/new/factories/backendModule.test.ts @@ -79,6 +79,7 @@ describe('backendModule factory', () => { modified = true; }, createTemporaryDirectory: () => fs.mkdtemp('test'), + license: 'Apache-2.0', }); expect(modified).toBe(true); diff --git a/packages/cli/src/lib/new/factories/backendModule.ts b/packages/cli/src/lib/new/factories/backendModule.ts index 67860b812e..de759538b1 100644 --- a/packages/cli/src/lib/new/factories/backendModule.ts +++ b/packages/cli/src/lib/new/factories/backendModule.ts @@ -75,6 +75,7 @@ export const backendModule = createFactory({ packageVersion: ctx.defaultVersion, privatePackage: ctx.private, npmRegistry: ctx.npmRegistry, + license: ctx.license, }, }); diff --git a/packages/cli/src/lib/new/factories/backendPlugin.test.ts b/packages/cli/src/lib/new/factories/backendPlugin.test.ts index f6eeb8cf33..3b90e2b0dd 100644 --- a/packages/cli/src/lib/new/factories/backendPlugin.test.ts +++ b/packages/cli/src/lib/new/factories/backendPlugin.test.ts @@ -78,6 +78,7 @@ describe('backendPlugin factory', () => { modified = true; }, createTemporaryDirectory: () => fs.mkdtemp('test'), + license: 'Apache-2.0', }); expect(modified).toBe(true); diff --git a/packages/cli/src/lib/new/factories/backendPlugin.ts b/packages/cli/src/lib/new/factories/backendPlugin.ts index fc77896461..9129a66075 100644 --- a/packages/cli/src/lib/new/factories/backendPlugin.ts +++ b/packages/cli/src/lib/new/factories/backendPlugin.ts @@ -64,6 +64,7 @@ export const backendPlugin = createFactory({ pluginVersion: ctx.defaultVersion, privatePackage: ctx.private, npmRegistry: ctx.npmRegistry, + license: ctx.license, }, }); diff --git a/packages/cli/src/lib/new/factories/frontendPlugin.test.ts b/packages/cli/src/lib/new/factories/frontendPlugin.test.ts index cca79dea2a..55e569a15f 100644 --- a/packages/cli/src/lib/new/factories/frontendPlugin.test.ts +++ b/packages/cli/src/lib/new/factories/frontendPlugin.test.ts @@ -80,6 +80,7 @@ describe('frontendPlugin factory', () => { modified = true; }, createTemporaryDirectory: () => fs.mkdtemp('test'), + license: 'Apache-2.0', }); expect(modified).toBe(true); @@ -174,6 +175,7 @@ const router = ( defaultVersion: '1.0.0', markAsModified: () => {}, createTemporaryDirectory: () => fs.mkdtemp('test'), + license: 'Apache-2.0', }); await expect( diff --git a/packages/cli/src/lib/new/factories/frontendPlugin.ts b/packages/cli/src/lib/new/factories/frontendPlugin.ts index 1058c879c1..41907d9d3a 100644 --- a/packages/cli/src/lib/new/factories/frontendPlugin.ts +++ b/packages/cli/src/lib/new/factories/frontendPlugin.ts @@ -67,6 +67,7 @@ export const frontendPlugin = createFactory({ pluginVersion: ctx.defaultVersion, privatePackage: ctx.private, npmRegistry: ctx.npmRegistry, + license: ctx.license, }, }); diff --git a/packages/cli/src/lib/new/factories/nodeLibraryPackage.test.ts b/packages/cli/src/lib/new/factories/nodeLibraryPackage.test.ts index e3673d21ba..69999761e9 100644 --- a/packages/cli/src/lib/new/factories/nodeLibraryPackage.test.ts +++ b/packages/cli/src/lib/new/factories/nodeLibraryPackage.test.ts @@ -64,6 +64,7 @@ describe('nodeLibraryPackage factory', () => { modified = true; }, createTemporaryDirectory: () => fs.mkdtemp('test'), + license: 'Apache-2.0', }); expect(modified).toBe(true); @@ -134,6 +135,7 @@ describe('nodeLibraryPackage factory', () => { defaultVersion: '1.0.0', markAsModified: () => {}, createTemporaryDirectory: () => fs.mkdtemp('test'), + license: 'Apache-2.0', }); expect(Task.forCommand).toHaveBeenCalledTimes(2); diff --git a/packages/cli/src/lib/new/factories/nodeLibraryPackage.ts b/packages/cli/src/lib/new/factories/nodeLibraryPackage.ts index 687caa7cd5..3d9029a01d 100644 --- a/packages/cli/src/lib/new/factories/nodeLibraryPackage.ts +++ b/packages/cli/src/lib/new/factories/nodeLibraryPackage.ts @@ -61,6 +61,7 @@ export const nodeLibraryPackage = createFactory({ pluginVersion: ctx.defaultVersion, privatePackage: ctx.private, npmRegistry: ctx.npmRegistry, + license: ctx.license, }, }); diff --git a/packages/cli/src/lib/new/factories/pluginCommon.test.ts b/packages/cli/src/lib/new/factories/pluginCommon.test.ts index 82c1c87169..8f01401435 100644 --- a/packages/cli/src/lib/new/factories/pluginCommon.test.ts +++ b/packages/cli/src/lib/new/factories/pluginCommon.test.ts @@ -62,6 +62,7 @@ describe('pluginCommon factory', () => { modified = true; }, createTemporaryDirectory: () => fs.mkdtemp('test'), + license: 'Apache-2.0', }); expect(modified).toBe(true); diff --git a/packages/cli/src/lib/new/factories/pluginCommon.ts b/packages/cli/src/lib/new/factories/pluginCommon.ts index 5f694124ea..eb17c70a5c 100644 --- a/packages/cli/src/lib/new/factories/pluginCommon.ts +++ b/packages/cli/src/lib/new/factories/pluginCommon.ts @@ -61,6 +61,7 @@ export const pluginCommon = createFactory({ privatePackage: ctx.private, npmRegistry: ctx.npmRegistry, pluginVersion: ctx.defaultVersion, + license: ctx.license, }, }); diff --git a/packages/cli/src/lib/new/factories/pluginNode.test.ts b/packages/cli/src/lib/new/factories/pluginNode.test.ts index d8d9ea33ab..b6aad0a129 100644 --- a/packages/cli/src/lib/new/factories/pluginNode.test.ts +++ b/packages/cli/src/lib/new/factories/pluginNode.test.ts @@ -62,6 +62,7 @@ describe('pluginNode factory', () => { modified = true; }, createTemporaryDirectory: () => fs.mkdtemp('test'), + license: 'Apache-2.0', }); expect(modified).toBe(true); diff --git a/packages/cli/src/lib/new/factories/pluginNode.ts b/packages/cli/src/lib/new/factories/pluginNode.ts index c7f9ba6f6a..8eaab3cadb 100644 --- a/packages/cli/src/lib/new/factories/pluginNode.ts +++ b/packages/cli/src/lib/new/factories/pluginNode.ts @@ -61,6 +61,7 @@ export const pluginNode = createFactory({ privatePackage: ctx.private, npmRegistry: ctx.npmRegistry, pluginVersion: ctx.defaultVersion, + license: ctx.license, }, }); diff --git a/packages/cli/src/lib/new/factories/pluginWeb.test.ts b/packages/cli/src/lib/new/factories/pluginWeb.test.ts index ff4211d8fa..20fbbbbdb7 100644 --- a/packages/cli/src/lib/new/factories/pluginWeb.test.ts +++ b/packages/cli/src/lib/new/factories/pluginWeb.test.ts @@ -62,6 +62,7 @@ describe('pluginWeb factory', () => { modified = true; }, createTemporaryDirectory: () => fs.mkdtemp('test'), + license: 'Apache-2.0', }); expect(modified).toBe(true); diff --git a/packages/cli/src/lib/new/factories/pluginWeb.ts b/packages/cli/src/lib/new/factories/pluginWeb.ts index dc8cb73dce..6635b0b0e1 100644 --- a/packages/cli/src/lib/new/factories/pluginWeb.ts +++ b/packages/cli/src/lib/new/factories/pluginWeb.ts @@ -61,6 +61,7 @@ export const pluginWeb = createFactory({ privatePackage: ctx.private, npmRegistry: ctx.npmRegistry, pluginVersion: ctx.defaultVersion, + license: ctx.license, }, }); diff --git a/packages/cli/src/lib/new/factories/scaffolderModule.test.ts b/packages/cli/src/lib/new/factories/scaffolderModule.test.ts index d83c2ce3f7..c4b9d78fc1 100644 --- a/packages/cli/src/lib/new/factories/scaffolderModule.test.ts +++ b/packages/cli/src/lib/new/factories/scaffolderModule.test.ts @@ -62,6 +62,7 @@ describe('scaffolderModule factory', () => { modified = true; }, createTemporaryDirectory: (name: string) => fs.mkdtemp(name), + license: 'Apache-2.0', }); expect(modified).toBe(true); diff --git a/packages/cli/src/lib/new/factories/scaffolderModule.ts b/packages/cli/src/lib/new/factories/scaffolderModule.ts index 07f67ce78c..4c279a49d4 100644 --- a/packages/cli/src/lib/new/factories/scaffolderModule.ts +++ b/packages/cli/src/lib/new/factories/scaffolderModule.ts @@ -78,6 +78,7 @@ export const scaffolderModule = createFactory({ privatePackage: ctx.private, npmRegistry: ctx.npmRegistry, pluginVersion: ctx.defaultVersion, + license: ctx.license, }, }); diff --git a/packages/cli/src/lib/new/factories/webLibraryPackage.test.ts b/packages/cli/src/lib/new/factories/webLibraryPackage.test.ts index b0c8461189..691f0b9f1c 100644 --- a/packages/cli/src/lib/new/factories/webLibraryPackage.test.ts +++ b/packages/cli/src/lib/new/factories/webLibraryPackage.test.ts @@ -64,6 +64,7 @@ describe('webLibraryPackage factory', () => { modified = true; }, createTemporaryDirectory: () => fs.mkdtemp('test'), + license: 'Apache-2.0', }); expect(modified).toBe(true); @@ -134,6 +135,7 @@ describe('webLibraryPackage factory', () => { defaultVersion: '1.0.0', markAsModified: () => {}, createTemporaryDirectory: () => fs.mkdtemp('test'), + license: 'Apache-2.0', }); expect(Task.forCommand).toHaveBeenCalledTimes(2); diff --git a/packages/cli/src/lib/new/factories/webLibraryPackage.ts b/packages/cli/src/lib/new/factories/webLibraryPackage.ts index 45e1085ff3..3c63127d7d 100644 --- a/packages/cli/src/lib/new/factories/webLibraryPackage.ts +++ b/packages/cli/src/lib/new/factories/webLibraryPackage.ts @@ -61,6 +61,7 @@ export const webLibraryPackage = createFactory({ pluginVersion: ctx.defaultVersion, privatePackage: ctx.private, npmRegistry: ctx.npmRegistry, + license: ctx.license, }, }); diff --git a/packages/cli/src/lib/new/types.ts b/packages/cli/src/lib/new/types.ts index 6a894bf9ef..534f99f94f 100644 --- a/packages/cli/src/lib/new/types.ts +++ b/packages/cli/src/lib/new/types.ts @@ -27,6 +27,8 @@ export interface CreateContext { isMonoRepo: boolean; /** The default version to use for new packages */ defaultVersion: string; + /** License to use for new packages */ + license: string; /** Creates a temporary directory. This will always be deleted after creation is done. */ createTemporaryDirectory(name: string): Promise; diff --git a/packages/cli/templates/default-backend-module/package.json.hbs b/packages/cli/templates/default-backend-module/package.json.hbs index 07eee73d50..db8b8749b3 100644 --- a/packages/cli/templates/default-backend-module/package.json.hbs +++ b/packages/cli/templates/default-backend-module/package.json.hbs @@ -4,7 +4,7 @@ "version": "{{packageVersion}}", "main": "src/index.ts", "types": "src/index.ts", - "license": "Apache-2.0", + "license": "{{license}}", {{#if privatePackage}} "private": {{privatePackage}}, {{/if}} diff --git a/packages/cli/templates/default-backend-plugin/package.json.hbs b/packages/cli/templates/default-backend-plugin/package.json.hbs index 8dd31cbc38..b05d1a844b 100644 --- a/packages/cli/templates/default-backend-plugin/package.json.hbs +++ b/packages/cli/templates/default-backend-plugin/package.json.hbs @@ -3,7 +3,7 @@ "version": "{{pluginVersion}}", "main": "src/index.ts", "types": "src/index.ts", - "license": "Apache-2.0", + "license": "{{license}}", {{#if privatePackage}} "private": {{privatePackage}}, {{/if}} diff --git a/packages/cli/templates/default-common-plugin-package/package.json.hbs b/packages/cli/templates/default-common-plugin-package/package.json.hbs index 992599ef6d..689c3e6f53 100644 --- a/packages/cli/templates/default-common-plugin-package/package.json.hbs +++ b/packages/cli/templates/default-common-plugin-package/package.json.hbs @@ -4,7 +4,7 @@ "version": "{{pluginVersion}}", "main": "src/index.ts", "types": "src/index.ts", - "license": "Apache-2.0", + "license": "{{license}}", {{#if privatePackage}} "private": {{privatePackage}}, {{/if}} diff --git a/packages/cli/templates/default-node-plugin-package/package.json.hbs b/packages/cli/templates/default-node-plugin-package/package.json.hbs index 45becd1bea..d58f95b3b2 100644 --- a/packages/cli/templates/default-node-plugin-package/package.json.hbs +++ b/packages/cli/templates/default-node-plugin-package/package.json.hbs @@ -4,7 +4,7 @@ "version": "{{pluginVersion}}", "main": "src/index.ts", "types": "src/index.ts", - "license": "Apache-2.0", + "license": "{{license}}", {{#if privatePackage}} "private": {{privatePackage}}, {{/if}} diff --git a/packages/cli/templates/default-plugin/package.json.hbs b/packages/cli/templates/default-plugin/package.json.hbs index c833c125f6..b4034fd742 100644 --- a/packages/cli/templates/default-plugin/package.json.hbs +++ b/packages/cli/templates/default-plugin/package.json.hbs @@ -3,7 +3,7 @@ "version": "{{pluginVersion}}", "main": "src/index.ts", "types": "src/index.ts", - "license": "Apache-2.0", + "license": "{{license}}", {{#if privatePackage}} "private": {{privatePackage}}, {{/if}} diff --git a/packages/cli/templates/default-react-plugin-package/package.json.hbs b/packages/cli/templates/default-react-plugin-package/package.json.hbs index 79f3430f46..bea066630f 100644 --- a/packages/cli/templates/default-react-plugin-package/package.json.hbs +++ b/packages/cli/templates/default-react-plugin-package/package.json.hbs @@ -4,7 +4,7 @@ "version": "{{pluginVersion}}", "main": "src/index.ts", "types": "src/index.ts", - "license": "Apache-2.0", + "license": "{{license}}", {{#if privatePackage}} "private": {{privatePackage}}, {{/if}} diff --git a/packages/cli/templates/node-library-package/package.json.hbs b/packages/cli/templates/node-library-package/package.json.hbs index a6ede31893..d56a51bcd6 100644 --- a/packages/cli/templates/node-library-package/package.json.hbs +++ b/packages/cli/templates/node-library-package/package.json.hbs @@ -3,7 +3,7 @@ "version": "{{pluginVersion}}", "main": "src/index.ts", "types": "src/index.ts", - "license": "Apache-2.0", + "license": "{{license}}", {{#if privatePackage}} "private": {{privatePackage}}, {{/if}} diff --git a/packages/cli/templates/scaffolder-module/package.json.hbs b/packages/cli/templates/scaffolder-module/package.json.hbs index 0ebe5dd5f4..df4bf352f4 100644 --- a/packages/cli/templates/scaffolder-module/package.json.hbs +++ b/packages/cli/templates/scaffolder-module/package.json.hbs @@ -4,7 +4,7 @@ "version": "{{pluginVersion}}", "main": "src/index.ts", "types": "src/index.ts", - "license": "Apache-2.0", + "license": "{{license}}", {{#if privatePackage}} "private": {{privatePackage}}, {{/if}} diff --git a/packages/cli/templates/web-library-package/package.json.hbs b/packages/cli/templates/web-library-package/package.json.hbs index 271417a525..64a693dd4c 100644 --- a/packages/cli/templates/web-library-package/package.json.hbs +++ b/packages/cli/templates/web-library-package/package.json.hbs @@ -3,7 +3,7 @@ "version": "{{pluginVersion}}", "main": "src/index.ts", "types": "src/index.ts", - "license": "Apache-2.0", + "license": "{{license}}", {{#if privatePackage}} "private": {{privatePackage}}, {{/if}} From 06e92aea6c5871cc53ca61a905b33e24b595031d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 31 Jul 2024 07:33:04 +0000 Subject: [PATCH 496/510] chore(deps): update dependency @playwright/test to v1.45.3 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/yarn.lock b/yarn.lock index 5b59e65a8e..b321863309 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4233,7 +4233,7 @@ __metadata: languageName: node linkType: hard -"@backstage/core-components@npm:^0.14.4, @backstage/core-components@npm:^0.14.9": +"@backstage/core-components@npm:^0.14.9": version: 0.14.9 resolution: "@backstage/core-components@npm:0.14.9" dependencies: @@ -4353,7 +4353,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-plugin-api@^1.8.2, @backstage/core-plugin-api@^1.9.2, @backstage/core-plugin-api@^1.9.3, @backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": +"@backstage/core-plugin-api@^1.8.2, @backstage/core-plugin-api@^1.9.3, @backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": version: 0.0.0-use.local resolution: "@backstage/core-plugin-api@workspace:packages/core-plugin-api" dependencies: @@ -13968,13 +13968,13 @@ __metadata: linkType: hard "@playwright/test@npm:^1.32.3": - version: 1.45.0 - resolution: "@playwright/test@npm:1.45.0" + version: 1.45.3 + resolution: "@playwright/test@npm:1.45.3" dependencies: - playwright: 1.45.0 + playwright: 1.45.3 bin: playwright: cli.js - checksum: 55fb72f393b05f6684b5098e0681712f71e1fe25aa6a00bd636133f9ccc26d096d61ee30f569b83368e4bf6a1288d2f8f6fd5364da5d396eab180f89f61b7164 + checksum: 3e2c88d40f98cf94ab7947263804d1ee78c4bb21a35c8dbb64855eed5565ffc688509c5f07bda5438cba6c354374981448dcba3dbe326d1699b4fef75c9ce43d languageName: node linkType: hard @@ -37160,27 +37160,27 @@ __metadata: languageName: node linkType: hard -"playwright-core@npm:1.45.0": - version: 1.45.0 - resolution: "playwright-core@npm:1.45.0" +"playwright-core@npm:1.45.3": + version: 1.45.3 + resolution: "playwright-core@npm:1.45.3" bin: playwright-core: cli.js - checksum: e81a55eeefa997fcb559527127c9cefbbabe81f196de486224e6c2a3a66852dab883379ff28a05b8008fb0ad4992840ad53c2415cee27e2d1778836210d9248e + checksum: cecb58877b2c643403d7a72c24a7aa0fdd087a3c7f9a5ea5403851336ea831d8e304b1f159aacbbabd12e5c47eaac054333746c9e5431ec07b13d64dbf3b50ec languageName: node linkType: hard -"playwright@npm:1.45.0": - version: 1.45.0 - resolution: "playwright@npm:1.45.0" +"playwright@npm:1.45.3": + version: 1.45.3 + resolution: "playwright@npm:1.45.3" dependencies: fsevents: 2.3.2 - playwright-core: 1.45.0 + playwright-core: 1.45.3 dependenciesMeta: fsevents: optional: true bin: playwright: cli.js - checksum: 2a5f827fdcc90f1ec0ea4d9e4f2021ae894df88d3c0577677a81f72a09d91fb15584346e63ec2f85bfc24f872976ff2a76cee6ca7d7f29a8cc3159ced4f25b50 + checksum: d9d23b155ccd001553214f710561b01e48eb409676102f8ab94c0b4aa5ac5f398becc1a96528b0554944e07e34189503d891913e0e0a4aa58ad36b9c08747983 languageName: node linkType: hard From c322bc4680117df16358162ba939c0731a0c968a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 31 Jul 2024 07:33:55 +0000 Subject: [PATCH 497/510] fix(deps): update aws-sdk-js-v3 monorepo to v3.374.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn.lock b/yarn.lock index 5b59e65a8e..b2dc4183d0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4233,7 +4233,7 @@ __metadata: languageName: node linkType: hard -"@backstage/core-components@npm:^0.14.4, @backstage/core-components@npm:^0.14.9": +"@backstage/core-components@npm:^0.14.9": version: 0.14.9 resolution: "@backstage/core-components@npm:0.14.9" dependencies: @@ -4353,7 +4353,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-plugin-api@^1.8.2, @backstage/core-plugin-api@^1.9.2, @backstage/core-plugin-api@^1.9.3, @backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": +"@backstage/core-plugin-api@^1.8.2, @backstage/core-plugin-api@^1.9.3, @backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": version: 0.0.0-use.local resolution: "@backstage/core-plugin-api@workspace:packages/core-plugin-api" dependencies: From d7a0aa326b5f654859b89c46f3da73d850820e98 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 31 Jul 2024 08:16:49 +0000 Subject: [PATCH 498/510] Version Packages (next) --- .changeset/create-app-1722413762.md | 5 + .changeset/pre.json | 4 + docs/releases/v1.30.0-next.2-changelog.md | 156 ++++++++++++++++++ package.json | 2 +- packages/app-next/CHANGELOG.md | 43 +++++ packages/app-next/package.json | 2 +- packages/app/CHANGELOG.md | 41 +++++ packages/app/package.json | 2 +- packages/cli/CHANGELOG.md | 18 ++ packages/cli/package.json | 2 +- packages/create-app/CHANGELOG.md | 8 + packages/create-app/package.json | 2 +- packages/e2e-test/CHANGELOG.md | 9 + packages/e2e-test/package.json | 2 +- .../techdocs-cli-embedded-app/CHANGELOG.md | 19 +++ .../techdocs-cli-embedded-app/package.json | 2 +- plugins/catalog-graph/CHANGELOG.md | 15 ++ plugins/catalog-graph/package.json | 2 +- 18 files changed, 326 insertions(+), 8 deletions(-) create mode 100644 .changeset/create-app-1722413762.md create mode 100644 docs/releases/v1.30.0-next.2-changelog.md diff --git a/.changeset/create-app-1722413762.md b/.changeset/create-app-1722413762.md new file mode 100644 index 0000000000..b50d431d4b --- /dev/null +++ b/.changeset/create-app-1722413762.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Bumped create-app version. diff --git a/.changeset/pre.json b/.changeset/pre.json index 92a9550739..8b33f2b80b 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -196,6 +196,8 @@ "bright-trainers-brake", "chilly-trains-sleep", "cool-insects-remember", + "cool-schools-vanish", + "create-app-1722413762", "cuddly-zebras-crash", "dry-squids-tap", "dull-ghosts-double", @@ -245,6 +247,7 @@ "six-rats-kick", "slow-toes-jog", "small-spoons-shout", + "smooth-countries-relate", "soft-gorillas-refuse", "spicy-lies-listen", "spicy-planets-provide", @@ -259,6 +262,7 @@ "thirty-paws-hope", "tiny-oranges-pretend", "tough-lies-repair", + "two-emus-work", "violet-jokes-wave", "wicked-bobcats-teach", "wild-eggs-exist", diff --git a/docs/releases/v1.30.0-next.2-changelog.md b/docs/releases/v1.30.0-next.2-changelog.md new file mode 100644 index 0000000000..cdf4164566 --- /dev/null +++ b/docs/releases/v1.30.0-next.2-changelog.md @@ -0,0 +1,156 @@ +# Release v1.30.0-next.2 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.30.0-next.2](https://backstage.github.io/upgrade-helper/?to=1.30.0-next.2) + +## @backstage/cli@0.27.0-next.2 + +### Patch Changes + +- b2d97fd: Fixing loading of additional config files with new `ConfigSources` +- adabb40: New command now supports setting package license +- Updated dependencies + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0-next.1 + - @backstage/errors@1.2.4 + - @backstage/eslint-plugin@0.1.8 + - @backstage/integration@1.14.0-next.0 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/create-app@0.5.18-next.2 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.14 + +## @backstage/plugin-catalog-graph@0.4.8-next.2 + +### Patch Changes + +- 4a529c2: Use `entityPresentationApi` for the node title and the icon. +- Updated dependencies + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-react@1.12.3-next.1 + +## example-app@0.2.100-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.27.0-next.2 + - @backstage/plugin-catalog-graph@0.4.8-next.2 + - @backstage/app-defaults@1.5.10-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/frontend-app-api@0.7.5-next.1 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-api-docs@0.11.8-next.1 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/plugin-catalog@1.21.2-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-import@0.12.2-next.1 + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.7-next.0 + - @backstage/plugin-devtools@0.1.17-next.1 + - @backstage/plugin-home@0.7.9-next.1 + - @backstage/plugin-kubernetes@0.11.13-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.14-next.1 + - @backstage/plugin-notifications@0.2.4-next.0 + - @backstage/plugin-org@0.6.28-next.1 + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/plugin-scaffolder@1.23.1-next.1 + - @backstage/plugin-scaffolder-react@1.11.0-next.1 + - @backstage/plugin-search@1.4.15-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/plugin-search-react@1.7.14-next.1 + - @backstage/plugin-signals@0.0.9-next.0 + - @backstage/plugin-techdocs@1.10.8-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.13-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + - @backstage/plugin-user-settings@0.8.11-next.1 + +## example-app-next@0.0.14-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.27.0-next.2 + - @backstage/plugin-catalog-graph@0.4.8-next.2 + - @backstage/app-defaults@1.5.10-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/frontend-app-api@0.7.5-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-api-docs@0.11.8-next.1 + - @backstage/plugin-app-visualizer@0.1.9-next.1 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/plugin-catalog@1.21.2-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-import@0.12.2-next.1 + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.7-next.0 + - @backstage/plugin-home@0.7.9-next.1 + - @backstage/plugin-kubernetes@0.11.13-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.14-next.1 + - @backstage/plugin-notifications@0.2.4-next.0 + - @backstage/plugin-org@0.6.28-next.1 + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/plugin-scaffolder@1.23.1-next.1 + - @backstage/plugin-scaffolder-react@1.11.0-next.1 + - @backstage/plugin-search@1.4.15-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/plugin-search-react@1.7.14-next.1 + - @backstage/plugin-signals@0.0.9-next.0 + - @backstage/plugin-techdocs@1.10.8-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.13-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + - @backstage/plugin-user-settings@0.8.11-next.1 + +## e2e-test@0.2.19-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.18-next.2 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + +## techdocs-cli-embedded-app@0.2.99-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.27.0-next.2 + - @backstage/app-defaults@1.5.10-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/test-utils@1.5.10-next.1 + - @backstage/theme@0.5.6 + - @backstage/plugin-catalog@1.21.2-next.1 + - @backstage/plugin-techdocs@1.10.8-next.1 + - @backstage/plugin-techdocs-react@1.2.7-next.0 diff --git a/package.json b/package.json index 0e93bd349c..8e7a047d7b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "root", - "version": "1.30.0-next.1", + "version": "1.30.0-next.2", "private": true, "repository": { "type": "git", diff --git a/packages/app-next/CHANGELOG.md b/packages/app-next/CHANGELOG.md index fe43f310b7..7eb9535771 100644 --- a/packages/app-next/CHANGELOG.md +++ b/packages/app-next/CHANGELOG.md @@ -1,5 +1,48 @@ # example-app-next +## 0.0.14-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.27.0-next.2 + - @backstage/plugin-catalog-graph@0.4.8-next.2 + - @backstage/app-defaults@1.5.10-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/frontend-app-api@0.7.5-next.1 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-api-docs@0.11.8-next.1 + - @backstage/plugin-app-visualizer@0.1.9-next.1 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/plugin-catalog@1.21.2-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-import@0.12.2-next.1 + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.7-next.0 + - @backstage/plugin-home@0.7.9-next.1 + - @backstage/plugin-kubernetes@0.11.13-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.14-next.1 + - @backstage/plugin-notifications@0.2.4-next.0 + - @backstage/plugin-org@0.6.28-next.1 + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/plugin-scaffolder@1.23.1-next.1 + - @backstage/plugin-scaffolder-react@1.11.0-next.1 + - @backstage/plugin-search@1.4.15-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/plugin-search-react@1.7.14-next.1 + - @backstage/plugin-signals@0.0.9-next.0 + - @backstage/plugin-techdocs@1.10.8-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.13-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + - @backstage/plugin-user-settings@0.8.11-next.1 + ## 0.0.14-next.1 ### Patch Changes diff --git a/packages/app-next/package.json b/packages/app-next/package.json index e64eb438e6..8a9d97d560 100644 --- a/packages/app-next/package.json +++ b/packages/app-next/package.json @@ -1,6 +1,6 @@ { "name": "example-app-next", - "version": "0.0.14-next.1", + "version": "0.0.14-next.2", "private": true, "repository": { "type": "git", diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index 78bff3c88e..4bcd5461a7 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,46 @@ # example-app +## 0.2.100-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.27.0-next.2 + - @backstage/plugin-catalog-graph@0.4.8-next.2 + - @backstage/app-defaults@1.5.10-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/frontend-app-api@0.7.5-next.1 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-api-docs@0.11.8-next.1 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/plugin-catalog@1.21.2-next.1 + - @backstage/plugin-catalog-common@1.0.26-next.0 + - @backstage/plugin-catalog-import@0.12.2-next.1 + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.7-next.0 + - @backstage/plugin-devtools@0.1.17-next.1 + - @backstage/plugin-home@0.7.9-next.1 + - @backstage/plugin-kubernetes@0.11.13-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.14-next.1 + - @backstage/plugin-notifications@0.2.4-next.0 + - @backstage/plugin-org@0.6.28-next.1 + - @backstage/plugin-permission-react@0.4.25-next.0 + - @backstage/plugin-scaffolder@1.23.1-next.1 + - @backstage/plugin-scaffolder-react@1.11.0-next.1 + - @backstage/plugin-search@1.4.15-next.1 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/plugin-search-react@1.7.14-next.1 + - @backstage/plugin-signals@0.0.9-next.0 + - @backstage/plugin-techdocs@1.10.8-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.13-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + - @backstage/plugin-user-settings@0.8.11-next.1 + ## 0.2.100-next.1 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index 0ab80dc42e..855d32fce7 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "example-app", - "version": "0.2.100-next.1", + "version": "0.2.100-next.2", "backstage": { "role": "frontend" }, diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 4098230493..df526b2b00 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/cli +## 0.27.0-next.2 + +### Patch Changes + +- b2d97fd: Fixing loading of additional config files with new `ConfigSources` +- adabb40: New command now supports setting package license +- Updated dependencies + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0-next.1 + - @backstage/errors@1.2.4 + - @backstage/eslint-plugin@0.1.8 + - @backstage/integration@1.14.0-next.0 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + ## 0.27.0-next.1 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 0b746fbaf8..768851ebc2 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/cli", - "version": "0.27.0-next.1", + "version": "0.27.0-next.2", "description": "CLI for developing Backstage plugins and apps", "backstage": { "role": "cli" diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index 24176ccf48..85587de268 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/create-app +## 0.5.18-next.2 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.14 + ## 0.5.18-next.1 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 848b6640e7..9128438e8e 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.18-next.1", + "version": "0.5.18-next.2", "publishConfig": { "access": "public" }, diff --git a/packages/e2e-test/CHANGELOG.md b/packages/e2e-test/CHANGELOG.md index f3294c82e0..488f48fd4b 100644 --- a/packages/e2e-test/CHANGELOG.md +++ b/packages/e2e-test/CHANGELOG.md @@ -1,5 +1,14 @@ # e2e-test +## 0.2.19-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.18-next.2 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + ## 0.2.19-next.1 ### Patch Changes diff --git a/packages/e2e-test/package.json b/packages/e2e-test/package.json index 22424cac2f..190d66c7b3 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.19-next.1", + "version": "0.2.19-next.2", "private": true, "backstage": { "role": "cli" diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md index af755dd888..728145048a 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.99-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.27.0-next.2 + - @backstage/app-defaults@1.5.10-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/test-utils@1.5.10-next.1 + - @backstage/theme@0.5.6 + - @backstage/plugin-catalog@1.21.2-next.1 + - @backstage/plugin-techdocs@1.10.8-next.1 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + ## 0.2.99-next.1 ### Patch Changes diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json index bbe4ef9aed..09635b74ed 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.99-next.1", + "version": "0.2.99-next.2", "private": true, "backstage": { "role": "frontend" diff --git a/plugins/catalog-graph/CHANGELOG.md b/plugins/catalog-graph/CHANGELOG.md index 566420808c..5648055a3e 100644 --- a/plugins/catalog-graph/CHANGELOG.md +++ b/plugins/catalog-graph/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-graph +## 0.4.8-next.2 + +### Patch Changes + +- 4a529c2: Use `entityPresentationApi` for the node title and the icon. +- Updated dependencies + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-react@1.12.3-next.1 + ## 0.4.8-next.1 ### Patch Changes diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json index 35508194a6..04fe835f5c 100644 --- a/plugins/catalog-graph/package.json +++ b/plugins/catalog-graph/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-graph", - "version": "0.4.8-next.1", + "version": "0.4.8-next.2", "backstage": { "role": "frontend-plugin", "pluginId": "catalog-graph", From 6816ab572ae887808fa37aee29ca8b6a091bd4c0 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 31 Jul 2024 10:31:08 +0200 Subject: [PATCH 499/510] chore: added a test Signed-off-by: blam --- .../wiring/createExtensionBlueprint.test.tsx | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx index 8b364f33c1..f57cc2b70e 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx @@ -19,6 +19,8 @@ import { coreExtensionData } from './coreExtensionData'; import { createExtensionBlueprint } from './createExtensionBlueprint'; import { createExtensionTester } from '@backstage/frontend-test-utils'; import { createExtensionDataRef } from './createExtensionDataRef'; +import { createExtensionInput } from './createExtensionInput'; +import { RouteRef } from '../routing'; function unused(..._any: any[]) {} @@ -242,4 +244,47 @@ describe('createExtensionBlueprint', () => { }, }).render(); }); + + it('should allow getting inputs properly', () => { + createExtensionBlueprint({ + kind: 'test-extension', + attachTo: { id: 'test', input: 'default' }, + inputs: { + test: createExtensionInput( + [ + coreExtensionData.routeRef, + coreExtensionData.reactElement.optional(), + ], + { singleton: true }, + ), + }, + output: [ + coreExtensionData.reactElement, + coreExtensionData.routeRef.optional(), + ], + factory(_, { inputs }) { + const route = inputs.test.get(coreExtensionData.routeRef); + const optional = inputs.test.get(coreExtensionData.reactElement); + + // @ts-expect-error + const optional2: JSX.Element = optional; + const optional3: JSX.Element | undefined = optional; + + const route2: RouteRef = route; + + unused(optional2, optional3, route2); + + if (!route) { + return [coreExtensionData.reactElement(
      )]; + } + + return [ + coreExtensionData.reactElement(
      ), + coreExtensionData.routeRef(route), + ]; + }, + }); + + expect(true).toBe(true); + }); }); From 80a0737fac6d0540ee7715b87726393de891e19b Mon Sep 17 00:00:00 2001 From: djamaile Date: Wed, 31 Jul 2024 14:25:16 +0200 Subject: [PATCH 500/510] chore: add packages config to backend-app-api Signed-off-by: djamaile --- .changeset/tricky-ducks-juggle.md | 5 +++++ packages/backend-app-api/config.d.ts | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 .changeset/tricky-ducks-juggle.md diff --git a/.changeset/tricky-ducks-juggle.md b/.changeset/tricky-ducks-juggle.md new file mode 100644 index 0000000000..7f91c978a2 --- /dev/null +++ b/.changeset/tricky-ducks-juggle.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-app-api': patch +--- + +Add `packages` to backend-app-api configuration schema diff --git a/packages/backend-app-api/config.d.ts b/packages/backend-app-api/config.d.ts index a23bca447b..966ca61ae0 100644 --- a/packages/backend-app-api/config.d.ts +++ b/packages/backend-app-api/config.d.ts @@ -287,6 +287,11 @@ export interface Config { } >; }; + /** + * @visibility frontend + * @deepVisibility frontend + */ + packages?: 'all' | { include?: string[]; exclude?: string[] }; }; /** Discovery options. */ From 87c872030031eaebb1465454596165172ff47298 Mon Sep 17 00:00:00 2001 From: Djam Date: Wed, 31 Jul 2024 14:33:37 +0200 Subject: [PATCH 501/510] fix: remove frontend visibility Signed-off-by: Djam --- packages/backend-app-api/config.d.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/backend-app-api/config.d.ts b/packages/backend-app-api/config.d.ts index 966ca61ae0..e94da62b77 100644 --- a/packages/backend-app-api/config.d.ts +++ b/packages/backend-app-api/config.d.ts @@ -287,10 +287,6 @@ export interface Config { } >; }; - /** - * @visibility frontend - * @deepVisibility frontend - */ packages?: 'all' | { include?: string[]; exclude?: string[] }; }; From 592e742f9b03d9cdf9d0b940f2fd47e9fdc5a496 Mon Sep 17 00:00:00 2001 From: Ben Lambert Date: Wed, 31 Jul 2024 14:34:51 +0200 Subject: [PATCH 502/510] Update v1.30.0-next.1-changelog.md Fixing changelog Signed-off-by: Ben Lambert --- docs/releases/v1.30.0-next.1-changelog.md | 1891 +-------------------- 1 file changed, 1 insertion(+), 1890 deletions(-) diff --git a/docs/releases/v1.30.0-next.1-changelog.md b/docs/releases/v1.30.0-next.1-changelog.md index 2f7153fe5c..efd746686b 100644 --- a/docs/releases/v1.30.0-next.1-changelog.md +++ b/docs/releases/v1.30.0-next.1-changelog.md @@ -4,10 +4,6 @@ Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.30.0-next.1](h ## @backstage/core-app-api@1.14.2-next.0 -# @backstage/core-app-api - -## 1.14.1-next.0 - ### Patch Changes - 9a46a81: The request to delete the session cookie when running the app in protected mode is now done with a plain `fetch` rather than `FetchApi`. This fixes a bug where the app would immediately try to sign-in again when removing the cookie during logout. @@ -16,1892 +12,7 @@ Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.30.0-next.1](h - @backstage/core-plugin-api@1.9.3 - @backstage/types@1.1.1 - @backstage/version-bridge@1.0.8 - -## 1.14.0 - -### Minor Changes - -- d3c39fc: Allow for the disabling of external routes through config, which was rendered impossible after the introduction of default targets. - - ```yaml - app: - routes: - bindings: - # This has the effect of removing the button for registering new - # catalog entities in the scaffolder template list view - scaffolder.registerComponent: false - ``` - -### Patch Changes - -- db2e2d5: Updated config schema to support app.routes.bindings -- Updated dependencies - - @backstage/config@1.2.0 - - @backstage/core-plugin-api@1.9.3 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.8 - -## 1.13.1-next.1 - -### Patch Changes - -- db2e2d5: Updated config schema to support app.routes.bindings -- Updated dependencies - - @backstage/core-plugin-api@1.9.3 - - @backstage/config@1.2.0 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.8 - -## 1.13.0-next.0 - -### Minor Changes - -- d3c39fc: Allow for the disabling of external routes through config, which was rendered impossible after the introduction of default targets. - - ```yaml - app: - routes: - bindings: - # This has the effect of removing the button for registering new - # catalog entities in the scaffolder template list view - scaffolder.registerComponent: false - ``` - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.9.3 - - @backstage/config@1.2.0 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.8 - -## 1.12.6 - -### Patch Changes - -- 35fbe09: Added support for configuration of route bindings through static configuration, and default targets for external route refs. - - In addition to configuring route bindings through code, it is now also possible to configure route bindings under the `app.routes.bindings` key, for example: - - ```yaml - app: - routes: - bindings: - catalog.createComponent: catalog-import.importPage - ``` - - Each key in the route binding object is of the form `.`, where the route name is key used in the `externalRoutes` object passed to `createPlugin`. The value is of the same form, but with the name taken from the plugin `routes` option instead. - - The equivalent of the above configuration in code is the following: - - ```ts - const app = createApp({ - // ... - bindRoutes({ bind }) { - bind(catalogPlugin.externalRoutes, { - createComponent: catalogImportPlugin.routes.importPage, - }); - }, - }); - ``` - -- Updated dependencies - - @backstage/core-plugin-api@1.9.3 - - @backstage/config@1.2.0 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.8 - -## 1.12.6-next.0 - -### Patch Changes - -- 35fbe09: Added support for configuration of route bindings through static configuration, and default targets for external route refs. - - In addition to configuring route bindings through code, it is now also possible to configure route bindings under the `app.routes.bindings` key, for example: - - ```yaml - app: - routes: - bindings: - catalog.createComponent: catalog-import.importPage - ``` - - Each key in the route binding object is of the form `.`, where the route name is key used in the `externalRoutes` object passed to `createPlugin`. The value is of the same form, but with the name taken from the plugin `routes` option instead. - - The equivalent of the above configuration in code is the following: - - ```ts - const app = createApp({ - // ... - bindRoutes({ bind }) { - bind(catalogPlugin.externalRoutes, { - createComponent: catalogImportPlugin.routes.importPage, - }); - }, - }); - ``` - -- Updated dependencies - - @backstage/core-plugin-api@1.9.3-next.0 - - @backstage/config@1.2.0 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.8 - -## 1.12.5 - -### Patch Changes - -- 1bed9a3: The Backstage identity session expiration check will no longer fall back to using the provider expiration. This was introduced to smooth out the rollout of Backstage release 1.18, and is no longer needed. - -## 1.12.4 - -### Patch Changes - -- c884b9a: The app is now aware of if it is being served from the `app-backend` with a separate public and protected bundles. When in protected mode the app will now continuously refresh the session cookie, as well as clear the cookie if the user signs out. -- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. -- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.9.2 - - @backstage/version-bridge@1.0.8 - - @backstage/config@1.2.0 - - @backstage/types@1.1.1 - -## 1.12.4-next.0 - -### Patch Changes - -- c884b9a: The app is now aware of if it is being served from the `app-backend` with a separate public and protected bundles. When in protected mode the app will now continuously refresh the session cookie, as well as clear the cookie if the user signs out. -- Updated dependencies - - @backstage/config@1.2.0 - - @backstage/core-plugin-api@1.9.1 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.7 - -## 1.12.3 - -### Patch Changes - -- e8f026a: Use ESM exports of react-use library -- Updated dependencies - - @backstage/core-plugin-api@1.9.1 - - @backstage/config@1.2.0 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.7 - -## 1.12.2 - -### Patch Changes - -- e8f026a: Use ESM exports of react-use library -- Updated dependencies - - @backstage/core-plugin-api@1.9.1 - - @backstage/config@1.2.0 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.7 - -## 1.12.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.2.0 - - @backstage/core-plugin-api@1.9.1 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.7 - -## 1.12.1-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.2.0-next.1 - - @backstage/core-plugin-api@1.9.1-next.1 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.7 - -## 1.12.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.2-next.0 - - @backstage/core-plugin-api@1.9.1-next.0 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.7 - -## 1.12.0 - -### Minor Changes - -- f919be9: Added a utility API for VMware Cloud auth; the API ref is available in the - `@backstage/core-plugin-api` and `@backstage/frontend-plugin-api` packages, the - implementation is in `@backstage/core-app-api` and a factory has been added to - `@backstage/app-defaults`. - -### Patch Changes - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- 8fe56a8: Widen `@types/react` dependency range to include version 18. -- 7da67ce: Change `defaultScopes` for Bitbucket auth from invalid `team` to `account`. -- Updated dependencies - - @backstage/core-plugin-api@1.9.0 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.7 - -## 1.12.0-next.1 - -### Minor Changes - -- f919be9: Added a utility API for VMware Cloud auth; the API ref is available in the - `@backstage/core-plugin-api` and `@backstage/frontend-plugin-api` packages, the - implementation is in `@backstage/core-app-api` and a factory has been added to - `@backstage/app-defaults`. - -### Patch Changes - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- 8fe56a8: Widen `@types/react` dependency range to include version 18. -- Updated dependencies - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.7 - -## 1.11.4-next.0 - -### Patch Changes - -- 7da67ce: Change `defaultScopes` for Bitbucket auth from invalid `team` to `account`. -- Updated dependencies - - @backstage/core-plugin-api@1.8.3-next.0 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.7 - -## 1.11.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.7 - -## 1.11.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2-next.0 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.7 - -## 1.11.2 - -### Patch Changes - -- 3e358b0: Added deprecation warning for React Router v6 beta, please make sure you have migrated your apps to use React Router v6 stable as support for the beta version will be removed. See the [migration tutorial](https://backstage.io/docs/tutorials/react-router-stable-migration) for more information. -- 0cbb03b: Fixing regular expression ReDoS with zod packages. Upgrading to latest. ref: -- Updated dependencies - - @backstage/core-plugin-api@1.8.1 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.7 - -## 1.11.2-next.1 - -### Patch Changes - -- 3e358b0dff: Added deprecation warning for React Router v6 beta, please make sure you have migrated your apps to use React Router v6 stable as support for the beta version will be removed. See the [migration tutorial](https://backstage.io/docs/tutorials/react-router-stable-migration) for more information. -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.7 - -## 1.11.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.0 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.7 - -## 1.11.1 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- 89d13e5618: Add current and default scopes when refreshing session -- 9ab0572217: Add component data `core.type` marker for `AppRouter` and `FlatRoutes`. -- Updated dependencies - - @backstage/core-plugin-api@1.8.0 - - @backstage/version-bridge@1.0.7 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - -## 1.11.1-next.0 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- 89d13e5618: Add current and default scopes when refreshing session -- 9ab0572217: Add component data `core.type` marker for `AppRouter` and `FlatRoutes`. -- Updated dependencies - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/version-bridge@1.0.7-next.0 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - -## 1.11.0 - -### Minor Changes - -- c9d9bfeca2: URL encode some well known unsafe characters in `RouteResolver` (and therefore `useRouteRef`) - -### Patch Changes - -- 29e4d8b76b: Fixed bug in `AppRouter` to determine the correct `signOutTargetUrl` if `app.baseUrl` contains a `basePath` -- acca17e91a: Wrap entire app in ``, enabling support for using translations outside plugins. -- 1a0616fa10: Add missing resource and template app icons -- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. -- f95af4e540: Updated dependency `@testing-library/dom` to `^9.0.0`. -- f1b349cfba: Fixed a bug in `TranslationApi` implementation where in some cases it wouldn't notify subscribers of language changes. -- Updated dependencies - - @backstage/core-plugin-api@1.7.0 - - @backstage/version-bridge@1.0.6 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - -## 1.11.0-next.2 - -### Minor Changes - -- c9d9bfeca2: URL encode some well known unsafe characters in `RouteResolver` (and therefore `useRouteRef`) - -### Patch Changes - -- acca17e91a: Wrap entire app in ``, enabling support for using translations outside plugins. -- Updated dependencies - - @backstage/core-plugin-api@1.7.0-next.1 - - @backstage/config@1.1.1-next.0 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.5 - -## 1.10.1-next.1 - -### Patch Changes - -- 1a0616fa10: Add missing resource and template app icons -- Updated dependencies - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/config@1.1.0 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.5 - -## 1.10.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/config@1.1.0 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.5 - -## 1.10.0 - -### Minor Changes - -- 18619f793c94: Fixed two bugs in how the `OAuth2Session` type represents the underlying data. The `expiresAt` and `backstageIdentity` are now both optional, since that's what they are in practice. This is not considered a breaking change since it was effectively a bug in the modelling of the state that this type represents, and the type was not used in any other external contract. -- 18619f793c94: The `OAuth` class which is used by all OAuth providers will now consider both the session expiration of both the Backstage identity as well as the upstream identity provider, and refresh the session with either of them is about to expire. -- 6e30769cc627: Introduced experimental support for internationalization. - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- 9fe827b380e1: Internal refactor -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/config@1.1.0 - - @backstage/core-plugin-api@1.6.0 - - @backstage/types@1.1.1 - - @backstage/version-bridge@1.0.5 - -## 1.10.0-next.3 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- 9fe827b380e1: Internal refactor -- Updated dependencies - - @backstage/config@1.1.0-next.2 - - @backstage/core-plugin-api@1.6.0-next.3 - - @backstage/types@1.1.1-next.0 - - @backstage/version-bridge@1.0.5-next.0 - -## 1.10.0-next.2 - -### Minor Changes - -- 6e30769cc627: Introduced experimental support for internationalization. - -### Patch Changes - -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/core-plugin-api@1.6.0-next.2 - - @backstage/config@1.1.0-next.1 - - @backstage/types@1.1.0 - - @backstage/version-bridge@1.0.4 - -## 1.10.0-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.0 - - @backstage/core-plugin-api@1.6.0-next.1 - - @backstage/types@1.1.0 - - @backstage/version-bridge@1.0.4 - -## 1.10.0-next.0 - -### Minor Changes - -- 18619f793c94: Fixed two bugs in how the `OAuth2Session` type represents the underlying data. The `expiresAt` and `backstageIdentity` are now both optional, since that's what they are in practice. This is not considered a breaking change since it was effectively a bug in the modelling of the state that this type represents, and the type was not used in any other external contract. -- 18619f793c94: The `OAuth` class which is used by all OAuth providers will now consider both the session expiration of both the Backstage identity as well as the upstream identity provider, and refresh the session with either of them is about to expire. - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.6.0-next.0 - - @backstage/config@1.0.8 - - @backstage/types@1.1.0 - - @backstage/version-bridge@1.0.4 - -## 1.9.1 - -### Patch Changes - -- 9ae4e7e63836: Fixed a bug that could cause `navigate` analytics events to be misattributed to the plugin mounted on the root route (e.g. the `home` plugin at `/`) when the route that was navigated to wasn't associated with a routable extension. -- Updated dependencies - - @backstage/core-plugin-api@1.5.3 - - @backstage/config@1.0.8 - - @backstage/types@1.1.0 - - @backstage/version-bridge@1.0.4 - -## 1.9.1-next.0 - -### Patch Changes - -- 9ae4e7e63836: Fixed a bug that could cause `navigate` analytics events to be misattributed to the plugin mounted on the root route (e.g. the `home` plugin at `/`) when the route that was navigated to wasn't associated with a routable extension. -- Updated dependencies - - @backstage/core-plugin-api@1.5.3 - - @backstage/config@1.0.8 - - @backstage/types@1.1.0 - - @backstage/version-bridge@1.0.4 - -## 1.9.0 - -### Minor Changes - -- a77ddf7ccd71: add login in popup options to config popup width and height - -### Patch Changes - -- 8174cf4c0edf: Fixing MUI / Material UI references -- Updated dependencies - - @backstage/core-plugin-api@1.5.3 - - @backstage/config@1.0.8 - - @backstage/types@1.1.0 - - @backstage/version-bridge@1.0.4 - -## 1.8.2-next.1 - -### Patch Changes - -- 8174cf4c0edf: Fixing MUI / Material UI references -- Updated dependencies - - @backstage/core-plugin-api@1.5.3-next.1 - - @backstage/config@1.0.8 - - @backstage/types@1.1.0 - - @backstage/version-bridge@1.0.4 - -## 1.8.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.3-next.0 - - @backstage/config@1.0.8 - -## 1.8.1 - -### Patch Changes - -- 12adfbc8fe2d: Fixed a bug that prevented accurate plugin and route data from being applied to `navigate` analytics events when users visited pages constructed with ``, ``, and similar components that are used to gather one or more routable extensions under a given path. -- ac677bc30ae0: Expose discovery.endpoints configuration to use FrontendHostDiscovery -- 74b216ee4e50: Add `PropsWithChildren` to usages of `ComponentType`, in preparation for React 18 where the children are no longer implicit. -- Updated dependencies - - @backstage/core-plugin-api@1.5.2 - - @backstage/types@1.1.0 - - @backstage/config@1.0.8 - - @backstage/version-bridge@1.0.4 - -## 1.8.1-next.0 - -### Patch Changes - -- 74b216ee4e50: Add `PropsWithChildren` to usages of `ComponentType`, in preparation for React 18 where the children are no longer implicit. -- Updated dependencies - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/config@1.0.7 - - @backstage/types@1.0.2 - - @backstage/version-bridge@1.0.4 - -## 1.8.0 - -### Minor Changes - -- c89437db899: The analytics' `navigate` event will now include the route parameters as attributes of the navigate event - -### Patch Changes - -- b645d70034a: Fixed a bug in the Azure auth provider which prevented getting access tokens with multiple scopes for one resource -- 42d817e76ab: Added `FrontendHostDiscovery` for config driven discovery implementation -- Updated dependencies - - @backstage/config@1.0.7 - - @backstage/core-plugin-api@1.5.1 - - @backstage/types@1.0.2 - - @backstage/version-bridge@1.0.4 - -## 1.8.0-next.1 - -### Minor Changes - -- c89437db899: The analytics' `navigate` event will now include the route parameters as attributes of the navigate event - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.1 - - @backstage/config@1.0.7 - -## 1.7.1-next.0 - -### Patch Changes - -- 42d817e76ab: Added `FrontendHostDiscovery` for config driven discovery implementation -- Updated dependencies - - @backstage/core-plugin-api@1.5.1 - - @backstage/config@1.0.7 - - @backstage/types@1.0.2 - - @backstage/version-bridge@1.0.4 - -## 1.7.0 - -### Minor Changes - -- 7908d72e033: Introduce a new global config parameter, `enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. -- c15e0cedbe1: The `AuthConnector` interface now supports specifying a set of scopes when - refreshing a session. The `DefaultAuthConnector` implementation passes the - `scope` query parameter to the auth-backend plugin appropriately. The - `RefreshingAuthSessionManager` passes any scopes in its `GetSessionRequest` - appropriately. - -### Patch Changes - -- 1e4f5e91b8e: Bump `zod` and `zod-to-json-schema` dependencies. -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-plugin-api@1.5.1 - - @backstage/version-bridge@1.0.4 - - @backstage/config@1.0.7 - - @backstage/types@1.0.2 - -## 1.7.0-next.3 - -### Minor Changes - -- c15e0cedbe1: The `AuthConnector` interface now supports specifying a set of scopes when - refreshing a session. The `DefaultAuthConnector` implementation passes the - `scope` query parameter to the auth-backend plugin appropriately. The - `RefreshingAuthSessionManager` passes any scopes in its `GetSessionRequest` - appropriately. - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.0.7 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/types@1.0.2 - - @backstage/version-bridge@1.0.4-next.0 - -## 1.7.0-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/config@1.0.7 - - @backstage/types@1.0.2 - - @backstage/version-bridge@1.0.4-next.0 - -## 1.7.0-next.1 - -### Patch Changes - -- 1e4f5e91b8e: Bump `zod` and `zod-to-json-schema` dependencies. -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-plugin-api@1.5.1-next.0 - - @backstage/version-bridge@1.0.4-next.0 - - @backstage/config@1.0.7 - - @backstage/types@1.0.2 - -## 1.7.0-next.0 - -### Minor Changes - -- 7908d72e033: Introduce a new global config parameter, `enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.0 - - @backstage/config@1.0.7 - - @backstage/types@1.0.2 - - @backstage/version-bridge@1.0.3 - -## 1.6.0 - -### Minor Changes - -- 456eaa8cf83: `OAuth2` now gets ID tokens from a session with the `openid` scope explicitly - requested. - - This should not be considered a breaking change, because spec-compliant OIDC - providers will already be returning ID tokens if and only if the `openid` scope - is granted. - - This change makes the dependence explicit, and removes the burden on - OAuth2-based providers which require an ID token (e.g. this is done by various - default [auth handlers](https://backstage.io/docs/auth/identity-resolver/#authhandler)) to add - `openid` to their default scopes. _That_ could carry another indirect benefit: - by removing `openid` from the default scopes for a provider, grants for - resource-specific access tokens can avoid requesting excess ID token-related - scopes. - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.5.0 - - @backstage/config@1.0.7 - - @backstage/types@1.0.2 - - @backstage/version-bridge@1.0.3 - -## 1.6.0-next.2 - -### Minor Changes - -- 456eaa8cf83: `OAuth2` now gets ID tokens from a session with the `openid` scope explicitly - requested. - - This should not be considered a breaking change, because spec-compliant OIDC - providers will already be returning ID tokens if and only if the `openid` scope - is granted. - - This change makes the dependence explicit, and removes the burden on - OAuth2-based providers which require an ID token (e.g. this is done by various - default [auth handlers](https://backstage.io/docs/auth/identity-resolver/#authhandler)) to add - `openid` to their default scopes. _That_ could carry another indirect benefit: - by removing `openid` from the default scopes for a provider, grants for - resource-specific access tokens can avoid requesting excess ID token-related - scopes. - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.0-next.2 - - @backstage/config@1.0.7-next.0 - -## 1.5.1-next.1 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.4.1-next.1 - - @backstage/config@1.0.7-next.0 - - @backstage/types@1.0.2 - - @backstage/version-bridge@1.0.3 - -## 1.5.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.4.1-next.0 - - @backstage/config@1.0.6 - - @backstage/types@1.0.2 - - @backstage/version-bridge@1.0.3 - -## 1.5.0 - -### Minor Changes - -- db10b6ef65: Added a Bitbucket Server Auth Provider and added its API to the app defaults - -### Patch Changes - -- dff4d8ddb1: Fixed an issue where an explicit port the frontend base URL could break the app. -- Updated dependencies - - @backstage/core-plugin-api@1.4.0 - - @backstage/config@1.0.6 - - @backstage/types@1.0.2 - - @backstage/version-bridge@1.0.3 - -## 1.4.1-next.0 - -### Patch Changes - -- dff4d8ddb1: Fixed an issue where an explicit port the frontend base URL could break the app. -- Updated dependencies - - @backstage/config@1.0.6 - - @backstage/core-plugin-api@1.3.0 - - @backstage/types@1.0.2 - - @backstage/version-bridge@1.0.3 - -## 1.4.0 - -### Minor Changes - -- bca8e8b393: Allow defining application level feature flags. See [Feature Flags documentation](https://backstage.io/docs/plugins/feature-flags#in-the-application) for reference. - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.3.0 - - @backstage/config@1.0.6 - - @backstage/types@1.0.2 - - @backstage/version-bridge@1.0.3 - -## 1.4.0-next.1 - -### Minor Changes - -- bca8e8b393: Allow defining application level feature flags. See [Feature Flags documentation](https://backstage.io/docs/plugins/feature-flags#in-the-application) for reference. - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.3.0-next.1 - - @backstage/config@1.0.6-next.0 - - @backstage/types@1.0.2 - - @backstage/version-bridge@1.0.3 - -## 1.3.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.0.6-next.0 - - @backstage/core-plugin-api@1.2.1-next.0 - - @backstage/types@1.0.2 - - @backstage/version-bridge@1.0.3 - -## 1.3.0 - -### Minor Changes - -- e0d9c9559a: Added a new `AppRouter` component and `app.createRoot()` method that replaces `app.getRouter()` and `app.getProvider()`, which are now deprecated. The new `AppRouter` component is a drop-in replacement for the old router component, while the new `app.createRoot()` method is used instead of the old provider component. - - An old app setup might look like this: - - ```tsx - const app = createApp(/* ... */); - - const AppProvider = app.getProvider(); - const AppRouter = app.getRouter(); - - const routes = ...; - - const App = () => ( - - - - - {routes} - - - ); - - export default App; - ``` - - With these new APIs, the setup now looks like this: - - ```tsx - import { AppRouter } from '@backstage/core-app-api'; - - const app = createApp(/* ... */); - - const routes = ...; - - export default app.createRoot( - <> - - - - {routes} - - , - ); - ``` - - Note that `app.createRoot()` accepts a React element, rather than a component. - -### Patch Changes - -- d3fea4ae0a: Internal fixes to avoid implicit usage of globals -- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries -- b4b5b02315: Tweak feature flag registration so that it happens immediately before the first rendering of the app, rather than just after. -- 6870b43dd1: Fix for the automatic rewriting of base URLs. -- 203271b746: Prevent duplicate feature flag components from rendering in the settings when using components -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. -- c3fa90e184: Updated dependency `zen-observable` to `^0.10.0`. -- 8015ff1258: Tweaked wording to use inclusive terminology -- 653d7912ac: Made `WebStorage` notify its subscribers when `localStorage` values change in other tabs/windows -- 63310e3987: Apps will now rewrite the `app.baseUrl` configuration to match the current `location.origin`. The `backend.baseUrl` will also be rewritten in the same way when the `app.baseUrl` and `backend.baseUrl` have matching origins. This will reduce the need for separate frontend builds for different environments. -- Updated dependencies - - @backstage/core-plugin-api@1.2.0 - - @backstage/version-bridge@1.0.3 - - @backstage/types@1.0.2 - - @backstage/config@1.0.5 - -## 1.3.0-next.4 - -### Minor Changes - -- e0d9c9559a: Added a new `AppRouter` component and `app.createRoot()` method that replaces `app.getRouter()` and `app.getProvider()`, which are now deprecated. The new `AppRouter` component is a drop-in replacement for the old router component, while the new `app.createRoot()` method is used instead of the old provider component. - - An old app setup might look like this: - - ```tsx - const app = createApp(/* ... */); - - const AppProvider = app.getProvider(); - const AppRouter = app.getRouter(); - - const routes = ...; - - const App = () => ( - - - - - {routes} - - - ); - - export default App; - ``` - - With these new APIs, the setup now looks like this: - - ```tsx - import { AppRouter } from '@backstage/core-app-api'; - - const app = createApp(/* ... */); - - const routes = ...; - - export default app.createRoot( - <> - - - - {routes} - - , - ); - ``` - - Note that `app.createRoot()` accepts a React element, rather than a component. - -### Patch Changes - -- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries -- Updated dependencies - - @backstage/config@1.0.5-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/types@1.0.2-next.1 - - @backstage/version-bridge@1.0.3-next.0 - -## 1.2.1-next.3 - -### Patch Changes - -- 6870b43dd1: Fix for the automatic rewriting of base URLs. -- 653d7912ac: Made `WebStorage` notify its subscribers when `localStorage` values change in other tabs/windows -- Updated dependencies - - @backstage/config@1.0.5-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/types@1.0.2-next.1 - - @backstage/version-bridge@1.0.3-next.0 - -## 1.2.1-next.2 - -### Patch Changes - -- b4b5b02315: Tweak feature flag registration so that it happens immediately before the first rendering of the app, rather than just after. -- 203271b746: Prevent duplicate feature flag components from rendering in the settings when using components -- 8015ff1258: Tweaked wording to use inclusive terminology -- 63310e3987: Apps will now rewrite the `app.baseUrl` configuration to match the current `location.origin`. The `backend.baseUrl` will also be rewritten in the same way when the `app.baseUrl` and `backend.baseUrl` have matching origins. This will reduce the need for separate frontend builds for different environments. -- Updated dependencies - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/config@1.0.5-next.1 - - @backstage/types@1.0.2-next.1 - - @backstage/version-bridge@1.0.3-next.0 - -## 1.2.1-next.1 - -### Patch Changes - -- d3fea4ae0a: Internal fixes to avoid implicit usage of globals -- c3fa90e184: Updated dependency `zen-observable` to `^0.10.0`. -- Updated dependencies - - @backstage/version-bridge@1.0.3-next.0 - - @backstage/core-plugin-api@1.1.1-next.1 - - @backstage/types@1.0.2-next.1 - - @backstage/config@1.0.5-next.1 - -## 1.2.1-next.0 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.1.1-next.0 - - @backstage/types@1.0.2-next.0 - - @backstage/config@1.0.5-next.0 - - @backstage/version-bridge@1.0.2 - -## 1.2.0 - -### Minor Changes - -- 9b737e5f2e: Updated the React Router wiring to make use of the new `basename` property of the router components in React Router v6 stable. To implement this, a new optional `basename` property has been added to the `Router` app component, which can be forwarded to the concrete router implementation in order to support this new behavior. This is done by default in any app that does not have a `Router` component override. -- 127fcad26d: Deprecated the `homepage` config as the component that used it - `HomepageTimer` - has been removed and replaced by the `HeaderWorldClock` in the home plugin - -### Patch Changes - -- Updated dependencies - - @backstage/version-bridge@1.0.2 - - @backstage/core-plugin-api@1.1.0 - - @backstage/types@1.0.1 - - @backstage/config@1.0.4 - -## 1.2.0-next.0 - -### Minor Changes - -- 9b737e5f2e: Updated the React Router wiring to make use of the new `basename` property of the router components in React Router v6 stable. To implement this, a new optional `basename` property has been added to the `Router` app component, which can be forwarded to the concrete router implementation in order to support this new behavior. This is done by default in any app that does not have a `Router` component override. -- 127fcad26d: Deprecated the `homepage` config as the component that used it - `HomepageTimer` - has been removed and replaced by the `HeaderWorldClock` in the home plugin - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/types@1.0.1-next.0 - - @backstage/config@1.0.4-next.0 - - @backstage/version-bridge@1.0.1 - -## 1.1.1 - -### Patch Changes - -- 27e6404aba: Fixed a bug where gathered index routes would fail to bind routable extensions. This would typically show up when placing a routable extension in the entity page overview tab. -- Updated dependencies - - @backstage/core-plugin-api@1.0.7 - - @backstage/config@1.0.3 - - @backstage/types@1.0.0 - - @backstage/version-bridge@1.0.1 - -## 1.1.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.0.3-next.2 - - @backstage/core-plugin-api@1.0.7-next.2 - - @backstage/types@1.0.0 - - @backstage/version-bridge@1.0.1 - -## 1.1.1-next.1 - -### Patch Changes - -- 27e6404aba: Fixed a bug where gathered index routes would fail to bind routable extensions. This would typically show up when placing a routable extension in the entity page overview tab. -- Updated dependencies - - @backstage/core-plugin-api@1.0.7-next.1 - - @backstage/config@1.0.3-next.1 - - @backstage/types@1.0.0 - - @backstage/version-bridge@1.0.1 - -## 1.1.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.0.3-next.0 - - @backstage/core-plugin-api@1.0.7-next.0 - - @backstage/types@1.0.0 - - @backstage/version-bridge@1.0.1 - -## 1.1.0 - -### Minor Changes - -- a448fea691: Updated the routing system to be compatible with React Router v6 stable. - -### Patch Changes - -- 817f3196f6: Updated React Router dependencies to be peer dependencies. - -- f9ec4e46e3: When using React Router v6 stable, it is now possible for components within the `Route` element tree to have `path` props, although they will be ignored. - -- 7d47def9c4: Removed dependency on `@types/jest`. - -- 744fea158b: Added `getSystemIcons()` function to the `AppContext` available through `useApp` that will pull a list of all the icons that have been registered in the App. - -- 667d917488: Updated dependency `msw` to `^0.47.0`. - -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. - -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. - -- 8448b53dd6: Clarify that the `WebStorage` observable returns `JsonValue` items. - -- 70299c99d5: Updated `FlatRoutes` to be compatible with React Router v6 stable. - -- e9d40ebf54: If you'd like to send analytics events to multiple implementations, you may now - do so using the `MultipleAnalyticsApi` implementation provided by this package. - - ```tsx - import { MultipleAnalyticsApi } from '@backstage/core-app-api'; - import { - analyticsApiRef, - configApiRef, - storageApiRef, - identityApiRef, - } from '@internal/backstage/core-plugin-api'; - import { CustomAnalyticsApi } from '@internal/analytics'; - import { VendorAnalyticsApi } from '@vendor/analytics'; - - createApiFactory({ - api: analyticsApiRef, - deps: { configApi: configApiRef, identityApi: identityApiRef, storageApi: storageApiRef }, - factory: ({ configApi, identityApi, storageApi }) => - MultipleAnalyticsApi.fromApis([ - VendorAnalyticsApi.fromConfig(configApi, { identityApi }), - CustomAnalyticsApi.fromConfig(configApi, { identityApi, storageApi }), - ]), - }), - ``` - -- Updated dependencies - - @backstage/core-plugin-api@1.0.6 - - @backstage/config@1.0.2 - -## 1.1.0-next.3 - -### Patch Changes - -- 7d47def9c4: Removed dependency on `@types/jest`. -- Updated dependencies - - @backstage/config@1.0.2-next.0 - - @backstage/core-plugin-api@1.0.6-next.3 - -## 1.1.0-next.2 - -### Patch Changes - -- f9ec4e46e3: When using React Router v6 stable, it is now possible for components within the `Route` element tree to have `path` props, although they will be ignored. - -- 667d917488: Updated dependency `msw` to `^0.47.0`. - -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. - -- e9d40ebf54: If you'd like to send analytics events to multiple implementations, you may now - do so using the `MultipleAnalyticsApi` implementation provided by this package. - - ```tsx - import { MultipleAnalyticsApi } from '@backstage/core-app-api'; - import { - analyticsApiRef, - configApiRef, - storageApiRef, - identityApiRef, - } from '@internal/backstage/core-plugin-api'; - import { CustomAnalyticsApi } from '@internal/analytics'; - import { VendorAnalyticsApi } from '@vendor/analytics'; - - createApiFactory({ - api: analyticsApiRef, - deps: { configApi: configApiRef, identityApi: identityApiRef, storageApi: storageApiRef }, - factory: ({ configApi, identityApi, storageApi }) => - MultipleAnalyticsApi.fromApis([ - VendorAnalyticsApi.fromConfig(configApi, { identityApi }), - CustomAnalyticsApi.fromConfig(configApi, { identityApi, storageApi }), - ]), - }), - ``` - -- Updated dependencies - - @backstage/core-plugin-api@1.0.6-next.2 - -## 1.1.0-next.1 - -### Minor Changes - -- a448fea691: Updated the routing system to be compatible with React Router v6 stable. - -### Patch Changes - -- 817f3196f6: Updated React Router dependencies to be peer dependencies. -- 70299c99d5: Updated `FlatRoutes` to be compatible with React Router v6 stable. -- Updated dependencies - - @backstage/core-plugin-api@1.0.6-next.1 - -## 1.0.6-next.0 - -### Patch Changes - -- 744fea158b: Added `getSystemIcons()` function to the `AppContext` available through `useApp` that will pull a list of all the icons that have been registered in the App. -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.6-next.0 - -## 1.0.5 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.0.5 - -## 1.0.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.0.5-next.0 - -## 1.0.4 - -### Patch Changes - -- 881fc75a75: Internal tweak removing usage of explicit type parameters for the `BackstagePlugin` type. -- 8fe2357101: The `signOut` method of the `IdentityApi` will now navigate the user back to the base URL of the app as indicated by the `app.baseUrl` config. -- a70869e775: Updated dependency `msw` to `^0.43.0`. -- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.4 - -## 1.0.4-next.1 - -### Patch Changes - -- 881fc75a75: Internal tweak removing usage of explicit type parameters for the `BackstagePlugin` type. -- a70869e775: Updated dependency `msw` to `^0.43.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.4-next.0 - -## 1.0.4-next.0 - -### Patch Changes - -- 8fe2357101: The `signOut` method of the `IdentityApi` will now navigate the user back to the base URL of the app as indicated by the `app.baseUrl` config. - -## 1.0.3 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- 19781483a2: Handle URLs as the first argument to `fetchApi`, when using the `plugin:` protocol -- Updated dependencies - - @backstage/core-plugin-api@1.0.3 - -## 1.0.3-next.0 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.3-next.0 - -## 1.0.2 - -### Patch Changes - -- 1fae1f57c9: Fix SAML session schema to no longer require the (deprecated) id, to unbreak session data storage. -- Updated dependencies - - @backstage/core-plugin-api@1.0.2 - - @backstage/config@1.0.1 - -## 1.0.2-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.0.1-next.0 - - @backstage/core-plugin-api@1.0.2-next.1 - -## 1.0.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.0.2-next.0 - -## 1.0.1 - -### Patch Changes - -- 7c7919777e: build(deps-dev): bump `@testing-library/react-hooks` from 7.0.2 to 8.0.0 -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 3ff2bfb66e: Refactored the route collection logic to prepare for future changes and avoid duplicate element tree traversal for the analytics context. -- a7bb762dab: fixed empty body issue for POST requests using FetchAPI with 'plugin://' prefix -- 230ad0826f: Bump to using `@types/node` v16 -- c47509e1a0: Implemented changes suggested by Deepsource.io including multiple double non-null assertion operators and unexpected awaits for non-promise values. -- Updated dependencies - - @backstage/core-plugin-api@1.0.1 - - @backstage/version-bridge@1.0.1 - -## 1.0.1-next.1 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 3ff2bfb66e: Refactored the route collection logic to prepare for future changes and avoid duplicate element tree traversal for the analytics context. -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/core-plugin-api@1.0.1-next.0 - -## 1.0.1-next.0 - -### Patch Changes - -- a7bb762dab: fixed empty body issue for POST requests using FetchAPI with 'plugin://' prefix -- c47509e1a0: Implemented changes suggested by Deepsource.io including multiple double non-null assertion operators and unexpected awaits for non-promise values. - -## 1.0.0 - -### Major Changes - -- b58c70c223: This package has been promoted to v1.0! To understand how this change affects the package, please check out our [versioning policy](https://backstage.io/docs/overview/versioning-policy). - -### Patch Changes - -- a422d7ce5e: chore(deps): bump `@testing-library/react` from 11.2.6 to 12.1.3 -- f24ef7864e: Minor typo fixes -- Updated dependencies - - @backstage/core-plugin-api@1.0.0 - - @backstage/version-bridge@1.0.0 - - @backstage/config@1.0.0 - - @backstage/types@1.0.0 - -## 0.6.0 - -### Minor Changes - -- bb2bb36651: **BREAKING**: Removed the deprecated `get` method from `StorageAPI` and its implementations, this method has been replaced by the `snapshot` method. The return value from snapshot no longer includes `newValue` which has been replaced by `value`. For getting notified when a value changes, use \`observe# @backstage/core-app-api. -- f3cce3dcf7: **BREAKING**: Removed export of `GithubSession` and `SamlSession` which are only used internally. -- af5eaa87f4: **BREAKING**: Removed deprecated `auth0AuthApiRef`, `oauth2ApiRef`, `samlAuthApiRef` and `oidcAuthApiRef` as these APIs are too generic to be useful. Instructions for how to migrate can be found at . -- dbf84eee55: **BREAKING**: Removed the deprecated `GithubAuth.normalizeScopes` method. - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@0.8.0 - -## 0.5.4 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@0.7.0 - -## 0.5.3 - -### Patch Changes - -- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5 -- c77c5c7eb6: Added `backstage.role` to `package.json` -- Updated dependencies - - @backstage/core-plugin-api@0.6.1 - - @backstage/config@0.1.14 - - @backstage/types@0.1.2 - - @backstage/version-bridge@0.1.2 - -## 0.5.2 - -### Patch Changes - -- 40775bd263: Switched out the `GithubAuth` implementation to use the common `OAuth2` implementation. This relies on the simultaneous change in `@backstage/plugin-auth-backend` that enabled access token storage in cookies rather than the current solution that's based on `LocalStorage`. - - > **NOTE:** Make sure you upgrade the `auth-backend` deployment before or at the same time as you deploy this change. - -## 0.5.2-next.0 - -### Patch Changes - -- 40775bd263: Switched out the `GithubAuth` implementation to use the common `OAuth2` implementation. This relies on the simultaneous change in `@backstage/plugin-auth-backend` that enabled access token storage in cookies rather than the current solution that's based on `LocalStorage`. - - > **NOTE:** Make sure you upgrade the `auth-backend` deployment before or at the same time as you deploy this change. - -## 0.5.1 - -### Patch Changes - -- f959c22787: Asynchronous methods on the identity API can now reliably be called at any time, including early in the bootstrap process or prior to successful sign-in. - - Previously in such situations, a `Tried to access IdentityApi before app was loaded` error would be thrown. Now, those methods will wait and resolve eventually (as soon as a concrete identity API is provided). - -## 0.5.0 - -### Minor Changes - -- ceebe25391: Removed deprecated `SignInResult` type, which was replaced with the new `onSignInSuccess` callback. - -### Patch Changes - -- fb565073ec: Add an `allowUrl` callback option to `FetchMiddlewares.injectIdentityAuth` -- f050eec2c0: Added validation during the application startup that detects if there are any plugins present that have not had their required external routes bound. Failing the validation will cause a hard crash as it is a programmer error. It lets you detect early on that there are dangling routes, rather than having them cause an error later on. -- Updated dependencies - - @backstage/core-plugin-api@0.6.0 - - @backstage/config@0.1.13 - -## 0.5.0-next.0 - -### Minor Changes - -- ceebe25391: Removed deprecated `SignInResult` type, which was replaced with the new `onSignInSuccess` callback. - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@0.6.0-next.0 - - @backstage/config@0.1.13-next.0 - -## 0.4.0 - -### Minor Changes - -- e2eb92c109: Removed previously deprecated `ApiRegistry` export. - -### Patch Changes - -- 34442cd5cf: Fixed an issue where valid SAML and GitHub sessions would be considered invalid and not be stored. - - Deprecated the `SamlSession` and `GithubSession` types. - -- 784d8078ab: Removed direct and transitive Material UI dependencies. - -- Updated dependencies - - @backstage/config@0.1.12 - - @backstage/core-plugin-api@0.5.0 - -## 0.3.1 - -### Patch Changes - -- 4ce51ab0f1: Internal refactor of the `react-use` imports to use `react-use/lib/*` instead. -- Updated dependencies - - @backstage/core-plugin-api@0.4.1 - - @backstage/core-components@0.8.3 - -## 0.3.0 - -### Minor Changes - -- a195284c7b: Updated `WebStorageApi` to reflect the `StorageApi` changes in `@backstage/core-plugin-api`. -- b3605da81c: - Removed deprecated definition `createApp` from `@backstage/core-app-api` which has been replaced by `@backstage/app-defaults#createApp` - - Removed deprecated type `BackstagePluginWithAnyOutput` - - Removed deprecated constructors for `GithubAuth`, `OAuth2`, and `SamlAuth` as the `create` method should be used instead -- 68f8b10ccd: - Removed deprecation configuration option `theme` from `AppTheme` of the `AppThemeApi` - - Removed reference to `theme` in the `app-defaults` default `AppTheme` - - Removed logic in `AppThemeProvider` that creates `ThemeProvider` from `appTheme.theme` - -### Patch Changes - -- 7927005152: Add `FetchApi` and related `fetchApiRef` which implement fetch, with an added Backstage token header when available. -- 518ddc00bc: Schema-validate local storage cached session info on load -- Updated dependencies - - @backstage/app-defaults@0.1.3 - - @backstage/core-plugin-api@0.4.0 - - @backstage/core-components@0.8.2 - -## 0.2.1 - -### Patch Changes - -- c11ce4f552: Deprecated `Auth0Auth`, pointing to using `OAuth2` directly instead. -- 9d6503e86c: Switched out usage of deprecated `OAuthRequestApi` types from `@backstage/core-plugin-api`. -- Updated dependencies - - @backstage/core-plugin-api@0.3.1 - - @backstage/core-components@0.8.1 - -## 0.2.0 - -### Minor Changes - -- a036b65c2f: **BREAKING CHANGE** - - The app `SignInPage` component has been updated to switch out the `onResult` callback for a new `onSignInSuccess` callback. This is an immediate breaking change without any deprecation period, as it was deemed to be the way of making this change that had the lowest impact. - - The new `onSignInSuccess` callback directly accepts an implementation of an `IdentityApi`, rather than a `SignInResult`. The `SignInPage` from `@backstage/core-component` has been updated to fit this new API, and as long as you pass on `props` directly you should not see any breakage. - - However, if you implement your own custom `SignInPage`, then this will be a breaking change and you need to migrate over to using the new callback. While doing so you can take advantage of the `UserIdentity.fromLegacy` helper from `@backstage/core-components` to make the migration simpler by still using the `SignInResult` type. This helper is also deprecated though and is only provided for immediate migration. Long-term it will be necessary to build the `IdentityApi` using for example `UserIdentity.create` instead. - - The following is an example of how you can migrate existing usage immediately using `UserIdentity.fromLegacy`: - - ```ts - onResult(signInResult); - // becomes - onSignInSuccess(UserIdentity.fromLegacy(signInResult)); - ``` - - The following is an example of how implement the new `onSignInSuccess` callback of the `SignInPage` using `UserIdentity.create`: - - ```ts - const identityResponse = await authApi.getBackstageIdentity(); - // Profile is optional and will be removed, but allows the - // synchronous getProfile method of the IdentityApi to be used. - const profile = await authApi.getProfile(); - onSignInSuccess( - UserIdentity.create({ - identity: identityResponse.identity, - authApi, - profile, - }), - ); - ``` - -### Patch Changes - -- cd450844f6: Moved React dependencies to `peerDependencies` and allow both React v16 and v17 to be used. -- dcd1a0c3f4: Minor improvement to the API reports, by not unpacking arguments directly -- Updated dependencies - - @backstage/core-components@0.8.0 - - @backstage/core-plugin-api@0.3.0 - - @backstage/app-defaults@0.1.2 - - @backstage/version-bridge@0.1.1 - -## 0.1.24 - -### Patch Changes - -- 0e7f256034: Fixed a bug where `useRouteRef` would fail in situations where relative navigation was needed and the app was is mounted on a sub-path. This would typically show up as a failure to navigate to a tab on an entity page. -- Updated dependencies - - @backstage/core-components@0.7.6 - - @backstage/theme@0.2.14 - - @backstage/core-plugin-api@0.2.2 - -## 0.1.23 - -### Patch Changes - -- bab752e2b3: Change default port of backend from 7000 to 7007. - - This is due to the AirPlay Receiver process occupying port 7000 and preventing local Backstage instances on MacOS to start. - - You can change the port back to 7000 or any other value by providing an `app-config.yaml` with the following values: - - backend: - listen: 0.0.0.0:7123 - baseUrl: http://localhost:7123 - - More information can be found here: - -- 000190de69: The `ApiRegistry` from `@backstage/core-app-api` class has been deprecated and will be removed in a future release. To replace it, we have introduced two new helpers that are exported from `@backstage/test-utils`, namely `TestApiProvider` and `TestApiRegistry`. - - These two new helpers are more tailored for writing tests and development setups, as they allow for partial implementations of each of the APIs. - - When migrating existing code it is typically best to prefer usage of `TestApiProvider` when possible, so for example the following code: - - ```tsx - render( - - {...} - - ) - ``` - - Would be migrated to this: - - ```tsx - render( - - {...} - - ) - ``` - - In cases where the `ApiProvider` is used in a more standalone way, for example to reuse a set of APIs across multiple tests, the `TestApiRegistry` can be used instead. Note that the `TestApiRegistry` only has a single static factory method, `.from()`, and it is slightly different from the existing `.from()` method on `ApiRegistry` in that it doesn't require the API pairs to be wrapped in an outer array. - - Usage that looks like this: - - ```ts - const apis = ApiRegistry.with( - identityApiRef, - mockIdentityApi as unknown as IdentityApi, - ).with(configApiRef, new ConfigReader({})); - ``` - - OR like this: - - ```ts - const apis = ApiRegistry.from([ - [identityApiRef, mockIdentityApi as unknown as IdentityApi], - [configApiRef, new ConfigReader({})], - ]); - ``` - - Would be migrated to this: - - ```ts - const apis = TestApiRegistry.from( - [identityApiRef, mockIdentityApi], - [configApiRef, new ConfigReader({})], - ); - ``` - - If your app is still using the `ApiRegistry` to construct the `apis` for `createApp`, we recommend that you move over to use the new method of supplying API factories instead, using `createApiFactory`. - -- Updated dependencies - - @backstage/core-plugin-api@0.2.1 - - @backstage/core-components@0.7.5 - -## 0.1.22 - -### Patch Changes - -- Reverted the `createApp` TypeScript type to match the one before version `0.1.21`, as it was an accidental breaking change. - -## 0.1.21 - -### Patch Changes - -- 0b1de52732: Migrated to using new `ErrorApiError` and `ErrorApiErrorContext` names. - -- ecd1fcb80a: Deprecated the `BackstagePluginWithAnyOutput` type. - -- 32bfbafb0f: Start exporting and marking several types as public to address errors in the API report. - -- 014cbf8cb9: The `createApp` function from `@backstage/core-app-api` has been deprecated, with two new options being provided as a replacement. - - The first and most commonly used one is `createApp` from the new `@backstage/app-defaults` package, which behaves just like the existing `createApp`. In the future this method is likely to be expanded to add more APIs and other pieces into the default setup, for example the Utility APIs from `@backstage/integration-react`. - - The other option that we now provide is to use `createSpecializedApp` from `@backstage/core-app-api`. This is a more low-level API where you need to provide a full set of options, including your own `components`, `icons`, `defaultApis`, and `themes`. The `createSpecializedApp` way of creating an app is particularly useful if you are not using `@backstage/core-components` or Material UI, as it allows you to avoid those dependencies completely. - -- 475edb5bc5: move the BehaviorSubject init into the constructor - -- Updated dependencies - - @backstage/core-components@0.7.4 - - @backstage/core-plugin-api@0.2.0 - - @backstage/app-defaults@0.1.1 - -## 0.1.20 - -### Patch Changes - -- 78c512ce8f: I have added default icons for the catalog, scaffolder, techdocs, and search. -- 8b4284cd5c: Improve API documentation for @backstage/core-plugin-api -- Updated dependencies - - @backstage/core-components@0.7.3 - - @backstage/theme@0.2.13 - - @backstage/core-plugin-api@0.1.13 - -## 0.1.19 - -### Patch Changes - -- 10615525f3: Switch to use the json and observable types from `@backstage/types` -- 41c49884d2: Start using the new `@backstage/types` package. Initially, this means using the `Observable` and `Json*` types from there. The types also remain in their old places but deprecated, and will be removed in a future release. -- 925a967f36: Replace usage of test-utils-core with test-utils -- 6b615e92c8: Api cleanup, adding `@public` where necessary and tweaking some comments -- Updated dependencies - - @backstage/config@0.1.11 - - @backstage/theme@0.2.12 - - @backstage/core-components@0.7.2 - - @backstage/core-plugin-api@0.1.12 - -## 0.1.18 - -### Patch Changes - -- 202f322927: Atlassian auth provider - - - AtlassianAuth added to core-app-api - - Atlassian provider added to plugin-auth-backend - - Updated user-settings with Atlassian connection - -- 36e67d2f24: Internal updates to apply more strict checks to throw errors. - -- Updated dependencies - - @backstage/core-components@0.7.1 - - @backstage/core-plugin-api@0.1.11 - -## 0.1.17 - -### Patch Changes - -- 75bc878221: Internal refactor to avoid importing all of `@material-ui/core`. -- Updated dependencies - - @backstage/core-components@0.7.0 - - @backstage/theme@0.2.11 - -## 0.1.16 - -### Patch Changes - -- d9fd798cc8: The Core App API now automatically instruments all route location changes using - the new Analytics API. Each location change triggers a `navigate` event, which - is an analogue of a "pageview" event in traditional web analytics systems. In - addition to the path, these events provide plugin-level metadata via the - analytics context, which can be useful for analyzing plugin usage: - - ```json - { - "action": "navigate", - "subject": "/the-path/navigated/to?with=params#and-hashes", - "context": { - "extension": "App", - "pluginId": "id-of-plugin-that-exported-the-route", - "routeRef": "associated-route-ref-id" - } - } - ``` - - These events can be identified and handled by checking for the action - `navigate` and the extension `App`. - -- 4c3eea7788: Bitbucket Cloud authentication - based on the existing GitHub authentication + changes around BB apis and updated scope. - - - BitbucketAuth added to core-app-api. - - Bitbucket provider added to plugin-auth-backend. - - Cosmetic entry for Bitbucket connection in user-settings Authentication Providers tab. - -- d6ad46eb22: Stop calling connector.removeSession in StaticAuthSessionManager, instead just discarding the - session locally. - -- Updated dependencies - - @backstage/core-components@0.6.1 - - @backstage/core-plugin-api@0.1.10 - -## 0.1.15 - -### Patch Changes - -- 0c4ee1876f: Enables late registration of plugins into the application by updating ApiHolder when additional plugins have been added in. -- Updated dependencies - - @backstage/core-plugin-api@0.1.9 - - @backstage/core-components@0.6.0 - -## 0.1.14 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.5.0 - - @backstage/config@0.1.10 - -## 0.1.13 - -### Patch Changes - -- 671015f132: Switch to using utilities from \`@backstage/version-bridge'. -- bd1981d609: Allow users to specify their own AppThemeProvider -- Updated dependencies - - @backstage/core-components@0.4.2 - - @backstage/core-plugin-api@0.1.8 - -## 0.1.12 - -### Patch Changes - -- 841666a19: Removed deprecated internal functions. -- Updated dependencies - - @backstage/core-components@0.4.1 - - @backstage/config@0.1.9 - - @backstage/core-plugin-api@0.1.7 - -## 0.1.11 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.4.0 - -## 0.1.10 - -### Patch Changes - -- cfcb486aa: Add system icons for the built-in entity types and use them in the entity list of the `catalog-import` plugin. - -- 392b36fa1: Added support for using authenticating via GitHub Apps in addition to GitHub OAuth Apps. It used to be possible to use GitHub Apps, but they did not handle session refresh correctly. - - Note that GitHub Apps handle OAuth scope at the app installation level, meaning that the `scope` parameter for `getAccessToken` has no effect. When calling `getAccessToken` in open source plugins, one should still include the appropriate scope, but also document in the plugin README what scopes are required in the case of GitHub Apps. - - In addition, the `authHandler` and `signInResolver` options have been implemented for the GitHub provider in the auth backend. - -- Updated dependencies - - @backstage/core-components@0.3.3 - - @backstage/config@0.1.8 - -## 0.1.9 - -### Patch Changes - -- 72a31c29a: Add support for additional app origins -- Updated dependencies - - @backstage/config@0.1.7 - - @backstage/core-components@0.3.2 - - @backstage/theme@0.2.10 - -## 0.1.8 - -### Patch Changes - -- 362657623: Add support for serving the app with a base path other than `/`, which is enabled by including the path in `app.baseUrl`. -- 56c773909: Switched `@types/react` dependency to request `*` rather than a specific version. -- Updated dependencies - - @backstage/core-components@0.3.1 - - @backstage/core-plugin-api@0.1.6 - -## 0.1.7 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.3.0 - - @backstage/config@0.1.6 - - @backstage/core-plugin-api@0.1.5 - -## 0.1.6 - -### Patch Changes - -- 9d40fcb1e: - Bumping `material-ui/core` version to at least `4.12.2` as they made some breaking changes in later versions which broke `Pagination` of the `Table`. - - Switching out `material-table` to `@material-table/core` for support for the later versions of `material-ui/core` - - This causes a minor API change to `@backstage/core-components` as the interface for `Table` re-exports the `prop` from the underlying `Table` components. - - `onChangeRowsPerPage` has been renamed to `onRowsPerPageChange` - - `onChangePage` has been renamed to `onPageChange` - - Migration guide is here: -- Updated dependencies - - @backstage/core-components@0.2.0 - - @backstage/core-plugin-api@0.1.4 - - @backstage/theme@0.2.9 - -## 0.1.5 - -### Patch Changes - -- ea249c6e6: Fix a bug in `FlatRoutes` that prevented outlets from working with the root route, as well as matching root routes too broadly. -- Updated dependencies - - @backstage/core-components@0.1.6 - -## 0.1.4 - -### Patch Changes - -- 62abffee4: Reintroduce export of `defaultConfigLoader`. -- Updated dependencies - - @backstage/core-components@0.1.4 - -## 0.1.3 - -### Patch Changes - -- dc3e7ce68: Introducing new UnhandledErrorForwarder installed by default. For catching unhandled promise rejections, you can override the API to align with general error handling. -- 5f4339b8c: Adding `FeatureFlag` component and treating `FeatureFlags` as first class citizens to composability API -- Updated dependencies - - @backstage/core-plugin-api@0.1.3 - -## 0.1.2 - -### Patch Changes - -- 9bca2a252: Fixes a type bug where supplying all app icons to `createApp` was required, rather than just a partial list. - -- 75b8537ce: This change adds automatic error boundaries around extensions. - - This means that all exposed parts of a plugin are wrapped in a general error boundary component, that is plugin aware. The default design for the error box is borrowed from `@backstage/errors`. To override the default "fallback", one must provide a component named `ErrorBoundaryFallback` to `createApp`, like so: - - ```ts - const app = createApp({ - components: { - ErrorBoundaryFallback: props => { - // a custom fallback component - return ( - <> -

      Oops.

      -

      - The plugin {props.plugin.getId()} failed with{' '} - {props.error.message} -

      - - - ); - }, - }, - }); - ``` - - The props here include: - - - `error`. An `Error` object or something that inherits it that represents the error that was thrown from any inner component. - - `resetError`. A callback that will simply attempt to mount the children of the error boundary again. - - `plugin`. A `BackstagePlugin` that can be used to look up info to be presented in the error message. For instance, you may want to keep a map of your internal plugins and team names or slack channels and present these when an error occurs. Typically, you'll do that by getting the plugin ID with `plugin.getId()`. - -- da8cba44f: Deprecate and disable the extension creation methods, which were added to this package by mistake and should only exist within `@backstage/core-plugin-api`. - -- 9bca2a252: Update `createApp` options to allow plugins with unknown output types in order to improve forwards and backwards compatibility. - -- Updated dependencies [e47336ea4] - -- Updated dependencies [75b8537ce] - -- Updated dependencies [da8cba44f] - - @backstage/core-components@0.1.2 - - @backstage/core-plugin-api@0.1.2 - -## 0.1.1 - -### Patch Changes - -- e7c5e4b30: Update installation instructions in README. -- Updated dependencies [031ccd45f] -- Updated dependencies [e7c5e4b30] - - @backstage/core-plugin-api@0.1.1 - - @backstage/core-components@0.1.1 - - @backstage/theme@0.2.8 - + - ## @backstage/config-loader@1.9.0-next.1 ### Minor Changes From 587f1ee44473bf4dd62fc1736407c1fe59e529f9 Mon Sep 17 00:00:00 2001 From: Ben Lambert Date: Wed, 31 Jul 2024 14:38:38 +0200 Subject: [PATCH 503/510] Update tricky-ducks-juggle.md Signed-off-by: Ben Lambert --- .changeset/tricky-ducks-juggle.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/tricky-ducks-juggle.md b/.changeset/tricky-ducks-juggle.md index 7f91c978a2..48c0d215bd 100644 --- a/.changeset/tricky-ducks-juggle.md +++ b/.changeset/tricky-ducks-juggle.md @@ -2,4 +2,4 @@ '@backstage/backend-app-api': patch --- -Add `packages` to backend-app-api configuration schema +Added configuration for the `packages` options to config schema From df784fe970a6d3b0ec30af6b39b31ed19f9df291 Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Wed, 31 Jul 2024 14:04:13 +0100 Subject: [PATCH 504/510] permissions: move MetadataResponse type to permission-common This was missed when moving MetadataResponseSerializedRule in 137fa342b4bf43c91e91d3b0b947b8d37c9e233e - seems useful to keep these two types together. Signed-off-by: MT Lewis --- .changeset/fair-hairs-mix.md | 6 ++++++ .changeset/friendly-cherries-applaud.md | 9 +++++++++ plugins/permission-common/api-report.md | 6 ++++++ plugins/permission-common/src/types/index.ts | 5 ++++- plugins/permission-common/src/types/integration.ts | 12 ++++++++++++ plugins/permission-node/api-report.md | 8 +++----- .../integration/createPermissionIntegrationRouter.ts | 7 +++---- 7 files changed, 43 insertions(+), 10 deletions(-) create mode 100644 .changeset/fair-hairs-mix.md create mode 100644 .changeset/friendly-cherries-applaud.md diff --git a/.changeset/fair-hairs-mix.md b/.changeset/fair-hairs-mix.md new file mode 100644 index 0000000000..6c06c7bf72 --- /dev/null +++ b/.changeset/fair-hairs-mix.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-permission-common': patch +--- + +Add the MetadataResponse type from @backstage/plugin-permission-node, since this +type might be used in frontend code. diff --git a/.changeset/friendly-cherries-applaud.md b/.changeset/friendly-cherries-applaud.md new file mode 100644 index 0000000000..c0160858f2 --- /dev/null +++ b/.changeset/friendly-cherries-applaud.md @@ -0,0 +1,9 @@ +--- +'@backstage/plugin-permission-node': patch +--- + +The MetadataResponse type has been moved to @backstage/plugin-permission-common +to match the recent move of MetadataResponseSerializedRule, and should be +imported from there going forward. To avoid an immediate breaking change, this +type is still re-exported from this package, but is marked as deprecated and +will be removed in a future release. diff --git a/plugins/permission-common/api-report.md b/plugins/permission-common/api-report.md index 12dd49d090..465c43846f 100644 --- a/plugins/permission-common/api-report.md +++ b/plugins/permission-common/api-report.md @@ -126,6 +126,12 @@ export function isResourcePermission( // @public export function isUpdatePermission(permission: Permission): boolean; +// @public +export type MetadataResponse = { + permissions?: Permission[]; + rules: MetadataResponseSerializedRule[]; +}; + // @public export type MetadataResponseSerializedRule = { name: string; diff --git a/plugins/permission-common/src/types/index.ts b/plugins/permission-common/src/types/index.ts index 1d2243447f..f5380541df 100644 --- a/plugins/permission-common/src/types/index.ts +++ b/plugins/permission-common/src/types/index.ts @@ -40,7 +40,10 @@ export type { NotCriteria, } from './api'; export type { DiscoveryApi } from './discovery'; -export type { MetadataResponseSerializedRule } from './integration'; +export type { + MetadataResponse, + MetadataResponseSerializedRule, +} from './integration'; export type { BasicPermission, PermissionAttributes, diff --git a/plugins/permission-common/src/types/integration.ts b/plugins/permission-common/src/types/integration.ts index 6c208bb775..d531140923 100644 --- a/plugins/permission-common/src/types/integration.ts +++ b/plugins/permission-common/src/types/integration.ts @@ -15,6 +15,7 @@ */ import zodToJsonSchema from 'zod-to-json-schema'; +import { Permission } from './permission'; /** * Serialized permission rules, with the paramsSchema @@ -28,3 +29,14 @@ export type MetadataResponseSerializedRule = { resourceType: string; paramsSchema?: ReturnType; }; + +/** + * Response type for the .metadata endpoint in + * {@link @backstage/plugin-permission-node#createPermissionIntegrationRouter} + * + * @public + */ +export type MetadataResponse = { + permissions?: Permission[]; + rules: MetadataResponseSerializedRule[]; +}; diff --git a/plugins/permission-node/api-report.md b/plugins/permission-node/api-report.md index 8a90a39728..36483bd342 100644 --- a/plugins/permission-node/api-report.md +++ b/plugins/permission-node/api-report.md @@ -17,6 +17,7 @@ import { DefinitivePolicyDecision } from '@backstage/plugin-permission-common'; import { DiscoveryService } from '@backstage/backend-plugin-api'; import express from 'express'; import { IdentifiedPermissionMessage } from '@backstage/plugin-permission-common'; +import { MetadataResponse as MetadataResponse_2 } from '@backstage/plugin-permission-common'; import { MetadataResponseSerializedRule as MetadataResponseSerializedRule_2 } from '@backstage/plugin-permission-common'; import { NotCriteria } from '@backstage/plugin-permission-common'; import { Permission } from '@backstage/plugin-permission-common'; @@ -188,11 +189,8 @@ export const makeCreatePermissionRule: < rule: PermissionRule, ) => PermissionRule; -// @public -export type MetadataResponse = { - permissions?: Permission[]; - rules: MetadataResponseSerializedRule[]; -}; +// @public @deprecated +export type MetadataResponse = MetadataResponse_2; // @public @deprecated export type MetadataResponseSerializedRule = MetadataResponseSerializedRule_2; diff --git a/plugins/permission-node/src/integration/createPermissionIntegrationRouter.ts b/plugins/permission-node/src/integration/createPermissionIntegrationRouter.ts index 7793d8ab8e..40d215d515 100644 --- a/plugins/permission-node/src/integration/createPermissionIntegrationRouter.ts +++ b/plugins/permission-node/src/integration/createPermissionIntegrationRouter.ts @@ -24,6 +24,7 @@ import { AuthorizeResult, DefinitivePolicyDecision, IdentifiedPermissionMessage, + MetadataResponse as CommonMetadataResponse, MetadataResponseSerializedRule as CommonMetadataResponseSerializedRule, Permission, PermissionCondition, @@ -119,11 +120,9 @@ export type MetadataResponseSerializedRule = * Response type for the .metadata endpoint. * * @public + * @deprecated Please import from `@backstage/plugin-permission-common` instead. */ -export type MetadataResponse = { - permissions?: Permission[]; - rules: MetadataResponseSerializedRule[]; -}; +export type MetadataResponse = CommonMetadataResponse; const applyConditions = ( criteria: PermissionCriteria>, From 878dfb2e5e9dcbee78cdd0d6ee0e2aecef86e674 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 31 Jul 2024 15:40:19 +0200 Subject: [PATCH 505/510] :nails: Signed-off-by: blam --- docs/releases/v1.30.0-next.1-changelog.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/releases/v1.30.0-next.1-changelog.md b/docs/releases/v1.30.0-next.1-changelog.md index efd746686b..1d93235740 100644 --- a/docs/releases/v1.30.0-next.1-changelog.md +++ b/docs/releases/v1.30.0-next.1-changelog.md @@ -12,7 +12,8 @@ Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.30.0-next.1](h - @backstage/core-plugin-api@1.9.3 - @backstage/types@1.1.1 - @backstage/version-bridge@1.0.8 - - + - + ## @backstage/config-loader@1.9.0-next.1 ### Minor Changes From 04759f206fb8f9b04ddcc226a746dd72fb15bd73 Mon Sep 17 00:00:00 2001 From: Stephen Glass Date: Wed, 31 Jul 2024 19:43:29 -0400 Subject: [PATCH 506/510] add null check for review state object check Signed-off-by: Stephen Glass --- .changeset/slow-ligers-drum.md | 5 +++++ .../src/next/components/ReviewState/util.test.ts | 6 +++++- .../src/next/components/ReviewState/util.ts | 4 ++-- 3 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 .changeset/slow-ligers-drum.md diff --git a/.changeset/slow-ligers-drum.md b/.changeset/slow-ligers-drum.md new file mode 100644 index 0000000000..867cc07cee --- /dev/null +++ b/.changeset/slow-ligers-drum.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-react': patch +--- + +Fix null check in `isJsonObject` utility function for scaffolder review state component diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/util.test.ts b/plugins/scaffolder-react/src/next/components/ReviewState/util.test.ts index 9b88ff157e..649d0c3160 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/util.test.ts +++ b/plugins/scaffolder-react/src/next/components/ReviewState/util.test.ts @@ -1,5 +1,5 @@ /* - * Copyright 2022 The Backstage Authors + * Copyright 2024 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,10 @@ describe('isJsonObject', () => { expect(isJsonObject(true)).toBe(false); expect(isJsonObject(undefined)).toBe(false); }); + + it('should return false for null values', () => { + expect(isJsonObject(null)).toBe(false); + }); }); describe('getLastKey', () => { diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/util.ts b/plugins/scaffolder-react/src/next/components/ReviewState/util.ts index 49c3b30e7a..d2caf71964 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/util.ts +++ b/plugins/scaffolder-react/src/next/components/ReviewState/util.ts @@ -1,5 +1,5 @@ /* - * Copyright 2022 The Backstage Authors + * Copyright 2024 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ import { JsonObject, JsonValue } from '@backstage/types'; export function isJsonObject(value?: JsonValue): value is JsonObject { - return typeof value === 'object' && !Array.isArray(value); + return typeof value === 'object' && value !== null && !Array.isArray(value); } // Helper function to get the last part of the key From 3123c16a0ac2b32e466d4eabef432dfbdcd3f947 Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Thu, 1 Aug 2024 11:41:28 +0100 Subject: [PATCH 507/510] search: fix incorrect metadata due to inconsistent package name According to the usual Backstage package naming conventions, @backstage/plugin-search-backend-node should be called @backstage/plugin-search-node. Because of this mismatch, metadata was generated incorrectly. Adjust the metadata in all search packages to include the node package, and fix the pluginId in the node package itself. Signed-off-by: MT Lewis Co-authored-by: Jack Palmer --- .changeset/healthy-timers-divide.md | 9 +++++++++ plugins/search-backend-node/package.json | 8 ++++++-- plugins/search-backend/package.json | 5 +++-- plugins/search-common/package.json | 5 +++-- plugins/search-react/package.json | 5 +++-- plugins/search/package.json | 5 +++-- 6 files changed, 27 insertions(+), 10 deletions(-) create mode 100644 .changeset/healthy-timers-divide.md diff --git a/.changeset/healthy-timers-divide.md b/.changeset/healthy-timers-divide.md new file mode 100644 index 0000000000..0b9d700723 --- /dev/null +++ b/.changeset/healthy-timers-divide.md @@ -0,0 +1,9 @@ +--- +'@backstage/plugin-search-backend-node': patch +'@backstage/plugin-search-backend': patch +'@backstage/plugin-search-common': patch +'@backstage/plugin-search-react': patch +'@backstage/plugin-search': patch +--- + +Fix package metadata diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index 710de9cd67..e2398e8245 100644 --- a/plugins/search-backend-node/package.json +++ b/plugins/search-backend-node/package.json @@ -4,9 +4,13 @@ "description": "A library for Backstage backend plugins that want to interact with the search backend plugin", "backstage": { "role": "node-library", - "pluginId": "search-backend", + "pluginId": "search", "pluginPackages": [ - "@backstage/plugin-search-backend-node" + "@backstage/plugin-search-backend-node", + "@backstage/plugin-search-backend", + "@backstage/plugin-search-common", + "@backstage/plugin-search-react", + "@backstage/plugin-search" ] }, "publishConfig": { diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index 8962162af6..2290a753ec 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -6,10 +6,11 @@ "role": "backend-plugin", "pluginId": "search", "pluginPackages": [ - "@backstage/plugin-search", + "@backstage/plugin-search-backend-node", "@backstage/plugin-search-backend", "@backstage/plugin-search-common", - "@backstage/plugin-search-react" + "@backstage/plugin-search-react", + "@backstage/plugin-search" ] }, "publishConfig": { diff --git a/plugins/search-common/package.json b/plugins/search-common/package.json index f569388c48..7f0462f69d 100644 --- a/plugins/search-common/package.json +++ b/plugins/search-common/package.json @@ -6,10 +6,11 @@ "role": "common-library", "pluginId": "search", "pluginPackages": [ - "@backstage/plugin-search", + "@backstage/plugin-search-backend-node", "@backstage/plugin-search-backend", "@backstage/plugin-search-common", - "@backstage/plugin-search-react" + "@backstage/plugin-search-react", + "@backstage/plugin-search" ] }, "publishConfig": { diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index 4fa50cca10..6d3933b1e4 100644 --- a/plugins/search-react/package.json +++ b/plugins/search-react/package.json @@ -5,10 +5,11 @@ "role": "web-library", "pluginId": "search", "pluginPackages": [ - "@backstage/plugin-search", + "@backstage/plugin-search-backend-node", "@backstage/plugin-search-backend", "@backstage/plugin-search-common", - "@backstage/plugin-search-react" + "@backstage/plugin-search-react", + "@backstage/plugin-search" ] }, "publishConfig": { diff --git a/plugins/search/package.json b/plugins/search/package.json index a4a5ea3593..e772207d4b 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -6,10 +6,11 @@ "role": "frontend-plugin", "pluginId": "search", "pluginPackages": [ - "@backstage/plugin-search", + "@backstage/plugin-search-backend-node", "@backstage/plugin-search-backend", "@backstage/plugin-search-common", - "@backstage/plugin-search-react" + "@backstage/plugin-search-react", + "@backstage/plugin-search" ] }, "publishConfig": { From c0f371f08b11fae8954540d83a86c6a24f970ca8 Mon Sep 17 00:00:00 2001 From: zeshanziya Date: Thu, 1 Aug 2024 19:07:03 +0530 Subject: [PATCH 508/510] remove deperecation Signed-off-by: zeshanziya --- docs/backend-system/core-services/root-logger.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/backend-system/core-services/root-logger.md b/docs/backend-system/core-services/root-logger.md index 733b7b8277..b0bd82cda9 100644 --- a/docs/backend-system/core-services/root-logger.md +++ b/docs/backend-system/core-services/root-logger.md @@ -17,7 +17,7 @@ The following example is how you can override the root logger service to add add ```ts import { coreServices } from '@backstage/backend-plugin-api'; -import { WinstonLogger } from '@backstage/backend-app-api'; +import { WinstonLogger } from '@backstage/backend-defaults/rootLogger'; const backend = createBackend(); From df7e7f57d2f657e545f1a4d7499473d3449e3c45 Mon Sep 17 00:00:00 2001 From: zeshanziya Date: Thu, 1 Aug 2024 19:08:15 +0530 Subject: [PATCH 509/510] add secret redactor example Signed-off-by: zeshanziya --- docs/backend-system/core-services/root-logger.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/backend-system/core-services/root-logger.md b/docs/backend-system/core-services/root-logger.md index b0bd82cda9..36bb276920 100644 --- a/docs/backend-system/core-services/root-logger.md +++ b/docs/backend-system/core-services/root-logger.md @@ -18,6 +18,7 @@ The following example is how you can override the root logger service to add add ```ts import { coreServices } from '@backstage/backend-plugin-api'; import { WinstonLogger } from '@backstage/backend-defaults/rootLogger'; +import { createConfigSecretEnumerator } from '@backstage/backend-defaults/rootConfig'; const backend = createBackend(); @@ -43,6 +44,12 @@ backend.add( transports: [new transports.Console()], }); + const secretEnumerator = await createConfigSecretEnumerator({ + logger, + }); + logger.addRedactions(secretEnumerator(config)); + config.subscribe?.(() => logger.addRedactions(secretEnumerator(config))); + return logger; }, }), From 530ca74ce87509707ac65c8943813eb06d37680e Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 1 Aug 2024 16:45:07 +0200 Subject: [PATCH 510/510] plugins/search-*: fix metadata ordering Signed-off-by: Patrik Oldsberg --- plugins/search-backend-node/package.json | 6 +++--- plugins/search-backend/package.json | 6 +++--- plugins/search-common/package.json | 6 +++--- plugins/search-react/package.json | 6 +++--- plugins/search/package.json | 6 +++--- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index e2398e8245..01337796b0 100644 --- a/plugins/search-backend-node/package.json +++ b/plugins/search-backend-node/package.json @@ -6,11 +6,11 @@ "role": "node-library", "pluginId": "search", "pluginPackages": [ - "@backstage/plugin-search-backend-node", + "@backstage/plugin-search", "@backstage/plugin-search-backend", + "@backstage/plugin-search-backend-node", "@backstage/plugin-search-common", - "@backstage/plugin-search-react", - "@backstage/plugin-search" + "@backstage/plugin-search-react" ] }, "publishConfig": { diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index 2290a753ec..0e39ff2638 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -6,11 +6,11 @@ "role": "backend-plugin", "pluginId": "search", "pluginPackages": [ - "@backstage/plugin-search-backend-node", + "@backstage/plugin-search", "@backstage/plugin-search-backend", + "@backstage/plugin-search-backend-node", "@backstage/plugin-search-common", - "@backstage/plugin-search-react", - "@backstage/plugin-search" + "@backstage/plugin-search-react" ] }, "publishConfig": { diff --git a/plugins/search-common/package.json b/plugins/search-common/package.json index 7f0462f69d..c58aff0c21 100644 --- a/plugins/search-common/package.json +++ b/plugins/search-common/package.json @@ -6,11 +6,11 @@ "role": "common-library", "pluginId": "search", "pluginPackages": [ - "@backstage/plugin-search-backend-node", + "@backstage/plugin-search", "@backstage/plugin-search-backend", + "@backstage/plugin-search-backend-node", "@backstage/plugin-search-common", - "@backstage/plugin-search-react", - "@backstage/plugin-search" + "@backstage/plugin-search-react" ] }, "publishConfig": { diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index 6d3933b1e4..87ebe36f14 100644 --- a/plugins/search-react/package.json +++ b/plugins/search-react/package.json @@ -5,11 +5,11 @@ "role": "web-library", "pluginId": "search", "pluginPackages": [ - "@backstage/plugin-search-backend-node", + "@backstage/plugin-search", "@backstage/plugin-search-backend", + "@backstage/plugin-search-backend-node", "@backstage/plugin-search-common", - "@backstage/plugin-search-react", - "@backstage/plugin-search" + "@backstage/plugin-search-react" ] }, "publishConfig": { diff --git a/plugins/search/package.json b/plugins/search/package.json index e772207d4b..e1cbfcd76a 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -6,11 +6,11 @@ "role": "frontend-plugin", "pluginId": "search", "pluginPackages": [ - "@backstage/plugin-search-backend-node", + "@backstage/plugin-search", "@backstage/plugin-search-backend", + "@backstage/plugin-search-backend-node", "@backstage/plugin-search-common", - "@backstage/plugin-search-react", - "@backstage/plugin-search" + "@backstage/plugin-search-react" ] }, "publishConfig": {