diff --git a/.changeset/beige-lamps-cry.md b/.changeset/beige-lamps-cry.md
new file mode 100644
index 0000000000..c77d5689c5
--- /dev/null
+++ b/.changeset/beige-lamps-cry.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog-backend-module-msgraph': patch
+---
+
+support advanced querying capabilities using the config option `queryMode`
diff --git a/.changeset/beige-suits-tell.md b/.changeset/beige-suits-tell.md
new file mode 100644
index 0000000000..e9e8c919a3
--- /dev/null
+++ b/.changeset/beige-suits-tell.md
@@ -0,0 +1,5 @@
+---
+'@backstage/cli': patch
+---
+
+Applied the fix from version `0.15.3` of this package, which is part of the `v0.71.1` release of Backstage.
diff --git a/.changeset/big-meals-fly.md b/.changeset/big-meals-fly.md
deleted file mode 100644
index be88400227..0000000000
--- a/.changeset/big-meals-fly.md
+++ /dev/null
@@ -1,8 +0,0 @@
----
-'@backstage/plugin-scaffolder-backend': patch
-'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch
-'@backstage/plugin-scaffolder-backend-module-rails': patch
-'@backstage/plugin-scaffolder-backend-module-yeoman': patch
----
-
-Updating documentation for supporting `apiVersion: scaffolder.backstage.io/v1beta3`
diff --git a/.changeset/big-months-deliver.md b/.changeset/big-months-deliver.md
deleted file mode 100644
index 1cf873beb1..0000000000
--- a/.changeset/big-months-deliver.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/cli': patch
----
-
-Added `--since ` flag for `repo build` command.`
diff --git a/.changeset/big-planets-train.md b/.changeset/big-planets-train.md
new file mode 100644
index 0000000000..3639c3546c
--- /dev/null
+++ b/.changeset/big-planets-train.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-gcalendar': minor
+---
+
+Added Google calendar widget
diff --git a/.changeset/brave-brooms-tie.md b/.changeset/brave-brooms-tie.md
deleted file mode 100644
index a4b986c9d5..0000000000
--- a/.changeset/brave-brooms-tie.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-'@backstage/create-app': patch
----
-
-Builtin support for cookiecutter based templates has been removed from `@backstage/plugin-scaffolder-backend`. Due to this, the `containerRunner` argument to its `createRouter` has also been removed.
-
-If you do not use cookiecutter templates and are fine with removing support from it in your own installation, update your `packages/backend/src/plugins/scaffolder.ts` file as follows:
-
-```diff
--import { DockerContainerRunner } from '@backstage/backend-common';
- import { CatalogClient } from '@backstage/catalog-client';
- import { createRouter } from '@backstage/plugin-scaffolder-backend';
--import Docker from 'dockerode';
- import { Router } from 'express';
- import type { PluginEnvironment } from '../types';
-
- export default async function createPlugin({
- reader,
- discovery,
- }: PluginEnvironment): Promise {
-- const dockerClient = new Docker();
-- const containerRunner = new DockerContainerRunner({ dockerClient });
--
- const catalogClient = new CatalogClient({ discoveryApi: discovery });
--
- return await createRouter({
-- containerRunner,
- logger,
- config,
- // ...
-```
-
-If you want to retain cookiecutter support, please use the `@backstage/plugin-scaffolder-backend-module-cookiecutter` package explicitly (see [its README](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-cookiecutter) for installation instructions).
diff --git a/.changeset/brown-points-impress.md b/.changeset/brown-points-impress.md
deleted file mode 100644
index 74d5e1019d..0000000000
--- a/.changeset/brown-points-impress.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-catalog': minor
----
-
-**BREAKING**: Removed the `AboutCard` component which has been replaced by `EntityAboutCard`.
diff --git a/.changeset/calm-boxes-smell.md b/.changeset/calm-boxes-smell.md
new file mode 100644
index 0000000000..55c33997dd
--- /dev/null
+++ b/.changeset/calm-boxes-smell.md
@@ -0,0 +1,5 @@
+---
+'@backstage/config-loader': patch
+---
+
+The `typescript-json-schema` dependency that is used during schema collection is now lazy loaded, as it eagerly loads in the TypeScript compiler.
diff --git a/.changeset/chilly-comics-jam.md b/.changeset/chilly-comics-jam.md
deleted file mode 100644
index 92d7f9014e..0000000000
--- a/.changeset/chilly-comics-jam.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-catalog-react': minor
----
-
-**BREAKING**: Removed `reduceCatalogFilters` and `reduceEntityFilters` due to low external utility value.
diff --git a/.changeset/clever-garlics-rescue.md b/.changeset/clever-garlics-rescue.md
deleted file mode 100644
index a7dd387042..0000000000
--- a/.changeset/clever-garlics-rescue.md
+++ /dev/null
@@ -1,20 +0,0 @@
----
-'@backstage/plugin-catalog-backend': minor
----
-
-**BREAKING**: Removed `GitLabDiscoveryProcessor`, which now instead should be imported from `@backstage/plugin-catalog-backend-module-gitlab`. NOTE THAT this processor was part of the default set of processors in the catalog backend, and if you are a user of discovery on GitLab, you MUST now add it manually in the catalog initialization code of your backend.
-
-```diff
-// In packages/backend/src/plugins/catalog.ts
-+import { GitLabDiscoveryProcessor } from '@backstage/plugin-catalog-backend-module-gitlab';
-
- export default async function createPlugin(
- env: PluginEnvironment,
- ): Promise {
- const builder = await CatalogBuilder.create(env);
-+ builder.addProcessor(
-+ GitLabDiscoveryProcessor.fromConfig(env.config, { logger: env.logger })
-+ );
-```
-
-**BREAKING**: Removed `AzureDevOpsDiscoveryProcessor`, which now instead should be imported from `@backstage/plugin-catalog-backend-module-azure`. This processor was not part of the set of default processors. If you were using it, you should already have a reference to it in your backend code and only need to update the import.
diff --git a/.changeset/cuddly-bags-rescue.md b/.changeset/cuddly-bags-rescue.md
new file mode 100644
index 0000000000..b67926dd69
--- /dev/null
+++ b/.changeset/cuddly-bags-rescue.md
@@ -0,0 +1,22 @@
+---
+'@backstage/backend-test-utils': patch
+'@backstage/create-app': patch
+'@backstage/plugin-airbrake': patch
+'@backstage/plugin-app-backend': patch
+'@backstage/plugin-azure-devops-backend': patch
+'@backstage/plugin-badges-backend': patch
+'@backstage/plugin-bazaar-backend': patch
+'@backstage/plugin-catalog-backend': patch
+'@backstage/plugin-catalog-backend-module-msgraph': patch
+'@backstage/plugin-jenkins-backend': patch
+'@backstage/plugin-kafka': patch
+'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch
+'@backstage/plugin-scaffolder-backend-module-rails': patch
+'@backstage/plugin-scaffolder-backend-module-yeoman': patch
+'@backstage/plugin-tech-insights-backend': patch
+'@backstage/plugin-tech-insights-backend-module-jsonfc': patch
+'@backstage/plugin-todo': patch
+'@backstage/plugin-todo-backend': patch
+---
+
+Minor README update
diff --git a/.changeset/curvy-forks-cross.md b/.changeset/curvy-forks-cross.md
deleted file mode 100644
index feced6ed0e..0000000000
--- a/.changeset/curvy-forks-cross.md
+++ /dev/null
@@ -1,14 +0,0 @@
----
-'@backstage/create-app': patch
----
-
-Removed the `cookiecutter-golang` template from the default `create-app` install as we no longer provide `cookiecutter` action out of the box.
-
-You can remove the template by removing the following lines from your `app-config.yaml` under `catalog.locations`:
-
-```diff
-- - type: url
-- target: https://github.com/spotify/cookiecutter-golang/blob/master/template.yaml
-- rules:
-- - allow: [Template]
-```
diff --git a/.changeset/dependabot-3e359a1.md b/.changeset/dependabot-3e359a1.md
new file mode 100644
index 0000000000..b50122a481
--- /dev/null
+++ b/.changeset/dependabot-3e359a1.md
@@ -0,0 +1,5 @@
+---
+'@backstage/config-loader': patch
+---
+
+build(deps): bump `typescript-json-schema` from 0.52.0 to 0.53.0
diff --git a/.changeset/dependabot-4014eb7.md b/.changeset/dependabot-4014eb7.md
deleted file mode 100644
index 7b4d64523a..0000000000
--- a/.changeset/dependabot-4014eb7.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/cli': patch
----
-
-chore(deps): bump `minimatch` from 5.0.0 to 5.0.1
diff --git a/.changeset/dependabot-6ef69ed.md b/.changeset/dependabot-6ef69ed.md
new file mode 100644
index 0000000000..825e9e9964
--- /dev/null
+++ b/.changeset/dependabot-6ef69ed.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-kubernetes-backend': patch
+---
+
+build(deps): bump `@google-cloud/container` from 2.3.0 to 3.0.0
diff --git a/.changeset/dependabot-ae5fb9c.md b/.changeset/dependabot-ae5fb9c.md
deleted file mode 100644
index 5648da2be7..0000000000
--- a/.changeset/dependabot-ae5fb9c.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-'@backstage/core-components': patch
-'@backstage/plugin-gcp-projects': patch
----
-
-chore(deps): bump `@react-hookz/web` from 12.3.0 to 13.0.0
diff --git a/.changeset/dependabot-afa578f.md b/.changeset/dependabot-afa578f.md
new file mode 100644
index 0000000000..be438c0149
--- /dev/null
+++ b/.changeset/dependabot-afa578f.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-airbrake': patch
+---
+
+build(deps): bump `object-hash` from 2.2.0 to 3.0.0
diff --git a/.changeset/dependabot-bf11310.md b/.changeset/dependabot-bf11310.md
new file mode 100644
index 0000000000..9b3034eb11
--- /dev/null
+++ b/.changeset/dependabot-bf11310.md
@@ -0,0 +1,66 @@
+---
+'@backstage/app-defaults': patch
+'@backstage/core-app-api': patch
+'@backstage/core-components': patch
+'@backstage/core-plugin-api': patch
+'@backstage/create-app': patch
+'@backstage/dev-utils': patch
+'@backstage/integration-react': patch
+'@backstage/test-utils': patch
+'@backstage/version-bridge': patch
+'@backstage/plugin-airbrake': patch
+'@backstage/plugin-allure': patch
+'@backstage/plugin-analytics-module-ga': patch
+'@backstage/plugin-apache-airflow': patch
+'@backstage/plugin-api-docs': patch
+'@backstage/plugin-azure-devops': patch
+'@backstage/plugin-badges': patch
+'@backstage/plugin-bitrise': patch
+'@backstage/plugin-catalog-graph': patch
+'@backstage/plugin-catalog-import': patch
+'@backstage/plugin-catalog-react': patch
+'@backstage/plugin-catalog': patch
+'@backstage/plugin-circleci': patch
+'@backstage/plugin-cloudbuild': patch
+'@backstage/plugin-code-climate': patch
+'@backstage/plugin-code-coverage': patch
+'@backstage/plugin-config-schema': patch
+'@backstage/plugin-cost-insights': patch
+'@backstage/plugin-explore-react': patch
+'@backstage/plugin-explore': patch
+'@backstage/plugin-firehydrant': patch
+'@backstage/plugin-fossa': patch
+'@backstage/plugin-gcp-projects': patch
+'@backstage/plugin-git-release-manager': patch
+'@backstage/plugin-github-actions': patch
+'@backstage/plugin-github-deployments': patch
+'@backstage/plugin-gitops-profiles': patch
+'@backstage/plugin-gocd': patch
+'@backstage/plugin-graphiql': patch
+'@backstage/plugin-home': patch
+'@backstage/plugin-ilert': patch
+'@backstage/plugin-jenkins': patch
+'@backstage/plugin-kafka': patch
+'@backstage/plugin-kubernetes': patch
+'@backstage/plugin-lighthouse': patch
+'@backstage/plugin-newrelic': patch
+'@backstage/plugin-org': patch
+'@backstage/plugin-pagerduty': patch
+'@backstage/plugin-periskop': patch
+'@backstage/plugin-permission-react': patch
+'@backstage/plugin-rollbar': patch
+'@backstage/plugin-scaffolder': patch
+'@backstage/plugin-search': patch
+'@backstage/plugin-sentry': patch
+'@backstage/plugin-shortcuts': patch
+'@backstage/plugin-sonarqube': patch
+'@backstage/plugin-splunk-on-call': patch
+'@backstage/plugin-tech-insights': patch
+'@backstage/plugin-tech-radar': patch
+'@backstage/plugin-techdocs': patch
+'@backstage/plugin-todo': patch
+'@backstage/plugin-user-settings': patch
+'@backstage/plugin-xcmetrics': patch
+---
+
+chore(deps): bump `@testing-library/react` from 11.2.6 to 12.1.3
diff --git a/.changeset/dependabot-d2397d3.md b/.changeset/dependabot-d2397d3.md
deleted file mode 100644
index 5f8bfbf59d..0000000000
--- a/.changeset/dependabot-d2397d3.md
+++ /dev/null
@@ -1,19 +0,0 @@
----
-'@backstage/backend-common': patch
-'@backstage/cli': patch
-'@backstage/config-loader': patch
-'@backstage/create-app': patch
-'@techdocs/cli': patch
-'@backstage/plugin-app-backend': patch
-'@backstage/plugin-auth-backend': patch
-'@backstage/plugin-catalog-backend': patch
-'@backstage/plugin-kubernetes-backend': patch
-'@backstage/plugin-rollbar-backend': patch
-'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch
-'@backstage/plugin-scaffolder-backend-module-rails': patch
-'@backstage/plugin-scaffolder-backend': patch
-'@backstage/plugin-techdocs-backend': patch
-'@backstage/plugin-techdocs-node': patch
----
-
-build(deps): bump `fs-extra` from 9.1.0 to 10.0.1
diff --git a/.changeset/eighty-taxis-wash.md b/.changeset/eighty-taxis-wash.md
new file mode 100644
index 0000000000..c89e7c7dea
--- /dev/null
+++ b/.changeset/eighty-taxis-wash.md
@@ -0,0 +1,8 @@
+---
+'@backstage/plugin-catalog-backend-module-github': patch
+'@backstage/plugin-catalog-backend-module-ldap': patch
+'@backstage/plugin-catalog-backend-module-msgraph': patch
+'@backstage/plugin-org': patch
+---
+
+Updated the code to handle User kind `spec.memberOf` now being optional.
diff --git a/.changeset/fair-ants-look.md b/.changeset/fair-ants-look.md
deleted file mode 100644
index 4e70a042f8..0000000000
--- a/.changeset/fair-ants-look.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-catalog-backend': minor
----
-
-**BREAKING**: Removed `AwsS3DiscoveryProcessor`, which now instead should be imported from `@backstage/plugin-catalog-backend-module-aws`.
diff --git a/.changeset/fair-roses-hide.md b/.changeset/fair-roses-hide.md
deleted file mode 100644
index 8f2c7a6660..0000000000
--- a/.changeset/fair-roses-hide.md
+++ /dev/null
@@ -1,21 +0,0 @@
----
-'@backstage/plugin-scaffolder': minor
-'@backstage/plugin-scaffolder-backend': minor
-'@backstage/plugin-scaffolder-common': minor
----
-
-The following deprecations are now breaking and have been removed:
-
-- **BREAKING**: Support for `backstage.io/v1beta2` Software Templates has been removed. Please migrate your legacy templates to the new `scaffolder.backstage.io/v1beta3` `apiVersion` by following the [migration guide](https://backstage.io/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3)
-
-- **BREAKING**: Removed the deprecated `TemplateMetadata`. Please use `TemplateInfo` instead.
-
-- **BREAKING**: Removed the deprecated `context.baseUrl`. It's now available on `context.templateInfo.baseUrl`.
-
-- **BREAKING**: Removed the deprecated `DispatchResult`, use `TaskBrokerDispatchResult` instead.
-
-- **BREAKING**: Removed the deprecated `runCommand`, use `executeShellCommond` instead.
-
-- **BREAKING**: Removed the deprecated `Status` in favour of `TaskStatus` instead.
-
-- **BREAKING**: Removed the deprecated `TaskState` in favour of `CurrentClaimedTask` instead.
diff --git a/.changeset/fair-turtles-fetch.md b/.changeset/fair-turtles-fetch.md
deleted file mode 100644
index ca61489f05..0000000000
--- a/.changeset/fair-turtles-fetch.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-catalog-backend': patch
----
-
-support Bitbucket Cloud's code search to discover catalog files (multiple per repo, Location entities for existing files only)
diff --git a/.changeset/fifty-brooms-whisper.md b/.changeset/fifty-brooms-whisper.md
deleted file mode 100644
index b4c45555a3..0000000000
--- a/.changeset/fifty-brooms-whisper.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-catalog': minor
----
-
-**BREAKING**: Removed `CatalogResultListItemProps` and `CatalogResultListItem`, replaced by `CatalogSearchResultListItemProps` and `CatalogSearchResultListItem`.
diff --git a/.changeset/fluffy-cameras-shop.md b/.changeset/fluffy-cameras-shop.md
new file mode 100644
index 0000000000..a84e99c24e
--- /dev/null
+++ b/.changeset/fluffy-cameras-shop.md
@@ -0,0 +1,44 @@
+---
+'@backstage/plugin-catalog-backend': minor
+---
+
+**BREAKING**: A number of types and classes have been removed, without a prior deprecation period. These were all very internal, essentially unused by the vast majority of users, and their being exposed was leading to excessive breaking of public interfaces for little-to-zero benefit. So for the 1.0 release of the catalog, the following interface changes have been made (but should have no effect on most users):
+
+- The return type of `CatalogBuilder.build()` now only has the fields `processingEngine` and `router` which is what most users actually consume; the other three fields (`entitiesCatalog`, `locationAnalyzer`, `locationService`) that see very little use have been removed. If you were relying on the presence of either of these in any way, please [open an issue](https://github.com/backstage/backstage/issues/new/choose) that describes your use case, and we'll see how we could fill the gap.
+
+- The function `createRouter` is removed; use `CatalogBuilder` as follows instead:
+
+ ```ts
+ const builder = await CatalogBuilder.create(env);
+ // add things as needed, e.g builder.addProcessor(new ScaffolderEntitiesProcessor());
+ const { processingEngine, router } = await builder.build();
+ await processingEngine.start();
+ return router;
+ ```
+
+- The following types were removed:
+
+ - `CatalogProcessingOrchestrator`
+ - `CatalogRule`
+ - `CatalogRulesEnforcer`
+ - `EntityAncestryResponse`
+ - `EntityFacetsRequest`
+ - `EntityFacetsResponse`
+ - `EntityPagination`
+ - `EntityProcessingRequest`
+ - `EntityProcessingResult`
+ - `EntitiesCatalog`
+ - `EntitiesRequest`
+ - `EntitiesResponse`
+ - `LocationService`
+ - `LocationInput`
+ - `LocationStore`
+ - `PageInfo`
+ - `RefreshOptions`
+ - `RefreshService`
+ - `RouterOptions`
+
+- The following classes were removed:
+
+ - `DefaultCatalogProcessingOrchestrator`
+ - `DefaultCatalogRulesEnforcer`
diff --git a/.changeset/four-schools-shake.md b/.changeset/four-schools-shake.md
new file mode 100644
index 0000000000..9fd81b5888
--- /dev/null
+++ b/.changeset/four-schools-shake.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog-backend': patch
+---
+
+Pass in auth token to ancestry endpoint
diff --git a/.changeset/fuzzy-roses-swim.md b/.changeset/fuzzy-roses-swim.md
deleted file mode 100644
index 234d79c96a..0000000000
--- a/.changeset/fuzzy-roses-swim.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-'@backstage/catalog-model': patch
----
-
-Updated `parseEntityRef` to allow `:` and `/` in the entity name. For example, parsing `'component:default/foo:bar'` will result in the name `'foo:bar'`.
-
-Note that only parsing `'foo:bar'` itself will result in the name `'bar'` and the entity kind `'foo'`, meaning this is a particularly nasty trap for user defined entity references. For this reason it is strongly discouraged to use names that contain these characters, and the catalog model does not allow it by default. However, this change now makes is possible to use these names if the default catalog validation is replaced, and in particular a high level of automation of the catalog population can limit issues that it might otherwise cause.
diff --git a/.changeset/gentle-dancers-greet.md b/.changeset/gentle-dancers-greet.md
deleted file mode 100644
index bf160a7099..0000000000
--- a/.changeset/gentle-dancers-greet.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-'@backstage/cli': patch
----
-
-Added a new ESLint configuration setup for packages, which utilizes package roles to generate the correct configuration. The new configuration is available at `@backstage/cli/config/eslint-factory`.
-
-Introduced a new `backstage-cli migrate package-lint-configs` command, which migrates old lint configurations to use `@backstage/cli/config/eslint-factory`.
diff --git a/.changeset/giant-bottles-eat.md b/.changeset/giant-bottles-eat.md
deleted file mode 100644
index d37343bfe4..0000000000
--- a/.changeset/giant-bottles-eat.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-airbrake': patch
----
-
-Fix a bug where API calls were being made and errors were being added to the snack bar when no project ID was present. This is a common use case for components that haven't added the Airbrake plugin annotation to their `catalog-info.yaml`.
diff --git a/.changeset/gorgeous-trains-clap.md b/.changeset/gorgeous-trains-clap.md
deleted file mode 100644
index d0abf6148a..0000000000
--- a/.changeset/gorgeous-trains-clap.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-catalog': patch
----
-
-Added an `allowedKinds` option to `CatalogKindHeader` to limit entity kinds available in the dropdown.
diff --git a/.changeset/great-hounds-allow.md b/.changeset/great-hounds-allow.md
deleted file mode 100644
index 54405fcf94..0000000000
--- a/.changeset/great-hounds-allow.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-catalog': patch
----
-
-Updated `CatalogKindHeader` to respond to external changes to query parameters in the URL, such as two sidebar links that apply different catalog filters.
diff --git a/.changeset/great-pots-fetch.md b/.changeset/great-pots-fetch.md
new file mode 100644
index 0000000000..34785dfb7f
--- /dev/null
+++ b/.changeset/great-pots-fetch.md
@@ -0,0 +1,5 @@
+---
+'@backstage/cli': minor
+---
+
+**BREAKING**: The provided Jest configuration now only matches files with a `.test.` infix, rather than any files that is suffixed with `test.`. In particular this means that files named just `test.ts` will no longer be considered a test file.
diff --git a/.changeset/grumpy-rules-fetch.md b/.changeset/grumpy-rules-fetch.md
new file mode 100644
index 0000000000..c864e46e3b
--- /dev/null
+++ b/.changeset/grumpy-rules-fetch.md
@@ -0,0 +1,5 @@
+---
+'@backstage/core-components': patch
+---
+
+Change header style `word-wrap` from `break-all` to `break-word`
diff --git a/.changeset/beige-lies-pay.md b/.changeset/heavy-kangaroos-confess.md
similarity index 64%
rename from .changeset/beige-lies-pay.md
rename to .changeset/heavy-kangaroos-confess.md
index 94206f9d9c..6d39e09db1 100644
--- a/.changeset/beige-lies-pay.md
+++ b/.changeset/heavy-kangaroos-confess.md
@@ -2,11 +2,12 @@
'@backstage/backend-common': patch
'@backstage/backend-tasks': patch
'@backstage/backend-test-utils': patch
-'@backstage/plugin-app-backend': patch
'@backstage/plugin-auth-backend': patch
'@backstage/plugin-bazaar-backend': patch
'@backstage/plugin-catalog-backend': patch
+'@backstage/plugin-code-coverage-backend': patch
+'@backstage/plugin-config-schema': patch
'@backstage/plugin-scaffolder-backend': patch
---
-Do some groundwork for supporting the `better-sqlite3` driver, to maybe eventually replace `@vscode/sqlite3` (#9912)
+Use `better-sqlite3` instead of `@vscode/sqlite3`
diff --git a/.changeset/kind-experts-lay.md b/.changeset/kind-experts-lay.md
deleted file mode 100644
index 00524bfe3a..0000000000
--- a/.changeset/kind-experts-lay.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-'@backstage/plugin-catalog-react': minor
----
-
-**BREAKING**: Removed the deprecated `loadCatalogOwnerRefs` function. Usages of this function can be directly replaced with `ownershipEntityRefs` from `identityApi.getBackstageIdentity()`.
-
-This also affects the `useEntityOwnership` hook in that it no longer uses `loadCatalogOwnerRefs`, meaning it will no longer load in additional relations and instead only rely on the `ownershipEntityRefs` from the `IdentityApi`.
diff --git a/.changeset/large-bottles-cheer.md b/.changeset/large-bottles-cheer.md
new file mode 100644
index 0000000000..edd62567f5
--- /dev/null
+++ b/.changeset/large-bottles-cheer.md
@@ -0,0 +1,6 @@
+---
+'@backstage/catalog-model': minor
+'@backstage/plugin-catalog-backend': minor
+---
+
+**BREAKING**: Removed the deprecated `metadata.generation` field entirely. It is no longer present in TS types, nor in the REST API output. Entities that have not yet been re-stitched may still have the field present for some time, but it will get phased out gradually by your catalog instance.
diff --git a/.changeset/late-pianos-attend.md b/.changeset/late-pianos-attend.md
deleted file mode 100644
index e1e0aac392..0000000000
--- a/.changeset/late-pianos-attend.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-catalog-react': minor
----
-
-**BREAKING**: Removed `useEntityFromUrl`.
diff --git a/.changeset/lazy-points-explain.md b/.changeset/lazy-points-explain.md
deleted file mode 100644
index ced31c2195..0000000000
--- a/.changeset/lazy-points-explain.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-scaffolder': minor
----
-
-**BREAKING**: Removed `ScaffolderTaskOutput.entityRef` and `ScaffolderTaskOutput.remoteUrl`, which both have been deprecated for over a year. Please use the `links` output instead.
diff --git a/.changeset/lovely-feet-do.md b/.changeset/lovely-feet-do.md
new file mode 100644
index 0000000000..637603aed0
--- /dev/null
+++ b/.changeset/lovely-feet-do.md
@@ -0,0 +1,5 @@
+---
+'@backstage/cli': patch
+---
+
+Fix for `overrides` not being properly forwarded from the extra configuration passed to `@backstage/cli/config/eslint-factory`.
diff --git a/.changeset/lucky-kangaroos-sneeze.md b/.changeset/lucky-kangaroos-sneeze.md
new file mode 100644
index 0000000000..badcd8a5cf
--- /dev/null
+++ b/.changeset/lucky-kangaroos-sneeze.md
@@ -0,0 +1,6 @@
+---
+'@backstage/plugin-scaffolder-backend': patch
+'@backstage/plugin-scaffolder-common': patch
+---
+
+Adding some documentation for exported things
diff --git a/.changeset/many-coins-drive.md b/.changeset/many-coins-drive.md
deleted file mode 100644
index b28a0b0519..0000000000
--- a/.changeset/many-coins-drive.md
+++ /dev/null
@@ -1,8 +0,0 @@
----
-'@backstage/plugin-scaffolder-backend': minor
----
-
-**BREAKING**:
-
-- Removed the `createFetchCookiecutterAction` export, please use the `@backstage/plugin-scaffolder-backend-module-cookiecutter` package explicitly (see [its README](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-cookiecutter) for installation instructions).
-- Removed the `containerRunner` argument from the types `RouterOptions` (as used by `createRouter`) and `CreateBuiltInActionsOptions` (as used by `createBuiltinActions`).
diff --git a/.changeset/many-swans-sort.md b/.changeset/many-swans-sort.md
deleted file mode 100644
index fec613cf00..0000000000
--- a/.changeset/many-swans-sort.md
+++ /dev/null
@@ -1,10 +0,0 @@
----
-'@backstage/plugin-catalog-backend': patch
----
-
-**BREAKING**:
-
-- Removed the previously deprecated `runPeriodically` export. Please use the `@backstage/backend-tasks` package instead, or copy [the actual implementation](https://github.com/backstage/backstage/blob/02875d4d56708c60f86f6b0a5b3da82e24988354/plugins/catalog-backend/src/util/runPeriodically.ts#L29) into your own code if you explicitly do not want coordination of task runs across your worker nodes.
-- Removed the previously deprecated `CatalogProcessorLocationResult.optional` field. Please set the corresponding `LocationSpec.presence` field to `'optional'` instead.
-- Related to the previous point, the `processingResult.location` function no longer has a second boolean `optional` argument. Please set the corresponding `LocationSpec.presence` field to `'optional'` instead.
-- Removed the previously deprecated `StaticLocationProcessor`. It has not been in use for some time; its functionality is covered by `ConfigLocationEntityProvider` instead.
diff --git a/.changeset/many-tools-buy.md b/.changeset/many-tools-buy.md
deleted file mode 100644
index c2a617edfd..0000000000
--- a/.changeset/many-tools-buy.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/backend-tasks': patch
----
-
-Relaxed the task ID requirement to now support any non-empty string
diff --git a/.changeset/mean-panthers-wonder.md b/.changeset/mean-panthers-wonder.md
deleted file mode 100644
index 1659c855f8..0000000000
--- a/.changeset/mean-panthers-wonder.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-scaffolder': patch
----
-
-Render markdown for description in software templates
diff --git a/.changeset/metal-beans-teach.md b/.changeset/metal-beans-teach.md
new file mode 100644
index 0000000000..f3971a2f29
--- /dev/null
+++ b/.changeset/metal-beans-teach.md
@@ -0,0 +1,7 @@
+---
+'@backstage/catalog-model': minor
+---
+
+**BREAKING**: Removed `EntityName`, use `CompoundEntityRef` type instead.
+
+**BREAKING**: Removed `getEntityName`, use `getCompoundEntityRef` instead.
diff --git a/.changeset/metal-glasses-join.md b/.changeset/metal-glasses-join.md
deleted file mode 100644
index aa7c6ecb9e..0000000000
--- a/.changeset/metal-glasses-join.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/backend-common': patch
----
-
-add support for ETag at `BitbucketUrlReader.readUrl`
diff --git a/.changeset/modern-windows-brush.md b/.changeset/modern-windows-brush.md
deleted file mode 100644
index 49c45eb41e..0000000000
--- a/.changeset/modern-windows-brush.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-'@backstage/catalog-model': minor
----
-
-**BREAKING**:
-
-- Removed the previously deprecated type `EntityRef`. Please use `string` for stringified entity refs, `CompoundEntityRef` for compound kind-namespace-name triplet objects, or custom objects like `{ kind?: string; namespace?: string; name: string }` and similar if you have need for partial types.
-- Removed the previously deprecated type `LocationSpec` type, which has been moved to `@backstage/plugin-catalog-backend`.
-- Removed the previously deprecated function `parseEntityName`. Please use `parseEntityRef` instead.
diff --git a/.changeset/moody-stingrays-tap.md b/.changeset/moody-stingrays-tap.md
new file mode 100644
index 0000000000..de86127eba
--- /dev/null
+++ b/.changeset/moody-stingrays-tap.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog-backend': minor
+---
+
+**BREAKING**: Removed the previously deprecated `results` export. Please use `processingResult` instead.
diff --git a/.changeset/nasty-seahorses-bathe.md b/.changeset/nasty-seahorses-bathe.md
deleted file mode 100644
index 884313e422..0000000000
--- a/.changeset/nasty-seahorses-bathe.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-'@backstage/plugin-catalog': patch
-'@backstage/plugin-rollbar': patch
----
-
-Removed usage of removed hook.
diff --git a/.changeset/neat-tools-design.md b/.changeset/neat-tools-design.md
deleted file mode 100644
index 92a52f0751..0000000000
--- a/.changeset/neat-tools-design.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/backend-test-utils': patch
----
-
-Add `setupRequestMockHandlers` which sets up a good `msw` server foundation, copied from `@backstage/test-utils` which is a frontend-only package and should not be used from backends.
diff --git a/.changeset/nervous-spiders-join.md b/.changeset/nervous-spiders-join.md
new file mode 100644
index 0000000000..fcbce29177
--- /dev/null
+++ b/.changeset/nervous-spiders-join.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog-react': minor
+---
+
+**BREAKING**: Removed the deprecated `favoriteEntityTooltip` and `favoriteEntityIcon` functions.
diff --git a/.changeset/new-books-protect.md b/.changeset/new-books-protect.md
deleted file mode 100644
index 568710ccd0..0000000000
--- a/.changeset/new-books-protect.md
+++ /dev/null
@@ -1,30 +0,0 @@
----
-'@backstage/plugin-catalog-backend-module-ldap': minor
----
-
-**BREAKING**: Added a `schedule` field to `LdapOrgEntityProvider.fromConfig`, which is required. If you want to retain the old behavior of scheduling the provider manually, you can set it to the string value `'manual'`. But you may want to leverage the ability to instead pass in the recurring task schedule information directly. This will allow you to simplify your backend setup code to not need an intermediate variable and separate scheduling code at the bottom.
-
-All things said, a typical setup might now look as follows:
-
-```diff
- // packages/backend/src/plugins/catalog.ts
-+import { Duration } from 'luxon';
-+import { LdapOrgEntityProvider } from '@backstage/plugin-catalog-backend-module-ldap';
- export default async function createPlugin(
- env: PluginEnvironment,
- ): Promise {
- const builder = await CatalogBuilder.create(env);
-+ // The target parameter below needs to match the ldap.providers.target
-+ // value specified in your app-config.
-+ builder.addEntityProvider(
-+ LdapOrgEntityProvider.fromConfig(env.config, {
-+ id: 'our-ldap-master',
-+ target: 'ldaps://ds.example.net',
-+ logger: env.logger,
-+ schedule: env.scheduler.createScheduledTaskRunner({
-+ frequency: Duration.fromObject({ minutes: 60 }),
-+ timeout: Duration.fromObject({ minutes: 15 }),
-+ }),
-+ }),
-+ );
-```
diff --git a/.changeset/new-maps-complain.md b/.changeset/new-maps-complain.md
new file mode 100644
index 0000000000..199a0c3280
--- /dev/null
+++ b/.changeset/new-maps-complain.md
@@ -0,0 +1,5 @@
+---
+'@backstage/integration': patch
+---
+
+Added an integration for Gerrit
diff --git a/.changeset/nice-windows-push.md b/.changeset/nice-windows-push.md
deleted file mode 100644
index 2d04141cf1..0000000000
--- a/.changeset/nice-windows-push.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-catalog-react': minor
----
-
-**BREAKING**: Removed `useEntityCompoundName`, use `useRouteRefParams(entityRouteRef)` instead.
diff --git a/.changeset/nine-frogs-yell.md b/.changeset/nine-frogs-yell.md
deleted file mode 100644
index 7513bea4a6..0000000000
--- a/.changeset/nine-frogs-yell.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-'@backstage/plugin-scaffolder': minor
----
-
-Removed the following previously deprecated exports:
-
-- **BREAKING**: Removed the deprecated `TemplateList` component and the `TemplateListProps` type. Please use the `TemplateCard` to create your own list component instead to render these lists.
-
-- **BREAKING**: Removed the deprecated `setSecret` method, please use `setSecrets` instead.
-
-- **BREAKING**: Removed the deprecated `TemplateCardComponent` and `TaskPageComponent` props from the `ScaffolderPage` component. These are now provided using the `components` prop with the shape `{{ TemplateCardComponent: () => JSX.Element, TaskPageComponent: () => JSX.Element }}`
-
-- **BREAKING**: Removed `JobStatus` as this type was actually a legacy type used in `v1alpha` templates and the workflow engine and should no longer be used or depended on.
diff --git a/.changeset/odd-hairs-remember.md b/.changeset/odd-hairs-remember.md
new file mode 100644
index 0000000000..e43300bfbf
--- /dev/null
+++ b/.changeset/odd-hairs-remember.md
@@ -0,0 +1,5 @@
+---
+'@backstage/catalog-client': minor
+---
+
+**BREAKING**: Removed the deprecated `presence` field in the `Location` and `AddLocationRequest` types. This field was already being ignored by the catalog backend and can be safely removed.
diff --git a/.changeset/odd-spoons-design.md b/.changeset/odd-spoons-design.md
new file mode 100644
index 0000000000..1d0ca96015
--- /dev/null
+++ b/.changeset/odd-spoons-design.md
@@ -0,0 +1,10 @@
+---
+'@backstage/plugin-catalog-backend': minor
+---
+
+**BREAKING**: Removed the following deprecated symbols:
+
+- `catalogBuilder.setRefreshInterval`, use `catalogBuilder.setProcessingInterval` instead.
+- `catalogBuilder.setRefreshIntervalSeconds`, use `catalogBuilder.setProcessingIntervalSeconds` instead.
+- `createRandomRefreshInterval`, use `createRandomProcessingInterval` instead.
+- `RefreshIntervalFunction`, use `ProcessingIntervalFunction` instead.
diff --git a/.changeset/olive-emus-speak.md b/.changeset/olive-emus-speak.md
deleted file mode 100644
index 3cb6a775cf..0000000000
--- a/.changeset/olive-emus-speak.md
+++ /dev/null
@@ -1,10 +0,0 @@
----
-'@backstage/plugin-auth-backend': patch
-'@backstage/plugin-badges-backend': patch
-'@backstage/plugin-catalog-graph': patch
-'@backstage/plugin-catalog-import': patch
-'@backstage/plugin-explore': patch
-'@backstage/plugin-fossa': patch
----
-
-Remove usages of now-removed `CatalogApi.getEntityByName`
diff --git a/.changeset/olive-roses-sleep.md b/.changeset/olive-roses-sleep.md
deleted file mode 100644
index b402a5b2aa..0000000000
--- a/.changeset/olive-roses-sleep.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/create-app': patch
----
-
-Updated the template to write the Backstage release version to `backstage.json`, rather than the version of `@backstage/create-app`. This change is applied automatically when running `backstage-cli versions:bump` in the latest version of the Backstage CLI.
diff --git a/.changeset/pink-poets-grin.md b/.changeset/pink-poets-grin.md
deleted file mode 100644
index d88431e9d5..0000000000
--- a/.changeset/pink-poets-grin.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-'@backstage/backend-common': patch
-'@backstage/plugin-auth-backend': patch
-'@backstage/plugin-catalog-backend': patch
-'@backstage/plugin-catalog-backend-module-msgraph': patch
-'@backstage/plugin-rollbar-backend': patch
-'@backstage/plugin-scaffolder-backend': patch
-'@backstage/plugin-techdocs-backend': patch
----
-
-Use `setupRequestMockHandlers` from `@backstage/backend-test-utils`
diff --git a/.changeset/polite-apples-relax.md b/.changeset/polite-apples-relax.md
deleted file mode 100644
index f6d10aaabf..0000000000
--- a/.changeset/polite-apples-relax.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-catalog-backend': patch
----
-
-Fixed display of the location in the log message that is printed when entity envelope validation fails.
diff --git a/.changeset/polite-melons-clap.md b/.changeset/polite-melons-clap.md
new file mode 100644
index 0000000000..a4356f8d21
--- /dev/null
+++ b/.changeset/polite-melons-clap.md
@@ -0,0 +1,15 @@
+---
+'@backstage/plugin-catalog-backend': minor
+---
+
+**BREAKING**: Removed the export of the `RecursivePartial` utility type. If you relied on this type it can be redefined like this:
+
+```ts
+type RecursivePartial = {
+ [P in keyof T]?: T[P] extends (infer U)[]
+ ? RecursivePartial[]
+ : T[P] extends object
+ ? RecursivePartial
+ : T[P];
+};
+```
diff --git a/.changeset/poor-ads-grab.md b/.changeset/poor-ads-grab.md
new file mode 100644
index 0000000000..75a56bf974
--- /dev/null
+++ b/.changeset/poor-ads-grab.md
@@ -0,0 +1,5 @@
+---
+'@backstage/codemods': patch
+---
+
+Inlined the table of symbols used by the `core-imports` codemod so that future updates to the core packages don't break the codemod. An entry for has also been added to direct imports of `createApp` to `@backstage/app-defaults`.
diff --git a/.changeset/popular-boxes-develop.md b/.changeset/popular-boxes-develop.md
deleted file mode 100644
index 65aae2c7df..0000000000
--- a/.changeset/popular-boxes-develop.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/cli': patch
----
-
-Applied the fix from version `0.15.1` of this package, which was part of the `v0.70.1` release of Backstage.
diff --git a/.changeset/popular-rats-return.md b/.changeset/popular-rats-return.md
deleted file mode 100644
index 3a91e6d707..0000000000
--- a/.changeset/popular-rats-return.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-'@backstage/backend-common': patch
-'@backstage/catalog-model': patch
-'@backstage/plugin-catalog-backend': patch
-'@backstage/plugin-catalog-common': patch
-'@backstage/plugin-catalog-react': patch
----
-
-Applied the fix for the `/alpha` entry point resolution that was part of the `v0.70.1` release of Backstage.
diff --git a/.changeset/pre.json b/.changeset/pre.json
deleted file mode 100644
index 8791f584d6..0000000000
--- a/.changeset/pre.json
+++ /dev/null
@@ -1,215 +0,0 @@
-{
- "mode": "pre",
- "tag": "next",
- "initialVersions": {
- "example-app": "0.2.67",
- "@backstage/app-defaults": "0.2.0",
- "example-backend": "0.2.67",
- "@backstage/backend-common": "0.12.0",
- "@backstage/backend-tasks": "0.1.10",
- "@backstage/backend-test-utils": "0.1.20",
- "@backstage/catalog-client": "0.8.0",
- "@backstage/catalog-model": "0.12.0",
- "@backstage/cli": "0.15.0",
- "@backstage/cli-common": "0.1.8",
- "@backstage/codemods": "0.1.34",
- "@backstage/config": "0.1.15",
- "@backstage/config-loader": "0.9.6",
- "@backstage/core-app-api": "0.6.0",
- "@backstage/core-components": "0.9.0",
- "@backstage/core-plugin-api": "0.8.0",
- "@backstage/create-app": "0.4.22",
- "@backstage/dev-utils": "0.2.24",
- "e2e-test": "0.2.0",
- "@backstage/errors": "0.2.2",
- "@backstage/integration": "0.8.0",
- "@backstage/integration-react": "0.1.24",
- "@backstage/release-manifests": "0.0.2",
- "@backstage/search-common": "0.3.0",
- "@techdocs/cli": "0.8.16",
- "techdocs-cli-embedded-app": "0.2.66",
- "@backstage/techdocs-common": "0.11.11",
- "@backstage/test-utils": "0.3.0",
- "@backstage/theme": "0.2.15",
- "@backstage/types": "0.1.3",
- "@backstage/version-bridge": "0.1.2",
- "@backstage/plugin-airbrake": "0.3.1",
- "@backstage/plugin-airbrake-backend": "0.2.1",
- "@backstage/plugin-allure": "0.1.17",
- "@backstage/plugin-analytics-module-ga": "0.1.12",
- "@backstage/plugin-apache-airflow": "0.1.9",
- "@backstage/plugin-api-docs": "0.8.1",
- "@backstage/plugin-app-backend": "0.3.28",
- "@backstage/plugin-auth-backend": "0.12.0",
- "@backstage/plugin-auth-node": "0.1.4",
- "@backstage/plugin-azure-devops": "0.1.17",
- "@backstage/plugin-azure-devops-backend": "0.3.7",
- "@backstage/plugin-azure-devops-common": "0.2.2",
- "@backstage/plugin-badges": "0.2.25",
- "@backstage/plugin-badges-backend": "0.1.22",
- "@backstage/plugin-bazaar": "0.1.16",
- "@backstage/plugin-bazaar-backend": "0.1.12",
- "@backstage/plugin-bitrise": "0.1.28",
- "@backstage/plugin-catalog": "0.9.1",
- "@backstage/plugin-catalog-backend": "0.23.0",
- "@backstage/plugin-catalog-backend-module-aws": "0.1.1",
- "@backstage/plugin-catalog-backend-module-azure": "0.0.0",
- "@backstage/plugin-catalog-backend-module-gitlab": "0.0.0",
- "@backstage/plugin-catalog-backend-module-ldap": "0.3.15",
- "@backstage/plugin-catalog-backend-module-msgraph": "0.2.18",
- "@backstage/plugin-catalog-common": "0.2.0",
- "@backstage/plugin-catalog-graph": "0.2.13",
- "@backstage/plugin-catalog-graphql": "0.3.5",
- "@backstage/plugin-catalog-import": "0.8.4",
- "@backstage/plugin-catalog-react": "0.8.0",
- "@backstage/plugin-cicd-statistics": "0.1.3",
- "@backstage/plugin-circleci": "0.3.1",
- "@backstage/plugin-cloudbuild": "0.3.1",
- "@backstage/plugin-code-climate": "0.1.1",
- "@backstage/plugin-code-coverage": "0.1.28",
- "@backstage/plugin-code-coverage-backend": "0.1.26",
- "@backstage/plugin-config-schema": "0.1.24",
- "@backstage/plugin-cost-insights": "0.11.23",
- "@backstage/plugin-explore": "0.3.32",
- "@backstage/plugin-explore-react": "0.0.14",
- "@backstage/plugin-firehydrant": "0.1.18",
- "@backstage/plugin-fossa": "0.2.33",
- "@backstage/plugin-gcp-projects": "0.3.20",
- "@backstage/plugin-git-release-manager": "0.3.14",
- "@backstage/plugin-github-actions": "0.5.1",
- "@backstage/plugin-github-deployments": "0.1.32",
- "@backstage/plugin-gitops-profiles": "0.3.19",
- "@backstage/plugin-gocd": "0.1.7",
- "@backstage/plugin-graphiql": "0.2.33",
- "@backstage/plugin-graphql-backend": "0.1.18",
- "@backstage/plugin-home": "0.4.17",
- "@backstage/plugin-ilert": "0.1.27",
- "@backstage/plugin-jenkins": "0.7.0",
- "@backstage/plugin-jenkins-backend": "0.1.17",
- "@backstage/plugin-jenkins-common": "0.1.0",
- "@backstage/plugin-kafka": "0.3.1",
- "@backstage/plugin-kafka-backend": "0.2.21",
- "@backstage/plugin-kubernetes": "0.6.1",
- "@backstage/plugin-kubernetes-backend": "0.4.11",
- "@backstage/plugin-kubernetes-common": "0.2.6",
- "@backstage/plugin-lighthouse": "0.3.1",
- "@backstage/plugin-newrelic": "0.3.19",
- "@backstage/plugin-newrelic-dashboard": "0.1.9",
- "@backstage/plugin-org": "0.5.1",
- "@backstage/plugin-pagerduty": "0.3.28",
- "@backstage/plugin-periskop": "0.0.0",
- "@backstage/plugin-periskop-backend": "0.0.0",
- "@backstage/plugin-permission-backend": "0.5.3",
- "@backstage/plugin-permission-common": "0.5.2",
- "@backstage/plugin-permission-node": "0.5.3",
- "@backstage/plugin-permission-react": "0.3.3",
- "@backstage/plugin-proxy-backend": "0.2.22",
- "@backstage/plugin-rollbar": "0.4.1",
- "@backstage/plugin-rollbar-backend": "0.1.25",
- "@backstage/plugin-scaffolder": "0.14.0",
- "@backstage/plugin-scaffolder-backend": "0.17.3",
- "@backstage/plugin-scaffolder-backend-module-cookiecutter": "0.2.3",
- "@backstage/plugin-scaffolder-backend-module-rails": "0.3.3",
- "@backstage/plugin-scaffolder-backend-module-yeoman": "0.2.1",
- "@backstage/plugin-scaffolder-common": "0.2.3",
- "@backstage/plugin-search": "0.7.2",
- "@backstage/plugin-search-backend": "0.4.6",
- "@backstage/plugin-search-backend-module-elasticsearch": "0.1.0",
- "@backstage/plugin-search-backend-module-pg": "0.3.0",
- "@backstage/plugin-search-backend-node": "0.5.0",
- "@backstage/plugin-search-common": "0.3.0",
- "@backstage/plugin-sentry": "0.3.39",
- "@backstage/plugin-shortcuts": "0.2.2",
- "@backstage/plugin-sonarqube": "0.3.1",
- "@backstage/plugin-splunk-on-call": "0.3.25",
- "@backstage/plugin-tech-insights": "0.1.11",
- "@backstage/plugin-tech-insights-backend": "0.2.8",
- "@backstage/plugin-tech-insights-backend-module-jsonfc": "0.1.12",
- "@backstage/plugin-tech-insights-common": "0.2.3",
- "@backstage/plugin-tech-insights-node": "0.2.6",
- "@backstage/plugin-tech-radar": "0.5.8",
- "@backstage/plugin-techdocs": "0.15.0",
- "@backstage/plugin-techdocs-backend": "0.14.1",
- "@backstage/plugin-techdocs-node": "0.11.11",
- "@backstage/plugin-todo": "0.2.3",
- "@backstage/plugin-todo-backend": "0.1.25",
- "@backstage/plugin-user-settings": "0.4.0",
- "@backstage/plugin-xcmetrics": "0.2.21"
- },
- "changesets": [
- "beige-lies-pay",
- "big-meals-fly",
- "big-months-deliver",
- "brave-brooms-tie",
- "brown-points-impress",
- "chilly-comics-jam",
- "clever-garlics-rescue",
- "curvy-forks-cross",
- "dependabot-4014eb7",
- "dependabot-ae5fb9c",
- "dependabot-d2397d3",
- "fair-ants-look",
- "fair-roses-hide",
- "fair-turtles-fetch",
- "fifty-brooms-whisper",
- "fuzzy-roses-swim",
- "gentle-dancers-greet",
- "great-hounds-allow",
- "kind-experts-lay",
- "late-pianos-attend",
- "lazy-points-explain",
- "many-coins-drive",
- "many-swans-sort",
- "many-tools-buy",
- "mean-panthers-wonder",
- "metal-glasses-join",
- "modern-windows-brush",
- "nasty-seahorses-bathe",
- "neat-tools-design",
- "new-books-protect",
- "nice-windows-push",
- "nine-frogs-yell",
- "olive-emus-speak",
- "olive-roses-sleep",
- "pink-poets-grin",
- "polite-apples-relax",
- "popular-boxes-develop",
- "popular-rats-return",
- "pretty-vans-unite",
- "proud-readers-nail",
- "quiet-pens-wait",
- "quiet-seals-fix",
- "red-kiwis-divide",
- "rich-ravens-clap",
- "search-byta-namnet",
- "search-common-people",
- "search-talking-in-code",
- "search-wellington-paranormal",
- "shaggy-apricots-hug",
- "shiny-eels-mix",
- "silent-cats-kneel",
- "slow-vans-rhyme",
- "something-else-here",
- "spotty-seals-press",
- "spotty-swans-run",
- "strong-beds-attack",
- "strong-pandas-roll",
- "swift-mails-sing",
- "tasty-carpets-fold",
- "techdocs-byta-namnet",
- "techdocs-empty-office",
- "techdocs-node-one",
- "ten-queens-dance",
- "ten-rats-join",
- "tender-berries-lie",
- "thick-games-dress",
- "thick-gifts-cheat",
- "twenty-birds-think",
- "twenty-fireants-turn",
- "twenty-planes-dress",
- "two-mails-boil",
- "warm-bananas-behave",
- "weak-schools-wash",
- "young-feet-flow"
- ]
-}
diff --git a/.changeset/pretty-vans-unite.md b/.changeset/pretty-vans-unite.md
deleted file mode 100644
index 318e86d069..0000000000
--- a/.changeset/pretty-vans-unite.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-'@backstage/cli': patch
----
-
-Package roles are now marked as stable and migration is encouraged. Please check out the [migration guide](https://backstage.io/docs/tutorials/package-role-migration).
-
-The new `package`, `repo`, and `migrate` command categories are now marked as stable.
-
-Marked all commands that are being replaced by the new `package` and `repo` commands as deprecated.
-
-The package templates used by the `create` command have all been updated to use package roles.
diff --git a/.changeset/proud-readers-nail.md b/.changeset/proud-readers-nail.md
deleted file mode 100644
index 9b5a6b980c..0000000000
--- a/.changeset/proud-readers-nail.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-'@backstage/plugin-airbrake-backend': patch
-'@backstage/plugin-code-climate': patch
----
-
-Added `backstage.role` to `package.json`
diff --git a/.changeset/quiet-pens-wait.md b/.changeset/quiet-pens-wait.md
deleted file mode 100644
index b7510eab3f..0000000000
--- a/.changeset/quiet-pens-wait.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-catalog-react': minor
----
-
-**BREAKING**: Removed `useEntityListProvider` use `useEntityList` instead.
diff --git a/.changeset/red-kiwis-divide.md b/.changeset/red-kiwis-divide.md
deleted file mode 100644
index 0bfb247093..0000000000
--- a/.changeset/red-kiwis-divide.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-scaffolder-backend': minor
----
-
-**BREAKING**: Removed the previously deprecated `OctokitProvider` class.
diff --git a/.changeset/rich-bobcats-behave.md b/.changeset/rich-bobcats-behave.md
new file mode 100644
index 0000000000..d873017624
--- /dev/null
+++ b/.changeset/rich-bobcats-behave.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog-graphql': patch
+---
+
+Do not use `metadata.generation` from entity data
diff --git a/.changeset/rich-mugs-dress.md b/.changeset/rich-mugs-dress.md
new file mode 100644
index 0000000000..585ffbdb1c
--- /dev/null
+++ b/.changeset/rich-mugs-dress.md
@@ -0,0 +1,29 @@
+---
+'@backstage/app-defaults': major
+'@backstage/catalog-client': major
+'@backstage/catalog-model': major
+'@backstage/config': major
+'@backstage/config-loader': major
+'@backstage/core-app-api': major
+'@backstage/core-plugin-api': major
+'@backstage/dev-utils': major
+'@backstage/errors': major
+'@backstage/integration': major
+'@backstage/integration-react': major
+'@backstage/test-utils': major
+'@backstage/types': major
+'@backstage/version-bridge': major
+'@backstage/plugin-catalog': major
+'@backstage/plugin-catalog-backend': major
+'@backstage/plugin-catalog-common': major
+'@backstage/plugin-catalog-react': major
+'@backstage/plugin-scaffolder': major
+'@backstage/plugin-scaffolder-backend': major
+'@backstage/plugin-scaffolder-common': major
+'@backstage/plugin-techdocs': major
+'@backstage/plugin-techdocs-backend': major
+'@backstage/plugin-techdocs-node': major
+'@techdocs/cli': major
+---
+
+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).
diff --git a/.changeset/rich-ravens-clap.md b/.changeset/rich-ravens-clap.md
deleted file mode 100644
index 913f87085f..0000000000
--- a/.changeset/rich-ravens-clap.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-catalog-backend-module-azure': minor
----
-
-Added package, moving out azure specific functionality from the catalog-backend
diff --git a/.changeset/rotten-bears-vanish.md b/.changeset/rotten-bears-vanish.md
new file mode 100644
index 0000000000..b988d061ca
--- /dev/null
+++ b/.changeset/rotten-bears-vanish.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-azure-devops': patch
+---
+
+Updated readme
diff --git a/.changeset/search-byta-namnet.md b/.changeset/search-byta-namnet.md
deleted file mode 100644
index c3abc81996..0000000000
--- a/.changeset/search-byta-namnet.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-search-common': patch
----
-
-Renamed `@backstage/search-common` to `@backstage/plugin-search-common`.
diff --git a/.changeset/search-common-people.md b/.changeset/search-common-people.md
deleted file mode 100644
index 2ed34c7573..0000000000
--- a/.changeset/search-common-people.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-'@backstage/search-common': patch
----
-
-**DEPRECATION**
-
-The `@backstage/search-common` package is being renamed `@backstage/plugin-search-common`. We may continue to publish changes to `@backstage/search-common` for a time, but will stop doing so in the near future. If you depend on this package, you should update your dependencies to point at the renamed package.
diff --git a/.changeset/search-pour-one-out-common.md b/.changeset/search-pour-one-out-common.md
new file mode 100644
index 0000000000..e4bc2b4f6a
--- /dev/null
+++ b/.changeset/search-pour-one-out-common.md
@@ -0,0 +1,5 @@
+---
+'@backstage/search-common': patch
+---
+
+This package is no longer maintained. Use `@backstage/plugin-search-common`, going forward.
diff --git a/.changeset/search-talking-in-code.md b/.changeset/search-talking-in-code.md
deleted file mode 100644
index 46de5f8343..0000000000
--- a/.changeset/search-talking-in-code.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-'@backstage/create-app': patch
----
-
-Postgres-based search is now installed when PG is chosen as the desired database for Backstage.
-
-There is no need to make this change in an existing Backstage backend. See [supported search engines](https://backstage.io/docs/features/search/search-engines) for details about production-ready search engines.
diff --git a/.changeset/search-wellington-paranormal.md b/.changeset/search-wellington-paranormal.md
deleted file mode 100644
index 7cd1ead2e8..0000000000
--- a/.changeset/search-wellington-paranormal.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-'@backstage/plugin-catalog-backend': patch
-'@backstage/plugin-catalog': patch
-'@backstage/plugin-search-backend-module-elasticsearch': patch
-'@backstage/plugin-search-backend-module-pg': patch
-'@backstage/plugin-search-backend-node': patch
-'@backstage/plugin-search-backend': patch
-'@backstage/plugin-search': patch
-'@backstage/plugin-techdocs-backend': patch
-'@backstage/plugin-techdocs-node': patch
----
-
-Use `@backstage/plugin-search-common` package instead of `@backstage/search-common`.
diff --git a/.changeset/shaggy-apricots-hug.md b/.changeset/shaggy-apricots-hug.md
deleted file mode 100644
index 62bea4c3bd..0000000000
--- a/.changeset/shaggy-apricots-hug.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-tech-radar': patch
----
-
-Tech Radar Ring names are now coloured from theme via theme.palette.text.primary (instead of a hard coded colour)
diff --git a/.changeset/shaggy-beers-unite.md b/.changeset/shaggy-beers-unite.md
new file mode 100644
index 0000000000..7649203f52
--- /dev/null
+++ b/.changeset/shaggy-beers-unite.md
@@ -0,0 +1,8 @@
+---
+'@backstage/plugin-catalog-react': minor
+---
+
+**BREAKING**: The following deprecated annotation reading helper functions were removed:
+
+- `getEntityMetadataViewUrl`, use `entity.metadata.annotations?.[ANNOTATION_VIEW_URL]` instead.
+- `getEntityMetadataEditUrl`, use `entity.metadata.annotations?.[ANNOTATION_EDIT_URL]` instead.
diff --git a/.changeset/shiny-eels-mix.md b/.changeset/shiny-eels-mix.md
deleted file mode 100644
index 2d886e9a7f..0000000000
--- a/.changeset/shiny-eels-mix.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/core-components': patch
----
-
-Add names to sidebar sub menu styles for customization
diff --git a/.changeset/silent-cats-kneel.md b/.changeset/silent-cats-kneel.md
deleted file mode 100644
index 9bd9cce0e0..0000000000
--- a/.changeset/silent-cats-kneel.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-catalog-backend-module-gitlab': minor
----
-
-Added package, moving out GitLab specific functionality from the catalog-backend
diff --git a/.changeset/silent-fishes-dream.md b/.changeset/silent-fishes-dream.md
new file mode 100644
index 0000000000..ea4b8c33c0
--- /dev/null
+++ b/.changeset/silent-fishes-dream.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog-backend': minor
+---
+
+**BREAKING**: The deprecated `CatalogEntityDocument` export has been removed, it can be imported from `@backstage/plugin-catalog-common` instead.
diff --git a/.changeset/sixty-countries-peel.md b/.changeset/sixty-countries-peel.md
new file mode 100644
index 0000000000..fbb539ef86
--- /dev/null
+++ b/.changeset/sixty-countries-peel.md
@@ -0,0 +1,38 @@
+---
+'@backstage/backend-common': patch
+'@backstage/catalog-model': patch
+'@backstage/cli': patch
+'@backstage/core-app-api': patch
+'@backstage/core-components': patch
+'@backstage/core-plugin-api': patch
+'@backstage/dev-utils': patch
+'@backstage/test-utils': patch
+'@backstage/plugin-api-docs': patch
+'@backstage/plugin-badges-backend': patch
+'@backstage/plugin-catalog': patch
+'@backstage/plugin-catalog-backend': patch
+'@backstage/plugin-catalog-backend-module-msgraph': patch
+'@backstage/plugin-catalog-graph': patch
+'@backstage/plugin-cicd-statistics': patch
+'@backstage/plugin-code-coverage-backend': patch
+'@backstage/plugin-cost-insights': patch
+'@backstage/plugin-git-release-manager': patch
+'@backstage/plugin-jenkins': patch
+'@backstage/plugin-jenkins-backend': patch
+'@backstage/plugin-kubernetes': patch
+'@backstage/plugin-kubernetes-backend': patch
+'@backstage/plugin-newrelic-dashboard': patch
+'@backstage/plugin-permission-common': patch
+'@backstage/plugin-permission-react': patch
+'@backstage/plugin-scaffolder': patch
+'@backstage/plugin-scaffolder-backend': patch
+'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch
+'@backstage/plugin-search': patch
+'@backstage/plugin-search-backend-node': patch
+'@backstage/plugin-techdocs': patch
+'@backstage/plugin-techdocs-backend': patch
+'@backstage/plugin-techdocs-node': patch
+'@backstage/plugin-xcmetrics': patch
+---
+
+Minor typo fixes
diff --git a/.changeset/slow-vans-rhyme.md b/.changeset/slow-vans-rhyme.md
deleted file mode 100644
index 6de924899f..0000000000
--- a/.changeset/slow-vans-rhyme.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/catalog-model': minor
----
-
-**BREAKING**: The default validator for `metadata.tags` now permits the colon (`:`) character as well.
diff --git a/.changeset/quiet-seals-fix.md b/.changeset/smart-snails-switch.md
similarity index 54%
rename from .changeset/quiet-seals-fix.md
rename to .changeset/smart-snails-switch.md
index d7c98958be..59bc948f8b 100644
--- a/.changeset/quiet-seals-fix.md
+++ b/.changeset/smart-snails-switch.md
@@ -2,4 +2,4 @@
'@backstage/plugin-catalog-backend-module-ldap': patch
---
-Ignore search referrals instead of throwing an error.
+Add config support for LDAP search options.
diff --git a/.changeset/something-else-here.md b/.changeset/something-else-here.md
deleted file mode 100644
index 46e5efcb07..0000000000
--- a/.changeset/something-else-here.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-'@backstage/create-app': patch
-'@backstage/plugin-catalog-backend': minor
----
-
-- **BREAKING**: Support for `backstage.io/v1beta2` Software Templates has been removed. Please migrate your legacy templates to the new `scaffolder.backstage.io/v1beta3` `apiVersion` by following the [migration guide](https://backstage.io/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3)
diff --git a/.changeset/spotty-seals-press.md b/.changeset/spotty-seals-press.md
deleted file mode 100644
index a0a69b2efc..0000000000
--- a/.changeset/spotty-seals-press.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-'@backstage/plugin-catalog-react': minor
----
-
-**BREAKING**: Removed `useOwnedEntities` and moved its usage internally to the scaffolder-backend where it's used.
-
-**BREAKING**: Removed `EntityTypeReturn` type which is now inlined.
diff --git a/.changeset/spotty-swans-run.md b/.changeset/spotty-swans-run.md
deleted file mode 100644
index 7a16343d69..0000000000
--- a/.changeset/spotty-swans-run.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/cli': patch
----
-
-The backend development setup now ignores the `"browser"` and `"module"` entry points in `package.json`, and instead always uses `"main"`.
diff --git a/.changeset/strong-beds-attack.md b/.changeset/strong-beds-attack.md
deleted file mode 100644
index f16c709daa..0000000000
--- a/.changeset/strong-beds-attack.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-'@backstage/plugin-catalog-react': patch
-'@backstage/plugin-org': patch
----
-
-Fixed EntityOwnerPicker and OwnershipCard url filter issue with more than 21 owners
diff --git a/.changeset/strong-dolphins-turn.md b/.changeset/strong-dolphins-turn.md
new file mode 100644
index 0000000000..4c59accba6
--- /dev/null
+++ b/.changeset/strong-dolphins-turn.md
@@ -0,0 +1,14 @@
+---
+'@backstage/catalog-model': minor
+---
+
+**BREAKING**: The User kind has an updated TypeScript type where `spec.memberOf`
+is optional.
+
+**NOTE HOWEVER**, that this only applies to the TypeScript types `UserEntity`
+and `UserEntityV1alpha1`. The catalog validation still requires the field to be
+set, even if it's in the form of an empty array. If you try to ingest data that
+stops producing this field, those entities _will be rejected_ by the catalog.
+The reason for these choices is that consumers will get a long grace period
+where old code still can rely on the underlying data being present, giving users
+ample time to update before actual breakages could happen.
diff --git a/.changeset/strong-pandas-roll.md b/.changeset/strong-pandas-roll.md
deleted file mode 100644
index e58e1c44c6..0000000000
--- a/.changeset/strong-pandas-roll.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-'@backstage/plugin-periskop': minor
-'@backstage/plugin-periskop-backend': minor
----
-
-Add periskop and periskop-backend plugin, for usage with exception aggregation tool https://periskop.io/
diff --git a/.changeset/strong-tomatoes-kneel.md b/.changeset/strong-tomatoes-kneel.md
new file mode 100644
index 0000000000..bdddb91ae2
--- /dev/null
+++ b/.changeset/strong-tomatoes-kneel.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog-backend-module-ldap': patch
+---
+
+Updated to no longer rely on the `RecursivePartial` export from `@backstage/plugin-catalog-backend`.
diff --git a/.changeset/swift-mails-sing.md b/.changeset/swift-mails-sing.md
deleted file mode 100644
index 3df53e0340..0000000000
--- a/.changeset/swift-mails-sing.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-techdocs': patch
----
-
-The panels of `TechDocsCustomHome` now use the `useEntityOwnership` hook to resolve ownership when the `'ownedByUser'` filter predicate is used.
diff --git a/.changeset/tasty-carpets-fold.md b/.changeset/tasty-carpets-fold.md
deleted file mode 100644
index a1e62413bc..0000000000
--- a/.changeset/tasty-carpets-fold.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-catalog-react': minor
----
-
-**BREAKING**: Removed the `useEntityKinds` hook, use `catalogApi.getEntityFacets({ facets: ['kind'] })` instead.
diff --git a/.changeset/techdocs-breezy-pans-flow.md b/.changeset/techdocs-breezy-pans-flow.md
new file mode 100644
index 0000000000..933a383c38
--- /dev/null
+++ b/.changeset/techdocs-breezy-pans-flow.md
@@ -0,0 +1,6 @@
+---
+'@backstage/plugin-techdocs-node': minor
+---
+
+- `DirectoryPreparer` now uses private constructor. Use static fromConfig method to instantiate.
+- `UrlPreparer` now uses private constructor. Use static fromConfig method to instantiate.
diff --git a/.changeset/techdocs-byta-namnet.md b/.changeset/techdocs-byta-namnet.md
deleted file mode 100644
index f77849513b..0000000000
--- a/.changeset/techdocs-byta-namnet.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-techdocs-node': patch
----
-
-Renamed `@backstage/techdocs-common` to `@backstage/plugin-techdocs-node`.
diff --git a/.changeset/techdocs-clever-pumas-warn.md b/.changeset/techdocs-clever-pumas-warn.md
new file mode 100644
index 0000000000..2aba8b9885
--- /dev/null
+++ b/.changeset/techdocs-clever-pumas-warn.md
@@ -0,0 +1,11 @@
+---
+'@backstage/plugin-techdocs-backend': minor
+---
+
+Removed deprecated exports, including:
+
+- deprecated config `generators` is now deleted and fully replaced with `techdocs.generator`
+- deprecated config `generators.techdocs` is now deleted and fully replaced with `techdocs.generator.runIn`
+- deprecated config `techdocs.requestUrl` is now deleted
+- deprecated config `techdocs.storageUrl` is now deleted
+- deprecated `createHttpResponse` is now deleted and calls to `/sync/:namespace/:kind/:name` needs to be done by an EventSource.
diff --git a/.changeset/techdocs-empty-office.md b/.changeset/techdocs-empty-office.md
deleted file mode 100644
index 082521be35..0000000000
--- a/.changeset/techdocs-empty-office.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-'@backstage/techdocs-common': patch
----
-
-**DEPRECATION**
-
-The `@backstage/techdocs-common` package is being renamed `@backstage/plugin-techdocs-node`. We may continue to publish changes to `@backstage/techdocs-common` for a time, but will stop doing so in the near future. If you depend on this package, you should update your dependencies to point at the renamed package.
diff --git a/.changeset/techdocs-node-one.md b/.changeset/techdocs-node-one.md
deleted file mode 100644
index 706c708c4a..0000000000
--- a/.changeset/techdocs-node-one.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-'@backstage/plugin-techdocs-backend': patch
-'@techdocs/cli': patch
----
-
-Use `@backstage/plugin-techdocs-node` package instead of `@backstage/techdocs-common`.
diff --git a/.changeset/techdocs-pour-one-out-common.md b/.changeset/techdocs-pour-one-out-common.md
new file mode 100644
index 0000000000..ed2940f62a
--- /dev/null
+++ b/.changeset/techdocs-pour-one-out-common.md
@@ -0,0 +1,5 @@
+---
+'@backstage/techdocs-common': patch
+---
+
+This package is no longer maintained. Use `@backstage/plugin-techdocs-node`, going forward.
diff --git a/.changeset/techdocs-slow-teachers-sleep.md b/.changeset/techdocs-slow-teachers-sleep.md
new file mode 100644
index 0000000000..5e50d92d2b
--- /dev/null
+++ b/.changeset/techdocs-slow-teachers-sleep.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-techdocs': patch
+---
+
+Long sidebars will no longer overflow the footer and will properly show a scrollbar when needed.
diff --git a/.changeset/techdocs-tiny-spies-knock.md b/.changeset/techdocs-tiny-spies-knock.md
new file mode 100644
index 0000000000..ffc3e75a01
--- /dev/null
+++ b/.changeset/techdocs-tiny-spies-knock.md
@@ -0,0 +1,12 @@
+---
+'@backstage/plugin-techdocs': minor
+---
+
+Removed deprecated exports, including:
+
+- deprecated `DocsResultListItem` is now deleted and fully replaced with `TechDocsSearchResultListItem`
+- deprecated `TechDocsPage` is now deleted and fully replaced with `TechDocsReaderPage`
+- deprecated `TechDocsPageHeader` is now deleted and fully replaced with `TechDocsReaderPageHeader`
+- deprecated `TechDocsPageHeaderProps` is now deleted and fully replaced with `TechDocsReaderPageHeaderProps`
+- deprecated `TechDocsPageRenderFunction` is now deleted and fully replaced with `TechDocsReaderPageRenderFunction`
+- deprecated config `techdocs.requestUrl` is now deleted and fully replaced with the discoveryApi
diff --git a/.changeset/ten-queens-dance.md b/.changeset/ten-queens-dance.md
deleted file mode 100644
index 947675aa46..0000000000
--- a/.changeset/ten-queens-dance.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-'@backstage/backend-tasks': minor
----
-
-**BREAKING**: The `TaskDefinition` type has been removed, and replaced by the equal pair `TaskScheduleDefinition` and `TaskInvocationDefinition`. The interface for `PluginTaskScheduler.scheduleTask` stays effectively unchanged, so this only affects you if you use the actual types directly.
-
-Added the method `PluginTaskScheduler.createTaskSchedule`, which returns a `TaskSchedule` wrapper that is convenient to pass down into classes that want to control their task invocations while the caller wants to retain control of the actual schedule chosen.
diff --git a/.changeset/ten-rats-join.md b/.changeset/ten-rats-join.md
deleted file mode 100644
index 6aa97be581..0000000000
--- a/.changeset/ten-rats-join.md
+++ /dev/null
@@ -1,8 +0,0 @@
----
-'@backstage/catalog-model': patch
----
-
-**DEPRECATION**:
-
-- Deprecated `CommonValidatorFunctions.isValidString`, please use `isNonEmptyString` instead which is equivalent but better named.
-- Deprecated `CommonValidatorFunctions.isValidTag`, with no replacement. Its purpose was too specific and not reusable, so it will be removed.
diff --git a/.changeset/tender-berries-lie.md b/.changeset/tender-berries-lie.md
deleted file mode 100644
index 74a3eb4707..0000000000
--- a/.changeset/tender-berries-lie.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/cli': patch
----
-
-Changed the logic for how modules are marked as external in the Rollup build of packages. Rather than only marking dependencies and build-in Node.js modules as external, all non-relative imports are now considered external.
diff --git a/.changeset/thick-games-dress.md b/.changeset/thick-games-dress.md
deleted file mode 100644
index 5ce2decd3f..0000000000
--- a/.changeset/thick-games-dress.md
+++ /dev/null
@@ -1,8 +0,0 @@
----
-'@backstage/backend-common': minor
----
-
-**BREAKING**:
-
-- Removed the (since way back) deprecated `createDatabase` export, please use `createDatabaseClient` instead.
-- Removed the (since way back) deprecated `SingleConnectionDatabaseManager` export, please use `DatabaseManager` instead.
diff --git a/.changeset/thick-gifts-cheat.md b/.changeset/thick-gifts-cheat.md
deleted file mode 100644
index 00154a8492..0000000000
--- a/.changeset/thick-gifts-cheat.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/catalog-client': minor
----
-
-**BREAKING**: Removed previously deprecated `CatalogApi.getEntityByName`, please use `getEntityByRef` instead.
diff --git a/.changeset/thin-candles-run.md b/.changeset/thin-candles-run.md
new file mode 100644
index 0000000000..2776373569
--- /dev/null
+++ b/.changeset/thin-candles-run.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog-react': minor
+---
+
+**BREAKING**: The `useEntity` hook no longer returns loading or error states, and will throw an error if the entity is not immediately available. In practice this means that `useEntity` can only be used in contexts where the entity is guaranteed to have been loaded, for example inside an `EntityLayout`. To access the loading state of the entity, use `useAsyncEntity` instead.
diff --git a/.changeset/tricky-months-sort.md b/.changeset/tricky-months-sort.md
new file mode 100644
index 0000000000..43956932f7
--- /dev/null
+++ b/.changeset/tricky-months-sort.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog-react': minor
+---
+
+**BREAKING**: Removed the deprecated `formatEntityRefTitle`, use `humanizeEntityRef` instead.
diff --git a/.changeset/twenty-birds-think.md b/.changeset/twenty-birds-think.md
deleted file mode 100644
index 5b1f9481c0..0000000000
--- a/.changeset/twenty-birds-think.md
+++ /dev/null
@@ -1,19 +0,0 @@
----
-'@backstage/create-app': patch
----
-
-Updated template to use package roles. To apply this change to an existing app, check out the [migration guide](https://backstage.io/docs/tutorials/package-role-migration).
-
-Specifically the following scripts in the root `package.json` have also been updated:
-
-```diff
-- "build": "lerna run build",
-+ "build": "backstage-cli repo build --all",
-
-...
-
-- "lint": "lerna run lint --since origin/master --",
-- "lint:all": "lerna run lint --",
-+ "lint": "backstage-cli repo lint --since origin/master",
-+ "lint:all": "backstage-cli repo lint",
-```
diff --git a/.changeset/twenty-fireants-turn.md b/.changeset/twenty-fireants-turn.md
deleted file mode 100644
index fd9dc17530..0000000000
--- a/.changeset/twenty-fireants-turn.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-scaffolder-backend': patch
----
-
-Allow passing more repo configuration for `publish:github` action
diff --git a/.changeset/twenty-planes-dress.md b/.changeset/twenty-planes-dress.md
deleted file mode 100644
index 4d1a5dc1d1..0000000000
--- a/.changeset/twenty-planes-dress.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-catalog-backend-module-aws': patch
----
-
-Added `AwsS3DiscoveryProcessor`, which was moved here from `@backstage/plugin-catalog-backend` where it previously resided.
diff --git a/.changeset/two-mails-boil.md b/.changeset/two-mails-boil.md
deleted file mode 100644
index 22651f1bd4..0000000000
--- a/.changeset/two-mails-boil.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/catalog-client': minor
----
-
-**BREAKING**: Removed `CatalogClient.getLocationByEntity` and `CatalogClient.getOriginLocationByEntity` which had previously been deprecated. Please use `CatalogApi.getLocationByRef` instead. Note that this only affects you if you were using `CatalogClient` (the class) directly, rather than `CatalogApi` (the interface), since it has been removed from the interface in an earlier release.
diff --git a/.changeset/warm-bananas-behave.md b/.changeset/warm-bananas-behave.md
deleted file mode 100644
index b1b6b4c8ec..0000000000
--- a/.changeset/warm-bananas-behave.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/cli': patch
----
-
-The `--since` flag of repo commands now silently falls back to using the provided `ref` directly if no merge base is available.
diff --git a/.changeset/warm-impalas-march.md b/.changeset/warm-impalas-march.md
new file mode 100644
index 0000000000..6db9900173
--- /dev/null
+++ b/.changeset/warm-impalas-march.md
@@ -0,0 +1,24 @@
+---
+'@backstage/create-app': patch
+---
+
+The main repo has switched from `@vscode/sqlite3` to `better-sqlite3` as its preferred SQLite installation. This decision was triggered by a number of issues with the former that arose because it needs build infrastructure in place and functional in order to be installed. The main drawback of this is that the new package uses the database client ID `better-sqlite3` instead of the plain `sqlite3`.
+
+If you want to perform the same switch in your own repository,
+
+- Replace all of your `package.json` dependencies on `@vscode/sqlite3` with the latest version of `better-sqlite3` instead
+
+ ```diff
+ "dependencies": {
+ - "@vscode/sqlite3": "^5.0.7",
+ + "better-sqlite3": "^7.5.0",
+ ```
+
+- In your app-config and tests, wherever you supply `client: 'sqlite3'`, instead supply `client: 'better-sqlite3`
+
+ ```diff
+ backend:
+ database:
+ - client: sqlite3
+ + client: better-sqlite3
+ ```
diff --git a/.changeset/weak-schools-wash.md b/.changeset/weak-schools-wash.md
deleted file mode 100644
index 86f3111d93..0000000000
--- a/.changeset/weak-schools-wash.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-catalog-react': minor
----
-
-**BREAKING**: Removed the deprecated `useOwnUser` hook. Existing usage can be replaced with `identityApi.getBackstageIdentity()`, followed by a call to `catalogClient.getEntityByRef(identity.userEntityRef)`.
diff --git a/.changeset/wicked-tools-return.md b/.changeset/wicked-tools-return.md
new file mode 100644
index 0000000000..e2183c0e73
--- /dev/null
+++ b/.changeset/wicked-tools-return.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-common': patch
+---
+
+Fix handling of bucket names with dots, in `AwsS3UrlReader`
diff --git a/.changeset/wild-lemons-pump.md b/.changeset/wild-lemons-pump.md
new file mode 100644
index 0000000000..e869abe2ac
--- /dev/null
+++ b/.changeset/wild-lemons-pump.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog-backend': minor
+---
+
+**BREAKING**: Removed the deprecated `presence` field from `LocationInput`.
diff --git a/.changeset/yellow-boxes-jump.md b/.changeset/yellow-boxes-jump.md
new file mode 100644
index 0000000000..4764c9c5fe
--- /dev/null
+++ b/.changeset/yellow-boxes-jump.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog-import': patch
+---
+
+No longer attempt to register locations as optional, since it's ignored.
diff --git a/.changeset/yellow-shirts-study.md b/.changeset/yellow-shirts-study.md
new file mode 100644
index 0000000000..7e464f1c26
--- /dev/null
+++ b/.changeset/yellow-shirts-study.md
@@ -0,0 +1,9 @@
+---
+'@backstage/catalog-model': minor
+'@backstage/plugin-catalog-backend': minor
+---
+
+**BREAKING**: Removed the `target` property from `EntityRelation`. This field has been replaced by `targetRef`.
+This means that `target: { name: 'team-a', kind: 'group', namespace: 'default' }` is now replaced with `targetRef: 'group:default/team-a'` in entity relations.
+
+The entities API endpoint still return the old `target` field for to ease transitions, however the future removal of this field will be considered non breaking.
diff --git a/.changeset/young-feet-flow.md b/.changeset/young-feet-flow.md
deleted file mode 100644
index 91e55da1d8..0000000000
--- a/.changeset/young-feet-flow.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-catalog-react': patch
----
-
-Internalized usage of `useOwnedEntities` hook.
diff --git a/.github/styles/vocab.txt b/.github/styles/vocab.txt
index 2614dd6b50..b8e432dd98 100644
--- a/.github/styles/vocab.txt
+++ b/.github/styles/vocab.txt
@@ -24,7 +24,7 @@ backported
backporting
Bigtable
Billett
-Bitbucket
+bitbucket
Bitrise
Blackbox
bool
@@ -61,6 +61,7 @@ const
cookiecutter
cron
cronjobs
+crontab
css
Datadog
dataflow
@@ -101,8 +102,9 @@ FireHydrant
Firekube
Firestore
Fiverr
+Gerrit
gitbeaker
-GitHub
+github
gitlab
GitLab
Gource
@@ -261,6 +263,7 @@ sanitization
scaffolded
scaffolder
Scaffolder
+scrollbar
seb
semlas
semver
diff --git a/.github/workflows/deploy_nightly.yml b/.github/workflows/deploy_nightly.yml
index ab4c9bcfdb..d5d3659625 100644
--- a/.github/workflows/deploy_nightly.yml
+++ b/.github/workflows/deploy_nightly.yml
@@ -58,6 +58,10 @@ jobs:
- name: build
run: yarn backstage-cli repo build
+ - name: build embedded techdocs app
+ working-directory: packages/techdocs-cli-embedded-app
+ run: yarn build
+
# Prepares a nightly release version of any package with pending changesets
# Pre-mode is exited if case we're in it, otherwise it has no effect
- name: prepare nightly release
diff --git a/.github/workflows/verify_windows.yml b/.github/workflows/verify_windows.yml
index 5326e293d3..6899b6ec2b 100644
--- a/.github/workflows/verify_windows.yml
+++ b/.github/workflows/verify_windows.yml
@@ -55,10 +55,6 @@ jobs:
- name: verify type dependencies
run: yarn lint:type-deps
- # The core packages need to be built for the codemods tests to work
- - name: build core packages
- run: lerna run --scope @backstage/core-* build
-
- name: test
run: yarn lerna -- run test
env:
diff --git a/ADOPTERS.md b/ADOPTERS.md
index 1961054237..7882e91aaa 100644
--- a/ADOPTERS.md
+++ b/ADOPTERS.md
@@ -2,105 +2,106 @@
_If you're using Backstage in your organization, please try to add your company name to this list. This really helps the project to gain momentum and credibility. It's a small contribution back to the project with a big impact._
-| Organization | Contact | Description of Use |
-| --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| [Spotify](https://www.spotify.com) | [@leemills83](https://github.com/leemills83) | Main interface towards all of Spotify's infrastructure and technical documentation. |
-| [bol.com](https://www.bol.com) | [@sagacity](https://github.com/sagacity) | Initial work being done to unify platform tooling. |
-| [DFDS](https://www.dfds.com) | [@carlsendk](https://github.com/carlsendk) | V2 self-service platform. |
-| [Roadie](https://roadie.io) | [@dtuite](https://github.com/dtuite) | Hosted, managed Backstage with easy set-up |
-| [Roku](https://www.roku.com) | [@timurista](https://github.com/timurista) | Initial work on Cloud engineering service platform. |
-| [SDA SE](https://sda.se) | [@dschwank](https://github.com/dschwank), [@iammnils](https://github.com/iammnils) | Central place for developing and sharing services in our insurance ecosystem. |
-| [H-E-B](https://www.heb.com) | [@german-j-rodriguez](https://github.com/german-j-rodriguez) | Initial work on Engineering Portal service platform. |
-| [American Airlines](https://www.aa.com) | [@paulpach](https://github.com/paulpach) | Central place for developers to develop and maintain applications |
-| [Kiwi.com](https://kiwi.com) | [@aexvir](https://github.com/aexvir) | Replacing the frontend of [The Zoo](https://github.com/kiwicom/the-zoo), their service registry. |
-| [Voi](https://www.voiscooters.com/) | [@K-Phoen](https://github.com/K-Phoen) | Developer portal, main gateway to our infrastructure, documentation and internal tooling. |
-| [Talkdesk](https://www.talkdesk.com) | [@jaime-talkdesk](https://github.com/jaime-talkdesk) | Initial work for Engineering Portal and Self Provisioning to R&D |
-| [Wealthsimple](https://www.wealthsimple.com) | [@andrewthauer](https://github.com/andrewthauer) | Developer portal, service catalog, documentation and tooling |
-| [Grab](https://www.grab.com) | [@althafh](https://github.com/althafh) | Initial work as a unified interface for all of Grab's internal tooling |
-| [Telenor Sweden](https://www.telenor.se) | [@O5ten](https://github.com/O5ten) | Building a developer portal for scaffolding projects towards our unified build environment and microservice stacks |
-| [Fiverr](https://www.fiverr.com) | [@nirga](https://github.com/nirga) | Unifying separate tools that developers are using today (i.e. monitoring, dead letter queues management, etc.) into a single platform. |
-| [Zalando SE](https://www.zalando.de) | [@leviferreira](https://github.com/leviferreira) | Building V2 of the Internal Development Portal. |
-| [LegalZoom](https://legalzoom.com) | [@backjo](https://github.com/backjo) | Developer portal - hub for all engineering projects and metadata. |
-| [Expedia Group](https://www.expediagroup.com) | [Mike Turner](mailto:miturner@expediagroup.com), [Sneha Kumar](mailto:snkumar@expediagroup.com), [@guillermomanzo](https://github.com/guillermomanzo), [Erik Lindgren](https://github.com/lindgren) | EG Common Developer Toolkit |
-| [Paddle.com](https://paddle.com) | [Ioannis Georgoulas](https://github.com/geototti21) | Developer portal (Tech Docs, Service Catalog, Internal Tooling), we use vanilla Backstage FE and custom BE implementation in Go |
-| [Acast.com](https://acast.com) | [Olle Lundberg](https://github.com/lndbrg) | Developer portal with tech docs, service catalog and a bunch of other internal tooling |
-| [Lunar](https://lunar.app) | [Jacob Valdemar](https://github.com/JacobValdemar) | Internal developer portal for service overview and insights, API documentation, technical guides, onboarding guides and RFC's. |
-| [Trendyol](https://trendyol.com) | [Gamze Senturk](https://github.com/gmzsenturk), [Mert Can Bilgic](https://github.com/mertcb) | The Developer Portal has been called `Pandora`. Provides an overview of Trendyol tech ecosystem. TechDocs, Catalog, Custom Plugins and Theme. |
-| [Peloton](https://www.onepeloton.com/) | [Jim Haughwout](https://github.com/JimHaughwout) | Creating our first developer portal and tech-docs. Exploring Service Catalog, Tech Insights and Cost Insights as well. |
-| [TELUS](https://telus.com) | [Seb Barre](https://github.com/sbarre) | The Go-to place to find answers about development and delivery at TELUS. |
-| [Brex](https://www.brex.com/) | [Vamsi Chitters](https://github.com/vamsikc) | A centralized UI to understand how a service fits in the whole Brex architecture and manage a team’s engineering dependencies. |
-| [Oriflame](https://www.oriflame.com/) | [Oriflame](https://github.com/oriflame) | Internal developer portal for services, single page apps and packages overview, API documentation, technical guides, tech-radar and more. |
-| [Booz Allen Hamilton](https://www.boozallen.com/) | [Jason Miller](https://github.com/JasonMiller-BAH) | Developer portal for a full-stack software development ecosystem that accelerates consistent and repeatable Modern Software Development practices for internal innovation and investments. |
-| [Netflix](https://www.netflix.com/) | [bleathem](https://github.com/bleathem) | Our Backstage implementation will be the front door to a unified experience connecting our internal platform products across important workflows with integrated knowledge and support. |
-| [b.well](https://www.icanbwell.com/) | [Jacob Rosales](https://github.com/jrosales) | Foundation for our engineering portal and cloud insights. |
-| [PagerDuty](https://www.pagerduty.com/) | [Mark Shaw](https://github.com/markshawtoronto) | Developer portal, initially focused on software templates and tech-docs. |
-| [MoonShiner](https://moonshiner.at) | [Fabian Hippmann](https://github.com/FabianHippmann) | Developer portal - helps us keep track of our customer projects, onboard new developers & improve our development process 🌕🚀🧑🚀 |
-| [FundApps](https://www.fundapps.co/) | [Elliot Greenwood](https://github.com/egnwd) | Developer Portal - A place for us to keep track of our projects and documentation for all services and processes |
-| [DAZN](https://dazn.com/) | [Lou Bichard](https://twitter.com/loujaybee), [Marco Crivellaro](https://github.com/crivetechie), [Alex Hollerith](mailto:alex.hollerith@dazn.com) | Ingesting all of DAZN's repos for the catalog, migrating our internal platform apps (pull request boards, release information, inner source marketplace etc) to Backstage plugins (where applicable). |
-| [HelloFresh](https://www.hellofresh.de/) | [@iammuho](https://github.com/iammuho), [@ElenaForester](https://github.com/ElenaForester), [@diegomarangoni](https://github.com/diegomarangoni) | Our developer portal at HelloFresh - Spread across an organisation of 500+ engineers globally. |
-| [FactSet](https://www.factset.com/) | [@kuangp](https://github.com/kuangp) | Developer portal to provide discoverability to all internal components, APIs, documentation, and scaffold templates with integrations to our internal infrastructure tools. |
-| [Workrise](https://www.workrise.com/) | [Michael Rode](https://github.com/michaelrode) | Developer portal, main gateway to our infrastructure, documentation and internal tooling. |
-| [RedVentures](https://www.redventures.com/) | [Chris Diaz](https://github.com/codingdiaz) | Developer portal that brings everything an engineer needs to provide value into a single pane of glass. |
-| [MavTek](https://www.mavtek.com/) | [@fgascon](https://github.com/fgascon) | Developer portal focused on standardizing practices, centralizing documentation and streamlining developer practices. |
-| [QuintoAndar](https://www.quintoandar.com.br/) | [@quintoandar](https://github.com/quintoandar) | Developer portal, services catalog and centralization of service metrics. |
-| [empathy.co](https://empathy.co/) | [@guillermotti](https://github.com/guillermotti) | Developer portal for tech docs, service catalog, plugin discovery and much more. |
-| [creditas.com](https://creditas.com/) | [@aureliosaraiva](https://github.com/aureliosaraiva) [@Creditas](https://github.com/creditas) | Centralization of all services, standards, documentation, etc. We started the deployment process. |
-| [Prisjakt](https://www.prisjakt.nu) / [PriceSpy](https://pricespy.co.uk) | [@kennylindahl](https://github.com/kennylindahl) | Internal developer portal - Documentation, scaffolding, software catalog, TechRadar, Gitlab org data integration |
-| [Powerspike](https://powerspike.tv/) | [@trelore](https://github.com/trelore) | Developer portal for documentation of core libraries and repositories. |
-| [2U](https://2u.com) | [Andrew Thal](https://github.com/athal7) | Development team home-base, promoting service discoverability, resource dependencies, and tech radar |
-| [Taxfix](https://taxfix.de/) | [Sami Ur Rehman](https://github.com/samiurrehman92) | Developer's portal with software catalog at it's core. Hosts API Specs, Tech Docs, Tech Radar and some custom plugins. |
-| [Busuu](https://busuu.com/) | [Adam Tester](https://github.com/adamtester) | Developer portal with service catalog, API docs, Event docs, service templating, and cost insights. |
-| [Loadsmart](https://loadsmart.com/) | [Loadsmart](https://github.com/loadsmart) | Improve services visibility and operations for service owners and developers. |
-| [Monzo](https://monzo.com/) | [@WillSewell](https://github.com/WillSewell), [@joechrisellis](https://github.com/joechrisellis) | Developer portal showing metadata and docs for over 2000 microservices. We have built a number of plugins such as a UI for our system to measure [software excellence](https://monzo.com/blog/2021/09/15/how-we-measure-software-excellence), and a UI to show deployment and config change events. |
-| [Vaimo](https://www.vaimo.com) | [@vaimo-magnus](https://github.com/vaimo-magnus) | Developer Portal for our developers at Vaimo, currently docs and self-service towards our internal PaaS based on k8s. Plans to extend the catalog into Projects, Environments etc |
-| [Wayfair](https://www.wayfair.com) | [@fransan](https://github.com/fransan), [@errskipower](https://github.com/errskipower), [@hrrs](https://github.com/hrrs) | Developer portal for service catalog, technical documentation, and APIs. |
-| [CircleHD](https://www.circlehd.com) | [@circlehddev](https://github.com/circlehddev) | Developer Portal for internal dev team across the globe |
-| [CastDesk](https://castdesk.com) | [@circlehddev](https://github.com/circlehddev) | Developer Portal for internal dev team across the globe |
-| [Santagostino](https://santagostino.it) | [@santagostino](https://github.com/santagostino) | Developer portal, gateway to our infrastructure, documentation, service catalog and internal tooling. |
-| [Peak](https://peak.ai) | [Luke Beamish](https://github.com/lukebeamish-peak) | Developer portal for all internal engineers to access documentation and tooling. |
-| [Gelato](https://gelato.com/) | [Dmitry Makarenko](https://github.com/dmitry-makarenko-gelato) | Developer portal: documentation, service templates, org structure, service catalog, plugins for integration with internal and third-party systems🚀. |
-| [GoCardless](https://gocardless.com/) | [James Turley](https://github.com/tragiclifestories) | Developer portal: documentation, service templates, org structure, service catalog, plugins for integration with internal systems. |
-| [Box](https://www.box.com) | [@kielosz](https://github.com/kielosz), [@jluk-box](https://github.com/jluk-box), [@ptychu](https://github.com/ptychu), [@alexrybch](https://github.com/alexrybch), [@szubster](https://github.com/szubster) | Developer portal for service catalog, integration with internal systems, new service onboarding. |
-| [Bazaarvoice](https://www.bazaarvoice.com) | [@niallmccullagh](https://github.com/niallmccullagh) | Developer portal for service catalog and scaffolds, publishing Github docs and API documentation, visualising our internal tech radar and our product engineering org structure. |
-| [Krateo PlatformOps](https://www.krateo.io) | [@projectkerberus](https://github.com/projectkerberus) | A multi-cloud control plane to create, manage and deploy any kind of resource easily and centrally via a Developer Portal that centralizes via a self-service catalog the templating and ownership of services, the available documentation, the overview of the components that compose an entire domain and all the data of the service lifecycle. |
-| [Adevinta](https://www.adevinta.com) | [Ray Sinnema](https://github.com/RemonSinnema) | Showcase shared services to our internal customers. |
-| [Splunk](https://www.splunk.com) | [@tonytamsf](https://github.com/tonytamsf) | Developer portal as a centralized place to find people, services, documentation, escalation policies and give bravos. This portal is also being used as a centralized search engine for engineering specific documentation. |
-| [SoundCloud](https://www.soundcloud.com) | [Julio Zynger](https://github.com/julioz) | Developer portal as a [humane registry](https://martinfowler.com/bliki/HumaneRegistry.html) for the organization: catalog of people, services, documentation, feature toggles, escalation policies, etc. |
-| [Volvofinans Bank](https://www.volvofinans.se) | [Johan Hammar](https://github.com/johanhammar) | Developer portal enabling engineers to manage and explore software and documentation. |
-| [Palo Alto Networks](https://www.paloaltonetworks.com) | [Jeremy Guarini](https://github.com/jeremyguarini), [Brian Lomeland](https://github.com/bbbmmmlll), [Palo Alto Networks](https://github.com/PaloAltoNetworks) | Developer portal, service catalog, documentation and tooling |
-| [Signal Iduna Group](https://www.signal-iduna.de/) | [Jonas Thomsen](https://github.com/JoThomsen) | Developer Portal, documentation, monitoring, service catalog for our insurance ecosystem |
-| [Tradeshift](https://www.tradeshift.com/) | [Soren Mathiasen](https://github.com/sorenmat) | Developer Portal: documentation, monitoring, service templates, service catalog for our micro services |
-| [Unity](https://unity.com) | [Ted Cordery](https://github.com/TeddyBallGame) | A centralized service catalog with documentation for our service engineers. |
-| [PicPay](https://www.picpay.com) | [Luis Baroni](https://github.com/lcsbaroni), [Renata Poluceno](https://github.com/renatapoluceno), [PicPay](https://github.com/picpay) | Developer portal for building services throught templates, service catalog with ownership of services, documentation and metrics providing autonomy and visibility for all. |
-| [Epic Games](https://www.epicgames.com) | [Brian Jung](https://github.com/brian-at-epic), [Jeff Goldian](https://github.com/jeffgoldian-Epic) | Developer Portal: Service Catalog, Documentation, Software Templates and more making our internal teams' lives easier! |
-| [Globo](https://globo.com) | [Carlos Gusmão](https://github.com/caeugusmao), [Guilherme Vierno](https://github.com/vierno), [Denis Aoki](https://github.com/dnsaoki2), [Maycon Dionisio](https://github.com/MayconDionisio), | Reduce the friction of accessing the information engineers need about Globo's digital services through a coherent and centralized experience. |
-| [QBE](https://www.qbe.com/) | [Daniel Steel](https://github.com/danielsteelqbe), [Pete Jespers](https://github.com/petejespersqbe) | Developer portal allowing our global teams to explore and create applications, documentation and cloud infrastructure easily and quickly 🚀 |
-| [GoTo](https://www.goto.com) | [Lorenzo Orsatti](https://github.com/lorsatti) | Improve onboarding experience of new developers. Discover faster and painlessly developer documentation, API definitions and team information. Provide useful dev metrics in a central place. Provide easy-to-use templates for new services. |
-| [Telstra](https://www.telstra.com.au) | [@kiranpatel11](https://github.com/kiranpatel11), [JasonC](https://github.com/JasonC17) | Primary usage: software catalog and templates Emerging usage : TechDocs, Explore Ecosystem, TechRadar, etc |
-| [Mosaico](https://www.mosaico.com.br/) | [Wédney Yuri](https://github.com/wedneyyuri),[@tino.milton](https://github.com/miltonjacomini) | A centralized service catalog of our documentation for our service engineers. |
-| [Mox Bank](https://www.mox.com/) | [Nick Laqua](https://github.com/nick-laqua-dragon) | "Single pane of glass" developer portal for providing a best-in-class developer experience to our product teams and making Mox the best tech environment in Hongkong 🥰🚀 |
-| [Keyloop](https://www.keyloop.com/) | [Andre Wanlin](https://github.com/awanlin) | Future-motive Developer Portal to help our teams create technology to make everything about buying and owning a car better. 🚗 |
-| [Simply Business](https://sbtech.simplybusiness.co.uk/) | [@addersuk](https://github.com/addersuk), [@LightningStairs](https://github.com/LightningStairs), [@punitcse](https://github.com/punitcse), [@moltenice](https://github.com/moltenice) | Central developer portal to access everything a developer needs such as docs, internal service catalog, and the ability to quickly create a new service from a template. Internally developed Backstage plugins allow us to customise the experience to how we work. |
-| [Overwolf](https://www.overwolf.com) | [@tomwolfgang](https://github.com/tomwolfgang) | Dev portal - software catalog, tech-docs, scaffolding |
-| [Hotmart](https://www.hotmart.com) | [@fabioviana-hotmart](https://github.com/fabioviana-hotmart) | The main Developers Portal to centralize docs, applications and technical metrics. |
-| [EF Education First](https://www.ef.com) | [Daan Boerlage](https://github.com/runebaas), [Rafał Nowosielski](https://github.com/rnowosielski) | Our developer portal - primarily used for cataloging and scaffolding with the ambition to expand with more feature adoptions over time |
-| [Power Home Remodeling](https://www.techatpower.com) | [Ben Langfeld](https://github.com/benlangfeld) | Developer portal to our internal services, build on open-source software (including Kubernetes) in our own datacenters. Our Portal allows our team members to navigate inherant complexity and standardise. |
-| [Livspace](https://www.livspace.com) | [Praveen Kumar](https://github.com/praveen-livspace) | Developer portal, service catalog, tech docs, API docs and plugins |
-| [Just Eat Takeaway](https://www.justeattakeaway.com) | [Kim Wilson](https://github.com/kwilson541) | Our developer portal which centralises applications, reduces cognitive load and provides teams insights. |
-| [Hopin](https://hopin.com) | [Vladimir Glafirov](https://github.com/vglafirov), [Chloe Lee](https://github.com/msfuko) | Developer portal to streamline the development practices. Integrated with service catalog, software templates, application monitoring, tech docs and plugins. |
-| [HBO Max](https://hbomax.com) | [@mdb](https://github.com/mdb), [@nesta219](https://github.com/nesta219), [@nmische](https://github.com/nmische), [@hbomark](https://github.com/hbomark) | Developer portal hosting service catalog and API documentation, as well as cloud infrastructure details, operational visibility tools, and a custom plugin for browsing notable platform change events, such as deployments and configuration updates. |
-| [RCHLO](https://www.riachuelo.com.br) & [MIDWAY](https://www.midway.com.br) | [@marcosborges](https://github.com/marcosborges), [@defaultbr](https://github.com/defaultbr) | Self-Service Platform |
-| [HP Inc](https://www.hp.com) | [Damon Kaswell](https://github.com/dekoding) | DevEx engagement hub (dev portal: docs, standards, Q&A) and extensive assets catalog (APIs, services, code, data, etc.) for the pan-HP internal developer community. |
-| [VMware](https://www.vmware.com) | [@mpriamo](https://github.com/mpriamo), [@krisapplegate](https://github.com/krisapplegate) | Part of [Tanzu Application Platform](https://docs.vmware.com/en/VMware-Tanzu-Application-Platform/index.html) offering; internal developer portal |
-| [Ualá](https://www.uala.com.ar/) | [Santiago Bernal](https://github.com/sabernal) | Initial work being done to centralize documentation for all our microservices and APIs, as well as scaffolding new services and tracking code quality |
-| [IKEA IT AB](https://www.ingka.com) | [@bjornramberg](https://github.com/bjornramberg), [@supriyachitale](https://github.com/supriyachitale) | Supporting engineers at scale with self serve access and connecting the dots of our engineering platform and services, enabling product teams to move faster and go further, and unleashing innovation, reuse and co-creation across the organisation. |
-| [Invitae](https://www.invitae.com/en) | [@ryan-hanchett](https://github.com/ryan-hanchett), [@gmandler42](https://github.com/gmandler42) | Centralized Developer Experience portal, putting all of our tooling behind a single pane of glass and creating a living service catalog. |
-| [Fortum](https://www.fortum.com/) | [@brunoamaroalmeida](https://github.com/brunoamaroalmeida), [@dhaval-vithalani](https://github.com/dhaval-vithalani), [@sunilkumarmohanty](https://github.com/sunilkumarmohanty) | A central portal containing information about our applications, services, processes and other software assets to be used by Fortum software engineering community. |
-| [Procore](https://www.procore.com/jobs/engineering) | [@shayon](https://github.com/Shayon), [@jamesdabbs-procore](https://github.com/jamesdabbs-procore) | Developer portal - centralized software catalog and templates to enable self serve and reduce cognitive load. |
-| [Bradesco](https://banco.bradesco/html/classic/sobre/index.shtm) | [@danilosoarescardoso](https://github.com/danilosoarescardoso) | Centralized developer portal with software catalog, software templates, techdocs and some plugins from community and by our own. |
-| [SeatGeek](https://seatgeek.com) | [@zhammer](https://github.com/zhammer) | Software catalog and documentation platform |
-| [Grupo Boticário](https://www.grupoboticario.com.br/) | [@chicoribas](https://github.com/chicoribas), [@fndiaz](https://github.com/fndiaz), [@digogid](https://github.com/digogid), [@manumbs](https://github.com/manumbs), [@haooliveira84](https://github.com/haooliveira84), [@Rhullyam](https://github.com/Rhullyam) | Centralized developer portal with catalog, documentation, and software templates to build a ready to go application, including pipelines (CI/CD) and cloud services provisioning |
-| [Snyk](https://snyk.io/) | [@robcresswell](https://github.com/robcresswell) | Developer portal for software discovery, API documentation and templating |
-| [Stilingue](https://www.stilingue.com.br/) | [@stilingue-inteligencia-artificial](https://github.com/Stilingue-IA), [@bbviana](https://github.com/bbviana) | Developer portal, services catalog and centralization of metrics from Grafana, Sentry and GCP. Furthermore, centralization of documentation and infra details like DNS, Network services, SSL and so on. |
-| [TUI Group](https://www.tuigroup.com/) | [Simon Stamm](https://github.com/simonstamm), [Christian Rudolph](https://github.com/ChrisRu82) | Developer portal for all engineer to provide discoverability to all internal components, APIs, documentation and to scaffold templates with integrations to our internal tools extended by plugins from our community. |
-| [Alliander](https://www.alliander.com/) | [@leon-vg](https://github.com/leon-vg), [@gieljl](https://github.com/gieljl), [@niekteg](https://github.com/niekteg) | Developer portal - software catalog, technical documentation, software templates, tech radar and exploration of used tools/services |
+| Organization | Contact | Description of Use |
+| --------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [Spotify](https://www.spotify.com) | [@leemills83](https://github.com/leemills83) | Main interface towards all of Spotify's infrastructure and technical documentation. |
+| [bol.com](https://www.bol.com) | [@sagacity](https://github.com/sagacity) | Initial work being done to unify platform tooling. |
+| [DFDS](https://www.dfds.com) | [@carlsendk](https://github.com/carlsendk) | V2 self-service platform. |
+| [Roadie](https://roadie.io) | [@dtuite](https://github.com/dtuite) | Hosted, managed Backstage with easy set-up |
+| [Roku](https://www.roku.com) | [@timurista](https://github.com/timurista) | Initial work on Cloud engineering service platform. |
+| [SDA SE](https://sda.se) | [@dschwank](https://github.com/dschwank), [@iammnils](https://github.com/iammnils) | Central place for developing and sharing services in our insurance ecosystem. |
+| [H-E-B](https://www.heb.com) | [@german-j-rodriguez](https://github.com/german-j-rodriguez) | Initial work on Engineering Portal service platform. |
+| [American Airlines](https://www.aa.com) | [@paulpach](https://github.com/paulpach) | Central place for developers to develop and maintain applications |
+| [Kiwi.com](https://kiwi.com) | [@aexvir](https://github.com/aexvir) | Replacing the frontend of [The Zoo](https://github.com/kiwicom/the-zoo), their service registry. |
+| [Voi](https://www.voiscooters.com/) | [@K-Phoen](https://github.com/K-Phoen) | Developer portal, main gateway to our infrastructure, documentation and internal tooling. |
+| [Talkdesk](https://www.talkdesk.com) | [@jaime-talkdesk](https://github.com/jaime-talkdesk) | Initial work for Engineering Portal and Self Provisioning to R&D |
+| [Wealthsimple](https://www.wealthsimple.com) | [@andrewthauer](https://github.com/andrewthauer) | Developer portal, service catalog, documentation and tooling |
+| [Grab](https://www.grab.com) | [@althafh](https://github.com/althafh) | Initial work as a unified interface for all of Grab's internal tooling |
+| [Telenor Sweden](https://www.telenor.se) | [@O5ten](https://github.com/O5ten) | Building a developer portal for scaffolding projects towards our unified build environment and microservice stacks |
+| [Fiverr](https://www.fiverr.com) | [@nirga](https://github.com/nirga) | Unifying separate tools that developers are using today (i.e. monitoring, dead letter queues management, etc.) into a single platform. |
+| [Zalando SE](https://www.zalando.de) | [@leviferreira](https://github.com/leviferreira) | Building V2 of the Internal Development Portal. |
+| [LegalZoom](https://legalzoom.com) | [@backjo](https://github.com/backjo) | Developer portal - hub for all engineering projects and metadata. |
+| [Expedia Group](https://www.expediagroup.com) | [Mike Turner](mailto:miturner@expediagroup.com), [Sneha Kumar](mailto:snkumar@expediagroup.com), [@guillermomanzo](https://github.com/guillermomanzo), [Erik Lindgren](https://github.com/lindgren) | EG Common Developer Toolkit |
+| [Paddle.com](https://paddle.com) | [Ioannis Georgoulas](https://github.com/geototti21) | Developer portal (Tech Docs, Service Catalog, Internal Tooling), we use vanilla Backstage FE and custom BE implementation in Go |
+| [Acast.com](https://acast.com) | [Olle Lundberg](https://github.com/lndbrg) | Developer portal with tech docs, service catalog and a bunch of other internal tooling |
+| [Lunar](https://lunar.app) | [Jacob Valdemar](https://github.com/JacobValdemar) | Internal developer portal for service overview and insights, API documentation, technical guides, onboarding guides and RFC's. |
+| [Trendyol](https://trendyol.com) | [Gamze Senturk](https://github.com/gmzsenturk), [Mert Can Bilgic](https://github.com/mertcb) | The Developer Portal has been called `Pandora`. Provides an overview of Trendyol tech ecosystem. TechDocs, Catalog, Custom Plugins and Theme. |
+| [Peloton](https://www.onepeloton.com/) | [Jim Haughwout](https://github.com/JimHaughwout) | Creating our first developer portal and tech-docs. Exploring Service Catalog, Tech Insights and Cost Insights as well. |
+| [TELUS](https://telus.com) | [Seb Barre](https://github.com/sbarre) | The Go-to place to find answers about development and delivery at TELUS. |
+| [Brex](https://www.brex.com/) | [Vamsi Chitters](https://github.com/vamsikc) | A centralized UI to understand how a service fits in the whole Brex architecture and manage a team’s engineering dependencies. |
+| [Oriflame](https://www.oriflame.com/) | [Oriflame](https://github.com/oriflame) | Internal developer portal for services, single page apps and packages overview, API documentation, technical guides, tech-radar and more. |
+| [Booz Allen Hamilton](https://www.boozallen.com/) | [Jason Miller](https://github.com/JasonMiller-BAH) | Developer portal for a full-stack software development ecosystem that accelerates consistent and repeatable Modern Software Development practices for internal innovation and investments. |
+| [Netflix](https://www.netflix.com/) | [bleathem](https://github.com/bleathem) | Our Backstage implementation will be the front door to a unified experience connecting our internal platform products across important workflows with integrated knowledge and support. |
+| [b.well](https://www.icanbwell.com/) | [Jacob Rosales](https://github.com/jrosales) | Foundation for our engineering portal and cloud insights. |
+| [PagerDuty](https://www.pagerduty.com/) | [Mark Shaw](https://github.com/markshawtoronto) | Developer portal, initially focused on software templates and tech-docs. |
+| [MoonShiner](https://moonshiner.at) | [Fabian Hippmann](https://github.com/FabianHippmann) | Developer portal - helps us keep track of our customer projects, onboard new developers & improve our development process 🌕🚀🧑🚀 |
+| [FundApps](https://www.fundapps.co/) | [Elliot Greenwood](https://github.com/egnwd) | Developer Portal - A place for us to keep track of our projects and documentation for all services and processes |
+| [DAZN](https://dazn.com/) | [Lou Bichard](https://twitter.com/loujaybee), [Marco Crivellaro](https://github.com/crivetechie), [Alex Hollerith](mailto:alex.hollerith@dazn.com) | Ingesting all of DAZN's repos for the catalog, migrating our internal platform apps (pull request boards, release information, inner source marketplace etc) to Backstage plugins (where applicable). |
+| [HelloFresh](https://www.hellofresh.de/) | [@iammuho](https://github.com/iammuho), [@ElenaForester](https://github.com/ElenaForester), [@diegomarangoni](https://github.com/diegomarangoni) | Our developer portal at HelloFresh - Spread across an organisation of 500+ engineers globally. |
+| [FactSet](https://www.factset.com/) | [@kuangp](https://github.com/kuangp) | Developer portal to provide discoverability to all internal components, APIs, documentation, and scaffold templates with integrations to our internal infrastructure tools. |
+| [Workrise](https://www.workrise.com/) | [Michael Rode](https://github.com/michaelrode) | Developer portal, main gateway to our infrastructure, documentation and internal tooling. |
+| [RedVentures](https://www.redventures.com/) | [Chris Diaz](https://github.com/codingdiaz) | Developer portal that brings everything an engineer needs to provide value into a single pane of glass. |
+| [MavTek](https://www.mavtek.com/) | [@fgascon](https://github.com/fgascon) | Developer portal focused on standardizing practices, centralizing documentation and streamlining developer practices. |
+| [QuintoAndar](https://www.quintoandar.com.br/) | [@quintoandar](https://github.com/quintoandar) | Developer portal, services catalog and centralization of service metrics. |
+| [empathy.co](https://empathy.co/) | [@guillermotti](https://github.com/guillermotti) | Developer portal for tech docs, service catalog, plugin discovery and much more. |
+| [creditas.com](https://creditas.com/) | [@aureliosaraiva](https://github.com/aureliosaraiva) [@Creditas](https://github.com/creditas) | Centralization of all services, standards, documentation, etc. We started the deployment process. |
+| [Prisjakt](https://www.prisjakt.nu) / [PriceSpy](https://pricespy.co.uk) | [@kennylindahl](https://github.com/kennylindahl) | Internal developer portal - Documentation, scaffolding, software catalog, TechRadar, Gitlab org data integration |
+| [Powerspike](https://powerspike.tv/) | [@trelore](https://github.com/trelore) | Developer portal for documentation of core libraries and repositories. |
+| [2U](https://2u.com) | [Andrew Thal](https://github.com/athal7) | Development team home-base, promoting service discoverability, resource dependencies, and tech radar |
+| [Taxfix](https://taxfix.de/) | [Sami Ur Rehman](https://github.com/samiurrehman92) | Developer's portal with software catalog at it's core. Hosts API Specs, Tech Docs, Tech Radar and some custom plugins. |
+| [Busuu](https://busuu.com/) | [Adam Tester](https://github.com/adamtester) | Developer portal with service catalog, API docs, Event docs, service templating, and cost insights. |
+| [Loadsmart](https://loadsmart.com/) | [Loadsmart](https://github.com/loadsmart) | Improve services visibility and operations for service owners and developers. |
+| [Monzo](https://monzo.com/) | [@WillSewell](https://github.com/WillSewell), [@joechrisellis](https://github.com/joechrisellis) | Developer portal showing metadata and docs for over 2000 microservices. We have built a number of plugins such as a UI for our system to measure [software excellence](https://monzo.com/blog/2021/09/15/how-we-measure-software-excellence), and a UI to show deployment and config change events. |
+| [Vaimo](https://www.vaimo.com) | [@vaimo-magnus](https://github.com/vaimo-magnus) | Developer Portal for our developers at Vaimo, currently docs and self-service towards our internal PaaS based on k8s. Plans to extend the catalog into Projects, Environments etc |
+| [Wayfair](https://www.wayfair.com) | [@fransan](https://github.com/fransan), [@errskipower](https://github.com/errskipower), [@hrrs](https://github.com/hrrs) | Developer portal for service catalog, technical documentation, and APIs. |
+| [CircleHD](https://www.circlehd.com) | [@circlehddev](https://github.com/circlehddev) | Developer Portal for internal dev team across the globe |
+| [CastDesk](https://castdesk.com) | [@circlehddev](https://github.com/circlehddev) | Developer Portal for internal dev team across the globe |
+| [Santagostino](https://santagostino.it) | [@santagostino](https://github.com/santagostino) | Developer portal, gateway to our infrastructure, documentation, service catalog and internal tooling. |
+| [Peak](https://peak.ai) | [Luke Beamish](https://github.com/lukebeamish-peak) | Developer portal for all internal engineers to access documentation and tooling. |
+| [Gelato](https://gelato.com/) | [Dmitry Makarenko](https://github.com/dmitry-makarenko-gelato) | Developer portal: documentation, service templates, org structure, service catalog, plugins for integration with internal and third-party systems🚀. |
+| [GoCardless](https://gocardless.com/) | [James Turley](https://github.com/tragiclifestories) | Developer portal: documentation, service templates, org structure, service catalog, plugins for integration with internal systems. |
+| [Box](https://www.box.com) | [@kielosz](https://github.com/kielosz), [@jluk-box](https://github.com/jluk-box), [@ptychu](https://github.com/ptychu), [@alexrybch](https://github.com/alexrybch), [@szubster](https://github.com/szubster) | Developer portal for service catalog, integration with internal systems, new service onboarding. |
+| [Bazaarvoice](https://www.bazaarvoice.com) | [@niallmccullagh](https://github.com/niallmccullagh) | Developer portal for service catalog and scaffolds, publishing Github docs and API documentation, visualising our internal tech radar and our product engineering org structure. |
+| [Krateo PlatformOps](https://www.krateo.io) | [@projectkerberus](https://github.com/projectkerberus) | A multi-cloud control plane to create, manage and deploy any kind of resource easily and centrally via a Developer Portal that centralizes via a self-service catalog the templating and ownership of services, the available documentation, the overview of the components that compose an entire domain and all the data of the service lifecycle. |
+| [Adevinta](https://www.adevinta.com) | [Ray Sinnema](https://github.com/RemonSinnema) | Showcase shared services to our internal customers. |
+| [Splunk](https://www.splunk.com) | [@tonytamsf](https://github.com/tonytamsf) | Developer portal as a centralized place to find people, services, documentation, escalation policies and give bravos. This portal is also being used as a centralized search engine for engineering specific documentation. |
+| [SoundCloud](https://www.soundcloud.com) | [Julio Zynger](https://github.com/julioz) | Developer portal as a [humane registry](https://martinfowler.com/bliki/HumaneRegistry.html) for the organization: catalog of people, services, documentation, feature toggles, escalation policies, etc. |
+| [Volvofinans Bank](https://www.volvofinans.se) | [Johan Hammar](https://github.com/johanhammar) | Developer portal enabling engineers to manage and explore software and documentation. |
+| [Palo Alto Networks](https://www.paloaltonetworks.com) | [Jeremy Guarini](https://github.com/jeremyguarini), [Brian Lomeland](https://github.com/bbbmmmlll), [Palo Alto Networks](https://github.com/PaloAltoNetworks) | Developer portal, service catalog, documentation and tooling |
+| [Signal Iduna Group](https://www.signal-iduna.de/) | [Jonas Thomsen](https://github.com/JoThomsen) | Developer Portal, documentation, monitoring, service catalog for our insurance ecosystem |
+| [Tradeshift](https://www.tradeshift.com/) | [Soren Mathiasen](https://github.com/sorenmat) | Developer Portal: documentation, monitoring, service templates, service catalog for our micro services |
+| [Unity](https://unity.com) | [Ted Cordery](https://github.com/TeddyBallGame) | A centralized service catalog with documentation for our service engineers. |
+| [PicPay](https://www.picpay.com) | [Luis Baroni](https://github.com/lcsbaroni), [Renata Poluceno](https://github.com/renatapoluceno), [PicPay](https://github.com/picpay) | Developer portal for building services through templates, service catalog with ownership of services, documentation and metrics providing autonomy and visibility for all. |
+| [Epic Games](https://www.epicgames.com) | [Brian Jung](https://github.com/brian-at-epic), [Jeff Goldian](https://github.com/jeffgoldian-Epic) | Developer Portal: Service Catalog, Documentation, Software Templates and more making our internal teams' lives easier! |
+| [Globo](https://globo.com) | [Carlos Gusmão](https://github.com/caeugusmao), [Guilherme Vierno](https://github.com/vierno), [Denis Aoki](https://github.com/dnsaoki2), [Maycon Dionisio](https://github.com/MayconDionisio), | Reduce the friction of accessing the information engineers need about Globo's digital services through a coherent and centralized experience. |
+| [QBE](https://www.qbe.com/) | [Daniel Steel](https://github.com/danielsteelqbe), [Pete Jespers](https://github.com/petejespersqbe) | Developer portal allowing our global teams to explore and create applications, documentation and cloud infrastructure easily and quickly 🚀 |
+| [GoTo](https://www.goto.com) | [Lorenzo Orsatti](https://github.com/lorsatti) | Improve onboarding experience of new developers. Discover faster and painlessly developer documentation, API definitions and team information. Provide useful dev metrics in a central place. Provide easy-to-use templates for new services. |
+| [Telstra](https://www.telstra.com.au) | [@kiranpatel11](https://github.com/kiranpatel11), [JasonC](https://github.com/JasonC17) | Primary usage: software catalog and templates Emerging usage : TechDocs, Explore Ecosystem, TechRadar, etc |
+| [Mosaico](https://www.mosaico.com.br/) | [Wédney Yuri](https://github.com/wedneyyuri),[@tino.milton](https://github.com/miltonjacomini) | A centralized service catalog of our documentation for our service engineers. |
+| [Mox Bank](https://www.mox.com/) | [Nick Laqua](https://github.com/nick-laqua-dragon) | "Single pane of glass" developer portal for providing a best-in-class developer experience to our product teams and making Mox the best tech environment in Hongkong 🥰🚀 |
+| [Keyloop](https://www.keyloop.com/) | [Andre Wanlin](https://github.com/awanlin) | Future-motive Developer Portal to help our teams create technology to make everything about buying and owning a car better. 🚗 |
+| [Simply Business](https://sbtech.simplybusiness.co.uk/) | [@addersuk](https://github.com/addersuk), [@LightningStairs](https://github.com/LightningStairs), [@punitcse](https://github.com/punitcse), [@moltenice](https://github.com/moltenice) | Central developer portal to access everything a developer needs such as docs, internal service catalog, and the ability to quickly create a new service from a template. Internally developed Backstage plugins allow us to customise the experience to how we work. |
+| [Overwolf](https://www.overwolf.com) | [@tomwolfgang](https://github.com/tomwolfgang) | Dev portal - software catalog, tech-docs, scaffolding |
+| [Hotmart](https://www.hotmart.com) | [@fabioviana-hotmart](https://github.com/fabioviana-hotmart) | The main Developers Portal to centralize docs, applications and technical metrics. |
+| [EF Education First](https://www.ef.com) | [Daan Boerlage](https://github.com/runebaas), [Rafał Nowosielski](https://github.com/rnowosielski) | Our developer portal - primarily used for cataloging and scaffolding with the ambition to expand with more feature adoptions over time |
+| [Power Home Remodeling](https://www.techatpower.com) | [Ben Langfeld](https://github.com/benlangfeld) | Developer portal to our internal services, build on open-source software (including Kubernetes) in our own datacenters. Our Portal allows our team members to navigate inherant complexity and standardise. |
+| [Livspace](https://www.livspace.com) | [Praveen Kumar](https://github.com/praveen-livspace) | Developer portal, service catalog, tech docs, API docs and plugins |
+| [Just Eat Takeaway](https://www.justeattakeaway.com) | [Kim Wilson](https://github.com/kwilson541) | Our developer portal which centralises applications, reduces cognitive load and provides teams insights. |
+| [Hopin](https://hopin.com) | [Vladimir Glafirov](https://github.com/vglafirov), [Chloe Lee](https://github.com/msfuko) | Developer portal to streamline the development practices. Integrated with service catalog, software templates, application monitoring, tech docs and plugins. |
+| [HBO Max](https://hbomax.com) | [@mdb](https://github.com/mdb), [@nesta219](https://github.com/nesta219), [@nmische](https://github.com/nmische), [@hbomark](https://github.com/hbomark) | Developer portal hosting service catalog and API documentation, as well as cloud infrastructure details, operational visibility tools, and a custom plugin for browsing notable platform change events, such as deployments and configuration updates. |
+| [RCHLO](https://www.riachuelo.com.br) & [MIDWAY](https://www.midway.com.br) | [@marcosborges](https://github.com/marcosborges), [@defaultbr](https://github.com/defaultbr) | Self-Service Platform |
+| [HP Inc](https://www.hp.com) | [Damon Kaswell](https://github.com/dekoding) | DevEx engagement hub (dev portal: docs, standards, Q&A) and extensive assets catalog (APIs, services, code, data, etc.) for the pan-HP internal developer community. |
+| [VMware](https://www.vmware.com) | [@mpriamo](https://github.com/mpriamo), [@krisapplegate](https://github.com/krisapplegate) | Part of [Tanzu Application Platform](https://docs.vmware.com/en/VMware-Tanzu-Application-Platform/index.html) offering; internal developer portal |
+| [Ualá](https://www.uala.com.ar/) | [Santiago Bernal](https://github.com/sabernal) | Initial work being done to centralize documentation for all our microservices and APIs, as well as scaffolding new services and tracking code quality |
+| [IKEA IT AB](https://www.ingka.com) | [@bjornramberg](https://github.com/bjornramberg), [@supriyachitale](https://github.com/supriyachitale) | Supporting engineers at scale with self serve access and connecting the dots of our engineering platform and services, enabling product teams to move faster and go further, and unleashing innovation, reuse and co-creation across the organisation. |
+| [Invitae](https://www.invitae.com/en) | [@ryan-hanchett](https://github.com/ryan-hanchett), [@gmandler42](https://github.com/gmandler42) | Centralized Developer Experience portal, putting all of our tooling behind a single pane of glass and creating a living service catalog. |
+| [Fortum](https://www.fortum.com/) | [@brunoamaroalmeida](https://github.com/brunoamaroalmeida), [@dhaval-vithalani](https://github.com/dhaval-vithalani), [@sunilkumarmohanty](https://github.com/sunilkumarmohanty) | A central portal containing information about our applications, services, processes and other software assets to be used by Fortum software engineering community. |
+| [Procore](https://www.procore.com/jobs/engineering) | [@shayon](https://github.com/Shayon), [@jamesdabbs-procore](https://github.com/jamesdabbs-procore) | Developer portal - centralized software catalog and templates to enable self serve and reduce cognitive load. |
+| [Bradesco](https://banco.bradesco/html/classic/sobre/index.shtm) | [@danilosoarescardoso](https://github.com/danilosoarescardoso) | Centralized developer portal with software catalog, software templates, techdocs and some plugins from community and by our own. |
+| [SeatGeek](https://seatgeek.com) | [@zhammer](https://github.com/zhammer) | Software catalog and documentation platform |
+| [Grupo Boticário](https://www.grupoboticario.com.br/) | [@chicoribas](https://github.com/chicoribas), [@fndiaz](https://github.com/fndiaz), [@digogid](https://github.com/digogid), [@manumbs](https://github.com/manumbs), [@haooliveira84](https://github.com/haooliveira84), [@Rhullyam](https://github.com/Rhullyam) | Centralized developer portal with catalog, documentation, and software templates to build a ready to go application, including pipelines (CI/CD) and cloud services provisioning |
+| [Snyk](https://snyk.io/) | [@robcresswell](https://github.com/robcresswell) | Developer portal for software discovery, API documentation and templating |
+| [Stilingue](https://www.stilingue.com.br/) | [@stilingue-inteligencia-artificial](https://github.com/Stilingue-IA), [@bbviana](https://github.com/bbviana) | Developer portal, services catalog and centralization of metrics from Grafana, Sentry and GCP. Furthermore, centralization of documentation and infra details like DNS, Network services, SSL and so on. |
+| [TUI Group](https://www.tuigroup.com/) | [Simon Stamm](https://github.com/simonstamm), [Christian Rudolph](https://github.com/ChrisRu82) | Developer portal for all engineer to provide discoverability to all internal components, APIs, documentation and to scaffold templates with integrations to our internal tools extended by plugins from our community. |
+| [Alliander](https://www.alliander.com/) | [@leon-vg](https://github.com/leon-vg), [@gieljl](https://github.com/gieljl), [@niekteg](https://github.com/niekteg) | Developer portal - software catalog, technical documentation, software templates, tech radar and exploration of used tools/services |
+| [Surevine](https://www.surevine.com/) | [@DJDANNY123](https://github.com/djdanny123) | Developer portal for software catalog, discovery and a view of the technologies we are using across the organisation, we are looking to explore how we can enrich our entities in Backstage by integrating a software bill of materials. |
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e853a68ad3..e4aad09207 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -120,7 +120,7 @@ We use [changesets](https://github.com/atlassian/changesets) to help us prepare
### When to use a changeset?
-Any time a patch, minor, or major change aligning to [Semantic Versioning](https://semver.org) is made to any published package in `packages/` or `plugins/`, a changeset should be used. It helps to align your change to the [Backstage stability index](https://backstage.io/docs/overview/stability-index) for the package you are changing, for example, when to provide additional clarity on deprecation or impacting changes which will then be included into CHANGELOGs.
+Any time a patch, minor, or major change aligning to [Semantic Versioning](https://semver.org) is made to any published package in `packages/` or `plugins/`, a changeset should be used. It helps to align your change to the [Backstage package versioning policy](https://backstage.io/docs/overview/versioning-policy#package-versioning-policy) for the package you are changing, for example, when to provide additional clarity on deprecation or impacting changes which will then be included into CHANGELOGs.
In general, changesets are only needed for changes to packages within `packages/` or `plugins/` directories, and only for the packages that are not marked as `private`. Changesets are also not needed for changes that do not affect the published version of each package, for example changes to tests or in-line source code comments.
diff --git a/README.md b/README.md
index e78800ef84..1078631926 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,6 @@
# [Backstage](https://backstage.io)
-_During March 7 to March 11 the maintainers will be taking part in Spotify's annual hack week. Development will continue as usual, but expect a slower pace for discussions and PR reviews. Why not take this opportunity to [build a plugin](https://backstage.io/docs/plugins/)?_
-
[](https://opensource.org/licenses/Apache-2.0)
[](https://www.cncf.io/projects)
[](https://github.com/backstage/backstage/actions?query=workflow%3A%22Main+Master+Build%22)
diff --git a/app-config.yaml b/app-config.yaml
index ab68d4398f..b3ca3c7203 100644
--- a/app-config.yaml
+++ b/app-config.yaml
@@ -33,7 +33,7 @@ backend:
listen:
port: 7007
database:
- client: sqlite3
+ client: better-sqlite3
connection: ':memory:'
cache:
store: memory
diff --git a/docs/architecture-decisions/adr006-avoid-react-fc.md b/docs/architecture-decisions/adr006-avoid-react-fc.md
index ea43cb215d..6a7c431655 100644
--- a/docs/architecture-decisions/adr006-avoid-react-fc.md
+++ b/docs/architecture-decisions/adr006-avoid-react-fc.md
@@ -45,7 +45,7 @@ const GoodComponent = ({ text, children }: GoodProps) => (
);
-/* Or as a shorthand, if no specifc child type is required */
+/* Or as a shorthand, if no specific child type is required */
type GoodProps = PropsWithChildren<{ text: string }>;
const GoodComponent = ({ text, children }: GoodProps) => (
- Compile and Execut...
+ Compile and Execute...
diff --git a/docs/auth/google/gcp-iap-auth.md b/docs/auth/google/gcp-iap-auth.md
index 7799517b5f..cdafeb1317 100644
--- a/docs/auth/google/gcp-iap-auth.md
+++ b/docs/auth/google/gcp-iap-auth.md
@@ -45,17 +45,14 @@ Add a `providerFactories` entry to the router in
```ts
import { createGcpIapProvider } from '@backstage/plugin-auth-backend';
-export default async function createPlugin({
- logger,
- database,
- config,
- discovery,
-}: PluginEnvironment): Promise {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
return await createRouter({
- logger,
- config,
- database,
- discovery,
+ logger: env.logger,
+ config: env.config,
+ database: env.database,
+ discovery: env.discovery,
providerFactories: {
'gcp-iap': createGcpIapProvider({
// Replace the auth handler if you want to customize the returned user
diff --git a/docs/auth/identity-resolver.md b/docs/auth/identity-resolver.md
index 3b355470d1..c336da38dd 100644
--- a/docs/auth/identity-resolver.md
+++ b/docs/auth/identity-resolver.md
@@ -29,9 +29,9 @@ sign-in resolvers and set them for any of the Authentication providers inside
```ts
import { DEFAULT_NAMESPACE, stringifyEntityRef } from '@backstage/catalog-model';
-export default async function createPlugin({
- ...
-}: PluginEnvironment): Promise {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
return await createRouter({
...
providerFactories: {
@@ -105,13 +105,13 @@ matching `google.com/email` annotation.
It can be enabled like this
-```tsx
+```ts
// File: packages/backend/src/plugins/auth.ts
import { googleEmailSignInResolver, createGoogleProvider } from '@backstage/plugin-auth-backend';
-export default async function createPlugin({
- ...
-}: PluginEnvironment): Promise {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
return await createRouter({
...
providerFactories: {
@@ -130,9 +130,9 @@ can do this using the `CatalogIdentityClient` provided as context to Sign-In
resolvers:
```ts
-export default async function createPlugin({
- ...
-}: PluginEnvironment): Promise {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
return await createRouter({
...
providerFactories: {
@@ -174,11 +174,11 @@ display name and profile picture.
This is also the place where you can do authorization and validation of the user
and throw errors if the user should not be allowed access in Backstage.
-```tsx
+```ts
// File: packages/backend/src/plugins/auth.ts
-export default async function createPlugin({
- ...
-}: PluginEnvironment): Promise {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
return await createRouter({
...
providerFactories: {
diff --git a/docs/features/kubernetes/configuration.md b/docs/features/kubernetes/configuration.md
index 702e0c7736..612f4903d9 100644
--- a/docs/features/kubernetes/configuration.md
+++ b/docs/features/kubernetes/configuration.md
@@ -255,7 +255,7 @@ CPU/Memory for pods returned by the API server. Defaults to `false`.
##### `exposeDashboard`
-This determines wether the `dashboardApp` and `dashboardParameters` should be
+This determines whether the `dashboardApp` and `dashboardParameters` should be
automatically configured in order to expose the GKE dashboard from the
Kubernetes plugin.
diff --git a/docs/features/kubernetes/installation.md b/docs/features/kubernetes/installation.md
index 2e0d9dccb9..18ceca9d92 100644
--- a/docs/features/kubernetes/installation.md
+++ b/docs/features/kubernetes/installation.md
@@ -60,15 +60,15 @@ add the following:
```typescript
// In packages/backend/src/plugins/kubernetes.ts
import { KubernetesBuilder } from '@backstage/plugin-kubernetes-backend';
+import { Router } from 'express';
import { PluginEnvironment } from '../types';
-export default async function createPlugin({
- logger,
- config,
-}: PluginEnvironment) {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
const { router } = await KubernetesBuilder.createBuilder({
- logger,
- config,
+ logger: env.logger,
+ config: env.config,
}).build();
return router;
}
diff --git a/docs/features/search/getting-started.md b/docs/features/search/getting-started.md
index 7c3717e22e..dc86b49947 100644
--- a/docs/features/search/getting-started.md
+++ b/docs/features/search/getting-started.md
@@ -150,20 +150,24 @@ import {
} from '@backstage/plugin-search-backend-node';
import { PluginEnvironment } from '../types';
import { DefaultCatalogCollator } from '@backstage/plugin-catalog-backend';
+import { Router } from 'express';
-export default async function createPlugin({
- logger,
- discovery,
- tokenManager,
-}: PluginEnvironment) {
- const searchEngine = new LunrSearchEngine({ logger });
- const indexBuilder = new IndexBuilder({ logger, searchEngine });
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
+ const searchEngine = new LunrSearchEngine({
+ logger: env.logger,
+ });
+ const indexBuilder = new IndexBuilder({
+ logger: env.logger,
+ searchEngine,
+ });
indexBuilder.addCollator({
defaultRefreshIntervalSeconds: 600,
collator: new DefaultCatalogCollator({
- discovery,
- tokenManager,
+ discovery: env.discovery,
+ tokenManager: env.tokenManager,
}),
});
@@ -174,7 +178,7 @@ export default async function createPlugin({
return await createRouter({
engine: indexBuilder.getSearchEngine(),
- logger,
+ logger: env.logger,
});
}
```
@@ -285,13 +289,13 @@ which are responsible for providing documents
number of collators with the `IndexBuilder` like this:
```typescript
-const indexBuilder = new IndexBuilder({ logger, searchEngine });
+const indexBuilder = new IndexBuilder({ logger: env.logger, searchEngine });
indexBuilder.addCollator({
defaultRefreshIntervalSeconds: 600,
collator: new DefaultCatalogCollator({
- discovery,
- tokenManager,
+ discovery: env.discovery,
+ tokenManager: env.tokenManager,
}),
});
@@ -311,8 +315,8 @@ its `defaultRefreshIntervalSeconds` value, like this:
indexBuilder.addCollator({
defaultRefreshIntervalSeconds: 600,
collator: new DefaultCatalogCollator({
- discovery,
- tokenManager,
+ discovery: env.discovery,
+ tokenManager: env.tokenManager,
}),
});
```
diff --git a/docs/features/search/how-to-guides.md b/docs/features/search/how-to-guides.md
index c41e9c7bdc..c5f53c905f 100644
--- a/docs/features/search/how-to-guides.md
+++ b/docs/features/search/how-to-guides.md
@@ -72,10 +72,10 @@ import { DefaultTechDocsCollatorFactory } from '@backstage/plugin-techdocs-backe
```typescript
indexBuilder.addCollator({
defaultRefreshIntervalSeconds: 600,
- factory: DefaultTechDocsCollatorFactory.fromConfig(config, {
- discovery,
- logger,
- tokenManager,
+ factory: DefaultTechDocsCollatorFactory.fromConfig(env.config, {
+ discovery: env.discovery,
+ logger: env.logger,
+ tokenManager: env.tokenManager,
}),
});
```
@@ -120,9 +120,9 @@ provided by `@backstage/plugin-catalog-backend` offers some configuration too!
indexBuilder.addCollator({
defaultRefreshIntervalSeconds: 600,
- collator: DefaultCatalogCollator.fromConfig(config, {
- discovery,
- tokenManager,
+ collator: DefaultCatalogCollator.fromConfig(env.config, {
+ discovery: env.discovery,
+ tokenManager: env.tokenManager,
+ filter: {
+ kind: ['API', 'Component', 'Domain', 'Group', 'System', 'User'],
+ },
@@ -167,18 +167,22 @@ provided by existing plugins, the migration process is fairly straightforward:
+import { DefaultCatalogCollatorFactory } from '@backstage/plugin-catalog-backend';
+import { DefaultTechDocsCollatorFactory } from '@backstage/plugin-techdocs-backend';
// ...
- const indexBuilder = new IndexBuilder({ logger, searchEngine });
+ const indexBuilder = new IndexBuilder({ logger: env.logger, searchEngine });
indexBuilder.addCollator({
defaultRefreshIntervalSeconds: 600,
- - collator: DefaultCatalogCollator.fromConfig(config, { discovery }),
- + factory: DefaultCatalogCollatorFactory.fromConfig(config, { discovery }),
+ - collator: DefaultCatalogCollator.fromConfig(env.config, {
+ discovery: env.discovery,
+ }),
+ + factory: DefaultCatalogCollatorFactory.fromConfig(env.config, {
+ discovery: env.discovery,
+ }),
});
indexBuilder.addCollator({
defaultRefreshIntervalSeconds: 600,
- - collator: DefaultTechDocsCollator.fromConfig(config, {
- + factory: DefaultTechDocsCollatorFactory.fromConfig(config, {
- discovery,
- logger,
+ - collator: DefaultTechDocsCollator.fromConfig(env.config, {
+ + factory: DefaultTechDocsCollatorFactory.fromConfig(env.config, {
+ discovery: env.discovery,
+ logger: env.logger,
}),
});
```
diff --git a/docs/features/search/search-engines.md b/docs/features/search/search-engines.md
index 8342c74096..f1fd4bd62b 100644
--- a/docs/features/search/search-engines.md
+++ b/docs/features/search/search-engines.md
@@ -17,7 +17,7 @@ provided search engines by using the exposed setter to set the modified query
translator into the instance.
```typescript
-const searchEngine = new LunrSearchEngine({ logger });
+const searchEngine = new LunrSearchEngine({ logger: env.logger });
searchEngine.setTranslator(new MyNewAndBetterQueryTranslator());
```
@@ -30,8 +30,8 @@ Lunr can be instantiated like this:
```typescript
// app/backend/src/plugins/search.ts
-const searchEngine = new LunrSearchEngine({ logger });
-const indexBuilder = new IndexBuilder({ logger, searchEngine });
+const searchEngine = new LunrSearchEngine({ logger: env.logger });
+const indexBuilder = new IndexBuilder({ logger: env.logger, searchEngine });
```
## Postgres
@@ -58,9 +58,9 @@ configured and make the following changes to your backend:
// In packages/backend/src/plugins/search.ts
// Initialize a connection to a search engine.
-const searchEngine = (await PgSearchEngine.supported(database))
- ? await PgSearchEngine.from({ database })
- : new LunrSearchEngine({ logger });
+const searchEngine = (await PgSearchEngine.supported(env.database))
+ ? await PgSearchEngine.from({ database: env.database })
+ : new LunrSearchEngine({ logger: env.logger });
```
## ElasticSearch
@@ -74,10 +74,10 @@ Similarly to Lunr above, ElasticSearch can be set up like this:
```typescript
// app/backend/src/plugins/search.ts
const searchEngine = await ElasticSearchSearchEngine.initialize({
- logger,
- config,
+ logger: env.logger,
+ config: env.config,
});
-const indexBuilder = new IndexBuilder({ logger, searchEngine });
+const indexBuilder = new IndexBuilder({ logger: env.logger, searchEngine });
```
For the engine to be available, your backend package needs a dependency into
diff --git a/docs/features/software-catalog/descriptor-format.md b/docs/features/software-catalog/descriptor-format.md
index 70a8aeaa51..86c832e3d2 100644
--- a/docs/features/software-catalog/descriptor-format.md
+++ b/docs/features/software-catalog/descriptor-format.md
@@ -64,7 +64,7 @@ spec:
This is the same entity as returned in JSON from the software catalog API:
-```js
+```json
{
"apiVersion": "backstage.io/v1alpha1",
"kind": "Component",
@@ -76,15 +76,16 @@ This is the same entity as returned in JSON from the software catalog API:
},
"description": "The place to be, for great artists",
"etag": "ZjU2MWRkZWUtMmMxZS00YTZiLWFmMWMtOTE1NGNiZDdlYzNk",
- "generation": 1,
"labels": {
"example.com/custom": "custom_label_value"
},
- "links": [{
- "url": "https://admin.example-org.com",
- "title": "Admin Dashboard",
- "icon": "dashboard"
- }],
+ "links": [
+ {
+ "url": "https://admin.example-org.com",
+ "title": "Admin Dashboard",
+ "icon": "dashboard"
+ }
+ ],
"tags": ["java"],
"name": "artist-web",
"uid": "2152f463-549d-4d8d-a94d-ce2b7676c6e2"
diff --git a/docs/features/software-catalog/extending-the-model.md b/docs/features/software-catalog/extending-the-model.md
index 340daae7d3..92ce153da2 100644
--- a/docs/features/software-catalog/extending-the-model.md
+++ b/docs/features/software-catalog/extending-the-model.md
@@ -471,6 +471,7 @@ We also provide a high-level example of what a catalog process for a custom
entity might look like:
```ts
+import { CatalogProcessor, processingResult } from '@backstage/catalog-backend';
import { entityKindSchemaValidator } from '@backstage/catalog-model';
export class FoobarEntitiesProcessor implements CatalogProcessor {
@@ -506,7 +507,7 @@ export class FoobarEntitiesProcessor implements CatalogProcessor {
// Here we can modify the entity or emit results related to the entity
// Typically you will want to emit any relations associated with the entity here
- emit(results.relation({ ... }))
+ emit(processingResult.relation({ ... }))
}
return entity;
diff --git a/docs/features/software-catalog/external-integrations.md b/docs/features/software-catalog/external-integrations.md
index 9f592e7cca..a344f478d7 100644
--- a/docs/features/software-catalog/external-integrations.md
+++ b/docs/features/software-catalog/external-integrations.md
@@ -368,7 +368,7 @@ The class will have this basic structure:
```ts
import { UrlReader } from '@backstage/backend-common';
import {
- results,
+ processingResult,
CatalogProcessor,
CatalogProcessorEmit,
LocationSpec,
@@ -396,10 +396,10 @@ export class SystemXReaderProcessor implements CatalogProcessor {
// your choosing.
const data = await this.reader.read(location.target);
const json = JSON.parse(data.toString());
- // Repeatedly call emit(results.entity(location, ))
+ // Repeatedly call emit(processingResult.entity(location, ))
} catch (error) {
const message = `Unable to read ${location.type}, ${error}`;
- emit(results.generalError(location, message));
+ emit(processingResult.generalError(location, message));
}
return true;
@@ -450,7 +450,7 @@ behavior for `system-x` that we implemented earlier.
import { UrlReader } from '@backstage/backend-common';
import { Entity } from '@backstage/catalog-model';
import {
- results,
+ processingResult,
CatalogProcessor,
CatalogProcessorEmit,
CatalogProcessorCache,
@@ -515,7 +515,7 @@ export class SystemXReaderProcessor implements CatalogProcessor {
// For this example the JSON payload is a single entity.
const entity: Entity = JSON.parse(response.buffer.toString());
- emit(results.entity(location, entity));
+ emit(processingResult.entity(location, entity));
// Update the cache with the new ETag and entity used for the next run.
await cache.set(CACHE_KEY, {
@@ -525,10 +525,10 @@ export class SystemXReaderProcessor implements CatalogProcessor {
} catch (error) {
if (error.name === 'NotModifiedError' && cacheItem) {
// The ETag matches and we have a cached value from the previous run.
- emit(results.entity(location, cacheItem.entity));
+ emit(processingResult.entity(location, cacheItem.entity));
}
const message = `Unable to read ${location.type}, ${error}`;
- emit(results.generalError(location, message));
+ emit(processingResult.generalError(location, message));
}
return true;
diff --git a/docs/features/software-templates/writing-custom-actions.md b/docs/features/software-templates/writing-custom-actions.md
index 8c57f202a7..06ab1d4f36 100644
--- a/docs/features/software-templates/writing-custom-actions.md
+++ b/docs/features/software-templates/writing-custom-actions.md
@@ -108,11 +108,11 @@ should have something similar to the below in
```ts
return await createRouter({
containerRunner,
- logger,
- config,
- database,
catalogClient,
- reader,
+ logger: env.logger,
+ config: env.config,
+ database: env.database,
+ reader: env.reader,
});
```
@@ -123,25 +123,25 @@ will set the available actions that the scaffolder has access to.
import { createBuiltinActions } from '@backstage/plugin-scaffolder-backend';
import { ScmIntegrations } from '@backstage/integration';
-const integrations = ScmIntegrations.fromConfig(config);
+const integrations = ScmIntegrations.fromConfig(env.config);
const builtInActions = createBuiltinActions({
containerRunner,
integrations,
- config,
catalogClient,
- reader,
+ config: env.config,
+ reader: env.reader,
});
const actions = [...builtInActions, createNewFileAction()];
return await createRouter({
containerRunner,
- logger,
- config,
- database,
catalogClient,
- reader,
actions,
+ logger: env.logger,
+ config: env.config,
+ database: env.database,
+ reader: env.reader,
});
```
@@ -156,6 +156,8 @@ scaffolder backend:
| Cookiecutter | [plugin-scaffolder-backend-module-cookiecutter](https://www.npmjs.com/package/@backstage/plugin-scaffolder-backend-module-cookiecutter) | [Backstage](https://backstage.io) |
| Rails | [plugin-scaffolder-backend-module-rails](https://www.npmjs.com/package/@backstage/plugin-scaffolder-backend-module-rails) | [Backstage](https://backstage.io) |
| HTTP requests | [scaffolder-backend-module-http-request](https://www.npmjs.com/package/@roadiehq/scaffolder-backend-module-http-request) | [Roadie](https://roadie.io) |
+| Utility actions | [scaffolder-backend-module-utils](https://www.npmjs.com/package/@roadiehq/scaffolder-backend-module-utils) | [Roadie](https://roadie.io) |
+| AWS cli actions | [scaffolder-backend-module-aws](https://www.npmjs.com/package/@roadiehq/scaffolder-backend-module-aws) | [Roadie](https://roadie.io) |
| Scaffolder .NET Actions | [plugin-scaffolder-dotnet-backend](https://www.npmjs.com/package/@plusultra/plugin-scaffolder-dotnet-backend) | [Alef Carlos](https://github.com/alefcarlos) |
Have fun! 🚀
diff --git a/docs/features/software-templates/writing-templates.md b/docs/features/software-templates/writing-templates.md
index 41061d45a3..9a1cfdf736 100644
--- a/docs/features/software-templates/writing-templates.md
+++ b/docs/features/software-templates/writing-templates.md
@@ -251,9 +251,46 @@ use `ui:widget: password` or set some properties of `ui:backstage`:
type: string
ui:backstage:
review:
- show: false # wont print any info about 'hidden' property on Review Step
+ show: false # won't print any info about 'hidden' property on Review Step
```
+### Remove sections or fields based on feature flags
+
+Based on feature flags you can hide sections or even only fields of your
+template. This is a good use case if you want to test experimental parameters in
+a production environment. To use it let's look at the following template:
+
+```yaml
+spec:
+ type: website
+ owner: team-a
+ parameters:
+ - name: Enter some stuff
+ description: Enter some stuff
+ backstage:featureFlag: experimental-feature
+ properties:
+ inputString:
+ type: string
+ title: string input test
+ inputObject:
+ type: object
+ title: object input test
+ description: a little nested thing never hurt anyone right?
+ properties:
+ first:
+ type: string
+ title: first
+ backstage:featureFlag: nested-experimental-feature
+ second:
+ type: number
+ title: second
+```
+
+If you have a feature flag `experimental-feature` active then
+your first step would be shown. The same goes for the nested properties in the
+spec. Make sure to use the key `backstage:featureFlag` in your templates if
+you want to use this functionality.
+
### The Repository Picker
In order to make working with repository providers easier, we've built a custom
diff --git a/docs/features/techdocs/configuration.md b/docs/features/techdocs/configuration.md
index 3edc55574f..d16e9142dc 100644
--- a/docs/features/techdocs/configuration.md
+++ b/docs/features/techdocs/configuration.md
@@ -161,11 +161,6 @@ techdocs:
# default value is 1000
readTimeout: 500
- # (Optional and Legacy) TechDocs makes API calls to techdocs-backend using this URL. e.g. get docs of an entity, get metadata, etc.
- # You don't have to specify this anymore.
-
- requestUrl: http://localhost:7007/api/techdocs
-
# (Optional and Legacy) Just another route in techdocs-backend where TechDocs requests the static files from. This URL uses an HTTP middleware
# to serve files from either a local directory or an External storage provider.
# You don't have to specify this anymore.
diff --git a/docs/features/techdocs/getting-started.md b/docs/features/techdocs/getting-started.md
index 37e135d1dc..e1e63c5c5b 100644
--- a/docs/features/techdocs/getting-started.md
+++ b/docs/features/techdocs/getting-started.md
@@ -81,18 +81,16 @@ import {
Publisher,
} from '@backstage/plugin-techdocs-backend';
import Docker from 'dockerode';
+import { Router } from 'express';
import { PluginEnvironment } from '../types';
-export default async function createPlugin({
- logger,
- config,
- discovery,
- reader,
-}: PluginEnvironment) {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
// Preparers are responsible for fetching source files for documentation.
- const preparers = await Preparers.fromConfig(config, {
- logger,
- reader,
+ const preparers = await Preparers.fromConfig(env.config, {
+ logger: env.logger,
+ reader: env.reader,
});
// Docker client (conditionally) used by the generators, based on techdocs.generators config.
@@ -100,17 +98,17 @@ export default async function createPlugin({
const containerRunner = new DockerContainerRunner({ dockerClient });
// Generators are used for generating documentation sites.
- const generators = await Generators.fromConfig(config, {
- logger,
+ const generators = await Generators.fromConfig(env.config, {
+ logger: env.logger,
containerRunner,
});
// Publisher is used for
// 1. Publishing generated files to storage
// 2. Fetching files from storage and passing them to TechDocs frontend.
- const publisher = await Publisher.fromConfig(config, {
- logger,
- discovery,
+ const publisher = await Publisher.fromConfig(env.config, {
+ logger: env.logger,
+ discovery: env.discovery,
});
// checks if the publisher is working and logs the result
@@ -120,9 +118,10 @@ export default async function createPlugin({
preparers,
generators,
publisher,
- logger,
- config,
- discovery,
+ logger: env.logger,
+ config: env.config,
+ discovery: env.discovery,
+ cache: env.cache,
});
}
```
diff --git a/docs/getting-started/configuration.md b/docs/getting-started/configuration.md
index 26dbca1442..3e418fadf0 100644
--- a/docs/getting-started/configuration.md
+++ b/docs/getting-started/configuration.md
@@ -78,7 +78,7 @@ from the previous steps.
```diff
backend:
database:
-- client: sqlite3
+- client: better-sqlite3
- connection: ':memory:'
+ # config options: https://node-postgres.com/api/client
+ client: pg
@@ -218,7 +218,7 @@ for 7 days, it's a lucky number.
-Set the scope to your likings. For this tutorial, selecting "repo" should be
+Set the scope to your likings. For this tutorial, selecting "repo" and "workflow" is required as the scaffolding job in this guide configures a GitHub actions workflow for the newly created project.
enough.
In the `app-config.yaml`, search for `integrations:` and add your token, like we
@@ -276,7 +276,7 @@ otherwise something went terribly wrong.
- Go to `create` and choose to create a website with the `React SSR Template`
- Type in a name, let's use `tutorial`
-- Select the group `group-a` which will own this new website, and go to the next
+- Select the group `team-a` which will own this new website, and go to the next
step
diff --git a/docs/integrations/aws-s3/discovery.md b/docs/integrations/aws-s3/discovery.md
index 4e72c80b95..5dfaf9dc39 100644
--- a/docs/integrations/aws-s3/discovery.md
+++ b/docs/integrations/aws-s3/discovery.md
@@ -27,8 +27,14 @@ catalog:
Note the `s3-discovery` type, as this is not a regular `url` processor.
-As this processor is not one of the default providers, you will also need to add
-the below to `packages/backend/src/plugins/catalog.ts`:
+As this processor is not one of the default providers, you will first need to install the AWS catalog plugin:
+
+```shell
+cd packages/backend
+yarn install @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 */
diff --git a/docs/integrations/azure/discovery.md b/docs/integrations/azure/discovery.md
index 1deec423a7..c6a9292fbf 100644
--- a/docs/integrations/azure/discovery.md
+++ b/docs/integrations/azure/discovery.md
@@ -12,6 +12,34 @@ DevOps organization and register entities matching the configured path. This can
be useful as an alternative to static locations or manually adding things to the
catalog.
+## Installation
+
+You will have to add the processors in the catalog initialization code of your
+backend. They are not installed by default, therefore you have to add a
+dependency to `@backstage/plugin-catalog-backend-module-azure` to your backend
+package.
+
+```bash
+# From your Backstage root directory
+cd packages/backend
+yarn add @backstage/plugin-catalog-backend-module-azure
+```
+
+And then add the processors to your catalog builder:
+
+```diff
+// In packages/backend/src/plugins/catalog.ts
++import { AzureDevOpsDiscoveryProcessor } from '@backstage/plugin-catalog-backend-module-azure';
+
+ export default async function createPlugin(
+ env: PluginEnvironment,
+ ): Promise {
+ const builder = await CatalogBuilder.create(env);
++ builder.addProcessor(AzureDevOpsDiscoveryProcessor.fromConfig(env.config, { logger: env.logger }));
+```
+
+## Configuration
+
To use the discovery processor, you'll need a Azure integration
[set up](locations.md) with a `AZURE_TOKEN`. Then you can add a location target
to the catalog configuration:
diff --git a/docs/integrations/bitbucket/discovery.md b/docs/integrations/bitbucket/discovery.md
index 28b0128f56..c31b3a2eed 100644
--- a/docs/integrations/bitbucket/discovery.md
+++ b/docs/integrations/bitbucket/discovery.md
@@ -11,6 +11,34 @@ catalog entities located in Bitbucket. The processor will crawl your Bitbucket
account and register entities matching the configured path. This can be useful
as an alternative to static locations or manually adding things to the catalog.
+## Installation
+
+You will have to add the processor in the catalog initialization code of your
+backend. The provider is not installed by default, therefore you have to add a
+dependency to `@backstage/plugin-catalog-backend-module-bitbucket` to your backend
+package.
+
+```bash
+# From your Backstage root directory
+cd packages/backend
+yarn add @backstage/plugin-catalog-backend-module-bitbucket
+```
+
+And then add the processor to your catalog builder:
+
+```diff
+// In packages/backend/src/plugins/catalog.ts
++import { BitbucketDiscoveryProcessor } from '@backstage/plugin-catalog-backend-module-bitbucket';
+
+ export default async function createPlugin(
+ env: PluginEnvironment,
+ ): Promise {
+ const builder = await CatalogBuilder.create(env);
++ builder.addProcessor(
++ BitbucketDiscoveryProcessor.fromConfig(env.config, { logger: env.logger })
++ );
+```
+
## Self-hosted Bitbucket Server
To use the discovery processor with a self-hosted Bitbucket Server, you'll need
@@ -137,14 +165,11 @@ matching repository is processed.
repository.
```typescript
-const customRepositoryParser: BitbucketRepositoryParser =
- async function* customRepositoryParser({ client, repository }) {
- // Custom logic for interpret the matching repository.
- // See defaultRepositoryParser for an example
- };
-
const processor = BitbucketDiscoveryProcessor.fromConfig(env.config, {
- parser: customRepositoryParser,
+ parser: async function* customRepositoryParser({ client, repository }) {
+ // Custom logic for interpreting the matching repository.
+ // See defaultRepositoryParser for an example
+ },
logger: env.logger,
});
```
diff --git a/docs/integrations/github/discovery.md b/docs/integrations/github/discovery.md
index 39cb026703..69491e3d1a 100644
--- a/docs/integrations/github/discovery.md
+++ b/docs/integrations/github/discovery.md
@@ -12,6 +12,53 @@ organization and register entities matching the configured path. This can be
useful as an alternative to static locations or manually adding things to the
catalog.
+## Installation
+
+You will have to add the processors in the catalog initialization code of your
+backend. They are 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
+cd packages/backend
+yarn add @backstage/plugin-catalog-backend-module-github
+```
+
+And then add the processors to your catalog builder:
+
+```diff
+// In packages/backend/src/plugins/catalog.ts
++import {
++ GithubDiscoveryProcessor,
++ GithubOrgReaderProcessor,
++} from '@backstage/plugin-catalog-backend-module-github';
++import {
++ ScmIntegrations,
++ DefaultGithubCredentialsProvider
++} from '@backstage/integration';
+
+ export default async function createPlugin(
+ env: PluginEnvironment,
+ ): Promise {
+ const builder = await CatalogBuilder.create(env);
++ const integrations = ScmIntegrations.fromConfig(env.config);
++ const githubCredentialsProvider =
++ DefaultGithubCredentialsProvider.fromIntegrations(integrations);
++ builder.addProcessor(
++ GithubDiscoveryProcessor.fromConfig(env.config, {
++ logger: env.logger,
++ githubCredentialsProvider,
++ }),
++ GithubOrgReaderProcessor.fromConfig(env.config, {
++ logger: env.logger,
++ githubCredentialsProvider,
++ }),
++ );
+```
+
+## Configuration
+
To use the discovery processor, you'll need a GitHub integration
[set up](locations.md) with a `GITHUB_TOKEN`. Then you can add a location target
to the catalog configuration:
diff --git a/docs/integrations/github/org.md b/docs/integrations/github/org.md
index 5843944e8a..975df2e555 100644
--- a/docs/integrations/github/org.md
+++ b/docs/integrations/github/org.md
@@ -19,8 +19,7 @@ entities that mirror your org setup.
## Installation
-The processor that performs the import, `GithubOrgReaderProcessor`, comes
-installed with the default setup of Backstage.
+See the [discovery](discovery.md) article for installation instructions.
## Configuration
@@ -70,6 +69,6 @@ import { GithubOrgReaderProcessor } from '@backstage/plugin-catalog-backend';
builder.replaceProcessors(
// ... other processor replacements
- GithubOrgReaderProcessor.fromConfig(config, { logger }),
+ GithubOrgReaderProcessor.fromConfig(env.config, { logger: env.logger }),
);
```
diff --git a/docs/local-dev/cli-build-system.md b/docs/local-dev/cli-build-system.md
index be07a67f22..91f4668f4e 100644
--- a/docs/local-dev/cli-build-system.md
+++ b/docs/local-dev/cli-build-system.md
@@ -66,7 +66,7 @@ These steps are generally kept isolated form each other, with each step focusing
on its specific task. For example, we do not do linting or type checking
together with the building or bundling. This is so that we can provide more
flexibility and avoid duplicate work, improving performance. It is strongly
-recommended that as a part of developing withing Backstage you use a code editor
+recommended that as a part of developing within Backstage you use a code editor
or IDE that has support for formatting, linting, and type checking.
Let's dive into a detailed look at each of these steps and how they are
diff --git a/docs/overview/stability-index.md b/docs/overview/stability-index.md
deleted file mode 100644
index 9b8983f3c0..0000000000
--- a/docs/overview/stability-index.md
+++ /dev/null
@@ -1,340 +0,0 @@
----
-id: stability-index
-title: Stability Index
-# prettier-ignore
-description: An overview of the commitment to stability for different parts of the Backstage codebase.
----
-
-## Overview
-
-The purpose of the Backstage Stability Index is to communicate the stability of
-various parts of the project. It is tracked using a scoring system where a
-higher score indicates a higher level of stability and is a commitment to
-smoother transitions between breaking changes. Importantly, the Stability Index
-does not supersede [semver](https://semver.org/), meaning we will still adhere
-to semver and only do breaking changes in minor releases as long as we are on
-`0.x`.
-
-Each package or section is assigned a stability score between 0 and 3, with each
-point building on top of the previous one:
-
-- **0** - Breaking changes are noted in the changelog, and documentation is
- updated.
-- **1** - The changelog entry includes a clearly documented upgrade path,
- providing guidance for how to migrate previous usage patterns to the new
- version.
-- **2** - Breaking changes always include a deprecation phase where both the old
- and the new APIs can be used in parallel. This deprecation must have been
- released for at least two weeks before the deprecated API is removed in a
- minor version bump.
-- **3** - The time limit for the deprecation is 3 months instead of two weeks.
-
-TL;DR:
-
-- **0** - There's a changelog entry.
-- **1** - There's a migration guide.
-- **2** - 2 weeks of deprecation.
-- **3** - 3 months of deprecation.
-
-## Packages
-
-### `example-app` [GitHub](https://github.com/backstage/backstage/tree/master/packages/app/)
-
-This is the `packages/app` package, and it serves as an example as well as
-utility for local development in the main Backstage repo.
-
-Stability: `N/A`
-
-### `example-backend` [GitHub](https://github.com/backstage/backstage/tree/master/packages/backend/)
-
-This is the `packages/backend` package, and it serves as an example as well as
-utility for local development in the main Backstage repo.
-
-Stability: `N/A`
-
-### `backend-common` [GitHub](https://github.com/backstage/backstage/tree/master/packages/backend-common/)
-
-A collection of common helpers to be used by both backend plugins, and for
-constructing backend packages.
-
-Stability: `1`
-
-### `catalog-client` [GitHub](https://github.com/backstage/backstage/tree/master/packages/catalog-client/)
-
-An HTTP client for interacting with the catalog backend. Usable both in frontend
-and Backend.
-
-Stability: `0`. This is a very new addition and we have some immediate changes
-planned.
-
-### `catalog-model` [GitHub](https://github.com/backstage/backstage/tree/master/packages/catalog-model/)
-
-Contains the core catalog model, and utilities for working with entities. Usable
-both in frontend and Backend.
-
-Stability: `2`. The catalog model is evolving, but because of the broad usage we
-
-want to ensure some stability.
-
-### `cli` [GitHub](https://github.com/backstage/backstage/tree/master/packages/cli/)
-
-The main toolchain used for Backstage development. The various CLI commands and
-options passed to those commands, as well as the environment variables read by
-the CLI, are considered to be the interface that the stability index refers to.
-The build output may change over time and is not considered a breaking change
-unless it is likely to affect external tooling.
-
-Stability: `2`
-
-### `cli-common` [GitHub](https://github.com/backstage/backstage/tree/master/packages/cli-common/)
-
-Lightweight utilities used by the various Backstage CLIs, not intended for
-external use.
-
-Stability: `N/A`
-
-### `config` [GitHub](https://github.com/backstage/backstage/tree/master/packages/config/)
-
-Provides the logic and interfaces for reading static configuration.
-
-Stability: `2`
-
-### `config-loader` [GitHub](https://github.com/backstage/backstage/tree/master/packages/config-loader/)
-
-Used to load in static configuration, mainly for use by the CLI and
-@backstage/backend-common.
-
-Stability: `1`. Mainly intended for internal use.
-
-### `core-app-api` [GitHub](https://github.com/backstage/backstage/tree/master/packages/core-app-api/)
-
-The APIs used exclusively in the app, such as `createApp` and the system icons.
-
-Stability: `2`.
-
-### `core-components` [GitHub](https://github.com/backstage/backstage/tree/master/packages/core-components/)
-
-A collection of React components for use in Backstage plugins and apps.
-Previously exported by `@backstage/core`.
-
-Stability: `1`. These components have not received a proper review of the API,
-but we also want to ensure stability.
-
-### `core-plugin-api` [GitHub](https://github.com/backstage/backstage/tree/master/packages/core-plugin-api/)
-
-The core API used to build Backstage plugins and apps.
-
-Stability: `2`.
-
-### `cost-insights` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/cost-insights)
-
-A frontend plugin that allows users to visualize, understand and optimize your
-team's cloud costs.
-
-Stability: `1`
-
-### `create-app` [GitHub](https://github.com/backstage/backstage/tree/master/packages/create-app/)
-
-The CLI used to scaffold new Backstage projects.
-
-Stability: `2`
-
-### `dev-utils` [GitHub](https://github.com/backstage/backstage/tree/master/packages/dev-utils/)
-
-Provides utilities for developing plugins in isolation.
-
-Stability: `0`. This package is largely broken and needs updates.
-
-### `e2e-test` [GitHub](https://github.com/backstage/backstage/tree/master/packages/e2e-test/)
-
-Internal CLI utility for running e2e tests.
-
-Stability: `N/A`
-
-### `integration` [GitHub](https://github.com/backstage/backstage/tree/master/packages/integration/)
-
-Provides shared utilities for managing integrations towards different types of
-third party systems. This package is currently internal and its functionality
-will likely be exposed via separate APIs in the future.
-
-Some of the functionality in this package is not available elsewhere yes, so if
-it's necessary it can be used, but there will be breaking changes.
-
-Stability: `0`
-
-### `storybook` [GitHub](https://github.com/backstage/backstage/tree/master/storybook/)
-
-Internal storybook build for publishing stories to
-https://backstage.io/storybook
-
-Stability: `N/A`
-
-### `test-utils` [GitHub](https://github.com/backstage/backstage/tree/master/packages/test-utils/)
-
-Utilities for writing tests for Backstage plugins and apps.
-
-Stability: `2`
-
-### `theme` [GitHub](https://github.com/backstage/backstage/tree/master/packages/theme/)
-
-The core Backstage MUI theme along with customization utilities.
-
-#### Section: TypeScript
-
-This is the TypeScript API exported by the theme package.
-
-Stability: `2`
-
-#### Section: Visual Theme
-
-The visual theme exported by the theme packages, where for example changing a
-color could be considered a breaking change.
-
-Stability: `1`
-
-## Plugins
-
-Many backend plugins are split into "REST API" and "TypeScript Interface"
-sections. The "TypeScript Interface" refers to the API used to integrate the
-plugin into the backend.
-
-Any plugin that is not listed below is untracked and can generally be considered
-unstable with a score of `0`. Open a Pull Request if you want your plugin to be
-added!
-
-### `api-docs` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/api-docs/)
-
-Components to discover and display API entities as an extension to the catalog
-plugin.
-
-Stability: `0`
-
-### `app-backend` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/app-backend/)
-
-A backend plugin that can be used to serve the frontend app and inject
-configuration.
-
-Stability: `2`
-
-### `auth-backend` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/auth-backend/)
-
-A backend plugin that implements the backend portion of the various
-authentication flows used in Backstage.
-
-#### Section: REST API
-
-Stability: `2`
-
-#### Section: TypeScript Interface
-
-Stability: `1`
-
-### `catalog` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/catalog/)
-
-The frontend plugin for the catalog, with the table and building blocks for the
-entity pages.
-
-Stability: `1`. We're planning some work to overhaul how entity pages are
-constructed.
-
-### `catalog-backend` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/catalog-backend/)
-
-The backend API for the catalog, also exposes the processing subsystem for
-customization of the catalog. Powers the @backstage/plugin-catalog frontend
-plugin.
-
-#### Section: REST API
-
-Stability: `1`. There are plans to remove and rework some endpoints.
-
-#### Section: TypeScript Interface
-
-Stability: `1`. There are plans to rework parts of the Processor interface.
-
-### `catalog-graphql` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/catalog-graphql/)
-
-Provides the catalog schema and resolvers for the GraphQL backend.
-
-Stability: `0`. Under heavy development and subject to change.
-
-### `explore` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/explore/)
-
-A frontend plugin that introduces the concept of exploring internal and external
-tooling in an organization.
-
-Stability: `0`. Only an example at the moment and not customizable.
-
-### `graphiql` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/graphiql/)
-
-Integrates GraphiQL as a tool to browse GraphQL API endpoints inside Backstage.
-
-Stability: `1`
-
-### `graphql` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/graphql-backend/)
-
-A backend plugin that provides
-
-Stability: `0`. Under heavy development and subject to change.
-
-### `kubernetes` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/kubernetes/)
-
-The frontend component of the Kubernetes plugin, used to browse and visualize
-Kubernetes resources.
-
-Stability: `1`.
-
-### `kubernetes-backend` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/kubernetes-backend/)
-
-The backend component of the Kubernetes plugin, used to fetch Kubernetes
-resources from clusters and associate them with entities in the Catalog.
-
-Stability: `1`.
-
-### `proxy-backend` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/proxy-backend/)
-
-A backend plugin used to set up proxying to other endpoints based on static
-configuration.
-
-Stability: `1`
-
-### `scaffolder` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/scaffolder/)
-
-The frontend scaffolder plugin where one can browse templates and initiate
-scaffolding jobs.
-
-Stability: `1`
-
-### `scaffolder-backend` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend/)
-
-The backend scaffolder plugin that provides an implementation for templates in
-the catalog.
-
-Stability: `2`.
-
-### `tech-radar` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/tech-radar/)
-
-Visualize your company's official guidelines of different areas of software
-development.
-
-Stability: `0`
-
-### `techdocs` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/techdocs/)
-
-The frontend component of the TechDocs plugin, used to browse technical
-documentation of entities.
-
-Stability: `1`
-
-### `techdocs-backend` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/techdocs-backend/)
-
-The backend component of the TechDocs plugin, used to transform and serve
-TechDocs.
-
-Stability: `0`
-
-### `user-settings` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/user-settings/)
-
-A frontend plugin that provides a page where the user can tweak various
-settings.
-
-Stability: `1`
diff --git a/docs/overview/versioning-policy.md b/docs/overview/versioning-policy.md
new file mode 100644
index 0000000000..7430f3c200
--- /dev/null
+++ b/docs/overview/versioning-policy.md
@@ -0,0 +1,137 @@
+---
+id: versioning-policy
+title: Release & Versioning Policy
+description:
+---
+
+The Backstage project is comprised of a set of software components that together
+form the Backstage platform. These components are both plugins as well as core
+platform libraries and tools. Each component is distributed as a collection of
+[packages](), which in the end is
+what you end up consuming as an adopter of Backstage.
+
+The number of Backstage packages that build up an application can be quite
+large, in the order of hundreds, with just the core platform packages being
+counted in the dozen. This creates a challenge for the integrators of a
+Backstage project, as there are a lot of moving parts and pieces to keep up to
+date.
+
+Our solution to this is collecting our most used components and their packages
+into an umbrella version that we call a Backstage release. Each release is a
+collection of packages at specific versions that have been verified to work
+together. Think of it as a toolbox that comes with batteries included, but you
+can always add more plugins and libraries from the open source ecosystem as well
+as build your own.
+
+## Release Lines
+
+The Backstage project is structured around two different release lines, a
+primary "main" release line, and a "next" release line that serves as a preview
+and pre-release of the next main-line release. Each of these release lines have
+their own release cadence and versioning policy.
+
+## Main Release Line
+
+Release cadence: Monthly
+
+The main release line in versioned with a major, minor and patch version but
+does **not** adhere to [semver](https://semver.org). The version format is
+`..`, for example `1.3.0`.
+
+An increment of the major version denotes a significant improvement or change to
+the Backstage platform. It may come with a large new set of features, or a
+switch in the product direction. These will be few and far between, and do not
+have any set cadence. Policy-wise they are no different than a minor release.
+
+Each regularly scheduled release will bring an increment to the minor version,
+as long as it is not a major release. Each new minor version can contain new
+functionality, breaking changes, and bug fixes, according the
+[versioning policy](#release-versioning-policy).
+
+Patch versions will only be released to address critical bug fixes. They are not
+bound to the regular cadence and are instead releases whenever needed.
+
+## Next Release Line
+
+Release cadence: Weekly
+
+The next release line is a weekly release of the project. Consuming these
+releases gives you early access to upcoming functionality in Backstage. There
+are however fewer guarantees around breaking changes in these releases, where
+moving from one release to the next may introduce significant breaking changes.
+
+## Release Versioning Policy
+
+The following versioning policy applies to the main-line releases only.
+
+- Breaking changes in Packages that have reached version `>=1.0.0` will only be
+ done when necessary and with the goal of having minimal impact. When possible,
+ there will always be a deprecation path for a breaking change.
+- Security fixes **may** be backported to older releases based on the simplicity
+ of the upgrade path, and the severity of the vulnerability.
+- Bug reports are valid only if reproducible in the most recent release, and bug
+ fixes are only applied to the next release.
+- We will do our best to adhere to this policy.
+
+### Skew Policy
+
+In order for Backstage to function properly the following versioning rules must
+be followed. The rules are referring to the
+[Package Architecture](https://backstage.io/docs/overview/architecture-overview#package-architecture).
+
+- The versions of all the packages in the `Frontend App Core` must be from the
+ same release, and it is recommended to keep `Common Tooling` on that release
+ too.
+- The Backstage dependencies of any given plugin should be from the same
+ release. This includes the packages from `Common Libraries`,
+ `Frontend Plugin Core`, and `Frontend Libraries`, or alternatively the
+ `Backend Libraries`.
+- There must be no package that is from a newer release than the
+ `Frontend App Core` packages in the app.
+- Frontend plugins with a corresponding backend plugin should be from the same
+ release. The update to the backend plugin **MUST** be deployed before or
+ together with the update to the frontend plugin.
+
+## Package Versioning Policy
+
+Every individual package is versioned according to [semver](https://semver.org).
+This versioning is completely decoupled from the Backstage release versioning,
+meaning you might for example have `@backstage/core-plugin-api` version `3.1.4`
+be part of the `1.12` Backstage release.
+
+Following versioning policy applies to all packages:
+
+- Breaking changes are noted in the changelog, and documentation is updated.
+- Breaking changes are prefixed with `**BREAKING**: ` in the changelog.
+- All public exports are considered stable and will have an entry in the
+ changelog
+- Breaking changes are recommended to document a clear upgrade path in the
+ changelog. This may be omitted for newly introduced or unstable packages.
+
+For packages at version `1.0.0` or above, the following policy also applies:
+
+- All exports are marked with a [release stage](#release-stages).
+- Breaking changes to stable exports include a deprecation phase if possible.
+ The deprecation must have been released for at least one mainline release
+ before it can be removed.
+- The release of breaking changes document a clear upgrade path in the
+ changelog, both when deprecations are introduced and when they are removed.
+- Exports that have been marked as `@alpha` or `@beta` may receive breaking
+ changes without a deprecation period, but the changes must still adhere to
+ semver.
+
+### Release Stages
+
+The release stages(`@alpha`, `@beta` `@public`) refers to the
+[TSDoc](https://tsdoc.org/) documentation tag of the export, and are also
+visible in the API report of each package.
+
+Backstage uses three stages to indicate the stability for each individual
+package export.
+
+- `@public` - considered stable and are available in the main package entry
+ point.
+- `@beta` - Not visible in the main package entry point, beta exports must be
+ accessed via `/beta` or `/alpha` imports.
+- `@alpha` - here be dragons. Not visible in the main package entry point, alpha
+ exports must be accessed via `/alpha` imports.
diff --git a/docs/plugins/backend-plugin.md b/docs/plugins/backend-plugin.md
index 5ff0e5a62f..65ff20ae46 100644
--- a/docs/plugins/backend-plugin.md
+++ b/docs/plugins/backend-plugin.md
@@ -76,9 +76,12 @@ following to it
```ts
import { createRouter } from '@internal/plugin-carmen-backend';
+import { Router } from 'express';
import { PluginEnvironment } from '../types';
-export default async function createPlugin(env: PluginEnvironment) {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
// Here is where you will add all of the required initialization code that
// your backend plugin needs to be able to start!
@@ -124,7 +127,9 @@ function, there is a `database` field. You can use that to get a
```ts
// in packages/backend/src/plugins/carmen.ts
-export default async function createPlugin(env: PluginEnvironment) {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
const db: Knex = await env.database.getClient();
// You will then pass this client into your actual plugin implementation
diff --git a/docs/plugins/testing.md b/docs/plugins/testing.md
index bd6061be19..aa7815728c 100644
--- a/docs/plugins/testing.md
+++ b/docs/plugins/testing.md
@@ -192,7 +192,7 @@ returns a result or displays an error or console message, like so:
**`StringUtil ellipsis`**
-```js
+```ts
export function ellipsis(text, maxLength, midCharIx = 0, ellipsis = '...') {
// Do something blackbox. We should not care about the internals,
// only inputs and outputs.
@@ -210,7 +210,7 @@ There are four things to test for in a utility function:
> Handle Invalid Input (handle thrown errors):
-```js
+```ts
it('Throws an error on improper arguments', () => {
expect(() => {
ellipsis();
@@ -220,7 +220,7 @@ it('Throws an error on improper arguments', () => {
> Verify default input arguments:
-```js
+```ts
it('Works with defaults', () => {
expect(ellipsis('Hello world', 3)).toBe('Hel...');
expect(ellipsis('', 3)).toBe('');
@@ -233,7 +233,7 @@ it('Works with defaults', () => {
This is especially true for edge cases!
-```js
+```ts
it('Works with midCharIx', () => {
expect(ellipsis('Hello world', 3, 6)).toBe('...o w...');
expect(ellipsis('', 3, 6)).toBe('');
@@ -265,7 +265,7 @@ For example:
**`./MyApi.js`**
-```js
+```ts
export {
fetchSomethingFromServer: () => {
// Live production call to a URI. Must be avoided during testing!
@@ -276,7 +276,7 @@ export {
**`./__mocks__/MyApi.js`**
-```js
+```ts
export {
fetchSomethingFromServer: () => {
// Simulate a production call, but avoid jest and just use a promise
@@ -287,7 +287,7 @@ export {
**`./MyApi.test.js`**
-```js
+```ts
/* eslint-disable import/first */
jest.mock('./MyApi'); // Instruct Jest to swap all future imports of './MyApi.js' to './__mocks__/MyApi.js'
diff --git a/docs/plugins/url-reader.md b/docs/plugins/url-reader.md
index 41aba98a66..0072c34cfb 100644
--- a/docs/plugins/url-reader.md
+++ b/docs/plugins/url-reader.md
@@ -44,7 +44,7 @@ import { URLReaders } from '@backstage/backend-common';
function makeCreateEnv(config: Config) {
// ....
- const reader = UrlReaders.default({ logger, config });
+ const reader = UrlReaders.default({ logger: root, config });
//
}
```
diff --git a/docs/tutorials/configuring-plugin-databases.md b/docs/tutorials/configuring-plugin-databases.md
index 9277bb5028..3e18b1f30e 100644
--- a/docs/tutorials/configuring-plugin-databases.md
+++ b/docs/tutorials/configuring-plugin-databases.md
@@ -33,17 +33,17 @@ Backstage's databases.
### Dependencies
Please ensure the appropriate database drivers are installed in your `backend`
-package. If you intend to use both `postgres` and `sqlite3`, you can install
+package. If you intend to use both PostgreSQL and SQLite, you can install
both of them.
```sh
cd packages/backend
-# install pg if you need postgres
+# install pg if you need PostgreSQL
yarn add pg
-# install sqlite3 if you intend to set it as the client
-yarn add sqlite3
+# install SQLite 3 if you intend to set it as the client
+yarn add better-sqlite3
```
From an operational perspective, you only need to install drivers for clients
@@ -66,14 +66,14 @@ configurations below.
### Minimal In-Memory Configuration
-In the example below, we are using `sqlite3` in-memory databases for all
+In the example below, we are using `better-sqlite3` in-memory databases for all
plugins. You may want to use this configuration for testing or other non-durable
use cases.
```yaml
backend:
database:
- client: sqlite3
+ client: better-sqlite3
connection: ':memory:'
```
@@ -138,7 +138,7 @@ backend:
### PostgreSQL and SQLite 3
The example below uses PostgreSQL (`pg`) as the database client for all plugins
-except the `auth` plugin which uses `sqlite3`. As the `auth` plugin's client
+except the `auth` plugin which uses `better-sqlite3`. As the `auth` plugin's client
type is different from the base client type, the connection configuration for
`auth` is used verbatim without extending the base configuration for PostgreSQL.
@@ -149,7 +149,7 @@ backend:
connection: 'postgresql://foo:bar@some.example-pg-instance.tld:5432'
plugin:
auth:
- client: sqlite3
+ client: better-sqlite3
connection: ':memory:'
```
diff --git a/docs/tutorials/package-role-migration.md b/docs/tutorials/package-role-migration.md
index 10d6eca586..0af5fdb615 100644
--- a/docs/tutorials/package-role-migration.md
+++ b/docs/tutorials/package-role-migration.md
@@ -33,7 +33,7 @@ the `@backstage/cli`.
### TL;DR, Step 1-4:
-This is a sorter version of all of the steps below, in case you're in a hurry.
+This is a shorter version of all of the steps below, in case you're in a hurry.
Run the following commands:
diff --git a/docs/tutorials/switching-sqlite-postgres.md b/docs/tutorials/switching-sqlite-postgres.md
index 8a7f90b21f..df5d78f56d 100644
--- a/docs/tutorials/switching-sqlite-postgres.md
+++ b/docs/tutorials/switching-sqlite-postgres.md
@@ -33,7 +33,7 @@ configuration for the backend:
```diff
backend:
database:
-- client: sqlite3
+- client: better-sqlite3
- connection: ':memory:'
+ # config options: https://node-postgres.com/api/client
+ client: pg
diff --git a/microsite/blog/2020-12-22-stability-index.md b/microsite/blog/2020-12-22-stability-index.md
index 95074a13a2..e49abb1a35 100644
--- a/microsite/blog/2020-12-22-stability-index.md
+++ b/microsite/blog/2020-12-22-stability-index.md
@@ -4,7 +4,9 @@ author: Patrik Oldsberg, Spotify
authorURL: https://github.com/Rugvip
---
-**TL;DR** Backstage is heading out of alpha and moving onto the path to stable releases and an eventual version 1.0. As the community and ecosystem continue to grow at an increasing rate, we want to provide a solid foundation for everyone building things in, with, and around Backstage. So, today we’re introducing the [Stability Index](https://backstage.io/docs/overview/stability-index) — a simple way to find out how likely (or unlikely) a specific package or plugin inside Backstage might be updated with major changes. By indicating the reliability of key features and APIs, this quick reference will help contributors and adopters better plan and coordinate their development efforts going forward.
+2022-01 update: The stability is now replaced by the [versioning policy](https://backstage.io/docs/overview/versioning-policy).
+
+**TL;DR** Backstage is heading out of alpha and moving onto the path to stable releases and an eventual version 1.0. As the community and ecosystem continue to grow at an increasing rate, we want to provide a solid foundation for everyone building things in, with, and around Backstage. So, today we’re introducing the [Stability Index](https://backstage.io/docs/overview/versioning-policy) — a simple way to find out how likely (or unlikely) a specific package or plugin inside Backstage might be updated with major changes. By indicating the reliability of key features and APIs, this quick reference will help contributors and adopters better plan and coordinate their development efforts going forward.

@@ -18,7 +20,7 @@ This rapid evolution can create uncertainty around which parts of the project ar
In order to tackle the problem of uncertainty, and help align contributors, we have recently introduced a Stability Index. Inspired by a [similar concept with the same name in Node.js](https://nodejs.org/docs/latest-v4.x/api/documentation.html#documentation_stability_index), it’s a score assigned to subsets of the project, indicating the level of maturity of the API and the commitment to backwards compatibility. However, because of the current phase of the project, we have used a slightly different implementation. Rather than the score indicating a perceived stability, a higher score is instead a commitment to providing a smoother upgrade path for users, both through better documentation and backwards compatibility. Importantly, the Stability Index does not supersede [semantic versioning](https://semver.org/) (or semver), meaning we will still adhere to semver and only do breaking changes in minor releases as long as we are on 0.x.
-You can find more details about the scores on the [Stability Index](https://backstage.io/docs/overview/stability-index) page, but the following is a TL;DR of the 0–3 scores:
+You can find more details about the scores on the [Stability Index](https://backstage.io/docs/overview/versioning-policy) page, but the following is a TL;DR of the 0–3 scores:
- **0** — There's a changelog entry.
- **1** — There's a migration guide.
diff --git a/microsite/data/plugins/opsgenie.yaml b/microsite/data/plugins/opsgenie.yaml
index 43ba040f75..3db06c04c8 100644
--- a/microsite/data/plugins/opsgenie.yaml
+++ b/microsite/data/plugins/opsgenie.yaml
@@ -3,7 +3,7 @@ title: Opsgenie
author: K-Phoen
authorUrl: https://github.com/K-Phoen
category: Monitoring
-description: Opsgenie offers a simple way to associate alerts to components and vizualize incidents.
+description: Opsgenie offers a simple way to associate alerts to components and visualize incidents.
documentation: https://github.com/K-Phoen/backstage-plugin-opsgenie/
iconUrl: https://avatars.githubusercontent.com/u/1818843?s=200&v=4
npmPackageName: '@k-phoen/backstage-plugin-opsgenie'
diff --git a/microsite/data/plugins/scaffolder-backend-roadie-aws.yaml b/microsite/data/plugins/scaffolder-backend-roadie-aws.yaml
new file mode 100644
index 0000000000..196a9388f9
--- /dev/null
+++ b/microsite/data/plugins/scaffolder-backend-roadie-aws.yaml
@@ -0,0 +1,9 @@
+---
+title: Scaffolder AWS cli actions
+author: roadie.io
+authorUrl: https://roadie.io/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=scaffolder-aws
+category: Scaffolder
+description: Here you can find some AWS cli actions
+documentation: https://github.com/RoadieHQ/roadie-backstage-plugins/blob/main/plugins/scaffolder-actions/scaffolder-backend-module-aws/README.md
+iconUrl: https://upload.wikimedia.org/wikipedia/commons/9/93/Amazon_Web_Services_Logo.svg
+npmPackageName: '@roadiehq/scaffolder-backend-module-aws'
diff --git a/microsite/data/plugins/scaffolder-backend-roadie-http-request.yaml b/microsite/data/plugins/scaffolder-backend-roadie-http-request.yaml
new file mode 100644
index 0000000000..8e61733ca1
--- /dev/null
+++ b/microsite/data/plugins/scaffolder-backend-roadie-http-request.yaml
@@ -0,0 +1,9 @@
+---
+title: Scaffolder HTTP request action
+author: roadie.io
+authorUrl: https://roadie.io/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=scaffolder-http-request
+category: Scaffolder
+description: An action to fire an arbitrary HTTP request
+documentation: https://github.com/RoadieHQ/roadie-backstage-plugins/blob/main/plugins/scaffolder-actions/scaffolder-backend-module-http-request/README.md
+iconUrl: img/scaffolder-http-request-logo.svg
+npmPackageName: '@roadiehq/scaffolder-backend-module-http-request'
diff --git a/microsite/data/plugins/scaffolder-backend-roadie-utils.yaml b/microsite/data/plugins/scaffolder-backend-roadie-utils.yaml
new file mode 100644
index 0000000000..3ed3a646dd
--- /dev/null
+++ b/microsite/data/plugins/scaffolder-backend-roadie-utils.yaml
@@ -0,0 +1,9 @@
+---
+title: Scaffolder utility actions
+author: roadie.io
+authorUrl: https://roadie.io/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=scaffolder-utils
+category: Scaffolder
+description: A collection of utility actions including sleep, zip and file manipulation.
+documentation: https://github.com/RoadieHQ/roadie-backstage-plugins/blob/main/plugins/scaffolder-actions/scaffolder-backend-module-utils/README.md
+iconUrl: img/scaffolder-utils-logo.png
+npmPackageName: '@roadiehq/scaffolder-backend-module-utils'
diff --git a/microsite/sidebars.json b/microsite/sidebars.json
index 1d409ae051..2a19c43ca3 100644
--- a/microsite/sidebars.json
+++ b/microsite/sidebars.json
@@ -7,7 +7,7 @@
"overview/vision",
"overview/background",
"overview/adopting",
- "overview/stability-index",
+ "overview/versioning-policy",
"overview/support",
"overview/glossary",
"overview/logos"
diff --git a/microsite/static/img/scaffolder-http-request-logo.svg b/microsite/static/img/scaffolder-http-request-logo.svg
new file mode 100644
index 0000000000..240930da60
--- /dev/null
+++ b/microsite/static/img/scaffolder-http-request-logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/microsite/static/img/scaffolder-utils-logo.png b/microsite/static/img/scaffolder-utils-logo.png
new file mode 100644
index 0000000000..192eba7c1d
Binary files /dev/null and b/microsite/static/img/scaffolder-utils-logo.png differ
diff --git a/mkdocs.yml b/mkdocs.yml
index 65e1a85bb4..9fa5eaabd3 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -12,7 +12,7 @@ nav:
- Vision: 'overview/vision.md'
- The Spotify Story: 'overview/background.md'
- Strategies for adopting: 'overview/adopting.md'
- - Stability Index: 'overview/stability-index.md'
+ - Release & Versioning Policy: 'overview/versioning-policy.md'
- Support and community: 'overview/support.md'
- Glossary: 'overview/glossary.md'
- Logo assets: 'overview/logos.md'
diff --git a/package.json b/package.json
index a880bb25cc..822acf3030 100644
--- a/package.json
+++ b/package.json
@@ -47,7 +47,7 @@
"resolutions": {
"**/@graphql-codegen/cli/**/ws": "^7.4.6"
},
- "version": "0.71.0-next.0",
+ "version": "0.71.0",
"dependencies": {
"@manypkg/get-packages": "^1.1.3",
"@microsoft/api-documenter": "^7.15.0",
diff --git a/packages/app-defaults/CHANGELOG.md b/packages/app-defaults/CHANGELOG.md
index 6231b61631..9a682b9a1b 100644
--- a/packages/app-defaults/CHANGELOG.md
+++ b/packages/app-defaults/CHANGELOG.md
@@ -1,5 +1,12 @@
# @backstage/app-defaults
+## 0.2.1
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.9.1
+
## 0.2.1-next.0
### Patch Changes
diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json
index 8cab2bdf07..5e322c6a21 100644
--- a/packages/app-defaults/package.json
+++ b/packages/app-defaults/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/app-defaults",
"description": "Provides the default wiring of a Backstage App",
- "version": "0.2.1-next.0",
+ "version": "0.2.1",
"private": false,
"publishConfig": {
"access": "public",
@@ -33,7 +33,7 @@
"start": "backstage-cli package start"
},
"dependencies": {
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-app-api": "^0.6.0",
"@backstage/core-plugin-api": "^0.8.0",
"@backstage/plugin-permission-react": "^0.3.3",
@@ -46,10 +46,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"@types/react": "^16.13.1 || ^17.0.0"
diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md
index 114a7f1e2f..81696113e2 100644
--- a/packages/app/CHANGELOG.md
+++ b/packages/app/CHANGELOG.md
@@ -1,5 +1,55 @@
# example-app
+## 0.2.68
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/cli@0.15.2
+ - @backstage/plugin-catalog@0.10.0
+ - @backstage/plugin-catalog-react@0.9.0
+ - @backstage/core-components@0.9.1
+ - @backstage/plugin-gcp-projects@0.3.21
+ - @backstage/plugin-scaffolder@0.15.0
+ - @backstage/catalog-model@0.13.0
+ - @backstage/plugin-airbrake@0.3.2
+ - @backstage/plugin-rollbar@0.4.2
+ - @backstage/plugin-catalog-graph@0.2.14
+ - @backstage/plugin-catalog-import@0.8.5
+ - @backstage/plugin-explore@0.3.33
+ - @backstage/plugin-catalog-common@0.2.2
+ - @backstage/plugin-search-common@0.3.1
+ - @backstage/plugin-search@0.7.3
+ - @backstage/plugin-tech-radar@0.5.9
+ - @backstage/plugin-org@0.5.2
+ - @backstage/plugin-techdocs@0.15.1
+ - @backstage/app-defaults@0.2.1
+ - @backstage/integration-react@0.1.25
+ - @backstage/plugin-apache-airflow@0.1.10
+ - @backstage/plugin-api-docs@0.8.2
+ - @backstage/plugin-azure-devops@0.1.18
+ - @backstage/plugin-badges@0.2.26
+ - @backstage/plugin-circleci@0.3.2
+ - @backstage/plugin-cloudbuild@0.3.2
+ - @backstage/plugin-code-coverage@0.1.29
+ - @backstage/plugin-cost-insights@0.11.24
+ - @backstage/plugin-github-actions@0.5.2
+ - @backstage/plugin-gocd@0.1.8
+ - @backstage/plugin-graphiql@0.2.34
+ - @backstage/plugin-home@0.4.18
+ - @backstage/plugin-jenkins@0.7.1
+ - @backstage/plugin-kafka@0.3.2
+ - @backstage/plugin-kubernetes@0.6.2
+ - @backstage/plugin-lighthouse@0.3.2
+ - @backstage/plugin-newrelic@0.3.20
+ - @backstage/plugin-newrelic-dashboard@0.1.10
+ - @backstage/plugin-pagerduty@0.3.29
+ - @backstage/plugin-sentry@0.3.40
+ - @backstage/plugin-shortcuts@0.2.3
+ - @backstage/plugin-tech-insights@0.1.12
+ - @backstage/plugin-todo@0.2.4
+ - @backstage/plugin-user-settings@0.4.1
+
## 0.2.68-next.0
### Patch Changes
diff --git a/packages/app/package.json b/packages/app/package.json
index 1d020d20de..c9bc3eef8c 100644
--- a/packages/app/package.json
+++ b/packages/app/package.json
@@ -1,68 +1,69 @@
{
"name": "example-app",
- "version": "0.2.68-next.0",
+ "version": "0.2.68",
"private": true,
"backstage": {
"role": "frontend"
},
"bundled": true,
"dependencies": {
- "@backstage/app-defaults": "^0.2.1-next.0",
- "@backstage/catalog-model": "^0.13.0-next.0",
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/app-defaults": "^0.2.1",
+ "@backstage/catalog-model": "^0.13.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
- "@backstage/integration-react": "^0.1.25-next.0",
- "@backstage/plugin-airbrake": "^0.3.2-next.0",
- "@backstage/plugin-api-docs": "^0.8.2-next.0",
- "@backstage/plugin-azure-devops": "^0.1.18-next.0",
- "@backstage/plugin-apache-airflow": "^0.1.10-next.0",
- "@backstage/plugin-badges": "^0.2.26-next.0",
- "@backstage/plugin-catalog": "^0.10.0-next.0",
- "@backstage/plugin-catalog-common": "^0.2.2-next.0",
- "@backstage/plugin-catalog-graph": "^0.2.14-next.0",
- "@backstage/plugin-catalog-import": "^0.8.5-next.0",
- "@backstage/plugin-catalog-react": "^0.9.0-next.0",
- "@backstage/plugin-circleci": "^0.3.2-next.0",
- "@backstage/plugin-cloudbuild": "^0.3.2-next.0",
- "@backstage/plugin-code-coverage": "^0.1.29-next.0",
- "@backstage/plugin-cost-insights": "^0.11.24-next.0",
- "@backstage/plugin-explore": "^0.3.33-next.0",
- "@backstage/plugin-gcp-projects": "^0.3.21-next.0",
- "@backstage/plugin-github-actions": "^0.5.2-next.0",
- "@backstage/plugin-gocd": "^0.1.8-next.0",
- "@backstage/plugin-graphiql": "^0.2.34-next.0",
- "@backstage/plugin-home": "^0.4.18-next.0",
- "@backstage/plugin-jenkins": "^0.7.1-next.0",
- "@backstage/plugin-kafka": "^0.3.2-next.0",
- "@backstage/plugin-kubernetes": "^0.6.2-next.0",
- "@backstage/plugin-lighthouse": "^0.3.2-next.0",
- "@backstage/plugin-newrelic": "^0.3.20-next.0",
- "@backstage/plugin-newrelic-dashboard": "^0.1.10-next.0",
- "@backstage/plugin-org": "^0.5.2-next.0",
- "@backstage/plugin-pagerduty": "0.3.29-next.0",
+ "@backstage/integration-react": "^0.1.25",
+ "@backstage/plugin-airbrake": "^0.3.2",
+ "@backstage/plugin-api-docs": "^0.8.2",
+ "@backstage/plugin-azure-devops": "^0.1.18",
+ "@backstage/plugin-apache-airflow": "^0.1.10",
+ "@backstage/plugin-badges": "^0.2.26",
+ "@backstage/plugin-catalog": "^0.10.0",
+ "@backstage/plugin-catalog-common": "^0.2.2",
+ "@backstage/plugin-catalog-graph": "^0.2.14",
+ "@backstage/plugin-catalog-import": "^0.8.5",
+ "@backstage/plugin-catalog-react": "^0.9.0",
+ "@backstage/plugin-circleci": "^0.3.2",
+ "@backstage/plugin-cloudbuild": "^0.3.2",
+ "@backstage/plugin-code-coverage": "^0.1.29",
+ "@backstage/plugin-cost-insights": "^0.11.24",
+ "@backstage/plugin-explore": "^0.3.33",
+ "@backstage/plugin-gcalendar": "^0.1.0",
+ "@backstage/plugin-gcp-projects": "^0.3.21",
+ "@backstage/plugin-github-actions": "^0.5.2",
+ "@backstage/plugin-gocd": "^0.1.8",
+ "@backstage/plugin-graphiql": "^0.2.34",
+ "@backstage/plugin-home": "^0.4.18",
+ "@backstage/plugin-jenkins": "^0.7.1",
+ "@backstage/plugin-kafka": "^0.3.2",
+ "@backstage/plugin-kubernetes": "^0.6.2",
+ "@backstage/plugin-lighthouse": "^0.3.2",
+ "@backstage/plugin-newrelic": "^0.3.20",
+ "@backstage/plugin-newrelic-dashboard": "^0.1.10",
+ "@backstage/plugin-org": "^0.5.2",
+ "@backstage/plugin-pagerduty": "0.3.29",
"@backstage/plugin-permission-react": "^0.3.3",
- "@backstage/plugin-rollbar": "^0.4.2-next.0",
- "@backstage/plugin-scaffolder": "^0.15.0-next.0",
- "@backstage/plugin-search": "^0.7.3-next.0",
- "@backstage/plugin-search-common": "^0.3.1-next.0",
- "@backstage/plugin-sentry": "^0.3.40-next.0",
- "@backstage/plugin-shortcuts": "^0.2.3-next.0",
- "@backstage/plugin-tech-radar": "^0.5.9-next.0",
- "@backstage/plugin-techdocs": "^0.15.1-next.0",
- "@backstage/plugin-todo": "^0.2.4-next.0",
- "@backstage/plugin-user-settings": "^0.4.1-next.0",
- "@backstage/plugin-tech-insights": "^0.1.12-next.0",
+ "@backstage/plugin-rollbar": "^0.4.2",
+ "@backstage/plugin-scaffolder": "^0.15.0",
+ "@backstage/plugin-search": "^0.7.3",
+ "@backstage/plugin-search-common": "^0.3.1",
+ "@backstage/plugin-sentry": "^0.3.40",
+ "@backstage/plugin-shortcuts": "^0.2.3",
+ "@backstage/plugin-tech-radar": "^0.5.9",
+ "@backstage/plugin-techdocs": "^0.15.1",
+ "@backstage/plugin-todo": "^0.2.4",
+ "@backstage/plugin-user-settings": "^0.4.1",
+ "@backstage/plugin-tech-insights": "^0.1.12",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.57",
"@octokit/rest": "^18.5.3",
- "@roadiehq/backstage-plugin-github-insights": "^1.5.0",
- "@roadiehq/backstage-plugin-github-pull-requests": "^1.4.0",
- "@roadiehq/backstage-plugin-travis-ci": "^1.3.6",
- "@roadiehq/backstage-plugin-buildkite": "^1.3.8",
+ "@roadiehq/backstage-plugin-buildkite": "^1.4.0",
+ "@roadiehq/backstage-plugin-github-insights": "^1.6.0",
+ "@roadiehq/backstage-plugin-github-pull-requests": "^1.5.0",
+ "@roadiehq/backstage-plugin-travis-ci": "^1.4.0",
"history": "^5.0.0",
"prop-types": "^15.7.2",
"react": "^17.0.2",
@@ -79,7 +80,7 @@
"@rjsf/core": "^3.2.1",
"@testing-library/cypress": "^8.0.2",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/jquery": "^3.3.34",
diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx
index 374d637b2e..befd3274f3 100644
--- a/packages/app/src/App.tsx
+++ b/packages/app/src/App.tsx
@@ -76,7 +76,7 @@ import { hot } from 'react-hot-loader/root';
import { Navigate, Route } from 'react-router';
import { apis } from './apis';
import { entityPage } from './components/catalog/EntityPage';
-import { HomePage } from './components/home/HomePage';
+import { homePage } from './components/home/HomePage';
import { Root } from './components/Root';
import { LowerCaseValuePickerFieldExtension } from './components/scaffolder/customScaffolderExtensions';
import { searchPage } from './components/search/SearchPage';
@@ -132,7 +132,7 @@ const routes = (
{/* TODO(rubenl): Move this to / once its more mature and components exist */}
}>
-
+ {homePage}
} />
(
+export const homePage = (
} pageTitleOverride="Home">
@@ -100,6 +101,9 @@ export const HomePage = () => (
]}
/>
+
+
+
diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md
index 64c8034fa4..a8d461eabb 100644
--- a/packages/backend-common/CHANGELOG.md
+++ b/packages/backend-common/CHANGELOG.md
@@ -1,5 +1,24 @@
# @backstage/backend-common
+## 0.13.0
+
+### Minor Changes
+
+- ae9d6fb3df: **BREAKING**:
+
+ - Removed the (since way back) deprecated `createDatabase` export, please use `createDatabaseClient` instead.
+ - Removed the (since way back) deprecated `SingleConnectionDatabaseManager` export, please use `DatabaseManager` instead.
+
+### Patch Changes
+
+- ab7cd7d70e: Do some groundwork for supporting the `better-sqlite3` driver, to maybe eventually replace `@vscode/sqlite3` (#9912)
+- e0a69ba49f: build(deps): bump `fs-extra` from 9.1.0 to 10.0.1
+- aefca2a7e9: add support for ETag at `BitbucketUrlReader.readUrl`
+- 3c2bc73901: Use `setupRequestMockHandlers` from `@backstage/backend-test-utils`
+- b1aacbf96a: Applied the fix for the `/alpha` entry point resolution that was part of the `v0.70.1` release of Backstage.
+- Updated dependencies
+ - @backstage/config-loader@0.9.7
+
## 0.13.0-next.0
### Minor Changes
diff --git a/packages/backend-common/config.d.ts b/packages/backend-common/config.d.ts
index 0c3e3132c0..058805aa62 100644
--- a/packages/backend-common/config.d.ts
+++ b/packages/backend-common/config.d.ts
@@ -70,7 +70,7 @@ export interface Config {
/** Database connection configuration, select base database type using the `client` field */
database: {
/** Default database client to use */
- client: 'sqlite3' | 'pg';
+ client: 'better-sqlite3' | 'sqlite3' | 'pg';
/**
* Base database connection string or Knex object
* @secret
@@ -106,7 +106,7 @@ export interface Config {
plugin?: {
[pluginId: string]: {
/** Database client override */
- client?: 'sqlite3' | 'pg';
+ client?: 'better-sqlite3' | 'sqlite3' | 'pg';
/**
* Database connection string or Knex object override
* @secret
diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json
index cc14851d94..5d6cf2e8df 100644
--- a/packages/backend-common/package.json
+++ b/packages/backend-common/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-common",
"description": "Common functionality library for Backstage backends",
- "version": "0.13.0-next.0",
+ "version": "0.13.0",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -36,7 +36,7 @@
"dependencies": {
"@backstage/cli-common": "^0.1.8",
"@backstage/config": "^0.1.15",
- "@backstage/config-loader": "^0.9.7-next.0",
+ "@backstage/config-loader": "^0.9.7",
"@backstage/errors": "^0.2.2",
"@backstage/integration": "^0.8.0",
"@backstage/types": "^0.1.3",
@@ -89,8 +89,8 @@
}
},
"devDependencies": {
- "@backstage/backend-test-utils": "^0.1.21-next.0",
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/backend-test-utils": "^0.1.21",
+ "@backstage/cli": "^0.15.2",
"@types/archiver": "^5.1.0",
"@types/compression": "^1.7.0",
"@types/concat-stream": "^2.0.0",
diff --git a/packages/backend-common/src/database/DatabaseManager.test.ts b/packages/backend-common/src/database/DatabaseManager.test.ts
index a48b1584aa..ea8aca38ea 100644
--- a/packages/backend-common/src/database/DatabaseManager.test.ts
+++ b/packages/backend-common/src/database/DatabaseManager.test.ts
@@ -93,17 +93,17 @@ describe('DatabaseManager', () => {
plugin: {
testdbname: {
connection: {
- database: 'database_name_overriden',
+ database: 'database_name_overridden',
},
},
differentclient: {
- client: 'sqlite3',
+ client: 'better-sqlite3',
connection: {
filename: 'plugin_with_different_client',
},
},
differentclientconnstring: {
- client: 'sqlite3',
+ client: 'better-sqlite3',
connection: ':memory:',
},
stringoverride: {
@@ -176,7 +176,7 @@ describe('DatabaseManager', () => {
new ConfigReader({
backend: {
database: {
- client: 'sqlite3',
+ client: 'better-sqlite3',
connection: ':memory:',
},
},
@@ -198,7 +198,7 @@ describe('DatabaseManager', () => {
new ConfigReader({
backend: {
database: {
- client: 'sqlite3',
+ client: 'better-sqlite3',
connection: 'some-file-path',
},
},
@@ -215,7 +215,7 @@ describe('DatabaseManager', () => {
new ConfigReader({
backend: {
database: {
- client: 'sqlite3',
+ client: 'better-sqlite3',
connection: {
directory: 'sqlite-files',
},
@@ -239,7 +239,7 @@ describe('DatabaseManager', () => {
new ConfigReader({
backend: {
database: {
- client: 'sqlite3',
+ client: 'better-sqlite3',
connection: {
directory: 'sqlite-files',
},
@@ -270,7 +270,7 @@ describe('DatabaseManager', () => {
new ConfigReader({
backend: {
database: {
- client: 'sqlite3',
+ client: 'better-sqlite3',
connection: {
directory: 'sqlite-files',
},
@@ -304,10 +304,10 @@ describe('DatabaseManager', () => {
const mockCalls = mocked(createDatabaseClient).mock.calls.splice(-1);
const [_baseConfig, overrides] = mockCalls[0];
- // simple case where only database name is overriden
+ // simple case where only database name is overridden
expect(overrides).toMatchObject({
connection: {
- database: 'database_name_overriden',
+ database: 'database_name_overridden',
},
});
});
@@ -349,7 +349,7 @@ describe('DatabaseManager', () => {
// plugin connection should be used as base config, client is different
expect(baseConfig.get()).toMatchObject({
- client: 'sqlite3',
+ client: 'better-sqlite3',
connection: config.backend.database.plugin[pluginId].connection,
});
});
@@ -361,10 +361,10 @@ describe('DatabaseManager', () => {
const mockCalls = mocked(createDatabaseClient).mock.calls.splice(-1);
const [baseConfig, overrides] = mockCalls[0];
- // plugin client should be sqlite3
- expect(baseConfig.get().client).toEqual('sqlite3');
+ // plugin client should be better-sqlite3
+ expect(baseConfig.get().client).toEqual('better-sqlite3');
- // sqlite3 uses 'filename' instead of 'database'
+ // SQLite uses 'filename' instead of 'database'
expect(overrides).toHaveProperty(
'connection.filename',
'plugin_with_different_client',
@@ -378,7 +378,7 @@ describe('DatabaseManager', () => {
const mockCalls = mocked(createDatabaseClient).mock.calls.splice(-1);
const [baseConfig, overrides] = mockCalls[0];
- expect(baseConfig.get().client).toEqual('sqlite3');
+ expect(baseConfig.get().client).toEqual('better-sqlite3');
expect(overrides).toHaveProperty('connection.filename', ':memory:');
});
@@ -465,7 +465,7 @@ describe('DatabaseManager', () => {
new ConfigReader({
backend: {
database: {
- client: 'sqlite3',
+ client: 'better-sqlite3',
pluginDivisionMode: 'schema',
connection: {
host: 'localhost',
@@ -484,7 +484,7 @@ describe('DatabaseManager', () => {
const [baseConfig, overrides] = mockCalls[0];
expect(baseConfig.get()).toMatchObject({
- client: 'sqlite3',
+ client: 'better-sqlite3',
connection: config.backend.database.connection,
});
@@ -581,7 +581,7 @@ describe('DatabaseManager', () => {
plugin: {
testdbname: {
connection: {
- database: 'database_name_overriden',
+ database: 'database_name_overridden',
host: 'newhost',
},
},
@@ -599,7 +599,7 @@ describe('DatabaseManager', () => {
expect(baseConfig.get()).toMatchObject({
client: 'pg',
connection: {
- database: 'database_name_overriden',
+ database: 'database_name_overridden',
host: 'newhost',
user: 'foo',
password: 'bar',
@@ -608,7 +608,7 @@ describe('DatabaseManager', () => {
expect(overrides).toHaveProperty('searchPath', ['testdbname']);
expect(overrides).toHaveProperty(
'connection.database',
- 'database_name_overriden',
+ 'database_name_overridden',
);
});
diff --git a/packages/backend-common/src/database/config.test.ts b/packages/backend-common/src/database/config.test.ts
index 01ec599cf4..a5bf4a79d2 100644
--- a/packages/backend-common/src/database/config.test.ts
+++ b/packages/backend-common/src/database/config.test.ts
@@ -101,7 +101,7 @@ describe('config', () => {
expect(
mergeDatabaseConfig(
{
- client: 'sqlite3',
+ client: 'better-sqlite3',
connection: ':memory:',
useNullAsDefault: true,
},
@@ -112,7 +112,27 @@ describe('config', () => {
},
),
).toEqual({
- client: 'sqlite3',
+ client: 'better-sqlite3',
+ connection: {
+ filename: '/path/to/file',
+ },
+ useNullAsDefault: true,
+ });
+ expect(
+ mergeDatabaseConfig(
+ {
+ client: 'better-sqlite3',
+ connection: ':memory:',
+ useNullAsDefault: true,
+ },
+ {
+ connection: {
+ filename: '/path/to/file',
+ },
+ },
+ ),
+ ).toEqual({
+ client: 'better-sqlite3',
connection: {
filename: '/path/to/file',
},
diff --git a/packages/backend-common/src/database/connection.test.ts b/packages/backend-common/src/database/connection.test.ts
index 6f02e7b2ed..044f807576 100644
--- a/packages/backend-common/src/database/connection.test.ts
+++ b/packages/backend-common/src/database/connection.test.ts
@@ -59,7 +59,7 @@ describe('database connection', () => {
expect(
createDatabaseClient(
new ConfigReader({
- client: 'sqlite3',
+ client: 'better-sqlite3',
connection: ':memory:',
}),
),
@@ -133,7 +133,7 @@ describe('database connection', () => {
});
it('returns Knex config for sqlite', () => {
- expect(createNameOverride('sqlite3', 'testsqlite')).toHaveProperty(
+ expect(createNameOverride('better-sqlite3', 'testsqlite')).toHaveProperty(
'connection.filename',
'testsqlite',
);
@@ -178,7 +178,9 @@ describe('database connection', () => {
});
it('throws error for sqlite', () => {
- expect(createSchemaOverride('sqlite3', 'testsqlite')).toBeUndefined();
+ expect(
+ createSchemaOverride('better-sqlite3', 'testsqlite'),
+ ).toBeUndefined();
});
it('returns Knex config for mysql', () => {
@@ -191,7 +193,7 @@ describe('database connection', () => {
});
describe('ensureSchemaExists', () => {
- it('returns sucessfully with pg client', async () => {
+ it('returns successfully with pg client', async () => {
await ensureSchemaExists(
new ConfigReader({
client: 'pg',
@@ -218,7 +220,7 @@ describe('database connection', () => {
return expect(
ensureSchemaExists(
new ConfigReader({
- client: 'sqlite3',
+ client: 'better-sqlite3',
schema: 'catalog',
connection: ':memory:',
}),
diff --git a/packages/backend-common/src/database/connectors/sqlite3.test.ts b/packages/backend-common/src/database/connectors/sqlite3.test.ts
index d751d895d0..2bd517d373 100644
--- a/packages/backend-common/src/database/connectors/sqlite3.test.ts
+++ b/packages/backend-common/src/database/connectors/sqlite3.test.ts
@@ -21,87 +21,6 @@ import {
createSqliteDatabaseClient,
} from './sqlite3';
-describe('sqlite3', () => {
- const createConfig = (connection: any) =>
- new ConfigReader({ client: 'sqlite3', connection });
-
- describe('buildSqliteDatabaseConfig', () => {
- it('builds an in-memory connection', () => {
- expect(buildSqliteDatabaseConfig(createConfig(':memory:'))).toEqual({
- client: 'sqlite3',
- connection: { filename: ':memory:' },
- useNullAsDefault: true,
- });
- });
-
- it('builds an in-memory connection by override with filename', () => {
- expect(
- buildSqliteDatabaseConfig(
- createConfig(path.join('path', 'to', 'foo')),
- { connection: ':memory:' },
- ),
- ).toEqual({
- client: 'sqlite3',
- connection: { filename: ':memory:' },
- useNullAsDefault: true,
- });
- });
-
- it('builds a persistent connection, normalize config with filename', () => {
- expect(
- buildSqliteDatabaseConfig(createConfig(path.join('path', 'to', 'foo'))),
- ).toEqual({
- client: 'sqlite3',
- connection: { filename: path.join('path', 'to', 'foo') },
- useNullAsDefault: true,
- });
- });
-
- it('builds a persistent connection', () => {
- expect(
- buildSqliteDatabaseConfig(
- createConfig({
- filename: path.join('path', 'to', 'foo'),
- }),
- ),
- ).toEqual({
- client: 'sqlite3',
- connection: {
- filename: path.join('path', 'to', 'foo'),
- },
- useNullAsDefault: true,
- });
- });
-
- it('replaces the connection with an override', () => {
- expect(
- buildSqliteDatabaseConfig(createConfig(':memory:'), {
- connection: { filename: path.join('path', 'to', 'foo') },
- }),
- ).toEqual({
- client: 'sqlite3',
- connection: {
- filename: path.join('path', 'to', 'foo'),
- },
- useNullAsDefault: true,
- });
- });
- });
-
- describe('createSqliteDatabaseClient', () => {
- it('creates an in memory knex instance', () => {
- expect(
- createSqliteDatabaseClient(
- createConfig({
- client: 'sqlite3',
- connection: ':memory:',
- }),
- ),
- ).toBeTruthy();
- });
- });
-});
-
describe('better-sqlite3', () => {
const createConfig = (connection: any) =>
new ConfigReader({ client: 'better-sqlite3', connection });
@@ -171,14 +90,7 @@ describe('better-sqlite3', () => {
describe('createSqliteDatabaseClient', () => {
it('creates an in memory knex instance', () => {
- expect(
- createSqliteDatabaseClient(
- createConfig({
- client: 'better-sqlite3',
- connection: ':memory:',
- }),
- ),
- ).toBeTruthy();
+ expect(createSqliteDatabaseClient(createConfig(':memory:'))).toBeTruthy();
});
});
});
diff --git a/packages/backend-common/src/database/util.ts b/packages/backend-common/src/database/util.ts
index a96eeb3a7b..0a7d3cd7f7 100644
--- a/packages/backend-common/src/database/util.ts
+++ b/packages/backend-common/src/database/util.ts
@@ -28,6 +28,7 @@ export function isDatabaseConflictError(e: unknown) {
return (
typeof message === 'string' &&
(/SQLITE_CONSTRAINT(?:_UNIQUE)?: UNIQUE/.test(message) ||
+ /UNIQUE constraint failed:/.test(message) ||
/unique constraint/.test(message))
);
}
diff --git a/packages/backend-common/src/reading/AwsS3UrlReader.test.ts b/packages/backend-common/src/reading/AwsS3UrlReader.test.ts
index 2911699a5d..01fd27f45a 100644
--- a/packages/backend-common/src/reading/AwsS3UrlReader.test.ts
+++ b/packages/backend-common/src/reading/AwsS3UrlReader.test.ts
@@ -18,7 +18,7 @@ import { ConfigReader } from '@backstage/config';
import { JsonObject } from '@backstage/types';
import { getVoidLogger } from '../logging';
import { DefaultReadTreeResponseFactory } from './tree';
-import { AwsS3UrlReader } from './AwsS3UrlReader';
+import { AwsS3UrlReader, parseUrl } from './AwsS3UrlReader';
import {
AwsS3Integration,
readAwsS3IntegrationConfig,
@@ -33,6 +33,82 @@ const treeResponseFactory = DefaultReadTreeResponseFactory.create({
config: new ConfigReader({}),
});
+describe('parseUrl', () => {
+ it('supports all aws formats', () => {
+ expect(
+ parseUrl('https://s3.us-west-2.amazonaws.com/my.bucket-3/a/puppy.jpg', {
+ host: 'amazonaws.com',
+ }),
+ ).toEqual({
+ path: 'a/puppy.jpg',
+ bucket: 'my.bucket-3',
+ region: 'us-west-2',
+ });
+ expect(
+ parseUrl('https://s3-us-west-2.amazonaws.com/my.bucket-3/a/puppy.jpg', {
+ host: 'amazonaws.com',
+ }),
+ ).toEqual({
+ path: 'a/puppy.jpg',
+ bucket: 'my.bucket-3',
+ region: 'us-west-2',
+ });
+ expect(
+ parseUrl('https://my.bucket-3.s3.us-west-2.amazonaws.com/a/puppy.jpg', {
+ host: 'amazonaws.com',
+ }),
+ ).toEqual({
+ path: 'a/puppy.jpg',
+ bucket: 'my.bucket-3',
+ region: 'us-west-2',
+ });
+ expect(
+ parseUrl(
+ 'https://ignored.s3.us-west-2.amazonaws.com/my.bucket-3/a/puppy.jpg',
+ {
+ host: 'amazonaws.com',
+ s3ForcePathStyle: true,
+ },
+ ),
+ ).toEqual({
+ path: 'a/puppy.jpg',
+ bucket: 'my.bucket-3',
+ region: 'us-west-2',
+ });
+ });
+
+ it('supports all non-aws formats', () => {
+ expect(
+ parseUrl('https://my-host.com/my.bucket-3/a/puppy.jpg', {
+ host: 'my-host.com',
+ }),
+ ).toEqual({
+ path: 'a/puppy.jpg',
+ bucket: 'my.bucket-3',
+ region: '',
+ });
+ expect(
+ parseUrl('https://my.bucket-3.my-host.com/a/puppy.jpg', {
+ host: 'my-host.com',
+ }),
+ ).toEqual({
+ path: 'a/puppy.jpg',
+ bucket: 'my.bucket-3',
+ region: '',
+ });
+ expect(
+ parseUrl('https://ignored.my-host.com/my.bucket-3/a/puppy.jpg', {
+ host: 'my-host.com',
+ s3ForcePathStyle: true,
+ }),
+ ).toEqual({
+ path: 'a/puppy.jpg',
+ bucket: 'my.bucket-3',
+ region: '',
+ });
+ });
+});
+
describe('AwsS3UrlReader', () => {
const createReader = (config: JsonObject): UrlReaderPredicateTuple[] => {
return AwsS3UrlReader.factory({
@@ -178,7 +254,7 @@ describe('AwsS3UrlReader', () => {
),
).rejects.toThrow(
Error(
- `Could not retrieve file from S3; caused by Error: invalid AWS S3 URL, cannot parse region from host in https://test-bucket.s3.us-east-2.NOTamazonaws.com/file.yaml`,
+ `Could not retrieve file from S3; caused by Error: Invalid AWS S3 URL https://test-bucket.s3.us-east-2.NOTamazonaws.com/file.yaml`,
),
);
});
@@ -234,7 +310,7 @@ describe('AwsS3UrlReader', () => {
),
).rejects.toThrow(
Error(
- `Could not retrieve file from S3; caused by Error: invalid AWS S3 URL, cannot parse region from host in https://test-bucket.s3.us-east-2.NOTamazonaws.com/file.yaml`,
+ `Could not retrieve file from S3; caused by Error: Invalid AWS S3 URL https://test-bucket.s3.us-east-2.NOTamazonaws.com/file.yaml`,
),
);
});
@@ -247,7 +323,14 @@ describe('AwsS3UrlReader', () => {
AWSMock.setSDKInstance(aws);
AWSMock.mock('S3', 'getObject', (_, callback) => {
- callback({ statusCode: 304 }, null);
+ const error: aws.AWSError = {
+ code: 'NotModified',
+ message: 'Not Modified',
+ statusCode: 304,
+ name: 'oops',
+ time: new Date('2019-01-01T00:00:00.000Z'),
+ };
+ callback(error, undefined);
});
const s3 = new aws.S3();
diff --git a/packages/backend-common/src/reading/AwsS3UrlReader.ts b/packages/backend-common/src/reading/AwsS3UrlReader.ts
index 86ff0e7d65..b3c7aae3bf 100644
--- a/packages/backend-common/src/reading/AwsS3UrlReader.ts
+++ b/packages/backend-common/src/reading/AwsS3UrlReader.ts
@@ -35,64 +35,82 @@ import {
import { ForwardedError, NotModifiedError } from '@backstage/errors';
import { ListObjectsV2Output, ObjectList } from 'aws-sdk/clients/s3';
-const parseURL = (
+/**
+ * Path style URLs: https://s3.(region).amazonaws.com/(bucket)/(key)
+ * The region can also be on the old form: https://s3-(region).amazonaws.com/(bucket)/(key)
+ * Virtual hosted style URLs: https://(bucket).s3.(region).amazonaws.com/(key)
+ * See https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html#path-style-access
+ */
+export function parseUrl(
url: string,
config: AwsS3IntegrationConfig,
-): { path: string; bucket: string; region: string } => {
- let { host, pathname } = new URL(url);
+): { path: string; bucket: string; region: string } {
+ const parsedUrl = new URL(url);
/**
* Removes the leading '/' from the pathname to be processed
* as a parameter by AWS S3 SDK getObject method.
*/
- pathname = pathname.substr(1);
+ const pathname = parsedUrl.pathname.substring(1);
+ const host = parsedUrl.host;
- let bucket;
- let region;
+ // Treat Amazon hosted separately because it has special region logic
+ if (config.host === 'amazonaws.com') {
+ const match = host.match(
+ /^(?:([a-z0-9.-]+)\.)?s3[.-]([a-z0-9-]+)\.amazonaws\.com$/,
+ );
+ if (!match) {
+ throw new Error(`Invalid AWS S3 URL ${url}`);
+ }
- /**
- * Path style URLs: https://s3.Region.amazonaws.com/bucket-name/key-name
- * Virtual hosted style URLs: https://bucket-name.s3.Region.amazonaws.com/key-name
- * See https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html#path-style-access
- */
- if (config.s3ForcePathStyle) {
- if (pathname.indexOf('/') < 0) {
- throw new Error(
- `invalid path-style AWS S3 URL, ${url} does not contain bucket in the path`,
- );
+ const [, hostBucket, hostRegion] = match;
+
+ if (config.s3ForcePathStyle || !hostBucket) {
+ const slashIndex = pathname.indexOf('/');
+ if (slashIndex < 0) {
+ throw new Error(
+ `Invalid path-style AWS S3 URL ${url}, does not contain bucket in the path`,
+ );
+ }
+
+ return {
+ path: pathname.substring(slashIndex + 1),
+ bucket: pathname.substring(0, slashIndex),
+ region: hostRegion,
+ };
}
- [bucket] = pathname.split('/');
- pathname = pathname.substr(bucket.length + 1);
- } else {
- if (host.indexOf('.') < 0) {
- throw new Error(
- `invalid virtual hosted-style AWS S3 URL, ${url} does not contain bucket prefix in the host`,
- );
- }
- [bucket] = host.split('.');
- host = host.substr(bucket.length + 1);
+
+ return {
+ path: pathname,
+ bucket: hostBucket,
+ region: hostRegion,
+ };
}
- // Only extract region from *.amazonaws.com hosts
- if (config.host === 'amazonaws.com') {
- // At this point bucket prefix is removed from host for virtual hosted URLs
- const match = host.match(/^s3\.([a-z\d-]+)\.amazonaws\.com$/);
- if (!match) {
+ const usePathStyle =
+ config.s3ForcePathStyle || host.length === config.host.length;
+
+ if (usePathStyle) {
+ const slashIndex = pathname.indexOf('/');
+ if (slashIndex < 0) {
throw new Error(
- `invalid AWS S3 URL, cannot parse region from host in ${url}`,
+ `Invalid path-style AWS S3 URL ${url}, does not contain bucket in the path`,
);
}
- region = match[1];
- } else {
- region = '';
+
+ return {
+ path: pathname.substring(slashIndex + 1),
+ bucket: pathname.substring(0, slashIndex),
+ region: '',
+ };
}
return {
path: pathname,
- bucket: bucket,
- region: region,
+ bucket: host.substring(0, host.length - config.host.length - 1),
+ region: '',
};
-};
+}
/**
* Implements a {@link UrlReader} for AWS S3 buckets.
@@ -104,11 +122,11 @@ export class AwsS3UrlReader implements UrlReader {
const integrations = ScmIntegrations.fromConfig(config);
return integrations.awsS3.list().map(integration => {
- const creds = AwsS3UrlReader.buildCredentials(integration);
+ const credentials = AwsS3UrlReader.buildCredentials(integration);
const s3 = new S3({
apiVersion: '2006-03-01',
- credentials: creds,
+ credentials,
endpoint: integration.config.endpoint,
s3ForcePathStyle: integration.config.s3ForcePathStyle,
});
@@ -180,7 +198,7 @@ export class AwsS3UrlReader implements UrlReader {
options?: ReadUrlOptions,
): Promise {
try {
- const { path, bucket, region } = parseURL(url, this.integration.config);
+ const { path, bucket, region } = parseUrl(url, this.integration.config);
aws.config.update({ region: region });
let params;
@@ -220,7 +238,7 @@ export class AwsS3UrlReader implements UrlReader {
options?: ReadTreeOptions,
): Promise {
try {
- const { path, bucket, region } = parseURL(url, this.integration.config);
+ const { path, bucket, region } = parseUrl(url, this.integration.config);
const allObjects: ObjectList = [];
const responses = [];
let continuationToken: string | undefined;
diff --git a/packages/backend-tasks/CHANGELOG.md b/packages/backend-tasks/CHANGELOG.md
index 2f41b37562..206e5633a8 100644
--- a/packages/backend-tasks/CHANGELOG.md
+++ b/packages/backend-tasks/CHANGELOG.md
@@ -1,5 +1,21 @@
# @backstage/backend-tasks
+## 0.2.0
+
+### Minor Changes
+
+- 9461f73643: **BREAKING**: The `TaskDefinition` type has been removed, and replaced by the equal pair `TaskScheduleDefinition` and `TaskInvocationDefinition`. The interface for `PluginTaskScheduler.scheduleTask` stays effectively unchanged, so this only affects you if you use the actual types directly.
+
+ Added the method `PluginTaskScheduler.createTaskSchedule`, which returns a `TaskSchedule` wrapper that is convenient to pass down into classes that want to control their task invocations while the caller wants to retain control of the actual schedule chosen.
+
+### Patch Changes
+
+- ab7cd7d70e: Do some groundwork for supporting the `better-sqlite3` driver, to maybe eventually replace `@vscode/sqlite3` (#9912)
+- 7290dda9d4: Relaxed the task ID requirement to now support any non-empty string
+- ae2ed04076: Add support for cron syntax to configure task frequency - `TaskScheduleDefinition.frequency` can now be both a `Duration` and an object on the form `{ cron: string }`, where the latter is expected to be on standard crontab format (e.g. `'0 */2 * * *'`).
+- Updated dependencies
+ - @backstage/backend-common@0.13.0
+
## 0.2.0-next.0
### Minor Changes
diff --git a/packages/backend-tasks/README.md b/packages/backend-tasks/README.md
index fe55f37afd..1bfab8a89b 100644
--- a/packages/backend-tasks/README.md
+++ b/packages/backend-tasks/README.md
@@ -22,7 +22,7 @@ const scheduler = TaskScheduler.fromConfig(rootConfig).forPlugin('my-plugin');
await scheduler.scheduleTask({
id: 'refresh_things',
- frequency: Duration.fromObject({ minutes: 10 }),
+ frequency: { cron: '*/5 * * * *' }, // every 5 minutes, also supports Duration
timeout: Duration.fromObject({ minutes: 15 }),
fn: async () => {
await entityProvider.run();
diff --git a/packages/backend-tasks/api-report.md b/packages/backend-tasks/api-report.md
index 98199a55b0..0093616d8f 100644
--- a/packages/backend-tasks/api-report.md
+++ b/packages/backend-tasks/api-report.md
@@ -36,7 +36,11 @@ export interface TaskRunner {
// @public
export interface TaskScheduleDefinition {
- frequency: Duration;
+ frequency:
+ | {
+ cron: string;
+ }
+ | Duration;
initialDelay?: Duration;
timeout: Duration;
}
diff --git a/packages/backend-tasks/package.json b/packages/backend-tasks/package.json
index b05a740e65..e4cecc5d85 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.2.0-next.0",
+ "version": "0.2.0",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -33,11 +33,12 @@
"start": "backstage-cli package start"
},
"dependencies": {
- "@backstage/backend-common": "^0.13.0-next.0",
+ "@backstage/backend-common": "^0.13.0",
"@backstage/config": "^0.1.15",
"@backstage/errors": "^0.2.2",
"@backstage/types": "^0.1.3",
"@types/luxon": "^2.0.4",
+ "cron": "^1.8.2",
"knex": "^1.0.2",
"lodash": "^4.17.21",
"luxon": "^2.0.2",
@@ -47,8 +48,9 @@
"zod": "^3.9.5"
},
"devDependencies": {
- "@backstage/backend-test-utils": "^0.1.21-next.0",
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/backend-test-utils": "^0.1.21",
+ "@backstage/cli": "^0.15.2",
+ "@types/cron": "^1.7.3",
"jest": "^26.0.1",
"wait-for-expect": "^3.0.2"
},
diff --git a/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.test.ts b/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.test.ts
index 993041bed4..646a2ce737 100644
--- a/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.test.ts
+++ b/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.test.ts
@@ -40,7 +40,7 @@ describe('PluginTaskManagerImpl', () => {
// TaskWorker.test.ts
describe('scheduleTask', () => {
it.each(databases.eachSupportedId())(
- 'can run the happy path, %p',
+ 'can run the v1 happy path, %p',
async databaseId => {
const { manager } = await init(databaseId);
@@ -58,6 +58,26 @@ describe('PluginTaskManagerImpl', () => {
},
60_000,
);
+
+ it.each(databases.eachSupportedId())(
+ 'can run the v2 happy path, %p',
+ async databaseId => {
+ const { manager } = await init(databaseId);
+
+ const fn = jest.fn();
+ await manager.scheduleTask({
+ id: 'task2',
+ timeout: Duration.fromMillis(5000),
+ frequency: { cron: '* * * * * *' },
+ fn,
+ });
+
+ await waitForExpect(() => {
+ expect(fn).toBeCalled();
+ });
+ },
+ 60_000,
+ );
});
// This is just to test the wrapper code; most of the actual tests are in
diff --git a/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.ts b/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.ts
index 8d50298ffd..8c3166b441 100644
--- a/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.ts
+++ b/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.ts
@@ -40,13 +40,16 @@ export class PluginTaskSchedulerImpl implements PluginTaskScheduler {
validateId(task.id);
const knex = await this.databaseFactory();
-
const worker = new TaskWorker(task.id, task.fn, knex, this.logger);
+
await worker.start(
{
- version: 1,
+ version: 2,
+ cadence:
+ 'cron' in task.frequency
+ ? task.frequency.cron
+ : task.frequency.toISO(),
initialDelayDuration: task.initialDelay?.toISO(),
- recurringAtMostEveryDuration: task.frequency.toISO(),
timeoutAfterDuration: task.timeout.toISO(),
},
{
diff --git a/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts b/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts
index c77fe4e925..27555036a1 100644
--- a/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts
+++ b/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts
@@ -56,7 +56,7 @@ export class PluginTaskSchedulerJanitor {
// SQLite currently (Oct 1 2021) returns a number for returning()
// statements, effectively ignoring them and instead returning the outcome
// of the delete() - and knex also emits a warning about that fact, which
- // is why we avoid that entirely for the sqlite3 driver.
+ // is why we avoid that entirely for the sqlite3 family of drivers.
// https://github.com/knex/knex/issues/4370
// https://github.com/mapbox/node-sqlite3/issues/1453
diff --git a/packages/backend-tasks/src/tasks/TaskScheduler.test.ts b/packages/backend-tasks/src/tasks/TaskScheduler.test.ts
index ce8e797503..2a5deddb19 100644
--- a/packages/backend-tasks/src/tasks/TaskScheduler.test.ts
+++ b/packages/backend-tasks/src/tasks/TaskScheduler.test.ts
@@ -39,7 +39,7 @@ describe('TaskScheduler', () => {
}
it.each(databases.eachSupportedId())(
- 'can return a working plugin impl, %p',
+ 'can return a working v1 plugin impl, %p',
async databaseId => {
const database = await createDatabase(databaseId);
const manager = new TaskScheduler(database, logger).forPlugin('test');
@@ -58,4 +58,25 @@ describe('TaskScheduler', () => {
},
60_000,
);
+
+ it.each(databases.eachSupportedId())(
+ 'can return a working v2 plugin impl, %p',
+ async databaseId => {
+ const database = await createDatabase(databaseId);
+ const manager = new TaskScheduler(database, logger).forPlugin('test');
+ const fn = jest.fn();
+
+ await manager.scheduleTask({
+ id: 'task2',
+ timeout: Duration.fromMillis(5000),
+ frequency: { cron: '* * * * * *' },
+ fn,
+ });
+
+ await waitForExpect(() => {
+ expect(fn).toBeCalled();
+ });
+ },
+ 60_000,
+ );
});
diff --git a/packages/backend-tasks/src/tasks/TaskWorker.test.ts b/packages/backend-tasks/src/tasks/TaskWorker.test.ts
index 7c8dad08bf..793e679c39 100644
--- a/packages/backend-tasks/src/tasks/TaskWorker.test.ts
+++ b/packages/backend-tasks/src/tasks/TaskWorker.test.ts
@@ -21,7 +21,7 @@ import waitForExpect from 'wait-for-expect';
import { migrateBackendTasks } from '../database/migrateBackendTasks';
import { DbTasksRow, DB_TASKS_TABLE } from '../database/tables';
import { TaskWorker } from './TaskWorker';
-import { TaskSettingsV1 } from './types';
+import { TaskSettingsV2 } from './types';
describe('TaskWorker', () => {
const logger = getVoidLogger();
@@ -42,11 +42,11 @@ describe('TaskWorker', () => {
const fn = jest.fn(
async () => new Promise(resolve => setTimeout(resolve, 50)),
);
- const settings: TaskSettingsV1 = {
- version: 1,
- initialDelayDuration: Duration.fromMillis(1000).toISO(),
- recurringAtMostEveryDuration: Duration.fromMillis(2000).toISO(),
- timeoutAfterDuration: Duration.fromMillis(60000).toISO(),
+ const settings: TaskSettingsV2 = {
+ version: 2,
+ cadence: '*/2 * * * * *',
+ initialDelayDuration: Duration.fromObject({ seconds: 1 }).toISO(),
+ timeoutAfterDuration: Duration.fromObject({ minutes: 1 }).toISO(),
};
const worker = new TaskWorker('task1', fn, knex, logger);
@@ -62,10 +62,10 @@ describe('TaskWorker', () => {
}),
);
expect(JSON.parse(row.settings_json)).toEqual({
- version: 1,
+ version: 2,
+ cadence: '*/2 * * * * *',
initialDelayDuration: 'PT1S',
- recurringAtMostEveryDuration: 'PT2S',
- timeoutAfterDuration: 'PT60S',
+ timeoutAfterDuration: 'PT1M',
});
await expect(worker.findReadyTask()).resolves.toEqual({
@@ -125,10 +125,10 @@ describe('TaskWorker', () => {
await migrateBackendTasks(knex);
const fn = jest.fn().mockRejectedValue(new Error('failed'));
- const settings: TaskSettingsV1 = {
- version: 1,
+ const settings: TaskSettingsV2 = {
+ version: 2,
initialDelayDuration: undefined,
- recurringAtMostEveryDuration: Duration.fromMillis(0).toISO(),
+ cadence: '* * * * * *',
timeoutAfterDuration: Duration.fromMillis(60000).toISO(),
};
@@ -151,18 +151,23 @@ describe('TaskWorker', () => {
const fn = jest.fn(
async () => new Promise(resolve => setTimeout(resolve, 50)),
);
- const settings: TaskSettingsV1 = {
- version: 1,
- recurringAtMostEveryDuration: Duration.fromMillis(0).toISO(),
+ const settings: TaskSettingsV2 = {
+ version: 2,
+ initialDelayDuration: undefined,
+ cadence: '* * * * * *',
timeoutAfterDuration: Duration.fromMillis(60000).toISO(),
};
const worker = new TaskWorker('task1', fn, knex, logger);
await worker.persistTask(settings);
- await expect(worker.findReadyTask()).resolves.toEqual({
- result: 'ready',
- settings,
+
+ await waitForExpect(async () => {
+ await expect(worker.findReadyTask()).resolves.toEqual({
+ result: 'ready',
+ settings,
+ });
});
+
await expect(worker.tryClaimTask('ticket', settings)).resolves.toBe(true);
let row = (await knex(DB_TASKS_TABLE))[0];
@@ -203,9 +208,10 @@ describe('TaskWorker', () => {
await migrateBackendTasks(knex);
const fn = jest.fn(async () => {});
- const settings: TaskSettingsV1 = {
- version: 1,
- recurringAtMostEveryDuration: Duration.fromMillis(0).toISO(),
+ const settings: TaskSettingsV2 = {
+ version: 2,
+ initialDelayDuration: undefined,
+ cadence: '* * * * * *',
timeoutAfterDuration: Duration.fromMillis(60000).toISO(),
};
@@ -218,10 +224,14 @@ describe('TaskWorker', () => {
const worker2 = new TaskWorker('task2', fn, knex, logger);
await worker2.persistTask(settings);
- await expect(worker2.findReadyTask()).resolves.toEqual({
- result: 'ready',
- settings,
+
+ await waitForExpect(async () => {
+ await expect(worker2.findReadyTask()).resolves.toEqual({
+ result: 'ready',
+ settings,
+ });
});
+
await knex(DB_TASKS_TABLE).where('id', '=', 'task2').delete();
await expect(worker2.tryClaimTask('ticket', settings)).resolves.toBe(
false,
@@ -229,10 +239,14 @@ describe('TaskWorker', () => {
const worker3 = new TaskWorker('task3', fn, knex, logger);
await worker3.persistTask(settings);
- await expect(worker3.findReadyTask()).resolves.toEqual({
- result: 'ready',
- settings,
+
+ await waitForExpect(async () => {
+ await expect(worker3.findReadyTask()).resolves.toEqual({
+ result: 'ready',
+ settings,
+ });
});
+
await expect(worker3.tryClaimTask('ticket', settings)).resolves.toBe(
true,
);
diff --git a/packages/backend-tasks/src/tasks/TaskWorker.ts b/packages/backend-tasks/src/tasks/TaskWorker.ts
index 5d33bfa7a1..84f45a7fe6 100644
--- a/packages/backend-tasks/src/tasks/TaskWorker.ts
+++ b/packages/backend-tasks/src/tasks/TaskWorker.ts
@@ -15,13 +15,14 @@
*/
import { Knex } from 'knex';
-import { Duration } from 'luxon';
+import { DateTime, Duration } from 'luxon';
import { AbortSignal } from 'node-abort-controller';
import { v4 as uuid } from 'uuid';
import { Logger } from 'winston';
import { DbTasksRow, DB_TASKS_TABLE } from '../database/tables';
-import { TaskFunction, TaskSettingsV1, taskSettingsV1Schema } from './types';
+import { TaskFunction, TaskSettingsV2, taskSettingsV2Schema } from './types';
import { delegateAbortController, nowPlus, sleep } from './util';
+import { CronTime } from 'cron';
const WORK_CHECK_FREQUENCY = Duration.fromObject({ seconds: 5 });
@@ -43,7 +44,7 @@ export class TaskWorker {
this.logger = logger;
}
- async start(settings: TaskSettingsV1, options?: { signal?: AbortSignal }) {
+ async start(settings: TaskSettingsV2, options?: { signal?: AbortSignal }) {
try {
await this.persistTask(settings);
} catch (e) {
@@ -123,22 +124,39 @@ export class TaskWorker {
/**
* Perform the initial store of the task info
*/
- async persistTask(settings: TaskSettingsV1) {
+ async persistTask(settings: TaskSettingsV2) {
// Perform an initial parse to ensure that we will definitely be able to
// read it back again.
- taskSettingsV1Schema.parse(settings);
+ taskSettingsV2Schema.parse(settings);
- const settingsJson = JSON.stringify(settings);
- const startAt = settings.initialDelayDuration
- ? nowPlus(Duration.fromISO(settings.initialDelayDuration), this.knex)
- : this.knex.fn.now();
+ const isCron = !settings?.cadence.startsWith('P');
+
+ let startAt: Knex.Raw;
+ if (settings.initialDelayDuration) {
+ startAt = nowPlus(
+ Duration.fromISO(settings.initialDelayDuration),
+ this.knex,
+ );
+ } else if (isCron) {
+ const time = new CronTime(settings.cadence)
+ .sendAt()
+ .add({ seconds: -1 }) // immediately, if "* * * * * *"
+ .toISOString();
+ startAt = this.knex.client.config.client.includes('sqlite3')
+ ? this.knex.raw('datetime(?)', [time])
+ : this.knex.raw(`?`, [time]);
+ } else {
+ startAt = this.knex.fn.now();
+ }
+
+ this.logger.debug(`task: ${this.taskId} configured to run at: ${startAt}`);
// It's OK if the task already exists; if it does, just replace its
// settings with the new value and start the loop as usual.
await this.knex(DB_TASKS_TABLE)
.insert({
id: this.taskId,
- settings_json: settingsJson,
+ settings_json: JSON.stringify(settings),
next_run_start_at: startAt,
})
.onConflict('id')
@@ -151,15 +169,14 @@ export class TaskWorker {
async findReadyTask(): Promise<
| { result: 'not-ready-yet' }
| { result: 'abort' }
- | { result: 'ready'; settings: TaskSettingsV1 }
+ | { result: 'ready'; settings: TaskSettingsV2 }
> {
const [row] = await this.knex(DB_TASKS_TABLE)
.where('id', '=', this.taskId)
.select({
settingsJson: 'settings_json',
ready: this.knex.raw(
- `
- CASE
+ `CASE
WHEN next_run_start_at <= ? AND current_run_ticket IS NULL THEN TRUE
ELSE FALSE
END`,
@@ -177,7 +194,8 @@ export class TaskWorker {
}
try {
- const settings = taskSettingsV1Schema.parse(JSON.parse(row.settingsJson));
+ const obj = JSON.parse(row.settingsJson);
+ const settings = taskSettingsV2Schema.parse(obj);
return { result: 'ready', settings };
} catch (e) {
this.logger.info(
@@ -199,7 +217,7 @@ export class TaskWorker {
*/
async tryClaimTask(
ticket: string,
- settings: TaskSettingsV1,
+ settings: TaskSettingsV2,
): Promise {
const startedAt = this.knex.fn.now();
const expiresAt = settings.timeoutAfterDuration
@@ -220,27 +238,37 @@ export class TaskWorker {
async tryReleaseTask(
ticket: string,
- settings: TaskSettingsV1,
+ settings: TaskSettingsV2,
): Promise {
- const { recurringAtMostEveryDuration } = settings;
+ const isCron = !settings?.cadence.startsWith('P');
- // We make an effort to keep the datetime calculations in the database
- // layer, making sure to not have to perform conversions back and forth and
- // leaning on the database as a central clock source
- const dbNull = this.knex.raw('null');
- const dt = Duration.fromISO(recurringAtMostEveryDuration).as('seconds');
- const nextRun = this.knex.client.config.client.includes('sqlite3')
- ? this.knex.raw('datetime(next_run_start_at, ?)', [`+${dt} seconds`])
- : this.knex.raw(`next_run_start_at + interval '${dt} seconds'`);
+ let nextRun: Knex.Raw;
+ if (isCron) {
+ const time = new CronTime(settings.cadence).sendAt().toISOString();
+ this.logger.debug(`task: ${this.taskId} will next occur around ${time}`);
+ nextRun = this.knex.client.config.client.includes('sqlite3')
+ ? this.knex.raw('datetime(?)', [time])
+ : this.knex.raw(`?`, [time]);
+ } else {
+ const dt = Duration.fromISO(settings.cadence).as('seconds');
+ this.logger.debug(
+ `task: ${this.taskId} will next occur around ${DateTime.now().plus({
+ seconds: dt,
+ })}`,
+ );
+ nextRun = this.knex.client.config.client.includes('sqlite3')
+ ? this.knex.raw('datetime(next_run_start_at, ?)', [`+${dt} seconds`])
+ : this.knex.raw(`next_run_start_at + interval '${dt} seconds'`);
+ }
const rows = await this.knex(DB_TASKS_TABLE)
.where('id', '=', this.taskId)
.where('current_run_ticket', '=', ticket)
.update({
next_run_start_at: nextRun,
- current_run_ticket: dbNull,
- current_run_started_at: dbNull,
- current_run_expires_at: dbNull,
+ current_run_ticket: this.knex.raw('null'),
+ current_run_started_at: this.knex.raw('null'),
+ current_run_expires_at: this.knex.raw('null'),
});
return rows === 1;
diff --git a/packages/backend-tasks/src/tasks/types.ts b/packages/backend-tasks/src/tasks/types.ts
index 35b5598700..acd651adcf 100644
--- a/packages/backend-tasks/src/tasks/types.ts
+++ b/packages/backend-tasks/src/tasks/types.ts
@@ -17,6 +17,7 @@
import { Duration } from 'luxon';
import { AbortSignal } from 'node-abort-controller';
import { z } from 'zod';
+import { CronTime } from 'cron';
/**
* A function that can be called as a scheduled task.
@@ -37,18 +38,8 @@ export type TaskFunction =
*/
export interface TaskScheduleDefinition {
/**
- * The maximum amount of time that a single task invocation can take, before
- * it's considered timed out and gets "released" such that a new invocation
- * is permitted to take place (possibly, then, on a different worker).
- *
- * If no value is given for this field then there is no timeout. This is
- * potentially dangerous.
- */
- timeout: Duration;
-
- /**
- * The amount of time that should pass between task invocation starts.
- * Essentially, this equals roughly how often you want the task to run.
+ * How often you want the task to run. The system does its best to avoid
+ * overlapping invocations.
*
* This is a best effort value; under some circumstances there can be
* deviations. For example, if the task runtime is longer than the frequency
@@ -56,12 +47,37 @@ export interface TaskScheduleDefinition {
* invocation of this task will be delayed until after the previous one
* finishes.
*
- * The system does its best to avoid overlapping invocations.
- *
- * If no value is given for this field then the task will only be invoked
- * once (on any worker) and then unscheduled automatically.
+ * This is a required field.
*/
- frequency: Duration;
+ frequency:
+ | {
+ /**
+ * A crontab style string.
+ *
+ * Overview:
+ *
+ * ```
+ * ┌────────────── second (optional)
+ * │ ┌──────────── minute
+ * │ │ ┌────────── hour
+ * │ │ │ ┌──────── day of month
+ * │ │ │ │ ┌────── month
+ * │ │ │ │ │ ┌──── day of week
+ * │ │ │ │ │ │
+ * │ │ │ │ │ │
+ * * * * * * *
+ * ```
+ */
+ cron: string;
+ }
+ | Duration;
+
+ /**
+ * The maximum amount of time that a single task invocation can take, before
+ * it's considered timed out and gets "released" such that a new invocation
+ * is permitted to take place (possibly, then, on a different worker).
+ */
+ timeout: Duration;
/**
* The amount of time that should pass before the first invocation happens.
@@ -70,7 +86,7 @@ export interface TaskScheduleDefinition {
* compute jobs.
*
* If no value is given for this field then the first invocation will happen
- * as soon as possible.
+ * as soon as possible according to the cadence.
*/
initialDelay?: Duration;
}
@@ -152,7 +168,21 @@ export interface PluginTaskScheduler {
function isValidOptionalDurationString(d: string | undefined): boolean {
try {
- return !d || Duration.fromISO(d).isValid === true;
+ return !d || Duration.fromISO(d).isValid;
+ } catch {
+ return false;
+ }
+}
+
+function isValidCronFormat(c: string | undefined): boolean {
+ try {
+ if (!c) {
+ return false;
+ }
+ // parse cron format to ensure it's a valid format.
+ // eslint-disable-next-line no-new
+ new CronTime(c);
+ return true;
} catch {
return false;
}
@@ -163,16 +193,46 @@ export const taskSettingsV1Schema = z.object({
initialDelayDuration: z
.string()
.optional()
- .refine(isValidOptionalDurationString, { message: 'Invalid duration' }),
+ .refine(isValidOptionalDurationString, {
+ message: 'Invalid duration, expecting ISO Period',
+ }),
recurringAtMostEveryDuration: z
.string()
- .refine(isValidOptionalDurationString, { message: 'Invalid duration' }),
- timeoutAfterDuration: z
- .string()
- .refine(isValidOptionalDurationString, { message: 'Invalid duration' }),
+ .refine(isValidOptionalDurationString, {
+ message: 'Invalid duration, expecting ISO Period',
+ }),
+ timeoutAfterDuration: z.string().refine(isValidOptionalDurationString, {
+ message: 'Invalid duration, expecting ISO Period',
+ }),
});
/**
* The properties that control a scheduled task (version 1).
*/
export type TaskSettingsV1 = z.infer;
+
+export const taskSettingsV2Schema = z.object({
+ version: z.literal(2),
+ cadence: z
+ .string()
+ .refine(isValidCronFormat, { message: 'Invalid cron' })
+ .or(
+ z.string().refine(isValidOptionalDurationString, {
+ message: 'Invalid duration, expecting ISO Period',
+ }),
+ ),
+ timeoutAfterDuration: z.string().refine(isValidOptionalDurationString, {
+ message: 'Invalid duration, expecting ISO Period',
+ }),
+ initialDelayDuration: z
+ .string()
+ .optional()
+ .refine(isValidOptionalDurationString, {
+ message: 'Invalid duration, expecting ISO Period',
+ }),
+});
+
+/**
+ * The properties that control a scheduled task (version 2).
+ */
+export type TaskSettingsV2 = z.infer;
diff --git a/packages/backend-test-utils/.snyk b/packages/backend-test-utils/.snyk
deleted file mode 100644
index ad62599e66..0000000000
--- a/packages/backend-test-utils/.snyk
+++ /dev/null
@@ -1,47 +0,0 @@
-# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
-version: v1.22.1
-# ignores vulnerabilities until expiry date; change duration by modifying expiry date
-ignore:
- SNYK-JS-TAR-1579155:
- - 'sqlite3 > node-gyp > tar':
- reason: >-
- The only usage is via node-gyp; there is no unpacking of untrusted tar
- files
- expires: 2022-11-11T14:30:05.581Z
- created: 2021-11-11T14:30:05.582Z
- SNYK-JS-TAR-1579152:
- - 'sqlite3 > node-gyp > tar':
- reason: >-
- The only usage is via node-gyp; there is no unpacking of untrusted tar
- files
- expires: 2022-11-11T14:30:05.581Z
- created: 2021-11-11T14:30:05.582Z
- SNYK-JS-TAR-1579147:
- - 'sqlite3 > node-gyp > tar':
- reason: >-
- The only usage is via node-gyp; there is no unpacking of untrusted tar
- files
- expires: 2022-11-11T14:30:05.581Z
- created: 2021-11-11T14:30:05.582Z
- SNYK-JS-TAR-1536758:
- - 'sqlite3 > node-gyp > tar':
- reason: >-
- The only usage is via node-gyp; there is no unpacking of untrusted tar
- files
- expires: 2022-11-11T14:30:05.581Z
- created: 2021-11-11T14:30:05.582Z
- SNYK-JS-TAR-1536531:
- - 'sqlite3 > node-gyp > tar':
- reason: >-
- The only usage is via node-gyp; there is no unpacking of untrusted tar
- files
- expires: 2022-11-11T14:30:05.581Z
- created: 2021-11-11T14:30:05.582Z
- SNYK-JS-TAR-1536528:
- - 'sqlite3 > node-gyp > tar':
- reason: >-
- The only usage is via node-gyp; there is no unpacking of untrusted tar
- files
- expires: 2022-11-11T14:30:05.581Z
- created: 2021-11-11T14:30:05.582Z
-patch: {}
diff --git a/packages/backend-test-utils/CHANGELOG.md b/packages/backend-test-utils/CHANGELOG.md
index a7dbcbd51f..bcf6d4a3f4 100644
--- a/packages/backend-test-utils/CHANGELOG.md
+++ b/packages/backend-test-utils/CHANGELOG.md
@@ -1,5 +1,15 @@
# @backstage/backend-test-utils
+## 0.1.21
+
+### Patch Changes
+
+- ab7cd7d70e: Do some groundwork for supporting the `better-sqlite3` driver, to maybe eventually replace `@vscode/sqlite3` (#9912)
+- 3c2bc73901: Add `setupRequestMockHandlers` which sets up a good `msw` server foundation, copied from `@backstage/test-utils` which is a frontend-only package and should not be used from backends.
+- Updated dependencies
+ - @backstage/backend-common@0.13.0
+ - @backstage/cli@0.15.2
+
## 0.1.21-next.0
### Patch Changes
diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json
index d5e0feac35..85965233d4 100644
--- a/packages/backend-test-utils/package.json
+++ b/packages/backend-test-utils/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-test-utils",
"description": "Test helpers library for Backstage backends",
- "version": "0.1.21-next.0",
+ "version": "0.1.21",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -34,10 +34,10 @@
"start": "backstage-cli package start"
},
"dependencies": {
- "@backstage/backend-common": "^0.13.0-next.0",
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/backend-common": "^0.13.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/config": "^0.1.15",
- "@vscode/sqlite3": "^5.0.7",
+ "better-sqlite3": "^7.5.0",
"knex": "^1.0.2",
"msw": "^0.35.0",
"mysql2": "^2.2.5",
@@ -46,7 +46,7 @@
"uuid": "^8.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"jest": "^26.0.1"
},
"files": [
diff --git a/packages/backend-test-utils/src/database/types.ts b/packages/backend-test-utils/src/database/types.ts
index 5aba48952f..083853ac78 100644
--- a/packages/backend-test-utils/src/database/types.ts
+++ b/packages/backend-test-utils/src/database/types.ts
@@ -66,6 +66,6 @@ export const allDatabases: Record =
},
SQLITE_3: {
name: 'SQLite 3.x',
- driver: 'sqlite3',
+ driver: 'better-sqlite3',
},
});
diff --git a/packages/backend/.snyk b/packages/backend/.snyk
deleted file mode 100644
index ad62599e66..0000000000
--- a/packages/backend/.snyk
+++ /dev/null
@@ -1,47 +0,0 @@
-# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
-version: v1.22.1
-# ignores vulnerabilities until expiry date; change duration by modifying expiry date
-ignore:
- SNYK-JS-TAR-1579155:
- - 'sqlite3 > node-gyp > tar':
- reason: >-
- The only usage is via node-gyp; there is no unpacking of untrusted tar
- files
- expires: 2022-11-11T14:30:05.581Z
- created: 2021-11-11T14:30:05.582Z
- SNYK-JS-TAR-1579152:
- - 'sqlite3 > node-gyp > tar':
- reason: >-
- The only usage is via node-gyp; there is no unpacking of untrusted tar
- files
- expires: 2022-11-11T14:30:05.581Z
- created: 2021-11-11T14:30:05.582Z
- SNYK-JS-TAR-1579147:
- - 'sqlite3 > node-gyp > tar':
- reason: >-
- The only usage is via node-gyp; there is no unpacking of untrusted tar
- files
- expires: 2022-11-11T14:30:05.581Z
- created: 2021-11-11T14:30:05.582Z
- SNYK-JS-TAR-1536758:
- - 'sqlite3 > node-gyp > tar':
- reason: >-
- The only usage is via node-gyp; there is no unpacking of untrusted tar
- files
- expires: 2022-11-11T14:30:05.581Z
- created: 2021-11-11T14:30:05.582Z
- SNYK-JS-TAR-1536531:
- - 'sqlite3 > node-gyp > tar':
- reason: >-
- The only usage is via node-gyp; there is no unpacking of untrusted tar
- files
- expires: 2022-11-11T14:30:05.581Z
- created: 2021-11-11T14:30:05.582Z
- SNYK-JS-TAR-1536528:
- - 'sqlite3 > node-gyp > tar':
- reason: >-
- The only usage is via node-gyp; there is no unpacking of untrusted tar
- files
- expires: 2022-11-11T14:30:05.581Z
- created: 2021-11-11T14:30:05.582Z
-patch: {}
diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md
index d6500304c0..f62b14b00d 100644
--- a/packages/backend/CHANGELOG.md
+++ b/packages/backend/CHANGELOG.md
@@ -1,5 +1,42 @@
# example-backend
+## 0.2.68
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.13.0
+ - @backstage/backend-tasks@0.2.0
+ - @backstage/plugin-app-backend@0.3.29
+ - @backstage/plugin-auth-backend@0.12.1
+ - @backstage/plugin-catalog-backend@0.24.0
+ - @backstage/plugin-scaffolder-backend@0.18.0
+ - @backstage/plugin-scaffolder-backend-module-rails@0.3.4
+ - @backstage/plugin-kubernetes-backend@0.4.12
+ - @backstage/plugin-rollbar-backend@0.1.26
+ - @backstage/plugin-techdocs-backend@0.14.2
+ - @backstage/catalog-model@0.13.0
+ - @backstage/plugin-badges-backend@0.1.23
+ - @backstage/plugin-search-backend-module-elasticsearch@0.1.1
+ - @backstage/plugin-search-backend-module-pg@0.3.1
+ - @backstage/plugin-search-backend-node@0.5.1
+ - @backstage/plugin-search-backend@0.4.7
+ - @backstage/catalog-client@0.9.0
+ - example-app@0.2.68
+ - @backstage/plugin-auth-node@0.1.5
+ - @backstage/plugin-azure-devops-backend@0.3.8
+ - @backstage/plugin-code-coverage-backend@0.1.27
+ - @backstage/plugin-graphql-backend@0.1.19
+ - @backstage/plugin-jenkins-backend@0.1.18
+ - @backstage/plugin-kafka-backend@0.2.22
+ - @backstage/plugin-permission-backend@0.5.4
+ - @backstage/plugin-permission-node@0.5.4
+ - @backstage/plugin-proxy-backend@0.2.23
+ - @backstage/plugin-tech-insights-backend@0.2.9
+ - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.13
+ - @backstage/plugin-tech-insights-node@0.2.7
+ - @backstage/plugin-todo-backend@0.1.26
+
## 0.2.68-next.0
### Patch Changes
diff --git a/packages/backend/knexfile.ts b/packages/backend/knexfile.ts
index ca05575153..93993c1d5c 100644
--- a/packages/backend/knexfile.ts
+++ b/packages/backend/knexfile.ts
@@ -16,7 +16,7 @@
module.exports = {
development: {
- client: 'sqlite3',
+ client: 'better-sqlite3',
connection: {
filename: './dev.sqlite3',
},
diff --git a/packages/backend/package.json b/packages/backend/package.json
index 50e7a9c3fb..a6f91e036f 100644
--- a/packages/backend/package.json
+++ b/packages/backend/package.json
@@ -1,6 +1,6 @@
{
"name": "example-backend",
- "version": "0.2.68-next.0",
+ "version": "0.2.68",
"main": "dist/index.cjs.js",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -27,42 +27,42 @@
"migrate:create": "knex migrate:make -x ts"
},
"dependencies": {
- "@backstage/backend-common": "^0.13.0-next.0",
- "@backstage/backend-tasks": "^0.2.0-next.0",
- "@backstage/catalog-client": "^0.9.0-next.0",
- "@backstage/catalog-model": "^0.13.0-next.0",
+ "@backstage/backend-common": "^0.13.0",
+ "@backstage/backend-tasks": "^0.2.0",
+ "@backstage/catalog-client": "^0.9.0",
+ "@backstage/catalog-model": "^0.13.0",
"@backstage/config": "^0.1.15",
"@backstage/integration": "^0.8.0",
- "@backstage/plugin-app-backend": "^0.3.29-next.0",
- "@backstage/plugin-auth-backend": "^0.12.1-next.0",
- "@backstage/plugin-auth-node": "^0.1.5-next.0",
- "@backstage/plugin-azure-devops-backend": "^0.3.8-next.0",
- "@backstage/plugin-badges-backend": "^0.1.23-next.0",
- "@backstage/plugin-catalog-backend": "^0.24.0-next.0",
- "@backstage/plugin-code-coverage-backend": "^0.1.27-next.0",
- "@backstage/plugin-graphql-backend": "^0.1.19-next.0",
- "@backstage/plugin-jenkins-backend": "^0.1.18-next.0",
- "@backstage/plugin-kubernetes-backend": "^0.4.12-next.0",
- "@backstage/plugin-kafka-backend": "^0.2.22-next.0",
- "@backstage/plugin-permission-backend": "^0.5.4-next.0",
+ "@backstage/plugin-app-backend": "^0.3.29",
+ "@backstage/plugin-auth-backend": "^0.12.1",
+ "@backstage/plugin-auth-node": "^0.1.5",
+ "@backstage/plugin-azure-devops-backend": "^0.3.8",
+ "@backstage/plugin-badges-backend": "^0.1.23",
+ "@backstage/plugin-catalog-backend": "^0.24.0",
+ "@backstage/plugin-code-coverage-backend": "^0.1.27",
+ "@backstage/plugin-graphql-backend": "^0.1.19",
+ "@backstage/plugin-jenkins-backend": "^0.1.18",
+ "@backstage/plugin-kubernetes-backend": "^0.4.12",
+ "@backstage/plugin-kafka-backend": "^0.2.22",
+ "@backstage/plugin-permission-backend": "^0.5.4",
"@backstage/plugin-permission-common": "^0.5.2",
- "@backstage/plugin-permission-node": "^0.5.4-next.0",
- "@backstage/plugin-proxy-backend": "^0.2.23-next.0",
- "@backstage/plugin-rollbar-backend": "^0.1.26-next.0",
- "@backstage/plugin-scaffolder-backend": "^0.18.0-next.0",
- "@backstage/plugin-scaffolder-backend-module-rails": "^0.3.4-next.0",
- "@backstage/plugin-search-backend": "^0.4.7-next.0",
- "@backstage/plugin-search-backend-node": "^0.5.1-next.0",
- "@backstage/plugin-search-backend-module-elasticsearch": "^0.1.1-next.0",
- "@backstage/plugin-search-backend-module-pg": "^0.3.1-next.0",
- "@backstage/plugin-techdocs-backend": "^0.14.2-next.0",
- "@backstage/plugin-tech-insights-backend": "^0.2.9-next.0",
- "@backstage/plugin-tech-insights-node": "^0.2.7-next.0",
- "@backstage/plugin-tech-insights-backend-module-jsonfc": "^0.1.13-next.0",
- "@backstage/plugin-todo-backend": "^0.1.26-next.0",
+ "@backstage/plugin-permission-node": "^0.5.4",
+ "@backstage/plugin-proxy-backend": "^0.2.23",
+ "@backstage/plugin-rollbar-backend": "^0.1.26",
+ "@backstage/plugin-scaffolder-backend": "^0.18.0",
+ "@backstage/plugin-scaffolder-backend-module-rails": "^0.3.4",
+ "@backstage/plugin-search-backend": "^0.4.7",
+ "@backstage/plugin-search-backend-node": "^0.5.1",
+ "@backstage/plugin-search-backend-module-elasticsearch": "^0.1.1",
+ "@backstage/plugin-search-backend-module-pg": "^0.3.1",
+ "@backstage/plugin-techdocs-backend": "^0.14.2",
+ "@backstage/plugin-tech-insights-backend": "^0.2.9",
+ "@backstage/plugin-tech-insights-node": "^0.2.7",
+ "@backstage/plugin-tech-insights-backend-module-jsonfc": "^0.1.13",
+ "@backstage/plugin-todo-backend": "^0.1.26",
"@gitbeaker/node": "^35.1.0",
"@octokit/rest": "^18.5.3",
- "@vscode/sqlite3": "^5.0.7",
+ "better-sqlite3": "^7.5.0",
"azure-devops-node-api": "^11.0.1",
"dockerode": "^3.3.1",
"example-app": "link:../app",
@@ -76,7 +76,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@types/dockerode": "^3.3.0",
"@types/express": "^4.17.6",
"@types/express-serve-static-core": "^4.17.5"
diff --git a/packages/backend/src/plugins/app.ts b/packages/backend/src/plugins/app.ts
index 0747d890e1..03d1ad95e7 100644
--- a/packages/backend/src/plugins/app.ts
+++ b/packages/backend/src/plugins/app.ts
@@ -18,15 +18,13 @@ import { createRouter } from '@backstage/plugin-app-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
-export default async function createPlugin({
- logger,
- config,
- database,
-}: PluginEnvironment): Promise {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
return await createRouter({
- logger,
- config,
- database,
+ logger: env.logger,
+ config: env.config,
+ database: env.database,
appPackageName: 'example-app',
});
}
diff --git a/packages/backend/src/plugins/auth.ts b/packages/backend/src/plugins/auth.ts
index 7f2b950c3c..da8eedcabc 100644
--- a/packages/backend/src/plugins/auth.ts
+++ b/packages/backend/src/plugins/auth.ts
@@ -18,18 +18,14 @@ import { createRouter } from '@backstage/plugin-auth-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
-export default async function createPlugin({
- logger,
- database,
- config,
- discovery,
- tokenManager,
-}: PluginEnvironment): Promise {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
return await createRouter({
- logger,
- config,
- database,
- discovery,
- tokenManager,
+ logger: env.logger,
+ config: env.config,
+ database: env.database,
+ discovery: env.discovery,
+ tokenManager: env.tokenManager,
});
}
diff --git a/packages/backend/src/plugins/azure-devops.ts b/packages/backend/src/plugins/azure-devops.ts
index 4120e655ed..67bba8ac85 100644
--- a/packages/backend/src/plugins/azure-devops.ts
+++ b/packages/backend/src/plugins/azure-devops.ts
@@ -18,9 +18,11 @@ import { createRouter } from '@backstage/plugin-azure-devops-backend';
import { Router } from 'express';
import type { PluginEnvironment } from '../types';
-export default function createPlugin({
- logger,
- config,
-}: PluginEnvironment): Promise {
- return createRouter({ logger, config });
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
+ return createRouter({
+ logger: env.logger,
+ config: env.config,
+ });
}
diff --git a/packages/backend/src/plugins/badges.ts b/packages/backend/src/plugins/badges.ts
index 0f579ccf91..37529689f3 100644
--- a/packages/backend/src/plugins/badges.ts
+++ b/packages/backend/src/plugins/badges.ts
@@ -18,15 +18,15 @@ import {
createRouter,
createDefaultBadgeFactories,
} from '@backstage/plugin-badges-backend';
+import { Router } from 'express';
import { PluginEnvironment } from '../types';
-export default async function createPlugin({
- config,
- discovery,
-}: PluginEnvironment) {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
return await createRouter({
- config,
- discovery,
+ config: env.config,
+ discovery: env.discovery,
badgeFactories: createDefaultBadgeFactories(),
});
}
diff --git a/packages/backend/src/plugins/codecoverage.ts b/packages/backend/src/plugins/codecoverage.ts
index 358cf36708..adb20da2b3 100644
--- a/packages/backend/src/plugins/codecoverage.ts
+++ b/packages/backend/src/plugins/codecoverage.ts
@@ -15,9 +15,12 @@
*/
import { createRouter } from '@backstage/plugin-code-coverage-backend';
+import { Router } from 'express';
import { PluginEnvironment } from '../types';
-export default async function createPlugin(env: PluginEnvironment) {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
return await createRouter({
config: env.config,
discovery: env.discovery,
diff --git a/packages/backend/src/plugins/graphql.ts b/packages/backend/src/plugins/graphql.ts
index 3c53f4a64e..c9aafa70ff 100644
--- a/packages/backend/src/plugins/graphql.ts
+++ b/packages/backend/src/plugins/graphql.ts
@@ -18,12 +18,11 @@ import { createRouter } from '@backstage/plugin-graphql-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
-export default async function createPlugin({
- logger,
- config,
-}: PluginEnvironment): Promise {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
return await createRouter({
- logger,
- config,
+ logger: env.logger,
+ config: env.config,
});
}
diff --git a/packages/backend/src/plugins/healthcheck.ts b/packages/backend/src/plugins/healthcheck.ts
index 897e56d381..d229584e13 100644
--- a/packages/backend/src/plugins/healthcheck.ts
+++ b/packages/backend/src/plugins/healthcheck.ts
@@ -18,8 +18,11 @@ import { createStatusCheckRouter } from '@backstage/backend-common';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
-export default async function createRouter({
- logger,
-}: PluginEnvironment): Promise {
- return await createStatusCheckRouter({ logger, path: '/healthcheck' });
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
+ return await createStatusCheckRouter({
+ logger: env.logger,
+ path: '/healthcheck',
+ });
}
diff --git a/packages/backend/src/plugins/jenkins.ts b/packages/backend/src/plugins/jenkins.ts
index 7717e711fb..d62200b0ac 100644
--- a/packages/backend/src/plugins/jenkins.ts
+++ b/packages/backend/src/plugins/jenkins.ts
@@ -22,18 +22,16 @@ import { Router } from 'express';
import { PluginEnvironment } from '../types';
import { CatalogClient } from '@backstage/catalog-client';
-export default async function createPlugin({
- logger,
- config,
- discovery,
-}: PluginEnvironment): Promise {
- const catalog = new CatalogClient({ discoveryApi: discovery });
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
+ const catalog = new CatalogClient({ discoveryApi: env.discovery });
return await createRouter({
- logger,
+ logger: env.logger,
jenkinsInfoProvider: DefaultJenkinsInfoProvider.fromConfig({
catalog,
- config,
+ config: env.config,
}),
});
}
diff --git a/packages/backend/src/plugins/kafka.ts b/packages/backend/src/plugins/kafka.ts
index baa9bb070f..784bad3145 100644
--- a/packages/backend/src/plugins/kafka.ts
+++ b/packages/backend/src/plugins/kafka.ts
@@ -18,9 +18,11 @@ import { createRouter } from '@backstage/plugin-kafka-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
-export default async function createPlugin({
- logger,
- config,
-}: PluginEnvironment): Promise {
- return await createRouter({ logger, config });
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
+ return await createRouter({
+ logger: env.logger,
+ config: env.config,
+ });
}
diff --git a/packages/backend/src/plugins/kubernetes.ts b/packages/backend/src/plugins/kubernetes.ts
index 6d40d89b66..8023d549ff 100644
--- a/packages/backend/src/plugins/kubernetes.ts
+++ b/packages/backend/src/plugins/kubernetes.ts
@@ -15,15 +15,15 @@
*/
import { KubernetesBuilder } from '@backstage/plugin-kubernetes-backend';
+import { Router } from 'express';
import { PluginEnvironment } from '../types';
-export default async function createPlugin({
- logger,
- config,
-}: PluginEnvironment) {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
const { router } = await KubernetesBuilder.createBuilder({
- logger,
- config,
+ logger: env.logger,
+ config: env.config,
}).build();
return router;
}
diff --git a/packages/backend/src/plugins/permission.ts b/packages/backend/src/plugins/permission.ts
index 557cea9a26..7337687c54 100644
--- a/packages/backend/src/plugins/permission.ts
+++ b/packages/backend/src/plugins/permission.ts
@@ -35,15 +35,14 @@ class AllowAllPermissionPolicy implements PermissionPolicy {
export default async function createPlugin(
env: PluginEnvironment,
): Promise {
- const { logger, discovery, config } = env;
return await createRouter({
- config,
- logger,
- discovery,
+ config: env.config,
+ logger: env.logger,
+ discovery: env.discovery,
policy: new AllowAllPermissionPolicy(),
identity: IdentityClient.create({
- discovery,
- issuer: await discovery.getExternalBaseUrl('auth'),
+ discovery: env.discovery,
+ issuer: await env.discovery.getExternalBaseUrl('auth'),
}),
});
}
diff --git a/packages/backend/src/plugins/proxy.ts b/packages/backend/src/plugins/proxy.ts
index ddffd1f018..273e791f1c 100644
--- a/packages/backend/src/plugins/proxy.ts
+++ b/packages/backend/src/plugins/proxy.ts
@@ -18,10 +18,12 @@ import { createRouter } from '@backstage/plugin-proxy-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
-export default async function createPlugin({
- logger,
- config,
- discovery,
-}: PluginEnvironment): Promise {
- return await createRouter({ logger, config, discovery });
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
+ return await createRouter({
+ logger: env.logger,
+ config: env.config,
+ discovery: env.discovery,
+ });
}
diff --git a/packages/backend/src/plugins/rollbar.ts b/packages/backend/src/plugins/rollbar.ts
index d2fbfdd43d..c679be40a7 100644
--- a/packages/backend/src/plugins/rollbar.ts
+++ b/packages/backend/src/plugins/rollbar.ts
@@ -18,9 +18,11 @@ import { createRouter } from '@backstage/plugin-rollbar-backend';
import { Router } from 'express';
import type { PluginEnvironment } from '../types';
-export default async function createPlugin({
- logger,
- config,
-}: PluginEnvironment): Promise {
- return await createRouter({ logger, config });
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
+ return await createRouter({
+ logger: env.logger,
+ config: env.config,
+ });
}
diff --git a/packages/backend/src/plugins/scaffolder.ts b/packages/backend/src/plugins/scaffolder.ts
index e0f3a4b1ca..465616f433 100644
--- a/packages/backend/src/plugins/scaffolder.ts
+++ b/packages/backend/src/plugins/scaffolder.ts
@@ -19,19 +19,18 @@ import { createRouter } from '@backstage/plugin-scaffolder-backend';
import { Router } from 'express';
import type { PluginEnvironment } from '../types';
-export default async function createPlugin({
- logger,
- config,
- database,
- reader,
- discovery,
-}: PluginEnvironment): Promise {
- const catalogClient = new CatalogClient({ discoveryApi: discovery });
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
+ const catalogClient = new CatalogClient({
+ discoveryApi: env.discovery,
+ });
+
return await createRouter({
- logger,
- config,
- database,
- catalogClient,
- reader,
+ logger: env.logger,
+ config: env.config,
+ database: env.database,
+ catalogClient: catalogClient,
+ reader: env.reader,
});
}
diff --git a/packages/backend/src/plugins/search.ts b/packages/backend/src/plugins/search.ts
index a90b47cd81..cb675a842c 100644
--- a/packages/backend/src/plugins/search.ts
+++ b/packages/backend/src/plugins/search.ts
@@ -13,11 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import {
- PluginDatabaseManager,
- useHotCleanup,
-} from '@backstage/backend-common';
-import { Config } from '@backstage/config';
+
+import { useHotCleanup } from '@backstage/backend-common';
import { DefaultCatalogCollatorFactory } from '@backstage/plugin-catalog-backend';
import { createRouter } from '@backstage/plugin-search-backend';
import { ElasticSearchSearchEngine } from '@backstage/plugin-search-backend-module-elasticsearch';
@@ -28,60 +25,52 @@ import {
SearchEngine,
} from '@backstage/plugin-search-backend-node';
import { DefaultTechDocsCollatorFactory } from '@backstage/plugin-techdocs-backend';
-import { Logger } from 'winston';
+import { Router } from 'express';
import { PluginEnvironment } from '../types';
-async function createSearchEngine({
- logger,
- database,
- config,
-}: {
- logger: Logger;
- database: PluginDatabaseManager;
- config: Config;
-}): Promise {
- if (config.has('search.elasticsearch')) {
+async function createSearchEngine(
+ env: PluginEnvironment,
+): Promise {
+ if (env.config.has('search.elasticsearch')) {
return await ElasticSearchSearchEngine.fromConfig({
- logger,
- config,
+ logger: env.logger,
+ config: env.config,
});
}
- if (await PgSearchEngine.supported(database)) {
- return await PgSearchEngine.from({ database });
+ if (await PgSearchEngine.supported(env.database)) {
+ return await PgSearchEngine.from({ database: env.database });
}
- return new LunrSearchEngine({ logger });
+ return new LunrSearchEngine({ logger: env.logger });
}
-export default async function createPlugin({
- logger,
- permissions,
- discovery,
- config,
- database,
- tokenManager,
-}: PluginEnvironment) {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
// Initialize a connection to a search engine.
- const searchEngine = await createSearchEngine({ config, logger, database });
- const indexBuilder = new IndexBuilder({ logger, searchEngine });
+ const searchEngine = await createSearchEngine(env);
+ const indexBuilder = new IndexBuilder({
+ logger: env.logger,
+ searchEngine,
+ });
// Collators are responsible for gathering documents known to plugins. This
// particular collator gathers entities from the software catalog.
indexBuilder.addCollator({
defaultRefreshIntervalSeconds: 600,
- factory: DefaultCatalogCollatorFactory.fromConfig(config, {
- discovery,
- tokenManager,
+ factory: DefaultCatalogCollatorFactory.fromConfig(env.config, {
+ discovery: env.discovery,
+ tokenManager: env.tokenManager,
}),
});
indexBuilder.addCollator({
defaultRefreshIntervalSeconds: 600,
- factory: DefaultTechDocsCollatorFactory.fromConfig(config, {
- discovery,
- logger,
- tokenManager,
+ factory: DefaultTechDocsCollatorFactory.fromConfig(env.config, {
+ discovery: env.discovery,
+ logger: env.logger,
+ tokenManager: env.tokenManager,
}),
});
@@ -97,8 +86,8 @@ export default async function createPlugin({
return await createRouter({
engine: indexBuilder.getSearchEngine(),
types: indexBuilder.getDocumentTypes(),
- permissions,
- config,
- logger,
+ permissions: env.permissions,
+ config: env.config,
+ logger: env.logger,
});
}
diff --git a/packages/backend/src/plugins/techInsights.ts b/packages/backend/src/plugins/techInsights.ts
index 7b0ded2240..e249b1db9b 100644
--- a/packages/backend/src/plugins/techInsights.ts
+++ b/packages/backend/src/plugins/techInsights.ts
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
import {
createRouter,
buildTechInsightsContext,
@@ -28,17 +29,14 @@ import {
JSON_RULE_ENGINE_CHECK_TYPE,
} from '@backstage/plugin-tech-insights-backend-module-jsonfc';
-export default async function createPlugin({
- logger,
- config,
- discovery,
- database,
-}: PluginEnvironment): Promise {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
const techInsightsContext = await buildTechInsightsContext({
- logger,
- config,
- database,
- discovery,
+ logger: env.logger,
+ config: env.config,
+ database: env.database,
+ discovery: env.discovery,
factRetrievers: [
createFactRetrieverRegistration({
cadence: '1 1 1 * *', // Example cron, At 01:01 on day-of-month 1.
@@ -54,6 +52,7 @@ export default async function createPlugin({
}),
],
factCheckerFactory: new JsonRulesEngineFactCheckerFactory({
+ logger: env.logger,
checks: [
{
id: 'simpleTestCheck',
@@ -93,13 +92,12 @@ export default async function createPlugin({
},
},
],
- logger,
}),
});
return await createRouter({
...techInsightsContext,
- logger,
- config,
+ logger: env.logger,
+ config: env.config,
});
}
diff --git a/packages/backend/src/plugins/techdocs.ts b/packages/backend/src/plugins/techdocs.ts
index c32bbccbb0..6e369f8f0f 100644
--- a/packages/backend/src/plugins/techdocs.ts
+++ b/packages/backend/src/plugins/techdocs.ts
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
import { DockerContainerRunner } from '@backstage/backend-common';
import {
createRouter,
@@ -24,17 +25,13 @@ import Docker from 'dockerode';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
-export default async function createPlugin({
- logger,
- config,
- discovery,
- reader,
- cache,
-}: PluginEnvironment): Promise {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
// Preparers are responsible for fetching source files for documentation.
- const preparers = await Preparers.fromConfig(config, {
- logger,
- reader,
+ const preparers = await Preparers.fromConfig(env.config, {
+ logger: env.logger,
+ reader: env.reader,
});
// Docker client (conditionally) used by the generators, based on techdocs.generators config.
@@ -42,17 +39,17 @@ export default async function createPlugin({
const containerRunner = new DockerContainerRunner({ dockerClient });
// Generators are used for generating documentation sites.
- const generators = await Generators.fromConfig(config, {
- logger,
+ const generators = await Generators.fromConfig(env.config, {
+ logger: env.logger,
containerRunner,
});
// Publisher is used for
// 1. Publishing generated files to storage
// 2. Fetching files from storage and passing them to TechDocs frontend.
- const publisher = await Publisher.fromConfig(config, {
- logger,
- discovery,
+ const publisher = await Publisher.fromConfig(env.config, {
+ logger: env.logger,
+ discovery: env.discovery,
});
// checks if the publisher is working and logs the result
@@ -62,9 +59,9 @@ export default async function createPlugin({
preparers,
generators,
publisher,
- logger,
- config,
- discovery,
- cache,
+ logger: env.logger,
+ config: env.config,
+ discovery: env.discovery,
+ cache: env.cache,
});
}
diff --git a/packages/backend/src/plugins/todo.ts b/packages/backend/src/plugins/todo.ts
index df90e5a41e..fb460b5f70 100644
--- a/packages/backend/src/plugins/todo.ts
+++ b/packages/backend/src/plugins/todo.ts
@@ -22,21 +22,24 @@ import {
import { Router } from 'express';
import { PluginEnvironment } from '../types';
-export default async function createPlugin({
- logger,
- reader,
- config,
- discovery,
-}: PluginEnvironment): Promise {
- const todoReader = TodoScmReader.fromConfig(config, {
- logger,
- reader,
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
+ const todoReader = TodoScmReader.fromConfig(env.config, {
+ logger: env.logger,
+ reader: env.reader,
});
- const catalogClient = new CatalogClient({ discoveryApi: discovery });
+
+ const catalogClient = new CatalogClient({
+ discoveryApi: env.discovery,
+ });
+
const todoService = new TodoReaderService({
todoReader,
catalogClient,
});
- return await createRouter({ todoService });
+ return await createRouter({
+ todoService,
+ });
}
diff --git a/packages/catalog-client/CHANGELOG.md b/packages/catalog-client/CHANGELOG.md
index f3b74c4d4d..d9683f0fe2 100644
--- a/packages/catalog-client/CHANGELOG.md
+++ b/packages/catalog-client/CHANGELOG.md
@@ -1,5 +1,17 @@
# @backstage/catalog-client
+## 0.9.0
+
+### Minor Changes
+
+- bf95bb806c: **BREAKING**: Removed previously deprecated `CatalogApi.getEntityByName`, please use `getEntityByRef` instead.
+- a3eb3d2afa: **BREAKING**: Removed `CatalogClient.getLocationByEntity` and `CatalogClient.getOriginLocationByEntity` which had previously been deprecated. Please use `CatalogApi.getLocationByRef` instead. Note that this only affects you if you were using `CatalogClient` (the class) directly, rather than `CatalogApi` (the interface), since it has been removed from the interface in an earlier release.
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/catalog-model@0.13.0
+
## 0.9.0-next.0
### Minor Changes
diff --git a/packages/catalog-client/api-report.md b/packages/catalog-client/api-report.md
index ac8f712e11..5fcae87dd5 100644
--- a/packages/catalog-client/api-report.md
+++ b/packages/catalog-client/api-report.md
@@ -11,7 +11,6 @@ export type AddLocationRequest = {
type?: string;
target: string;
dryRun?: boolean;
- presence?: 'optional' | 'required';
};
// @public
@@ -79,7 +78,7 @@ export class CatalogClient implements CatalogApi {
};
});
addLocation(
- { type, target, dryRun, presence }: AddLocationRequest,
+ { type, target, dryRun }: AddLocationRequest,
options?: CatalogRequestOptions,
): Promise;
getEntities(
@@ -195,7 +194,6 @@ type Location_2 = {
id: string;
type: string;
target: string;
- presence?: 'optional' | 'required';
};
export { Location_2 as Location };
```
diff --git a/packages/catalog-client/package.json b/packages/catalog-client/package.json
index cf9246d5a2..b05b0d45c1 100644
--- a/packages/catalog-client/package.json
+++ b/packages/catalog-client/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/catalog-client",
"description": "An isomorphic client for the catalog backend",
- "version": "0.9.0-next.0",
+ "version": "0.9.0",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -33,12 +33,12 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.13.0-next.0",
+ "@backstage/catalog-model": "^0.13.0",
"@backstage/errors": "^0.2.2",
"cross-fetch": "^3.1.5"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@types/jest": "^26.0.7",
"msw": "^0.35.0"
},
diff --git a/packages/catalog-client/src/CatalogClient.ts b/packages/catalog-client/src/CatalogClient.ts
index 85aada616c..371ac55db4 100644
--- a/packages/catalog-client/src/CatalogClient.ts
+++ b/packages/catalog-client/src/CatalogClient.ts
@@ -272,7 +272,7 @@ export class CatalogClient implements CatalogApi {
* {@inheritdoc CatalogApi.addLocation}
*/
async addLocation(
- { type = 'url', target, dryRun, presence }: AddLocationRequest,
+ { type = 'url', target, dryRun }: AddLocationRequest,
options?: CatalogRequestOptions,
): Promise {
const response = await this.fetchApi.fetch(
@@ -285,7 +285,7 @@ export class CatalogClient implements CatalogApi {
...(options?.token && { Authorization: `Bearer ${options?.token}` }),
},
method: 'POST',
- body: JSON.stringify({ type, target, presence }),
+ body: JSON.stringify({ type, target }),
},
);
diff --git a/packages/catalog-client/src/types/api.ts b/packages/catalog-client/src/types/api.ts
index ba0c5e9359..389b82c081 100644
--- a/packages/catalog-client/src/types/api.ts
+++ b/packages/catalog-client/src/types/api.ts
@@ -244,8 +244,6 @@ export type Location = {
id: string;
type: string;
target: string;
- /** @deprecated This field is is ignored */
- presence?: 'optional' | 'required';
};
/**
@@ -257,8 +255,6 @@ export type AddLocationRequest = {
type?: string;
target: string;
dryRun?: boolean;
- /** @deprecated This field is is ignored */
- presence?: 'optional' | 'required';
};
/**
diff --git a/packages/catalog-model/CHANGELOG.md b/packages/catalog-model/CHANGELOG.md
index 8a35937c07..9bb530efac 100644
--- a/packages/catalog-model/CHANGELOG.md
+++ b/packages/catalog-model/CHANGELOG.md
@@ -1,5 +1,29 @@
# @backstage/catalog-model
+## 0.13.0
+
+### Minor Changes
+
+- 51a9f8f122: **BREAKING**:
+
+ - Removed the previously deprecated type `EntityRef`. Please use `string` for stringified entity refs, `CompoundEntityRef` for compound kind-namespace-name triplet objects, or custom objects like `{ kind?: string; namespace?: string; name: string }` and similar if you have need for partial types.
+ - Removed the previously deprecated type `LocationSpec` type, which has been moved to `@backstage/plugin-catalog-backend`.
+ - Removed the previously deprecated function `parseEntityName`. Please use `parseEntityRef` instead.
+
+- d1d488e371: **BREAKING**: The default validator for `metadata.tags` now permits the colon (`:`) character as well.
+
+### Patch Changes
+
+- 2952566587: Updated `parseEntityRef` to allow `:` and `/` in the entity name. For example, parsing `'component:default/foo:bar'` will result in the name `'foo:bar'`.
+
+ Note that only parsing `'foo:bar'` itself will result in the name `'bar'` and the entity kind `'foo'`, meaning this is a particularly nasty trap for user defined entity references. For this reason it is strongly discouraged to use names that contain these characters, and the catalog model does not allow it by default. However, this change now makes is possible to use these names if the default catalog validation is replaced, and in particular a high level of automation of the catalog population can limit issues that it might otherwise cause.
+
+- b1aacbf96a: Applied the fix for the `/alpha` entry point resolution that was part of the `v0.70.1` release of Backstage.
+- d1d488e371: **DEPRECATION**:
+
+ - Deprecated `CommonValidatorFunctions.isValidString`, please use `isNonEmptyString` instead which is equivalent but better named.
+ - Deprecated `CommonValidatorFunctions.isValidTag`, with no replacement. Its purpose was too specific and not reusable, so it will be removed.
+
## 0.13.0-next.0
### Minor Changes
diff --git a/packages/catalog-model/api-report.md b/packages/catalog-model/api-report.md
index 90242f9293..fca23d6ab9 100644
--- a/packages/catalog-model/api-report.md
+++ b/packages/catalog-model/api-report.md
@@ -165,7 +165,6 @@ export type EntityLink = {
export type EntityMeta = JsonObject & {
uid?: string;
etag?: string;
- generation?: number;
name: string;
namespace?: string;
title?: string;
@@ -176,9 +175,6 @@ export type EntityMeta = JsonObject & {
links?: EntityLink[];
};
-// @public @deprecated
-export type EntityName = CompoundEntityRef;
-
// @public
export const EntityPolicies: {
allOf(policies: EntityPolicy[]): EntityPolicy;
@@ -193,7 +189,6 @@ export type EntityPolicy = {
// @public
export type EntityRelation = {
type: string;
- target: CompoundEntityRef;
targetRef: string;
};
@@ -228,9 +223,6 @@ export class FieldFormatEntityPolicy implements EntityPolicy {
// @public
export function getCompoundEntityRef(entity: Entity): CompoundEntityRef;
-// @public @deprecated
-export const getEntityName: typeof getCompoundEntityRef;
-
// @public
export function getEntitySourceLocation(entity: Entity): {
type: string;
@@ -455,7 +447,7 @@ interface UserEntityV1alpha1 extends Entity {
email?: string;
picture?: string;
};
- memberOf: string[];
+ memberOf?: string[];
};
}
export { UserEntityV1alpha1 as UserEntity };
diff --git a/packages/catalog-model/examples/apis/swapi-graphql.yaml b/packages/catalog-model/examples/apis/swapi-graphql.yaml
index f3d924fc53..ccddc537e7 100644
--- a/packages/catalog-model/examples/apis/swapi-graphql.yaml
+++ b/packages/catalog-model/examples/apis/swapi-graphql.yaml
@@ -529,7 +529,7 @@ spec:
terrains: [String]
"""
- The percentage of the planet surface that is naturally occuring water or bodies
+ The percentage of the planet surface that is naturally occurring water or bodies
of water.
"""
surfaceWater: Float
diff --git a/packages/catalog-model/package.json b/packages/catalog-model/package.json
index bd0e88acbf..d07a5a6861 100644
--- a/packages/catalog-model/package.json
+++ b/packages/catalog-model/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/catalog-model",
"description": "Types and validators that help describe the model of a Backstage Catalog",
- "version": "0.13.0-next.0",
+ "version": "0.13.0",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -43,7 +43,7 @@
"uuid": "^8.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@types/jest": "^26.0.7",
"@types/json-schema": "^7.0.5",
"@types/lodash": "^4.14.151",
diff --git a/packages/catalog-model/src/entity/Entity.ts b/packages/catalog-model/src/entity/Entity.ts
index 029d9e095b..96f19b2c8a 100644
--- a/packages/catalog-model/src/entity/Entity.ts
+++ b/packages/catalog-model/src/entity/Entity.ts
@@ -15,7 +15,6 @@
*/
import { JsonObject } from '@backstage/types';
-import { CompoundEntityRef } from '../types';
import { EntityStatus } from './EntityStatus';
/**
@@ -109,17 +108,6 @@ export type EntityMeta = JsonObject & {
*/
etag?: string;
- /**
- * A positive nonzero number that indicates the current generation of data
- * for this entity; the value is incremented each time the spec changes.
- *
- * This field can not be set by the user at creation time, and the server
- * will reject an attempt to do so. The field will be populated in read
- * operations.
- * @deprecated field is not supported.
- */
- generation?: number;
-
/**
* The name of the entity.
*
@@ -196,13 +184,6 @@ export type EntityRelation = {
*/
type: string;
- /**
- * The target entity of this relation.
- *
- * @deprecated use targetRef instead
- */
- target: CompoundEntityRef;
-
/**
* The entity ref of the target of this relation.
*/
diff --git a/packages/catalog-model/src/entity/index.ts b/packages/catalog-model/src/entity/index.ts
index f46f53945f..45ee673167 100644
--- a/packages/catalog-model/src/entity/index.ts
+++ b/packages/catalog-model/src/entity/index.ts
@@ -35,7 +35,6 @@ export type {
export * from './policies';
export {
getCompoundEntityRef,
- getEntityName,
parseEntityRef,
stringifyEntityRef,
} from './ref';
diff --git a/packages/catalog-model/src/entity/policies/FieldFormatEntityPolicy.test.ts b/packages/catalog-model/src/entity/policies/FieldFormatEntityPolicy.test.ts
index 3e2639fff9..f32236e977 100644
--- a/packages/catalog-model/src/entity/policies/FieldFormatEntityPolicy.test.ts
+++ b/packages/catalog-model/src/entity/policies/FieldFormatEntityPolicy.test.ts
@@ -28,7 +28,6 @@ describe('FieldFormatEntityPolicy', () => {
metadata:
uid: e01199ab-08cc-44c2-8e19-5c29ded82521
etag: lsndfkjsndfkjnsdfkjnsd==
- generation: 13
name: my-component-yay
namespace: the-namespace
labels:
diff --git a/packages/catalog-model/src/entity/policies/FieldFormatEntityPolicy.ts b/packages/catalog-model/src/entity/policies/FieldFormatEntityPolicy.ts
index 22d0e5e997..18e9523478 100644
--- a/packages/catalog-model/src/entity/policies/FieldFormatEntityPolicy.ts
+++ b/packages/catalog-model/src/entity/policies/FieldFormatEntityPolicy.ts
@@ -29,8 +29,7 @@ import { Entity } from '../Entity';
*
* @remarks
*
- * This does not take into account machine generated fields such as uid, etag
- * and generation.
+ * This does not take into account machine generated fields such as uid and etag.
*
* @public
*/
diff --git a/packages/catalog-model/src/entity/policies/NoForeignRootFieldsEntityPolicy.test.ts b/packages/catalog-model/src/entity/policies/NoForeignRootFieldsEntityPolicy.test.ts
index fb1d703829..f9b5a75c33 100644
--- a/packages/catalog-model/src/entity/policies/NoForeignRootFieldsEntityPolicy.test.ts
+++ b/packages/catalog-model/src/entity/policies/NoForeignRootFieldsEntityPolicy.test.ts
@@ -28,7 +28,6 @@ describe('NoForeignRootFieldsEntityPolicy', () => {
metadata:
uid: e01199ab-08cc-44c2-8e19-5c29ded82521
etag: lsndfkjsndfkjnsdfkjnsd==
- generation: 13
name: my-component-yay
namespace: the-namespace
labels:
diff --git a/packages/catalog-model/src/entity/policies/SchemaValidEntityPolicy.test.ts b/packages/catalog-model/src/entity/policies/SchemaValidEntityPolicy.test.ts
index c263689446..4752296ed5 100644
--- a/packages/catalog-model/src/entity/policies/SchemaValidEntityPolicy.test.ts
+++ b/packages/catalog-model/src/entity/policies/SchemaValidEntityPolicy.test.ts
@@ -29,7 +29,6 @@ describe('SchemaValidEntityPolicy', () => {
metadata:
uid: e01199ab-08cc-44c2-8e19-5c29ded82521
etag: lsndfkjsndfkjnsdfkjnsd==
- generation: 13
name: my-component-yay
namespace: the-namespace
labels:
@@ -127,26 +126,6 @@ describe('SchemaValidEntityPolicy', () => {
await expect(policy.enforce(data)).rejects.toThrow(/etag/);
});
- it('accepts missing generation', async () => {
- delete data.metadata.generation;
- await expect(policy.enforce(data)).resolves.toBe(data);
- });
-
- it('rejects bad generation type', async () => {
- data.metadata.generation = 'a';
- await expect(policy.enforce(data)).rejects.toThrow(/generation/);
- });
-
- it('rejects zero generation', async () => {
- data.metadata.generation = 0;
- await expect(policy.enforce(data)).rejects.toThrow(/generation/);
- });
-
- it('rejects non-integer generation', async () => {
- data.metadata.generation = 1.5;
- await expect(policy.enforce(data)).rejects.toThrow(/generation/);
- });
-
it('rejects missing name', async () => {
delete data.metadata.name;
await expect(policy.enforce(data)).rejects.toThrow(/name/);
diff --git a/packages/catalog-model/src/entity/ref.ts b/packages/catalog-model/src/entity/ref.ts
index cfe979423f..e52a2e7fb0 100644
--- a/packages/catalog-model/src/entity/ref.ts
+++ b/packages/catalog-model/src/entity/ref.ts
@@ -44,17 +44,6 @@ function parseRefString(ref: string): {
return { kind, namespace, name };
}
-/**
- * Extracts the kind, namespace and name that form the compound entity ref
- * triplet of the given entity.
- *
- * @public
- * @deprecated Use getCompoundEntityRef instead
- * @param entity - An entity
- * @returns The compound entity ref
- */
-export const getEntityName = getCompoundEntityRef;
-
/**
* Extracts the kind, namespace and name that form the compound entity ref
* triplet of the given entity.
diff --git a/packages/catalog-model/src/index.ts b/packages/catalog-model/src/index.ts
index b5ccfed149..eec3d91468 100644
--- a/packages/catalog-model/src/index.ts
+++ b/packages/catalog-model/src/index.ts
@@ -24,5 +24,5 @@ export * from './entity';
export { EntityPolicies } from './EntityPolicies';
export * from './kinds';
export * from './location';
-export type { EntityName, CompoundEntityRef } from './types';
+export type { CompoundEntityRef } from './types';
export * from './validation';
diff --git a/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts b/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts
index 82aaebd9d6..55c9b176ea 100644
--- a/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts
+++ b/packages/catalog-model/src/kinds/UserEntityV1alpha1.ts
@@ -32,7 +32,7 @@ export interface UserEntityV1alpha1 extends Entity {
email?: string;
picture?: string;
};
- memberOf: string[];
+ memberOf?: string[];
};
}
diff --git a/packages/catalog-model/src/schema/EntityMeta.schema.json b/packages/catalog-model/src/schema/EntityMeta.schema.json
index 7b2b9d3f82..cfdf9539c2 100644
--- a/packages/catalog-model/src/schema/EntityMeta.schema.json
+++ b/packages/catalog-model/src/schema/EntityMeta.schema.json
@@ -6,7 +6,6 @@
{
"uid": "e01199ab-08cc-44c2-8e19-5c29ded82521",
"etag": "lsndfkjsndfkjnsdfkjnsd==",
- "generation": 13,
"name": "my-component-yay",
"namespace": "the-namespace",
"labels": {
@@ -34,13 +33,6 @@
"examples": ["lsndfkjsndfkjnsdfkjnsd=="],
"minLength": 1
},
- "generation": {
- "type": "integer",
- "description": "A positive nonzero number that indicates the current generation of data for this entity; the value is incremented each time the spec changes. This field can not be set by the user at creation time, and the server will reject an attempt to do so. The field will be populated in read operations.",
- "examples": [1],
- "minimum": 1,
- "deprecated": true
- },
"name": {
"type": "string",
"description": "The name of the entity. Must be unique within the catalog at any given point in time, for any given namespace + kind pair.",
diff --git a/packages/catalog-model/src/types.ts b/packages/catalog-model/src/types.ts
index 7b3f23c64f..a66f34cc4d 100644
--- a/packages/catalog-model/src/types.ts
+++ b/packages/catalog-model/src/types.ts
@@ -25,11 +25,3 @@ export type CompoundEntityRef = {
namespace: string;
name: string;
};
-
-/**
- * A complete entity name, with the full kind-namespace-name triplet.
- *
- * @deprecated Use CompoundEntityRef instead
- * @public
- */
-export type EntityName = CompoundEntityRef;
diff --git a/packages/catalog-model/src/validation/entityKindSchemaValidator.test.ts b/packages/catalog-model/src/validation/entityKindSchemaValidator.test.ts
index f954a2388c..ee8f39b140 100644
--- a/packages/catalog-model/src/validation/entityKindSchemaValidator.test.ts
+++ b/packages/catalog-model/src/validation/entityKindSchemaValidator.test.ts
@@ -28,7 +28,6 @@ describe('entityKindSchemaValidator', () => {
metadata: {
uid: 'e01199ab-08cc-44c2-8e19-5c29ded82521',
etag: 'lsndfkjsndfkjnsdfkjnsd==',
- generation: 13,
name: 'test',
namespace: 'ns',
labels: {
diff --git a/packages/catalog-model/src/validation/entitySchemaValidator.test.ts b/packages/catalog-model/src/validation/entitySchemaValidator.test.ts
index b486de1df2..12f890d9db 100644
--- a/packages/catalog-model/src/validation/entitySchemaValidator.test.ts
+++ b/packages/catalog-model/src/validation/entitySchemaValidator.test.ts
@@ -27,7 +27,6 @@ describe('entitySchemaValidator', () => {
metadata: {
uid: 'e01199ab-08cc-44c2-8e19-5c29ded82521',
etag: 'lsndfkjsndfkjnsdfkjnsd==',
- generation: 13,
name: 'test',
namespace: 'ns',
title: 'My Component, Yay',
@@ -154,26 +153,6 @@ describe('entitySchemaValidator', () => {
expect(() => validator(entity)).toThrow(/etag/);
});
- it('accepts missing generation', () => {
- delete entity.metadata.generation;
- expect(() => validator(entity)).not.toThrow();
- });
-
- it('rejects bad generation type', () => {
- entity.metadata.generation = 'a';
- expect(() => validator(entity)).toThrow(/generation/);
- });
-
- it('rejects zero generation', () => {
- entity.metadata.generation = 0;
- expect(() => validator(entity)).toThrow(/generation/);
- });
-
- it('rejects non-integer generation', () => {
- entity.metadata.generation = 1.5;
- expect(() => validator(entity)).toThrow(/generation/);
- });
-
it('rejects missing name', () => {
delete entity.metadata.name;
expect(() => validator(entity)).toThrow(/name/);
diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md
index b3ab3fc0e7..08704d48a8 100644
--- a/packages/cli/CHANGELOG.md
+++ b/packages/cli/CHANGELOG.md
@@ -1,5 +1,38 @@
# @backstage/cli
+## 0.15.3
+
+### Patch Changes
+
+- Fixed an issue where the CLI would try and fail to require the `package.json` of other Backstage packages, like `@backstage/dev-utils/package.json`.
+
+## 0.15.2
+
+### Patch Changes
+
+- 2c528506aa: Added `--since ` flag for `repo build` command.`
+- 60799cc5be: build(deps-dev): bump `@types/npm-packlist` from 1.1.2 to 3.0.0
+- d3d1b82198: chore(deps): bump `minimatch` from 5.0.0 to 5.0.1
+- e0a69ba49f: build(deps): bump `fs-extra` from 9.1.0 to 10.0.1
+- 44cc7c3b95: Added a new ESLint configuration setup for packages, which utilizes package roles to generate the correct configuration. The new configuration is available at `@backstage/cli/config/eslint-factory`.
+
+ Introduced a new `backstage-cli migrate package-lint-configs` command, which migrates old lint configurations to use `@backstage/cli/config/eslint-factory`.
+
+- b1aacbf96a: Applied the fix from version `0.15.1` of this package, which was part of the `v0.70.1` release of Backstage.
+- d2ecde959b: Package roles are now marked as stable and migration is encouraged. Please check out the [migration guide](https://backstage.io/docs/tutorials/package-role-migration).
+
+ The new `package`, `repo`, and `migrate` command categories are now marked as stable.
+
+ Marked all commands that are being replaced by the new `package` and `repo` commands as deprecated.
+
+ The package templates used by the `create` command have all been updated to use package roles.
+
+- f06da37290: The backend development setup now ignores the `"browser"` and `"module"` entry points in `package.json`, and instead always uses `"main"`.
+- 6a1fe077ad: Changed the logic for how modules are marked as external in the Rollup build of packages. Rather than only marking dependencies and build-in Node.js modules as external, all non-relative imports are now considered external.
+- dc6002a7b9: The `--since` flag of repo commands now silently falls back to using the provided `ref` directly if no merge base is available.
+- Updated dependencies
+ - @backstage/config-loader@0.9.7
+
## 0.15.2-next.0
### Patch Changes
diff --git a/packages/cli/config/eslint-factory.js b/packages/cli/config/eslint-factory.js
index 67f30ac359..e04e3bdb2d 100644
--- a/packages/cli/config/eslint-factory.js
+++ b/packages/cli/config/eslint-factory.js
@@ -37,6 +37,7 @@ function createConfig(dir, extraConfig = {}) {
env,
parserOptions,
ignorePatterns,
+ overrides,
rules,
tsRules,
@@ -173,6 +174,7 @@ function createConfig(dir, extraConfig = {}) {
],
},
},
+ ...(overrides ?? []),
],
};
}
diff --git a/packages/cli/config/jest.js b/packages/cli/config/jest.js
index d5b85b9748..1472260e33 100644
--- a/packages/cli/config/jest.js
+++ b/packages/cli/config/jest.js
@@ -112,7 +112,7 @@ async function getProjectConfig(targetPath, displayName) {
},
// A bit more opinionated
- testMatch: ['**/?(*.)test.{js,jsx,ts,tsx,mjs,cjs}'],
+ testMatch: ['**/*.test.{js,jsx,ts,tsx,mjs,cjs}'],
transformIgnorePatterns: [`/node_modules/(?:${transformIgnorePattern})/`],
};
diff --git a/packages/cli/package.json b/packages/cli/package.json
index 46ce22f98c..43e8ea04eb 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/cli",
"description": "CLI for developing Backstage plugins and apps",
- "version": "0.15.2-next.0",
+ "version": "0.15.2",
"private": false,
"publishConfig": {
"access": "public"
@@ -33,7 +33,7 @@
"dependencies": {
"@backstage/cli-common": "^0.1.8",
"@backstage/config": "^0.1.15",
- "@backstage/config-loader": "^0.9.7-next.0",
+ "@backstage/config-loader": "^0.9.7",
"@backstage/errors": "^0.2.2",
"@backstage/release-manifests": "^0.0.2",
"@backstage/types": "^0.1.3",
@@ -121,12 +121,12 @@
"zod": "^3.11.6"
},
"devDependencies": {
- "@backstage/backend-common": "^0.13.0-next.0",
+ "@backstage/backend-common": "^0.13.0",
"@backstage/config": "^0.1.15",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/dev-utils": "^0.2.25",
"@backstage/test-utils": "^0.3.0",
"@backstage/theme": "^0.2.15",
"@types/diff": "^5.0.0",
@@ -137,7 +137,7 @@
"@types/minimatch": "^3.0.5",
"@types/mock-fs": "^4.13.0",
"@types/node": "^14.14.32",
- "@types/npm-packlist": "^1.1.2",
+ "@types/npm-packlist": "^3.0.0",
"@types/recursive-readdir": "^2.2.0",
"@types/rollup-plugin-peer-deps-external": "^2.2.0",
"@types/rollup-plugin-postcss": "^3.1.4",
diff --git a/packages/cli/src/lib/builder/buildTypeDefinitionsWorker.ts b/packages/cli/src/lib/builder/buildTypeDefinitionsWorker.ts
index 43e5cbc526..2533131a40 100644
--- a/packages/cli/src/lib/builder/buildTypeDefinitionsWorker.ts
+++ b/packages/cli/src/lib/builder/buildTypeDefinitionsWorker.ts
@@ -16,7 +16,7 @@
/**
* NOTE: This is a worker thread function that is stringified and executed
- * withing a `worker_threads.Worker`. Everything in this function must
+ * within a `worker_threads.Worker`. Everything in this function must
* be self-contained.
* Using TypeScript is fine as it is transpiled before being stringified.
*/
diff --git a/packages/cli/src/lib/diff/types.ts b/packages/cli/src/lib/diff/types.ts
index d22d690196..ba649f66ff 100644
--- a/packages/cli/src/lib/diff/types.ts
+++ b/packages/cli/src/lib/diff/types.ts
@@ -19,7 +19,7 @@ export type WriteFileFunc = (contents: string) => Promise;
export type FileDiff = {
// Relative path within the target directory
path: string;
- // Wether the target file exists in the target directory.
+ // Whether the target file exists in the target directory.
missing: boolean;
// Contents of the file in the target directory, or an empty string if the file is missing.
targetContents: string;
diff --git a/packages/cli/src/lib/version.ts b/packages/cli/src/lib/version.ts
index d65e1e06d6..1cddf773f4 100644
--- a/packages/cli/src/lib/version.ts
+++ b/packages/cli/src/lib/version.ts
@@ -19,7 +19,8 @@ import semver from 'semver';
import { paths } from './paths';
import { Lockfile } from './versioning';
-/* eslint-disable import/no-extraneous-dependencies,monorepo/no-internal-import */
+/* eslint-disable monorepo/no-relative-import */
+
/*
This is a list of all packages used by the templates. If dependencies are added or removed,
this list should be updated as well.
@@ -33,16 +34,16 @@ Rollup will extract the value of the version field in each package at build time
leaving any imports in place.
*/
-import { version as backendCommon } from '@backstage/backend-common/package.json';
-import { version as cli } from '@backstage/cli/package.json';
-import { version as config } from '@backstage/config/package.json';
-import { version as coreAppApi } from '@backstage/core-app-api/package.json';
-import { version as coreComponents } from '@backstage/core-components/package.json';
-import { version as corePluginApi } from '@backstage/core-plugin-api/package.json';
-import { version as devUtils } from '@backstage/dev-utils/package.json';
-import { version as testUtils } from '@backstage/test-utils/package.json';
-import { version as theme } from '@backstage/theme/package.json';
-import { version as scaffolderBackend } from '@backstage/plugin-scaffolder-backend/package.json';
+import { version as backendCommon } from '../../../../packages/backend-common/package.json';
+import { version as cli } from '../../../../packages/cli/package.json';
+import { version as config } from '../../../../packages/config/package.json';
+import { version as coreAppApi } from '../../../../packages/core-app-api/package.json';
+import { version as coreComponents } from '../../../../packages/core-components/package.json';
+import { version as corePluginApi } from '../../../../packages/core-plugin-api/package.json';
+import { version as devUtils } from '../../../../packages/dev-utils/package.json';
+import { version as testUtils } from '../../../../packages/test-utils/package.json';
+import { version as theme } from '../../../../packages/theme/package.json';
+import { version as scaffolderBackend } from '../../../../plugins/scaffolder-backend/package.json';
export const packageVersions: Record = {
'@backstage/backend-common': backendCommon,
diff --git a/packages/cli/templates/default-plugin/package.json.hbs b/packages/cli/templates/default-plugin/package.json.hbs
index f7985b497e..7f7e046605 100644
--- a/packages/cli/templates/default-plugin/package.json.hbs
+++ b/packages/cli/templates/default-plugin/package.json.hbs
@@ -45,7 +45,7 @@
"@backstage/dev-utils": "{{versionQuery '@backstage/dev-utils'}}",
"@backstage/test-utils": "{{versionQuery '@backstage/test-utils'}}",
"@testing-library/jest-dom": "{{versionQuery '@testing-library/jest-dom' '5.10.1'}}",
- "@testing-library/react": "{{versionQuery '@testing-library/react' '11.2.5'}}",
+ "@testing-library/react": "{{versionQuery '@testing-library/react' '12.1.3'}}",
"@testing-library/user-event": "{{versionQuery '@testing-library/user-event' '13.1.8'}}",
"@types/jest": "{{versionQuery '@types/jest' '26.0.7'}}",
"@types/node": "{{versionQuery '@types/node' '14.14.32'}}",
diff --git a/packages/codemods/CHANGELOG.md b/packages/codemods/CHANGELOG.md
index 5bf6535a62..73b9e54575 100644
--- a/packages/codemods/CHANGELOG.md
+++ b/packages/codemods/CHANGELOG.md
@@ -1,5 +1,12 @@
# @backstage/codemods
+## 0.1.35
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.9.1
+
## 0.1.35-next.0
### Patch Changes
diff --git a/packages/codemods/package.json b/packages/codemods/package.json
index 1c863db6cf..7c1e9a0d12 100644
--- a/packages/codemods/package.json
+++ b/packages/codemods/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/codemods",
"description": "A collection of codemods for Backstage projects",
- "version": "0.1.35-next.0",
+ "version": "0.1.35",
"private": false,
"publishConfig": {
"access": "public",
@@ -35,9 +35,6 @@
},
"dependencies": {
"@backstage/cli-common": "^0.1.8",
- "@backstage/core-app-api": "*",
- "@backstage/core-components": "0.9.1-next.0",
- "@backstage/core-plugin-api": "*",
"chalk": "^4.0.0",
"jscodeshift": "^0.13.0",
"jscodeshift-add-imports": "^1.0.10"
diff --git a/packages/codemods/src/tests/core-imports.test.ts b/packages/codemods/src/tests/core-imports.test.ts
index 0b416e5c8e..56500fd914 100644
--- a/packages/codemods/src/tests/core-imports.test.ts
+++ b/packages/codemods/src/tests/core-imports.test.ts
@@ -45,9 +45,9 @@ return something()
it('should refactor imports', () => {
const input = `
/* COPYRIGHT: ME */
-import { Button as MyButton, createApiRef, createSpecializedApp } from '@backstage/core';
+import { Button as MyButton, createApiRef, createApp } from '@backstage/core';
-const app = createSpecializedApp();
+const app = createApp();
const apiRef = createApiRef();
const button =
`;
@@ -57,9 +57,9 @@ const button =
import { Button as MyButton } from '@backstage/core-components';
import { createApiRef } from '@backstage/core-plugin-api';
-import { createSpecializedApp } from '@backstage/core-app-api';
+import { createApp } from '@backstage/app-defaults';
-const app = createSpecializedApp();
+const app = createApp();
const apiRef = createApiRef();
const button =
`;
diff --git a/packages/codemods/transforms/core-imports.js b/packages/codemods/transforms/core-imports.js
index f744a9c412..bcce7554d4 100644
--- a/packages/codemods/transforms/core-imports.js
+++ b/packages/codemods/transforms/core-imports.js
@@ -15,29 +15,258 @@
*/
const addImports = require('jscodeshift-add-imports');
-const { resolve: resolvePath } = require('path');
-const fs = require('fs');
-
-function findExports(packageName) {
- const packagePath = require.resolve(`${packageName}/package.json`);
- const typesPath = resolvePath(packagePath, '../dist/index.d.ts');
- const content = fs.readFileSync(typesPath, 'utf8');
-
- // For each export statement in the type declarations we grab the exported symbol names
- return content
- .split(/export \{ (.*) \}/)
- .filter((_, i) => i % 2)
- .flatMap(symbolsStr =>
- symbolsStr
- .split(', ')
- .map(exported => exported.match(/.* as (.*)/)?.[1] || exported),
- );
-}
+// The symbols in this table are out of date, but it does NOT need updating.
+// They're from a snapshot in the past and only need to handle the migration
+// away from @backstage/core.
const symbolTable = {
- '@backstage/core-app-api': findExports('@backstage/core-app-api'),
- '@backstage/core-components': findExports('@backstage/core-components'),
- '@backstage/core-plugin-api': findExports('@backstage/core-plugin-api'),
+ '@backstage/app-defaults': ['createApp'],
+ '@backstage/core-app-api': [
+ 'ConfigReader',
+ 'AlertApiForwarder',
+ 'ApiFactoryHolder',
+ 'ApiFactoryRegistry',
+ 'ApiProvider',
+ 'ApiRegistry',
+ 'ApiResolver',
+ 'AppComponents',
+ 'AppConfigLoader',
+ 'AppContext',
+ 'AppOptions',
+ 'AppRouteBinder',
+ 'AppThemeSelector',
+ 'Auth0Auth',
+ 'BackstageApp',
+ 'BackstagePluginWithAnyOutput',
+ 'BootErrorPageProps',
+ 'ErrorAlerter',
+ 'ErrorApiForwarder',
+ 'ErrorBoundaryFallbackProps',
+ 'FeatureFlagged',
+ 'FeatureFlaggedProps',
+ 'FlatRoutes',
+ 'GithubAuth',
+ 'GithubSession',
+ 'GitlabAuth',
+ 'GoogleAuth',
+ 'LocalStorageFeatureFlags',
+ 'MicrosoftAuth',
+ 'OAuth2',
+ 'OAuth2Session',
+ 'OAuthRequestManager',
+ 'OktaAuth',
+ 'OneLoginAuth',
+ 'SamlAuth',
+ 'SignInPageProps',
+ 'SignInResult',
+ 'UrlPatternDiscovery',
+ 'WebStorage',
+ ],
+ '@backstage/core-components': [
+ 'AlertDisplay',
+ 'Avatar',
+ 'Breadcrumbs',
+ 'BrokenImageIcon',
+ 'Button',
+ 'CardTab',
+ 'CatalogIcon',
+ 'ChatIcon',
+ 'CodeSnippet',
+ 'Content',
+ 'ContentHeader',
+ 'CopyTextButton',
+ 'DashboardIcon',
+ 'DependencyGraph',
+ 'DependencyGraphTypes',
+ 'DismissableBanner',
+ 'DocsIcon',
+ 'EmailIcon',
+ 'EmptyState',
+ 'ErrorBoundary',
+ 'ErrorPage',
+ 'ErrorPanel',
+ 'ErrorPanelProps',
+ 'FeatureCalloutCircular',
+ 'Gauge',
+ 'GaugeCard',
+ 'GitHubIcon',
+ 'GroupIcon',
+ 'Header',
+ 'HeaderIconLinkRow',
+ 'HeaderLabel',
+ 'HeaderTabs',
+ 'HelpIcon',
+ 'HomepageTimer',
+ 'HorizontalScrollGrid',
+ 'IconLinkVerticalProps',
+ 'InfoCard',
+ 'InfoCardVariants',
+ 'IntroCard',
+ 'ItemCard',
+ 'ItemCardGrid',
+ 'ItemCardGridProps',
+ 'ItemCardHeader',
+ 'ItemCardHeaderProps',
+ 'Lifecycle',
+ 'LinearGauge',
+ 'Link',
+ 'LinkProps',
+ 'MarkdownContent',
+ 'MissingAnnotationEmptyState',
+ 'OAuthRequestDialog',
+ 'OverflowTooltip',
+ 'Page',
+ 'Progress',
+ 'ResponseErrorPanel',
+ 'RoutedTabs',
+ 'SIDEBAR_INTRO_LOCAL_STORAGE',
+ 'Select',
+ 'Sidebar',
+ 'SidebarContext',
+ 'SidebarContextType',
+ 'SidebarDivider',
+ 'SidebarIntro',
+ 'SidebarItem',
+ 'SidebarPage',
+ 'SidebarPinStateContext',
+ 'SidebarPinStateContextType',
+ 'SidebarSearchField',
+ 'SidebarSpace',
+ 'SidebarSpacer',
+ 'SignInPage',
+ 'SignInProviderConfig',
+ 'SimpleStepper',
+ 'SimpleStepperStep',
+ 'StatusAborted',
+ 'StatusError',
+ 'StatusOK',
+ 'StatusPending',
+ 'StatusRunning',
+ 'StatusWarning',
+ 'StructuredMetadataTable',
+ 'SubvalueCell',
+ 'SupportButton',
+ 'SupportConfig',
+ 'SupportItem',
+ 'SupportItemLink',
+ 'Tab',
+ 'TabbedCard',
+ 'TabbedLayout',
+ 'Table',
+ 'TableColumn',
+ 'TableFilter',
+ 'TableProps',
+ 'TableState',
+ 'Tabs',
+ 'TrendLine',
+ 'UserIcon',
+ 'WarningIcon',
+ 'WarningPanel',
+ 'sidebarConfig',
+ 'useQueryParamState',
+ 'useSupportConfig',
+ ],
+ '@backstage/core-plugin-api': [
+ 'AlertApi',
+ 'AlertMessage',
+ 'AnyApiFactory',
+ 'AnyApiRef',
+ 'ApiFactory',
+ 'ApiHolder',
+ 'ApiRef',
+ 'ApiRefType',
+ 'ApiRefsToTypes',
+ 'AppComponents',
+ 'AppContext',
+ 'AppTheme',
+ 'AppThemeApi',
+ 'AuthProvider',
+ 'AuthRequestOptions',
+ 'AuthRequester',
+ 'AuthRequesterOptions',
+ 'BackstageIdentity',
+ 'BackstageIdentityApi',
+ 'BackstagePlugin',
+ 'BootErrorPageProps',
+ 'ConfigApi',
+ 'DiscoveryApi',
+ 'ElementCollection',
+ 'ErrorApi',
+ 'ErrorBoundaryFallbackProps',
+ 'ErrorContext',
+ 'Extension',
+ 'ExternalRouteRef',
+ 'FeatureFlag',
+ 'FeatureFlagOutput',
+ 'FeatureFlagState',
+ 'FeatureFlagsApi',
+ 'FeatureFlagsHooks',
+ 'FeatureFlagsSaveOptions',
+ 'IconComponent',
+ 'IdentityApi',
+ 'OAuthApi',
+ 'OAuthRequestApi',
+ 'OAuthScope',
+ 'Observable',
+ 'Observer',
+ 'OpenIdConnectApi',
+ 'PendingAuthRequest',
+ 'PluginConfig',
+ 'PluginHooks',
+ 'PluginOutput',
+ 'ProfileInfo',
+ 'ProfileInfoApi',
+ 'RouteOptions',
+ 'RoutePath',
+ 'RouteRef',
+ 'SessionApi',
+ 'SessionState',
+ 'SignInPageProps',
+ 'SignInResult',
+ 'StorageApi',
+ 'StorageValueChange',
+ 'SubRouteRef',
+ 'Subscription',
+ 'TypesToApiRefs',
+ 'UserFlags',
+ 'alertApiRef',
+ 'appThemeApiRef',
+ 'attachComponentData',
+ 'auth0AuthApiRef',
+ 'configApiRef',
+ 'createApiFactory',
+ 'createApiRef',
+ 'createComponentExtension',
+ 'createExternalRouteRef',
+ 'createPlugin',
+ 'createReactExtension',
+ 'createRoutableExtension',
+ 'createRouteRef',
+ 'createSubRouteRef',
+ 'discoveryApiRef',
+ 'errorApiRef',
+ 'featureFlagsApiRef',
+ 'getComponentData',
+ 'githubAuthApiRef',
+ 'gitlabAuthApiRef',
+ 'googleAuthApiRef',
+ 'identityApiRef',
+ 'microsoftAuthApiRef',
+ 'oauth2ApiRef',
+ 'oauthRequestApiRef',
+ 'oidcAuthApiRef',
+ 'oktaAuthApiRef',
+ 'oneloginAuthApiRef',
+ 'samlAuthApiRef',
+ 'storageApiRef',
+ 'useApi',
+ 'useApiHolder',
+ 'useApp',
+ 'useElementFilter',
+ 'useRouteRef',
+ 'useRouteRefParams',
+ 'withApis',
+ ],
};
const reverseSymbolTable = Object.entries(symbolTable).reduce(
diff --git a/packages/config-loader/CHANGELOG.md b/packages/config-loader/CHANGELOG.md
index 362edc78cf..50ec2afac1 100644
--- a/packages/config-loader/CHANGELOG.md
+++ b/packages/config-loader/CHANGELOG.md
@@ -1,5 +1,11 @@
# @backstage/config-loader
+## 0.9.7
+
+### Patch Changes
+
+- e0a69ba49f: build(deps): bump `fs-extra` from 9.1.0 to 10.0.1
+
## 0.9.7-next.0
### Patch Changes
diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json
index 71a0e4e650..027c4a605d 100644
--- a/packages/config-loader/package.json
+++ b/packages/config-loader/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/config-loader",
"description": "Config loading functionality used by Backstage backend, and CLI",
- "version": "0.9.7-next.0",
+ "version": "0.9.7",
"private": false,
"publishConfig": {
"access": "public",
@@ -46,7 +46,7 @@
"json-schema-merge-allof": "^0.8.1",
"json-schema-traverse": "^1.0.0",
"node-fetch": "^2.6.7",
- "typescript-json-schema": "^0.52.0",
+ "typescript-json-schema": "^0.53.0",
"yaml": "^1.9.2",
"yup": "^0.32.9"
},
diff --git a/packages/config-loader/src/lib/schema/collect.test.ts b/packages/config-loader/src/lib/schema/collect.test.ts
index 877cbb54e3..2754f788dd 100644
--- a/packages/config-loader/src/lib/schema/collect.test.ts
+++ b/packages/config-loader/src/lib/schema/collect.test.ts
@@ -28,6 +28,9 @@ const mockSchema = {
},
};
+// Gotta make sure this is in the compiler cache before we start mocking the filesystem
+require('typescript-json-schema');
+
// We need to load in actual TS libraries when using mock-fs.
// This lookup is to allow the `typescript` dependency to exist either
// at top level or inside node_modules of typescript-json-schema
diff --git a/packages/config-loader/src/lib/schema/collect.ts b/packages/config-loader/src/lib/schema/collect.ts
index 3ff161cec4..98feffebb2 100644
--- a/packages/config-loader/src/lib/schema/collect.ts
+++ b/packages/config-loader/src/lib/schema/collect.ts
@@ -22,7 +22,6 @@ import {
sep,
} from 'path';
import { ConfigSchemaPackageEntry } from './types';
-import { getProgramFromFiles, generateSchema } from 'typescript-json-schema';
import { JsonObject } from '@backstage/types';
import { assertError } from '@backstage/errors';
@@ -149,7 +148,7 @@ export async function collectConfigSchemas(
...packagePaths.map(path => processItem({ name: path, packagePath: path })),
]);
- const tsSchemas = compileTsSchemas(tsSchemaPaths);
+ const tsSchemas = await compileTsSchemas(tsSchemaPaths);
return schemas.concat(tsSchemas);
}
@@ -157,11 +156,17 @@ export async function collectConfigSchemas(
// This handles the support of TypeScript .d.ts config schema declarations.
// We collect all typescript schema definition and compile them all in one go.
// This is much faster than compiling them separately.
-function compileTsSchemas(paths: string[]) {
+async function compileTsSchemas(paths: string[]) {
if (paths.length === 0) {
return [];
}
+ // Lazy loaded, because this brings up all of TypeScript and we don't
+ // want that eagerly loaded in tests
+ const { getProgramFromFiles, generateSchema } = await import(
+ 'typescript-json-schema'
+ );
+
const program = getProgramFromFiles(paths, {
incremental: false,
isolatedModules: true,
diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json
index f0776fcb85..b1250172a7 100644
--- a/packages/core-app-api/package.json
+++ b/packages/core-app-api/package.json
@@ -52,7 +52,7 @@
"@backstage/cli": "^0.15.2-next.0",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/react-hooks": "^7.0.2",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
diff --git a/packages/core-app-api/src/app/types.ts b/packages/core-app-api/src/app/types.ts
index 902e64c09f..ff7a43d0eb 100644
--- a/packages/core-app-api/src/app/types.ts
+++ b/packages/core-app-api/src/app/types.ts
@@ -190,7 +190,7 @@ export type AppOptions = {
/**
* A collection of ApiFactories to register in the application as default APIs.
- * Theses APIs can not be overridden by plugin factories, but can be overridden
+ * These APIs cannot be overridden by plugin factories, but can be overridden
* by plugin APIs provided through the
* A collection of ApiFactories to register in the application to either
* add new ones, or override factories provided by default or by plugins.
diff --git a/packages/core-app-api/src/routing/collectors.tsx b/packages/core-app-api/src/routing/collectors.tsx
index 320f1a66d8..46734707a6 100644
--- a/packages/core-app-api/src/routing/collectors.tsx
+++ b/packages/core-app-api/src/routing/collectors.tsx
@@ -93,7 +93,7 @@ export const routeParentCollector = createCollector(
acc.set(routeRef, parentRouteRef.sticky);
// When we encounter a mount point with an explicit path, we stop gathering
- // mount points withing the children and remove the sticky state
+ // mount points within the children and remove the sticky state
if (node.props?.path) {
nextParent = routeRef;
} else {
diff --git a/packages/core-components/CHANGELOG.md b/packages/core-components/CHANGELOG.md
index 64a3d0614d..6bb05b9b6a 100644
--- a/packages/core-components/CHANGELOG.md
+++ b/packages/core-components/CHANGELOG.md
@@ -1,5 +1,12 @@
# @backstage/core-components
+## 0.9.1
+
+### Patch Changes
+
+- 23568dd328: chore(deps): bump `@react-hookz/web` from 12.3.0 to 13.0.0
+- 95667624c1: Add names to sidebar sub menu styles for customization
+
## 0.9.1-next.0
### Patch Changes
diff --git a/packages/core-components/package.json b/packages/core-components/package.json
index d71bcff3cf..4b5be0537b 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.9.1-next.0",
+ "version": "0.9.1",
"private": false,
"publishConfig": {
"access": "public",
@@ -79,10 +79,10 @@
},
"devDependencies": {
"@backstage/core-app-api": "^0.6.0",
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/react-hooks": "^7.0.2",
"@testing-library/user-event": "^13.1.8",
"@types/classnames": "^2.2.9",
diff --git a/packages/core-components/src/components/EmptyState/EmptyState.test.tsx b/packages/core-components/src/components/EmptyState/EmptyState.test.tsx
index 620e8d4d31..6487fcf4e6 100644
--- a/packages/core-components/src/components/EmptyState/EmptyState.test.tsx
+++ b/packages/core-components/src/components/EmptyState/EmptyState.test.tsx
@@ -20,7 +20,7 @@ import { renderWithEffects, wrapInTestApp } from '@backstage/test-utils';
import Button from '@material-ui/core/Button';
describe('', () => {
- it('render EmptyState component with type annotaion is missing', async () => {
+ it('render EmptyState component with type annotation is missing', async () => {
const rendered = await renderWithEffects(
wrapInTestApp(
(
},
title: {
color: theme.palette.bursts.fontColor,
- wordBreak: 'break-all',
+ wordBreak: 'break-word',
fontSize: theme.typography.h3.fontSize,
marginBottom: 0,
},
diff --git a/packages/core-components/src/layout/Sidebar/Page.tsx b/packages/core-components/src/layout/Sidebar/Page.tsx
index 3b0efb62c1..464d0a893e 100644
--- a/packages/core-components/src/layout/Sidebar/Page.tsx
+++ b/packages/core-components/src/layout/Sidebar/Page.tsx
@@ -151,7 +151,7 @@ export function SidebarPage(props: SidebarPageProps) {
* This hook provides a react ref to the main content.
* Allows to set an element as the main content and focus on that component.
*
- * *Note: If `contentRef` is not set `focusContent` is noop. `Content` component sets this ref automaticaly*
+ * *Note: If `contentRef` is not set `focusContent` is noop. `Content` component sets this ref automatically*
*
* @public
* @example
diff --git a/packages/core-components/src/layout/Sidebar/config.ts b/packages/core-components/src/layout/Sidebar/config.ts
index 55b9787b13..b72e6f4601 100644
--- a/packages/core-components/src/layout/Sidebar/config.ts
+++ b/packages/core-components/src/layout/Sidebar/config.ts
@@ -56,7 +56,7 @@ export type SidebarContextType = {
};
/**
- * Context wether the `Sidebar` is open
+ * Context whether the `Sidebar` is open
*/
export const SidebarContext = createContext({
isOpen: false,
diff --git a/packages/core-plugin-api/package.json b/packages/core-plugin-api/package.json
index dd7056c8de..06463d378a 100644
--- a/packages/core-plugin-api/package.json
+++ b/packages/core-plugin-api/package.json
@@ -50,7 +50,7 @@
"@backstage/core-app-api": "^0.6.0",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/react-hooks": "^7.0.2",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
diff --git a/packages/core-plugin-api/src/apis/definitions/FeatureFlagsApi.ts b/packages/core-plugin-api/src/apis/definitions/FeatureFlagsApi.ts
index ac43bbebe8..946bd1d37a 100644
--- a/packages/core-plugin-api/src/apis/definitions/FeatureFlagsApi.ts
+++ b/packages/core-plugin-api/src/apis/definitions/FeatureFlagsApi.ts
@@ -17,7 +17,7 @@
import { ApiRef, createApiRef } from '../system';
/**
- * Fetaure flag descriptor.
+ * Feature flag descriptor.
*
* @public
*/
diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md
index c9b83a1157..7c13b4ff0b 100644
--- a/packages/create-app/CHANGELOG.md
+++ b/packages/create-app/CHANGELOG.md
@@ -1,5 +1,73 @@
# @backstage/create-app
+## 0.4.23
+
+### Patch Changes
+
+- f9c7bdd899: Builtin support for cookiecutter based templates has been removed from `@backstage/plugin-scaffolder-backend`. Due to this, the `containerRunner` argument to its `createRouter` has also been removed.
+
+ If you do not use cookiecutter templates and are fine with removing support from it in your own installation, update your `packages/backend/src/plugins/scaffolder.ts` file as follows:
+
+ ```diff
+ -import { DockerContainerRunner } from '@backstage/backend-common';
+ import { CatalogClient } from '@backstage/catalog-client';
+ import { createRouter } from '@backstage/plugin-scaffolder-backend';
+ -import Docker from 'dockerode';
+ import { Router } from 'express';
+ import type { PluginEnvironment } from '../types';
+
+ export default async function createPlugin({
+ reader,
+ discovery,
+ }: PluginEnvironment): Promise {
+ - const dockerClient = new Docker();
+ - const containerRunner = new DockerContainerRunner({ dockerClient });
+ -
+ const catalogClient = new CatalogClient({ discoveryApi: discovery });
+ -
+ return await createRouter({
+ - containerRunner,
+ logger,
+ config,
+ // ...
+ ```
+
+ If you want to retain cookiecutter support, please use the `@backstage/plugin-scaffolder-backend-module-cookiecutter` package explicitly (see [its README](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-cookiecutter) for installation instructions).
+
+- 8a57b6595b: Removed the `cookiecutter-golang` template from the default `create-app` install as we no longer provide `cookiecutter` action out of the box.
+
+ You can remove the template by removing the following lines from your `app-config.yaml` under `catalog.locations`:
+
+ ```diff
+ - - type: url
+ - target: https://github.com/spotify/cookiecutter-golang/blob/master/template.yaml
+ - rules:
+ - - allow: [Template]
+ ```
+
+- e0a69ba49f: build(deps): bump `fs-extra` from 9.1.0 to 10.0.1
+- 1201383b60: Updated the template to write the Backstage release version to `backstage.json`, rather than the version of `@backstage/create-app`. This change is applied automatically when running `backstage-cli versions:bump` in the latest version of the Backstage CLI.
+- c543fe3ff2: Postgres-based search is now installed when PG is chosen as the desired database for Backstage.
+
+ There is no need to make this change in an existing Backstage backend. See [supported search engines](https://backstage.io/docs/features/search/search-engines) for details about production-ready search engines.
+
+- 55150919ed: - **BREAKING**: Support for `backstage.io/v1beta2` Software Templates has been removed. Please migrate your legacy templates to the new `scaffolder.backstage.io/v1beta3` `apiVersion` by following the [migration guide](https://backstage.io/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3)
+- bde30664c4: Updated template to use package roles. To apply this change to an existing app, check out the [migration guide](https://backstage.io/docs/tutorials/package-role-migration).
+
+ Specifically the following scripts in the root `package.json` have also been updated:
+
+ ```diff
+ - "build": "lerna run build",
+ + "build": "backstage-cli repo build --all",
+
+ ...
+
+ - "lint": "lerna run lint --since origin/master --",
+ - "lint:all": "lerna run lint --",
+ + "lint": "backstage-cli repo lint --since origin/master",
+ + "lint:all": "backstage-cli repo lint",
+ ```
+
## 0.4.23-next.0
### Patch Changes
diff --git a/packages/create-app/package.json b/packages/create-app/package.json
index 838d54b0f4..cadd64b5ce 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.4.23-next.0",
+ "version": "0.4.23",
"private": false,
"publishConfig": {
"access": "public"
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 3afed0ed82..02139f8084 100644
--- a/packages/create-app/templates/default-app/app-config.yaml.hbs
+++ b/packages/create-app/templates/default-app/app-config.yaml.hbs
@@ -25,7 +25,7 @@ backend:
credentials: true
{{#if dbTypeSqlite}}
database:
- client: sqlite3
+ client: better-sqlite3
connection: ':memory:'
{{/if}}
{{#if dbTypePG}}
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 71d2ac9b3b..2ad394c68e 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
@@ -41,7 +41,7 @@
"devDependencies": {
"@backstage/test-utils": "^{{version '@backstage/test-utils'}}",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^10.4.1",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^12.0.7",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
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 79d6772d7e..69a09daef2 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
@@ -46,7 +46,7 @@
"pg": "^8.3.0",
{{/if}}
{{#if dbTypeSqlite}}
- "@vscode/sqlite3": "^5.0.7",
+ "better-sqlite3": "^7.5.0",
{{/if}}
"winston": "^3.2.1"
},
diff --git a/packages/create-app/templates/default-app/packages/backend/src/plugins/app.ts b/packages/create-app/templates/default-app/packages/backend/src/plugins/app.ts
index 14e19a19b1..7c37f68467 100644
--- a/packages/create-app/templates/default-app/packages/backend/src/plugins/app.ts
+++ b/packages/create-app/templates/default-app/packages/backend/src/plugins/app.ts
@@ -2,15 +2,13 @@ import { createRouter } from '@backstage/plugin-app-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
-export default async function createPlugin({
- logger,
- config,
- database,
-}: PluginEnvironment): Promise {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
return await createRouter({
- logger,
- config,
- database,
+ logger: env.logger,
+ config: env.config,
+ database: env.database,
appPackageName: 'app',
});
}
diff --git a/packages/create-app/templates/default-app/packages/backend/src/plugins/auth.ts b/packages/create-app/templates/default-app/packages/backend/src/plugins/auth.ts
index 015c86466f..1476e66150 100644
--- a/packages/create-app/templates/default-app/packages/backend/src/plugins/auth.ts
+++ b/packages/create-app/templates/default-app/packages/backend/src/plugins/auth.ts
@@ -2,18 +2,14 @@ import { createRouter } from '@backstage/plugin-auth-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
-export default async function createPlugin({
- logger,
- database,
- config,
- discovery,
- tokenManager,
-}: PluginEnvironment): Promise {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
return await createRouter({
- logger,
- config,
- database,
- discovery,
- tokenManager,
+ logger: env.logger,
+ config: env.config,
+ database: env.database,
+ discovery: env.discovery,
+ tokenManager: env.tokenManager,
});
}
diff --git a/packages/create-app/templates/default-app/packages/backend/src/plugins/proxy.ts b/packages/create-app/templates/default-app/packages/backend/src/plugins/proxy.ts
index 506f6d98f9..54ec3937e9 100644
--- a/packages/create-app/templates/default-app/packages/backend/src/plugins/proxy.ts
+++ b/packages/create-app/templates/default-app/packages/backend/src/plugins/proxy.ts
@@ -2,10 +2,12 @@ import { createRouter } from '@backstage/plugin-proxy-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
-export default async function createPlugin({
- logger,
- config,
- discovery,
-}: PluginEnvironment): Promise {
- return await createRouter({ logger, config, discovery });
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
+ return await createRouter({
+ logger: env.logger,
+ config: env.config,
+ discovery: env.discovery,
+ });
}
diff --git a/packages/create-app/templates/default-app/packages/backend/src/plugins/scaffolder.ts b/packages/create-app/templates/default-app/packages/backend/src/plugins/scaffolder.ts
index a460fd8a6d..7ce5fcf31a 100644
--- a/packages/create-app/templates/default-app/packages/backend/src/plugins/scaffolder.ts
+++ b/packages/create-app/templates/default-app/packages/backend/src/plugins/scaffolder.ts
@@ -3,19 +3,18 @@ import { createRouter } from '@backstage/plugin-scaffolder-backend';
import { Router } from 'express';
import type { PluginEnvironment } from '../types';
-export default async function createPlugin({
- logger,
- config,
- database,
- reader,
- discovery,
-}: PluginEnvironment): Promise {
- const catalogClient = new CatalogClient({ discoveryApi: discovery });
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
+ const catalogClient = new CatalogClient({
+ discoveryApi: env.discovery,
+ });
+
return await createRouter({
- logger,
- config,
- database,
+ logger: env.logger,
+ config: env.config,
+ database: env.database,
+ reader: env.reader,
catalogClient,
- reader,
});
}
diff --git a/packages/create-app/templates/default-app/packages/backend/src/plugins/search.ts.hbs b/packages/create-app/templates/default-app/packages/backend/src/plugins/search.ts.hbs
index d8ad991e8a..8f44a35b16 100644
--- a/packages/create-app/templates/default-app/packages/backend/src/plugins/search.ts.hbs
+++ b/packages/create-app/templates/default-app/packages/backend/src/plugins/search.ts.hbs
@@ -10,42 +10,44 @@ import { PgSearchEngine } from '@backstage/plugin-search-backend-module-pg';
import { PluginEnvironment } from '../types';
import { DefaultCatalogCollatorFactory } from '@backstage/plugin-catalog-backend';
import { DefaultTechDocsCollatorFactory } from '@backstage/plugin-techdocs-backend';
+import { Router } from 'express';
-export default async function createPlugin({
- logger,
- permissions,
- discovery,
- config,
- tokenManager,
-}: PluginEnvironment) {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
// Initialize a connection to a search engine.
{{#if dbTypeSqlite}}
- const searchEngine = new LunrSearchEngine({ logger });
+ const searchEngine = new LunrSearchEngine({
+ logger: env.logger,
+ });
{{/if}}
{{#if dbTypePG}}
- const searchEngine = (await PgSearchEngine.supported(database))
- ? await PgSearchEngine.from({ database })
- : new LunrSearchEngine({ logger });
+ const searchEngine = (await PgSearchEngine.supported(env.database))
+ ? await PgSearchEngine.from({ database: env.database })
+ : new LunrSearchEngine({ logger: env.logger });
{{/if}}
- const indexBuilder = new IndexBuilder({ logger, searchEngine });
+ const indexBuilder = new IndexBuilder({
+ logger: env.logger,
+ searchEngine,
+ });
// Collators are responsible for gathering documents known to plugins. This
// collator gathers entities from the software catalog.
indexBuilder.addCollator({
defaultRefreshIntervalSeconds: 600,
- factory: DefaultCatalogCollatorFactory.fromConfig(config, {
- discovery,
- tokenManager,
+ factory: DefaultCatalogCollatorFactory.fromConfig(env.config, {
+ discovery: env.discovery,
+ tokenManager: env.tokenManager,
}),
});
// collator gathers entities from techdocs.
indexBuilder.addCollator({
defaultRefreshIntervalSeconds: 600,
- factory: DefaultTechDocsCollatorFactory.fromConfig(config, {
- discovery,
- logger,
- tokenManager,
+ factory: DefaultTechDocsCollatorFactory.fromConfig(env.config, {
+ discovery: env.discovery,
+ logger: env.logger,
+ tokenManager: env.tokenManager,
}),
});
@@ -61,8 +63,8 @@ export default async function createPlugin({
return await createRouter({
engine: indexBuilder.getSearchEngine(),
types: indexBuilder.getDocumentTypes(),
- permissions,
- config,
- logger,
+ permissions: env.permissions,
+ config: env.config,
+ logger: env.logger,
});
}
diff --git a/packages/create-app/templates/default-app/packages/backend/src/plugins/techdocs.ts b/packages/create-app/templates/default-app/packages/backend/src/plugins/techdocs.ts
index 054c64db65..be8bb0c06f 100644
--- a/packages/create-app/templates/default-app/packages/backend/src/plugins/techdocs.ts
+++ b/packages/create-app/templates/default-app/packages/backend/src/plugins/techdocs.ts
@@ -9,17 +9,13 @@ import Docker from 'dockerode';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
-export default async function createPlugin({
- logger,
- config,
- discovery,
- reader,
- cache,
-}: PluginEnvironment): Promise {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
// Preparers are responsible for fetching source files for documentation.
- const preparers = await Preparers.fromConfig(config, {
- logger,
- reader,
+ const preparers = await Preparers.fromConfig(env.config, {
+ logger: env.logger,
+ reader: env.reader,
});
// Docker client (conditionally) used by the generators, based on techdocs.generators config.
@@ -27,17 +23,17 @@ export default async function createPlugin({
const containerRunner = new DockerContainerRunner({ dockerClient });
// Generators are used for generating documentation sites.
- const generators = await Generators.fromConfig(config, {
- logger,
+ const generators = await Generators.fromConfig(env.config, {
+ logger: env.logger,
containerRunner,
});
// Publisher is used for
// 1. Publishing generated files to storage
// 2. Fetching files from storage and passing them to TechDocs frontend.
- const publisher = await Publisher.fromConfig(config, {
- logger,
- discovery,
+ const publisher = await Publisher.fromConfig(env.config, {
+ logger: env.logger,
+ discovery: env.discovery,
});
// checks if the publisher is working and logs the result
@@ -47,9 +43,9 @@ export default async function createPlugin({
preparers,
generators,
publisher,
- logger,
- config,
- discovery,
- cache,
+ logger: env.logger,
+ config: env.config,
+ discovery: env.discovery,
+ cache: env.cache,
});
}
diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md
index 32fbf7e9cb..3e4a028e5f 100644
--- a/packages/dev-utils/CHANGELOG.md
+++ b/packages/dev-utils/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/dev-utils
+## 0.2.25
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.9.0
+ - @backstage/core-components@0.9.1
+ - @backstage/catalog-model@0.13.0
+ - @backstage/app-defaults@0.2.1
+ - @backstage/integration-react@0.1.25
+
## 0.2.25-next.0
### Patch Changes
diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json
index f9c3bbc166..1d77d87600 100644
--- a/packages/dev-utils/package.json
+++ b/packages/dev-utils/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/dev-utils",
"description": "Utilities for developing Backstage plugins.",
- "version": "0.2.25-next.0",
+ "version": "0.2.25",
"private": false,
"publishConfig": {
"access": "public",
@@ -33,19 +33,19 @@
"start": "backstage-cli package start"
},
"dependencies": {
- "@backstage/app-defaults": "^0.2.1-next.0",
+ "@backstage/app-defaults": "^0.2.1",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
- "@backstage/catalog-model": "^0.13.0-next.0",
- "@backstage/integration-react": "^0.1.25-next.0",
- "@backstage/plugin-catalog-react": "^0.9.0-next.0",
+ "@backstage/catalog-model": "^0.13.0",
+ "@backstage/integration-react": "^0.1.25",
+ "@backstage/plugin-catalog-react": "^0.9.0",
"@backstage/test-utils": "^0.3.0",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"react-use": "^17.2.4",
"react-hot-loader": "^4.13.0",
@@ -59,7 +59,7 @@
"react-dom": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32"
},
diff --git a/packages/dev-utils/src/devApp/render.tsx b/packages/dev-utils/src/devApp/render.tsx
index 36d6abcfd1..9f9fcd8ca6 100644
--- a/packages/dev-utils/src/devApp/render.tsx
+++ b/packages/dev-utils/src/devApp/render.tsx
@@ -148,7 +148,7 @@ export class DevAppBuilder {
}
/**
- * Adds an array of themes to overide the default theme.
+ * Adds an array of themes to override the default theme.
*/
addThemes(themes: AppTheme[]) {
this.themes = themes;
diff --git a/packages/integration-react/CHANGELOG.md b/packages/integration-react/CHANGELOG.md
index 082b8ba701..9ded26d06b 100644
--- a/packages/integration-react/CHANGELOG.md
+++ b/packages/integration-react/CHANGELOG.md
@@ -1,5 +1,12 @@
# @backstage/integration-react
+## 0.1.25
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.9.1
+
## 0.1.25-next.0
### Patch Changes
diff --git a/packages/integration-react/package.json b/packages/integration-react/package.json
index 16863b2ef2..fbd9739d08 100644
--- a/packages/integration-react/package.json
+++ b/packages/integration-react/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/integration-react",
"description": "Frontend package for managing integrations towards external systems",
- "version": "0.1.25-next.0",
+ "version": "0.1.25",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -25,7 +25,7 @@
},
"dependencies": {
"@backstage/config": "^0.1.15",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
"@backstage/integration": "^0.8.0",
"@backstage/theme": "^0.2.15",
@@ -38,11 +38,11 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/cli": "^0.15.2",
+ "@backstage/dev-utils": "^0.2.25",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
diff --git a/packages/integration/api-report.md b/packages/integration/api-report.md
index 9a6ba03f8e..84bca54a90 100644
--- a/packages/integration/api-report.md
+++ b/packages/integration/api-report.md
@@ -112,6 +112,35 @@ export function defaultScmResolveUrl(options: {
lineNumber?: number;
}): string;
+// @public
+export class GerritIntegration implements ScmIntegration {
+ constructor(integrationConfig: GerritIntegrationConfig);
+ // (undocumented)
+ get config(): GerritIntegrationConfig;
+ // (undocumented)
+ static factory: ScmIntegrationsFactory;
+ // (undocumented)
+ resolveEditUrl(url: string): string;
+ // (undocumented)
+ resolveUrl(options: {
+ url: string;
+ base: string;
+ lineNumber?: number;
+ }): string;
+ // (undocumented)
+ get title(): string;
+ // (undocumented)
+ get type(): string;
+}
+
+// @public
+export type GerritIntegrationConfig = {
+ host: string;
+ baseUrl?: string;
+ username?: string;
+ password?: string;
+};
+
// @public
export function getAzureCommitsUrl(url: string): string;
@@ -293,6 +322,8 @@ export interface IntegrationsByType {
// (undocumented)
bitbucket: ScmIntegrationsGroup;
// (undocumented)
+ gerrit: ScmIntegrationsGroup;
+ // (undocumented)
github: ScmIntegrationsGroup;
// (undocumented)
gitlab: ScmIntegrationsGroup;
@@ -328,6 +359,16 @@ export function readBitbucketIntegrationConfigs(
configs: Config[],
): BitbucketIntegrationConfig[];
+// @public
+export function readGerritIntegrationConfig(
+ config: Config,
+): GerritIntegrationConfig;
+
+// @public
+export function readGerritIntegrationConfigs(
+ configs: Config[],
+): GerritIntegrationConfig[];
+
// @public
export function readGitHubIntegrationConfig(
config: Config,
@@ -381,6 +422,8 @@ export interface ScmIntegrationRegistry
// (undocumented)
bitbucket: ScmIntegrationsGroup;
// (undocumented)
+ gerrit: ScmIntegrationsGroup;
+ // (undocumented)
github: ScmIntegrationsGroup;
// (undocumented)
gitlab: ScmIntegrationsGroup;
@@ -408,6 +451,8 @@ export class ScmIntegrations implements ScmIntegrationRegistry {
// (undocumented)
static fromConfig(config: Config): ScmIntegrations;
// (undocumented)
+ get gerrit(): ScmIntegrationsGroup;
+ // (undocumented)
get github(): ScmIntegrationsGroup;
// (undocumented)
get gitlab(): ScmIntegrationsGroup;
diff --git a/packages/integration/config.d.ts b/packages/integration/config.d.ts
index 0b88a8ff81..e2d26be28e 100644
--- a/packages/integration/config.d.ts
+++ b/packages/integration/config.d.ts
@@ -60,6 +60,31 @@ export interface Config {
appPassword?: string;
}>;
+ /** Integration configuration for Gerrit */
+ gerrit?: Array<{
+ /**
+ * The hostname of the given Gerrit instance
+ * @visibility frontend
+ */
+ host: string;
+ /**
+ * The base url for the Gerrit instance.
+ * @visibility frontend
+ */
+ baseUrl?: string;
+ /**
+ * The username to use for authenticated requests.
+ * @visibility secret
+ */
+ username?: string;
+ /**
+ * Gerrit password used to authenticate requests. This can be either a password
+ * or a generated access token.
+ * @visibility secret
+ */
+ password?: string;
+ }>;
+
/** Integration configuration for GitHub */
github?: Array<{
/**
diff --git a/packages/integration/src/ScmIntegrations.test.ts b/packages/integration/src/ScmIntegrations.test.ts
index f0a6e5d72d..2e6f2f1472 100644
--- a/packages/integration/src/ScmIntegrations.test.ts
+++ b/packages/integration/src/ScmIntegrations.test.ts
@@ -19,6 +19,8 @@ import { AzureIntegrationConfig } from './azure';
import { AzureIntegration } from './azure/AzureIntegration';
import { BitbucketIntegrationConfig } from './bitbucket';
import { BitbucketIntegration } from './bitbucket/BitbucketIntegration';
+import { GerritIntegrationConfig } from './gerrit';
+import { GerritIntegration } from './gerrit/GerritIntegration';
import { GitHubIntegrationConfig } from './github';
import { GitHubIntegration } from './github/GitHubIntegration';
import { GitLabIntegrationConfig } from './gitlab';
@@ -39,6 +41,10 @@ describe('ScmIntegrations', () => {
host: 'bitbucket.local',
} as BitbucketIntegrationConfig);
+ const gerrit = new GerritIntegration({
+ host: 'gerrit.local',
+ } as GerritIntegrationConfig);
+
const github = new GitHubIntegration({
host: 'github.local',
} as GitHubIntegrationConfig);
@@ -51,6 +57,7 @@ describe('ScmIntegrations', () => {
awsS3: basicIntegrations([awsS3], item => item.config.host),
azure: basicIntegrations([azure], item => item.config.host),
bitbucket: basicIntegrations([bitbucket], item => item.config.host),
+ gerrit: basicIntegrations([gerrit], item => item.config.host),
github: basicIntegrations([github], item => item.config.host),
gitlab: basicIntegrations([gitlab], item => item.config.host),
});
@@ -59,13 +66,14 @@ describe('ScmIntegrations', () => {
expect(i.awsS3.byUrl('https://awss3.local')).toBe(awsS3);
expect(i.azure.byUrl('https://azure.local')).toBe(azure);
expect(i.bitbucket.byUrl('https://bitbucket.local')).toBe(bitbucket);
+ expect(i.gerrit.byUrl('https://gerrit.local')).toBe(gerrit);
expect(i.github.byUrl('https://github.local')).toBe(github);
expect(i.gitlab.byUrl('https://gitlab.local')).toBe(gitlab);
});
it('can list', () => {
expect(i.list()).toEqual(
- expect.arrayContaining([awsS3, azure, bitbucket, github, gitlab]),
+ expect.arrayContaining([awsS3, azure, bitbucket, gerrit, github, gitlab]),
);
});
@@ -73,12 +81,14 @@ describe('ScmIntegrations', () => {
expect(i.byUrl('https://awss3.local')).toBe(awsS3);
expect(i.byUrl('https://azure.local')).toBe(azure);
expect(i.byUrl('https://bitbucket.local')).toBe(bitbucket);
+ expect(i.byUrl('https://gerrit.local')).toBe(gerrit);
expect(i.byUrl('https://github.local')).toBe(github);
expect(i.byUrl('https://gitlab.local')).toBe(gitlab);
expect(i.byHost('awss3.local')).toBe(awsS3);
expect(i.byHost('azure.local')).toBe(azure);
expect(i.byHost('bitbucket.local')).toBe(bitbucket);
+ expect(i.byHost('gerrit.local')).toBe(gerrit);
expect(i.byHost('github.local')).toBe(github);
expect(i.byHost('gitlab.local')).toBe(gitlab);
});
diff --git a/packages/integration/src/ScmIntegrations.ts b/packages/integration/src/ScmIntegrations.ts
index add9e4e016..8638b814ec 100644
--- a/packages/integration/src/ScmIntegrations.ts
+++ b/packages/integration/src/ScmIntegrations.ts
@@ -18,6 +18,7 @@ import { Config } from '@backstage/config';
import { AwsS3Integration } from './awsS3/AwsS3Integration';
import { AzureIntegration } from './azure/AzureIntegration';
import { BitbucketIntegration } from './bitbucket/BitbucketIntegration';
+import { GerritIntegration } from './gerrit/GerritIntegration';
import { GitHubIntegration } from './github/GitHubIntegration';
import { GitLabIntegration } from './gitlab/GitLabIntegration';
import { defaultScmResolveUrl } from './helpers';
@@ -33,6 +34,7 @@ export interface IntegrationsByType {
awsS3: ScmIntegrationsGroup;
azure: ScmIntegrationsGroup;
bitbucket: ScmIntegrationsGroup;
+ gerrit: ScmIntegrationsGroup;
github: ScmIntegrationsGroup;
gitlab: ScmIntegrationsGroup;
}
@@ -50,6 +52,7 @@ export class ScmIntegrations implements ScmIntegrationRegistry {
awsS3: AwsS3Integration.factory({ config }),
azure: AzureIntegration.factory({ config }),
bitbucket: BitbucketIntegration.factory({ config }),
+ gerrit: GerritIntegration.factory({ config }),
github: GitHubIntegration.factory({ config }),
gitlab: GitLabIntegration.factory({ config }),
});
@@ -71,6 +74,10 @@ export class ScmIntegrations implements ScmIntegrationRegistry {
return this.byType.bitbucket;
}
+ get gerrit(): ScmIntegrationsGroup {
+ return this.byType.gerrit;
+ }
+
get github(): ScmIntegrationsGroup {
return this.byType.github;
}
diff --git a/packages/integration/src/gerrit/GerritIntegration.test.ts b/packages/integration/src/gerrit/GerritIntegration.test.ts
new file mode 100644
index 0000000000..6b5e228bb6
--- /dev/null
+++ b/packages/integration/src/gerrit/GerritIntegration.test.ts
@@ -0,0 +1,113 @@
+/*
+ * 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 { ConfigReader } from '@backstage/config';
+import { GerritIntegration } from './GerritIntegration';
+
+describe('GerritIntegration', () => {
+ it('has a working factory', () => {
+ const integrations = GerritIntegration.factory({
+ config: new ConfigReader({
+ integrations: {
+ gerrit: [
+ {
+ host: 'gerrit-review.example.com',
+ username: 'gerrituser',
+ baseUrl: 'https://gerrit-review.example.com/gerrit',
+ password: '1234',
+ },
+ ],
+ },
+ }),
+ });
+ expect(integrations.list().length).toBe(1);
+ expect(integrations.list()[0].config.host).toBe(
+ 'gerrit-review.example.com',
+ );
+ expect(integrations.list()[0].config.baseUrl).toBe(
+ 'https://gerrit-review.example.com/gerrit',
+ );
+ });
+
+ it('returns the basics', () => {
+ const integration = new GerritIntegration({
+ host: 'gerrit-review.example.com',
+ } as any);
+ expect(integration.type).toBe('gerrit');
+ expect(integration.title).toBe('gerrit-review.example.com');
+ });
+
+ describe('resolveUrl', () => {
+ it('works for valid urls', () => {
+ const integration = new GerritIntegration({
+ host: 'gerrit-review.example.com',
+ } as any);
+
+ expect(
+ integration.resolveUrl({
+ url: 'https://gerrit-review.example.com/catalog-info.yaml',
+ base: 'https://gerrit-review.example.com/catalog-info.yaml',
+ lineNumber: 9,
+ }),
+ ).toBe('https://gerrit-review.example.com/catalog-info.yaml#9');
+ });
+
+ it('handles line numbers', () => {
+ const integration = new GerritIntegration({
+ host: 'gerrit-review.example.com',
+ } as any);
+
+ expect(
+ integration.resolveUrl({
+ url: '',
+ base: 'https://gerrit-review.example.com/catalog-info.yaml#4',
+ lineNumber: 9,
+ }),
+ ).toBe('https://gerrit-review.example.com/catalog-info.yaml#9');
+ });
+ });
+
+ describe('resolves with a relative url', () => {
+ it('works for valid urls', () => {
+ const integration = new GerritIntegration({
+ host: 'gerrit-review.example.com',
+ } as any);
+
+ expect(
+ integration.resolveUrl({
+ url: './skeleton',
+ base: 'https://gerrit-review.example.com/gerrit/plugins/repo/+/refs/heads/master/template.yaml',
+ }),
+ ).toBe(
+ 'https://gerrit-review.example.com/gerrit/plugins/repo/+/refs/heads/master/skeleton',
+ );
+ });
+ });
+
+ it('resolve edit URL', () => {
+ const integration = new GerritIntegration({
+ host: 'gerrit-review.example.com',
+ } as any);
+
+ // Resolve edit URLs is not applicable for gerrit. Return the input
+ // url as is.
+ expect(
+ integration.resolveEditUrl(
+ 'https://gerrit-review.example.com/catalog-info.yaml',
+ ),
+ ).toBe('https://gerrit-review.example.com/catalog-info.yaml');
+ });
+});
diff --git a/packages/integration/src/gerrit/GerritIntegration.ts b/packages/integration/src/gerrit/GerritIntegration.ts
new file mode 100644
index 0000000000..97eb9372c0
--- /dev/null
+++ b/packages/integration/src/gerrit/GerritIntegration.ts
@@ -0,0 +1,76 @@
+/*
+ * 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 { basicIntegrations } from '../helpers';
+import { ScmIntegration, ScmIntegrationsFactory } from '../types';
+import {
+ GerritIntegrationConfig,
+ readGerritIntegrationConfigs,
+} from './config';
+
+/**
+ * A Gerrit based integration.
+ *
+ * @public
+ */
+export class GerritIntegration implements ScmIntegration {
+ static factory: ScmIntegrationsFactory = ({ config }) => {
+ const configs = readGerritIntegrationConfigs(
+ config.getOptionalConfigArray('integrations.gerrit') ?? [],
+ );
+ return basicIntegrations(
+ configs.map(c => new GerritIntegration(c)),
+ i => i.config.host,
+ );
+ };
+
+ constructor(private readonly integrationConfig: GerritIntegrationConfig) {}
+
+ get type(): string {
+ return 'gerrit';
+ }
+
+ get title(): string {
+ return this.integrationConfig.host;
+ }
+
+ get config(): GerritIntegrationConfig {
+ return this.integrationConfig;
+ }
+
+ resolveUrl(options: {
+ url: string;
+ base: string;
+ lineNumber?: number;
+ }): string {
+ const { url, base, lineNumber } = options;
+ let updated;
+ if (url) {
+ updated = new URL(url, base);
+ } else {
+ updated = new URL(base);
+ }
+ if (lineNumber) {
+ updated.hash = lineNumber.toString();
+ }
+ return updated.toString();
+ }
+
+ resolveEditUrl(url: string): string {
+ // Not applicable for gerrit.
+ return url;
+ }
+}
diff --git a/packages/integration/src/gerrit/config.test.ts b/packages/integration/src/gerrit/config.test.ts
new file mode 100644
index 0000000000..ce1ddccd75
--- /dev/null
+++ b/packages/integration/src/gerrit/config.test.ts
@@ -0,0 +1,149 @@
+/*
+ * 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 { Config, ConfigReader } from '@backstage/config';
+import { loadConfigSchema } from '@backstage/config-loader';
+import {
+ GerritIntegrationConfig,
+ readGerritIntegrationConfig,
+ readGerritIntegrationConfigs,
+} from './config';
+
+describe('readGerritIntegrationConfig', () => {
+ function buildConfig(data: Partial): Config {
+ return new ConfigReader(data);
+ }
+
+ async function buildFrontendConfig(
+ data: Partial,
+ ): Promise {
+ const fullSchema = await loadConfigSchema({
+ dependencies: ['@backstage/integration'],
+ });
+ const serializedSchema = fullSchema.serialize() as {
+ schemas: { value: { properties?: { integrations?: object } } }[];
+ };
+ const schema = await loadConfigSchema({
+ serialized: {
+ ...serializedSchema, // only include schemas that apply to integrations
+ schemas: serializedSchema.schemas.filter(
+ s => s.value?.properties?.integrations,
+ ),
+ },
+ });
+ const processed = schema.process(
+ [{ data: { integrations: { gerrit: [data] } }, context: 'app' }],
+ { visibility: ['frontend'] },
+ );
+ return new ConfigReader((processed[0].data as any).integrations.gerrit[0]);
+ }
+
+ it('reads all values', () => {
+ const output = readGerritIntegrationConfig(
+ buildConfig({
+ host: 'a.com',
+ baseUrl: 'https://a.com/api',
+ username: 'u',
+ password: 'p',
+ }),
+ );
+ expect(output).toEqual({
+ host: 'a.com',
+ baseUrl: 'https://a.com/api',
+ username: 'u',
+ password: 'p',
+ });
+ });
+
+ it('can create a default value if the API base URL is missing', () => {
+ const output = readGerritIntegrationConfig(
+ buildConfig({
+ host: 'a.com',
+ }),
+ );
+ expect(output).toEqual({
+ host: 'a.com',
+ baseUrl: 'https://a.com',
+ username: undefined,
+ password: undefined,
+ });
+ });
+
+ it('rejects funky configs', () => {
+ const valid: any = {
+ host: 'a.com',
+ };
+ expect(() =>
+ readGerritIntegrationConfig(buildConfig({ ...valid, host: 2 })),
+ ).toThrow(/host/);
+ expect(() =>
+ readGerritIntegrationConfig(buildConfig({ ...valid, baseUrl: 2 })),
+ ).toThrow(/baseUrl/);
+ });
+
+ it('works on the frontend', async () => {
+ expect(
+ readGerritIntegrationConfig(
+ await buildFrontendConfig({
+ host: 'a.com',
+ baseUrl: 'https://a.com/gerrit',
+ username: 'u',
+ password: 'p',
+ }),
+ ),
+ ).toEqual({
+ host: 'a.com',
+ baseUrl: 'https://a.com/gerrit',
+ });
+ });
+});
+
+describe('readGerritIntegrationConfigs', () => {
+ function buildConfig(data: Partial[]): Config[] {
+ return data.map(item => new ConfigReader(item));
+ }
+
+ it('reads all values', () => {
+ const output = readGerritIntegrationConfigs(
+ buildConfig([
+ {
+ host: 'a.com',
+ baseUrl: 'https://a.com/api',
+ username: 'u',
+ password: 'p',
+ },
+ {
+ host: 'b.com',
+ baseUrl: 'https://b.com/api',
+ },
+ ]),
+ );
+ expect(output).toEqual([
+ {
+ host: 'a.com',
+ baseUrl: 'https://a.com/api',
+ username: 'u',
+ password: 'p',
+ },
+ {
+ host: 'b.com',
+ baseUrl: 'https://b.com/api',
+ username: undefined,
+ password: undefined,
+ },
+ ]);
+ });
+});
diff --git a/packages/integration/src/gerrit/config.ts b/packages/integration/src/gerrit/config.ts
new file mode 100644
index 0000000000..339b590c11
--- /dev/null
+++ b/packages/integration/src/gerrit/config.ts
@@ -0,0 +1,101 @@
+/*
+ * 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 { Config } from '@backstage/config';
+import { trimEnd } from 'lodash';
+import { isValidHost, isValidUrl } from '../helpers';
+
+/**
+ * The configuration parameters for a single Gerrit API provider.
+ *
+ * @public
+ */
+export type GerritIntegrationConfig = {
+ /**
+ * The host of the target that this matches on, e.g. "gerrit-review.com"
+ */
+ host: string;
+
+ /**
+ * The optional base URL of the Gerrit instance. It is assumed that https
+ * is used and that the base path is "/" on the host. If that is not the
+ * case set the complete base url to the gerrit instance, e.g.
+ * "https://gerrit-review.com/gerrit". This is the url that you would open
+ * in a browser.
+ */
+ baseUrl?: string;
+
+ /**
+ * The username to use for requests to gerrit.
+ */
+ username?: string;
+
+ /**
+ * The password or http token to use for authentication.
+ */
+ password?: string;
+};
+
+/**
+ * Reads a single Gerrit integration config.
+ *
+ * @param config - The config object of a single integration
+ *
+ * @public
+ */
+export function readGerritIntegrationConfig(
+ config: Config,
+): GerritIntegrationConfig {
+ const host = config.getString('host');
+ let baseUrl = config.getOptionalString('baseUrl');
+ const username = config.getOptionalString('username');
+ const password = config.getOptionalString('password');
+
+ if (!isValidHost(host)) {
+ throw new Error(
+ `Invalid Gerrit integration config, '${host}' is not a valid host`,
+ );
+ } else if (baseUrl && !isValidUrl(baseUrl)) {
+ throw new Error(
+ `Invalid Gerrit integration config, '${baseUrl}' is not a valid baseUrl`,
+ );
+ }
+ if (baseUrl) {
+ baseUrl = trimEnd(baseUrl, '/');
+ } else {
+ baseUrl = `https://${host}`;
+ }
+
+ return {
+ host,
+ baseUrl,
+ username,
+ password,
+ };
+}
+
+/**
+ * Reads a set of Gerrit integration configs.
+ *
+ * @param configs - All of the integration config objects
+ *
+ * @public
+ */
+export function readGerritIntegrationConfigs(
+ configs: Config[],
+): GerritIntegrationConfig[] {
+ return configs.map(readGerritIntegrationConfig);
+}
diff --git a/packages/integration/src/gerrit/index.ts b/packages/integration/src/gerrit/index.ts
new file mode 100644
index 0000000000..baad597a22
--- /dev/null
+++ b/packages/integration/src/gerrit/index.ts
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+export { GerritIntegration } from './GerritIntegration';
+export {
+ readGerritIntegrationConfig,
+ readGerritIntegrationConfigs,
+} from './config';
+export type { GerritIntegrationConfig } from './config';
diff --git a/packages/integration/src/index.ts b/packages/integration/src/index.ts
index 2f33b76ab3..cf0eeca51a 100644
--- a/packages/integration/src/index.ts
+++ b/packages/integration/src/index.ts
@@ -22,6 +22,7 @@
export * from './azure';
export * from './bitbucket';
+export * from './gerrit';
export * from './github';
export * from './gitlab';
export * from './googleGcs';
diff --git a/packages/integration/src/registry.ts b/packages/integration/src/registry.ts
index 5864695e25..5ab5d049fb 100644
--- a/packages/integration/src/registry.ts
+++ b/packages/integration/src/registry.ts
@@ -18,6 +18,7 @@ import { ScmIntegration, ScmIntegrationsGroup } from './types';
import { AwsS3Integration } from './awsS3/AwsS3Integration';
import { AzureIntegration } from './azure/AzureIntegration';
import { BitbucketIntegration } from './bitbucket/BitbucketIntegration';
+import { GerritIntegration } from './gerrit/GerritIntegration';
import { GitHubIntegration } from './github/GitHubIntegration';
import { GitLabIntegration } from './gitlab/GitLabIntegration';
@@ -31,6 +32,7 @@ export interface ScmIntegrationRegistry
awsS3: ScmIntegrationsGroup;
azure: ScmIntegrationsGroup;
bitbucket: ScmIntegrationsGroup;
+ gerrit: ScmIntegrationsGroup;
github: ScmIntegrationsGroup;
gitlab: ScmIntegrationsGroup;
diff --git a/packages/search-common/CHANGELOG.md b/packages/search-common/CHANGELOG.md
index 3b1b082083..66262033e2 100644
--- a/packages/search-common/CHANGELOG.md
+++ b/packages/search-common/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/search-common
+## 0.3.1
+
+### Patch Changes
+
+- d52155466a: **DEPRECATION**
+
+ The `@backstage/search-common` package is being renamed `@backstage/plugin-search-common`. We may continue to publish changes to `@backstage/search-common` for a time, but will stop doing so in the near future. If you depend on this package, you should update your dependencies to point at the renamed package.
+
+- Updated dependencies
+ - @backstage/plugin-search-common@0.3.1
+
## 0.3.1-next.0
### Patch Changes
diff --git a/packages/search-common/README.md b/packages/search-common/README.md
index 3a75dac4c2..80b0c09c40 100644
--- a/packages/search-common/README.md
+++ b/packages/search-common/README.md
@@ -1,7 +1,5 @@
# @backstage/search-common
-**WARNING**: This package is moving to `@backstage/plugin-search-common`.
-Please update any dependencies you may have, as this package will no longer be
-published or updated in the near future.
-
-Common functionalities for Search, to be shared between various search-enabled plugins.
+This package has been moved to `@backstage/plugin-search-common` and is no
+longer maintained. Please update any dependencies you have on this package
+accordingly.
diff --git a/packages/search-common/package.json b/packages/search-common/package.json
index d84bda9edc..800260c44c 100644
--- a/packages/search-common/package.json
+++ b/packages/search-common/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/search-common",
- "description": "Common functionalities for Search, to be shared between various search-enabled plugins",
- "version": "0.3.1-next.0",
+ "description": "No longer maintained. Use @backstage/plugin-search-common instead.",
+ "version": "0.3.1",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -19,10 +19,6 @@
"url": "https://github.com/backstage/backstage",
"directory": "packages/search-common"
},
- "keywords": [
- "backstage",
- "search"
- ],
"license": "Apache-2.0",
"files": [
"dist"
@@ -39,7 +35,7 @@
"url": "https://github.com/backstage/backstage/issues"
},
"dependencies": {
- "@backstage/plugin-search-common": "^0.3.1-next.0"
+ "@backstage/plugin-search-common": "0.3.1"
},
"devDependencies": {},
"jest": {
diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md
index 51f0bc8b00..7f9482c7b3 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.67
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/cli@0.15.2
+ - @backstage/plugin-catalog@0.10.0
+ - @backstage/core-components@0.9.1
+ - @backstage/catalog-model@0.13.0
+ - @backstage/plugin-techdocs@0.15.1
+ - @backstage/app-defaults@0.2.1
+ - @backstage/integration-react@0.1.25
+
## 0.2.67-next.0
### Patch Changes
diff --git a/packages/techdocs-cli-embedded-app/app-config.yaml b/packages/techdocs-cli-embedded-app/app-config.yaml
index 56e63ff97c..6ede05b587 100644
--- a/packages/techdocs-cli-embedded-app/app-config.yaml
+++ b/packages/techdocs-cli-embedded-app/app-config.yaml
@@ -7,4 +7,3 @@ backend:
techdocs:
builder: 'external'
- requestUrl: http://localhost:3000/api
diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json
index 700036dd3c..1104958262 100644
--- a/packages/techdocs-cli-embedded-app/package.json
+++ b/packages/techdocs-cli-embedded-app/package.json
@@ -1,22 +1,22 @@
{
"name": "techdocs-cli-embedded-app",
- "version": "0.2.67-next.0",
+ "version": "0.2.67",
"private": true,
"backstage": {
"role": "frontend"
},
"bundled": true,
"dependencies": {
- "@backstage/app-defaults": "^0.2.1-next.0",
- "@backstage/catalog-model": "^0.13.0-next.0",
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/app-defaults": "^0.2.1",
+ "@backstage/catalog-model": "^0.13.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/config": "^0.1.15",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
- "@backstage/integration-react": "^0.1.25-next.0",
- "@backstage/plugin-catalog": "^0.10.0-next.0",
- "@backstage/plugin-techdocs": "^0.15.1-next.0",
+ "@backstage/integration-react": "^0.1.25",
+ "@backstage/plugin-catalog": "^0.10.0",
+ "@backstage/plugin-techdocs": "^0.15.1",
"@backstage/test-utils": "^0.3.0",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.11.0",
@@ -29,9 +29,9 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
diff --git a/packages/techdocs-cli-embedded-app/src/apis.ts b/packages/techdocs-cli-embedded-app/src/apis.ts
index 1fe6ba8086..d230a9f83c 100644
--- a/packages/techdocs-cli-embedded-app/src/apis.ts
+++ b/packages/techdocs-cli-embedded-app/src/apis.ts
@@ -64,17 +64,11 @@ class TechDocsDevStorageApi implements TechDocsStorageApi {
}
async getApiOrigin() {
- return (
- this.configApi.getOptionalString('techdocs.requestUrl') ??
- (await this.discoveryApi.getBaseUrl('techdocs'))
- );
+ return await this.discoveryApi.getBaseUrl('techdocs');
}
async getStorageUrl() {
- return (
- this.configApi.getOptionalString('techdocs.storageUrl') ??
- `${await this.discoveryApi.getBaseUrl('techdocs')}/static/docs`
- );
+ return `${await this.discoveryApi.getBaseUrl('techdocs')}/static/docs`;
}
async getBuilder() {
@@ -134,10 +128,7 @@ class TechDocsDevApi implements TechDocsApi {
}
async getApiOrigin() {
- return (
- this.configApi.getOptionalString('techdocs.requestUrl') ??
- (await this.discoveryApi.getBaseUrl('techdocs'))
- );
+ return await this.discoveryApi.getBaseUrl('techdocs');
}
async getEntityMetadata(_entityId: any) {
diff --git a/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx b/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx
index f2dcefc00e..56686dd081 100644
--- a/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx
+++ b/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx
@@ -35,8 +35,8 @@ import { Content } from '@backstage/core-components';
import {
Reader,
- TechDocsPage,
- TechDocsPageHeader,
+ TechDocsReaderPage,
+ TechDocsReaderPageHeader,
} from '@backstage/plugin-techdocs';
const useStyles = makeStyles((theme: Theme) => ({
@@ -146,19 +146,19 @@ const DefaultTechDocsPage = () => {
};
return (
-
+
{({ entityRef, onReady }) => (
<>
-
-
+
>
)}
-
+
);
};
diff --git a/packages/techdocs-cli-embedded-app/src/config.ts b/packages/techdocs-cli-embedded-app/src/config.ts
index 482ceb41ec..ae801dac2a 100644
--- a/packages/techdocs-cli-embedded-app/src/config.ts
+++ b/packages/techdocs-cli-embedded-app/src/config.ts
@@ -22,7 +22,6 @@ const PRODUCTION_CONFIG = {
},
techdocs: {
builder: 'external',
- requestUrl: 'http://localhost:3000/api',
},
};
@@ -32,7 +31,6 @@ const DEVELOPMENT_CONFIG = {
},
techdocs: {
builder: 'external',
- requestUrl: 'http://localhost:7007/api',
},
};
diff --git a/packages/techdocs-cli/CHANGELOG.md b/packages/techdocs-cli/CHANGELOG.md
index e668940718..6716a03e01 100644
--- a/packages/techdocs-cli/CHANGELOG.md
+++ b/packages/techdocs-cli/CHANGELOG.md
@@ -1,5 +1,16 @@
# @techdocs/cli
+## 0.8.17
+
+### Patch Changes
+
+- e0a69ba49f: build(deps): bump `fs-extra` from 9.1.0 to 10.0.1
+- 91bf1e6c1a: Use `@backstage/plugin-techdocs-node` package instead of `@backstage/techdocs-common`.
+- Updated dependencies
+ - @backstage/backend-common@0.13.0
+ - @backstage/plugin-techdocs-node@0.11.12
+ - @backstage/catalog-model@0.13.0
+
## 0.8.17-next.0
### Patch Changes
diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json
index 758cab9856..42069bb8e2 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": "0.8.17-next.0",
+ "version": "0.8.17",
"private": false,
"publishConfig": {
"access": "public"
@@ -37,7 +37,7 @@
"techdocs-cli": "bin/techdocs-cli"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@types/commander": "^2.12.2",
"@types/fs-extra": "^9.0.6",
"@types/http-proxy": "^1.17.4",
@@ -62,11 +62,11 @@
"ext": "ts"
},
"dependencies": {
- "@backstage/backend-common": "^0.13.0-next.0",
- "@backstage/catalog-model": "^0.13.0-next.0",
+ "@backstage/backend-common": "^0.13.0",
+ "@backstage/catalog-model": "^0.13.0",
"@backstage/cli-common": "^0.1.8",
"@backstage/config": "^0.1.15",
- "@backstage/plugin-techdocs-node": "^0.11.12-next.0",
+ "@backstage/plugin-techdocs-node": "^0.11.12",
"@types/dockerode": "^3.3.0",
"commander": "^6.1.0",
"dockerode": "^3.3.1",
diff --git a/packages/techdocs-common/CHANGELOG.md b/packages/techdocs-common/CHANGELOG.md
index 87c6ea0da9..55c2743088 100644
--- a/packages/techdocs-common/CHANGELOG.md
+++ b/packages/techdocs-common/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/techdocs-common
+## 0.11.12
+
+### Patch Changes
+
+- cea6f10b97: **DEPRECATION**
+
+ The `@backstage/techdocs-common` package is being renamed `@backstage/plugin-techdocs-node`. We may continue to publish changes to `@backstage/techdocs-common` for a time, but will stop doing so in the near future. If you depend on this package, you should update your dependencies to point at the renamed package.
+
+- Updated dependencies
+ - @backstage/plugin-techdocs-node@0.11.12
+
## 0.11.12-next.0
### Patch Changes
diff --git a/packages/techdocs-common/README.md b/packages/techdocs-common/README.md
index 452b09b60b..052eae7ab2 100644
--- a/packages/techdocs-common/README.md
+++ b/packages/techdocs-common/README.md
@@ -1,53 +1,5 @@
# @backstage/techdocs-common
-**WARNING**: This package is moving to `@backstage/plugin-techdocs-node`.
-Please update any dependencies you may have, as this package will no longer be
-published or updated in the near future.
-
-Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli
-
-This package is used by `techdocs-backend` to serve docs from different types of publishers (Google GCS, Local, etc.).
-It is also used to build docs and publish them to storage, by both `techdocs-backend` and `techdocs-cli`.
-
-## Usage
-
-Create a preparer instance from the [preparers available](/plugins/techdocs-node/src/stages/prepare) at which takes an Entity instance.
-Run the [docs generator](/plugins/techdocs-node/src/stages/generate) on the prepared directory.
-Publish the generated directory files to a [storage](/plugins/techdocs-node/src/stages/publish) of your choice.
-
-Example:
-
-```js
-async () => {
- const preparedDir = await preparer.prepare(entity);
-
- const parsedLocationAnnotation = getLocationForEntity(entity);
- const { resultDir } = await generator.run({
- directory: preparedDir,
- dockerClient: dockerClient,
- parsedLocationAnnotation,
- });
-
- await publisher.publish({
- entity: entity,
- directory: resultDir,
- });
-};
-```
-
-## Features
-
-Currently the build process is split up in these three stages.
-
-- Preparers
-- Generators
-- Publishers
-
-Preparers read your entity data and creates a working directory with your documentation source code. For example if you have set your `backstage.io/techdocs-ref` to `url:https://github.com/backstage/backstage.git` it will clone that repository to a temp folder and pass that on to the generator.
-
-Generators takes the prepared source and runs the `techdocs-container` on it. It then passes on the output folder of that build to the publisher.
-
-Publishers gets a folder path from the generator and publish it to your storage solution. Read documentation to know more about configuring storage solutions.
-http://backstage.io/docs/features/techdocs/configuration
-
-Any of these can be extended. We want to extend our support to most of the storage providers (Publishers) and source code host providers (Preparers).
+This package has been moved to `@backstage/plugin-techdocs-node` and is no
+longer maintained. Please update any dependencies you have on this package
+accordingly.
diff --git a/packages/techdocs-common/package.json b/packages/techdocs-common/package.json
index 6d897a2f08..c56f0b63be 100644
--- a/packages/techdocs-common/package.json
+++ b/packages/techdocs-common/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/techdocs-common",
- "description": "Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli",
- "version": "0.11.12-next.0",
+ "description": "No longer maintained. Use @backstage/plugin-techdocs-node instead.",
+ "version": "0.11.12",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -19,10 +19,6 @@
"url": "https://github.com/backstage/backstage",
"directory": "packages/techdocs-common"
},
- "keywords": [
- "techdocs",
- "backstage"
- ],
"license": "Apache-2.0",
"files": [
"dist"
@@ -40,7 +36,7 @@
"url": "https://github.com/backstage/backstage/issues"
},
"dependencies": {
- "@backstage/plugin-techdocs-node": "^0.11.12-next.0"
+ "@backstage/plugin-techdocs-node": "0.11.12"
},
"devDependencies": {},
"jest": {
diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json
index 2f0aa0e988..0cf752a72d 100644
--- a/packages/test-utils/package.json
+++ b/packages/test-utils/package.json
@@ -43,7 +43,7 @@
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.11.2",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"cross-fetch": "^3.1.5",
"react-router": "6.0.0-beta.0",
diff --git a/packages/test-utils/src/testUtils/apis/ErrorApi/MockErrorApi.ts b/packages/test-utils/src/testUtils/apis/ErrorApi/MockErrorApi.ts
index 96918b4e47..c7c8556355 100644
--- a/packages/test-utils/src/testUtils/apis/ErrorApi/MockErrorApi.ts
+++ b/packages/test-utils/src/testUtils/apis/ErrorApi/MockErrorApi.ts
@@ -54,7 +54,7 @@ const nullObservable = {
/**
* Mock implementation of the {@link core-plugin-api#ErrorApi} to be used in tests.
- * Incudes withForError and getErrors methods for error testing.
+ * Includes withForError and getErrors methods for error testing.
* @public
*/
export class MockErrorApi implements ErrorApi {
diff --git a/packages/version-bridge/package.json b/packages/version-bridge/package.json
index 463e7841ed..a954998e76 100644
--- a/packages/version-bridge/package.json
+++ b/packages/version-bridge/package.json
@@ -39,7 +39,7 @@
"devDependencies": {
"@backstage/cli": "^0.15.2-next.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/react-hooks": "^7.0.2"
},
"files": [
diff --git a/plugins/airbrake-backend/CHANGELOG.md b/plugins/airbrake-backend/CHANGELOG.md
index 9826c90e72..1267c8bb7d 100644
--- a/plugins/airbrake-backend/CHANGELOG.md
+++ b/plugins/airbrake-backend/CHANGELOG.md
@@ -1,5 +1,13 @@
# @backstage/plugin-airbrake-backend
+## 0.2.2
+
+### Patch Changes
+
+- 4f79204c47: Added `backstage.role` to `package.json`
+- Updated dependencies
+ - @backstage/backend-common@0.13.0
+
## 0.2.2-next.0
### Patch Changes
diff --git a/plugins/airbrake-backend/package.json b/plugins/airbrake-backend/package.json
index c8c87dd117..046d7dbd31 100644
--- a/plugins/airbrake-backend/package.json
+++ b/plugins/airbrake-backend/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-airbrake-backend",
- "version": "0.2.2-next.0",
+ "version": "0.2.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -22,7 +22,7 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.13.0-next.0",
+ "@backstage/backend-common": "^0.13.0",
"@backstage/config": "^0.1.15",
"@types/express": "*",
"express": "^4.17.1",
@@ -33,7 +33,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@types/http-proxy-middleware": "^0.19.3",
"@types/supertest": "^2.0.8",
"supertest": "^6.1.6",
diff --git a/plugins/airbrake/CHANGELOG.md b/plugins/airbrake/CHANGELOG.md
index 374cdc7c7c..b4c8dc5228 100644
--- a/plugins/airbrake/CHANGELOG.md
+++ b/plugins/airbrake/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-airbrake
+## 0.3.2
+
+### Patch Changes
+
+- c5a462bff1: Fix a bug where API calls were being made and errors were being added to the snack bar when no project ID was present. This is a common use case for components that haven't added the Airbrake plugin annotation to their `catalog-info.yaml`.
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.9.0
+ - @backstage/core-components@0.9.1
+ - @backstage/catalog-model@0.13.0
+ - @backstage/dev-utils@0.2.25
+
## 0.3.2-next.0
### Patch Changes
diff --git a/plugins/airbrake/README.md b/plugins/airbrake/README.md
index bc830c326d..1aae77bd47 100644
--- a/plugins/airbrake/README.md
+++ b/plugins/airbrake/README.md
@@ -60,13 +60,12 @@ The Airbrake plugin provides connectivity between Backstage and Airbrake (https:
extractAirbrakeConfig,
} from '@backstage/plugin-airbrake-backend';
- export default async function createPlugin({
- logger,
- config,
- }: PluginEnvironment): Promise {
+ export default async function createPlugin(
+ env: PluginEnvironment,
+ ): Promise {
return createRouter({
- logger,
- airbrakeConfig: extractAirbrakeConfig(config),
+ logger: env.logger,
+ airbrakeConfig: extractAirbrakeConfig(env.config),
});
}
```
diff --git a/plugins/airbrake/package.json b/plugins/airbrake/package.json
index 52e1244230..4f2eeec043 100644
--- a/plugins/airbrake/package.json
+++ b/plugins/airbrake/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-airbrake",
- "version": "0.3.2-next.0",
+ "version": "0.3.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -23,29 +23,29 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.13.0-next.0",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/catalog-model": "^0.13.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
- "@backstage/plugin-catalog-react": "^0.9.0-next.0",
+ "@backstage/dev-utils": "^0.2.25",
+ "@backstage/plugin-catalog-react": "^0.9.0",
"@backstage/test-utils": "^0.3.0",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.57",
- "object-hash": "^2.2.0",
+ "object-hash": "^3.0.0",
"react-use": "^17.2.4"
},
"peerDependencies": {
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/app-defaults": "^0.2.1-next.0",
- "@backstage/cli": "^0.15.2-next.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/app-defaults": "^0.2.1",
+ "@backstage/cli": "^0.15.2",
+ "@backstage/dev-utils": "^0.2.25",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
diff --git a/plugins/airbrake/src/components/EntityAirbrakeWidget/EntityAirbrakeWidget.test.tsx b/plugins/airbrake/src/components/EntityAirbrakeWidget/EntityAirbrakeWidget.test.tsx
index e8d09b5e65..a7243f5f0f 100644
--- a/plugins/airbrake/src/components/EntityAirbrakeWidget/EntityAirbrakeWidget.test.tsx
+++ b/plugins/airbrake/src/components/EntityAirbrakeWidget/EntityAirbrakeWidget.test.tsx
@@ -45,7 +45,7 @@ describe('EntityAirbrakeWidget', () => {
expect(exampleData.groups.length).toBeGreaterThan(0);
for (const group of exampleData.groups) {
expect(
- await widget.getByText(group.errors[0].message),
+ await widget.findByText(group.errors[0].message),
).toBeInTheDocument();
}
});
diff --git a/plugins/allure/CHANGELOG.md b/plugins/allure/CHANGELOG.md
index 6520fef7f4..40de2ce66f 100644
--- a/plugins/allure/CHANGELOG.md
+++ b/plugins/allure/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-allure
+## 0.1.18
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.9.0
+ - @backstage/core-components@0.9.1
+ - @backstage/catalog-model@0.13.0
+
## 0.1.18-next.0
### Patch Changes
diff --git a/plugins/allure/package.json b/plugins/allure/package.json
index ade58d7180..9b7ed7282b 100644
--- a/plugins/allure/package.json
+++ b/plugins/allure/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-allure",
"description": "A Backstage plugin that integrates with Allure",
- "version": "0.1.18-next.0",
+ "version": "0.1.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -25,10 +25,10 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.13.0-next.0",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/catalog-model": "^0.13.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
- "@backstage/plugin-catalog-react": "^0.9.0-next.0",
+ "@backstage/plugin-catalog-react": "^0.9.0",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -40,12 +40,12 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/dev-utils": "^0.2.25",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
diff --git a/plugins/analytics-module-ga/CHANGELOG.md b/plugins/analytics-module-ga/CHANGELOG.md
index fdf4f1704a..a25a25e940 100644
--- a/plugins/analytics-module-ga/CHANGELOG.md
+++ b/plugins/analytics-module-ga/CHANGELOG.md
@@ -1,5 +1,12 @@
# @backstage/plugin-analytics-module-ga
+## 0.1.13
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.9.1
+
## 0.1.13-next.0
### Patch Changes
diff --git a/plugins/analytics-module-ga/package.json b/plugins/analytics-module-ga/package.json
index f3d684dce3..376173b9b2 100644
--- a/plugins/analytics-module-ga/package.json
+++ b/plugins/analytics-module-ga/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-analytics-module-ga",
- "version": "0.1.13-next.0",
+ "version": "0.1.13",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -25,7 +25,7 @@
},
"dependencies": {
"@backstage/config": "^0.1.15",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
@@ -38,12 +38,12 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/dev-utils": "^0.2.25",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
diff --git a/plugins/apache-airflow/CHANGELOG.md b/plugins/apache-airflow/CHANGELOG.md
index f1e24ae6d5..40af918ebf 100644
--- a/plugins/apache-airflow/CHANGELOG.md
+++ b/plugins/apache-airflow/CHANGELOG.md
@@ -1,5 +1,12 @@
# @backstage/plugin-apache-airflow
+## 0.1.10
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.9.1
+
## 0.1.10-next.0
### Patch Changes
diff --git a/plugins/apache-airflow/package.json b/plugins/apache-airflow/package.json
index 5e36dcca52..86d12e6f11 100644
--- a/plugins/apache-airflow/package.json
+++ b/plugins/apache-airflow/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-apache-airflow",
- "version": "0.1.10-next.0",
+ "version": "0.1.10",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -23,7 +23,7 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -36,12 +36,12 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/dev-utils": "^0.2.25",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
diff --git a/plugins/api-docs/CHANGELOG.md b/plugins/api-docs/CHANGELOG.md
index f145c80222..b2fc5f0110 100644
--- a/plugins/api-docs/CHANGELOG.md
+++ b/plugins/api-docs/CHANGELOG.md
@@ -1,5 +1,15 @@
# @backstage/plugin-api-docs
+## 0.8.2
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog@0.10.0
+ - @backstage/plugin-catalog-react@0.9.0
+ - @backstage/core-components@0.9.1
+ - @backstage/catalog-model@0.13.0
+
## 0.8.2-next.0
### Patch Changes
diff --git a/plugins/api-docs/dev/graphql-example-api.yaml b/plugins/api-docs/dev/graphql-example-api.yaml
index f3d924fc53..ccddc537e7 100644
--- a/plugins/api-docs/dev/graphql-example-api.yaml
+++ b/plugins/api-docs/dev/graphql-example-api.yaml
@@ -529,7 +529,7 @@ spec:
terrains: [String]
"""
- The percentage of the planet surface that is naturally occuring water or bodies
+ The percentage of the planet surface that is naturally occurring water or bodies
of water.
"""
surfaceWater: Float
diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json
index 0edaa58731..1abd50a577 100644
--- a/plugins/api-docs/package.json
+++ b/plugins/api-docs/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-api-docs",
"description": "A Backstage plugin that helps represent API entities in the frontend",
- "version": "0.8.2-next.0",
+ "version": "0.8.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -34,11 +34,11 @@
},
"dependencies": {
"@asyncapi/react-component": "1.0.0-next.33",
- "@backstage/catalog-model": "^0.13.0-next.0",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/catalog-model": "^0.13.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
- "@backstage/plugin-catalog": "^0.10.0-next.0",
- "@backstage/plugin-catalog-react": "^0.9.0-next.0",
+ "@backstage/plugin-catalog": "^0.10.0",
+ "@backstage/plugin-catalog-react": "^0.9.0",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -56,12 +56,12 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/dev-utils": "^0.2.25",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
diff --git a/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.test.tsx b/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.test.tsx
index f84f66cee8..afb836ecc9 100644
--- a/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.test.tsx
+++ b/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.test.tsx
@@ -94,11 +94,6 @@ describe('', () => {
},
relations: [
{
- target: {
- kind: 'api',
- namespace: 'my-namespace',
- name: 'target-name',
- },
targetRef: 'api:my-namespace/target-name',
type: RELATION_CONSUMES_API,
},
diff --git a/plugins/api-docs/src/components/ApisCards/HasApisCard.test.tsx b/plugins/api-docs/src/components/ApisCards/HasApisCard.test.tsx
index daa909c7f8..85b353f04e 100644
--- a/plugins/api-docs/src/components/ApisCards/HasApisCard.test.tsx
+++ b/plugins/api-docs/src/components/ApisCards/HasApisCard.test.tsx
@@ -94,11 +94,6 @@ describe('', () => {
},
relations: [
{
- target: {
- kind: 'api',
- namespace: 'my-namespace',
- name: 'target-name',
- },
targetRef: 'api:my-namespace/target-name',
type: RELATION_HAS_PART,
},
diff --git a/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.test.tsx b/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.test.tsx
index 852386140c..40ffeff330 100644
--- a/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.test.tsx
+++ b/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.test.tsx
@@ -94,11 +94,6 @@ describe('', () => {
},
relations: [
{
- target: {
- kind: 'api',
- namespace: 'my-namespace',
- name: 'target-name',
- },
targetRef: 'api:my-namespace/target-name',
type: RELATION_PROVIDES_API,
},
diff --git a/plugins/api-docs/src/components/ComponentsCards/ConsumingComponentsCard.test.tsx b/plugins/api-docs/src/components/ComponentsCards/ConsumingComponentsCard.test.tsx
index a62b2119c7..abc91d8793 100644
--- a/plugins/api-docs/src/components/ComponentsCards/ConsumingComponentsCard.test.tsx
+++ b/plugins/api-docs/src/components/ComponentsCards/ConsumingComponentsCard.test.tsx
@@ -97,11 +97,6 @@ describe('', () => {
},
relations: [
{
- target: {
- kind: 'component',
- namespace: 'my-namespace',
- name: 'target-name',
- },
targetRef: 'component:my-namespace/target-name',
type: RELATION_API_CONSUMED_BY,
},
diff --git a/plugins/api-docs/src/components/ComponentsCards/ProvidingComponentsCard.test.tsx b/plugins/api-docs/src/components/ComponentsCards/ProvidingComponentsCard.test.tsx
index 1a0aae12c7..bdd45c3d58 100644
--- a/plugins/api-docs/src/components/ComponentsCards/ProvidingComponentsCard.test.tsx
+++ b/plugins/api-docs/src/components/ComponentsCards/ProvidingComponentsCard.test.tsx
@@ -97,11 +97,6 @@ describe('', () => {
},
relations: [
{
- target: {
- kind: 'component',
- namespace: 'my-namespace',
- name: 'target-name',
- },
targetRef: 'component:my-namespace/target-name',
type: RELATION_API_PROVIDED_BY,
},
diff --git a/plugins/app-backend/CHANGELOG.md b/plugins/app-backend/CHANGELOG.md
index c93408d321..082605d859 100644
--- a/plugins/app-backend/CHANGELOG.md
+++ b/plugins/app-backend/CHANGELOG.md
@@ -1,5 +1,15 @@
# @backstage/plugin-app-backend
+## 0.3.29
+
+### Patch Changes
+
+- ab7cd7d70e: Do some groundwork for supporting the `better-sqlite3` driver, to maybe eventually replace `@vscode/sqlite3` (#9912)
+- e0a69ba49f: build(deps): bump `fs-extra` from 9.1.0 to 10.0.1
+- Updated dependencies
+ - @backstage/backend-common@0.13.0
+ - @backstage/config-loader@0.9.7
+
## 0.3.29-next.0
### Patch Changes
diff --git a/plugins/app-backend/README.md b/plugins/app-backend/README.md
index a35cecfb9c..21e0253bac 100644
--- a/plugins/app-backend/README.md
+++ b/plugins/app-backend/README.md
@@ -18,7 +18,7 @@ Now add the plugin router to your app, creating it for example like this:
```ts
const router = await createRouter({
- logger,
+ logger: env.logger,
appPackageName: 'example-app',
});
```
diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json
index 3ff2b14a19..7a57385afe 100644
--- a/plugins/app-backend/package.json
+++ b/plugins/app-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-app-backend",
"description": "A Backstage backend plugin that serves the Backstage frontend app",
- "version": "0.3.29-next.0",
+ "version": "0.3.29",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -33,8 +33,8 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.13.0-next.0",
- "@backstage/config-loader": "^0.9.7-next.0",
+ "@backstage/backend-common": "^0.13.0",
+ "@backstage/config-loader": "^0.9.7",
"@backstage/config": "^0.1.15",
"@backstage/types": "^0.1.3",
"@types/express": "^4.17.6",
@@ -50,8 +50,8 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/backend-test-utils": "^0.1.21-next.0",
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/backend-test-utils": "^0.1.21",
+ "@backstage/cli": "^0.15.2",
"@backstage/types": "^0.1.3",
"@types/supertest": "^2.0.8",
"mock-fs": "^5.1.0",
diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md
index 6ee4b7d146..13761f4e6c 100644
--- a/plugins/auth-backend/CHANGELOG.md
+++ b/plugins/auth-backend/CHANGELOG.md
@@ -1,5 +1,19 @@
# @backstage/plugin-auth-backend
+## 0.12.1
+
+### Patch Changes
+
+- ab7cd7d70e: Do some groundwork for supporting the `better-sqlite3` driver, to maybe eventually replace `@vscode/sqlite3` (#9912)
+- e0a69ba49f: build(deps): bump `fs-extra` from 9.1.0 to 10.0.1
+- bf95bb806c: Remove usages of now-removed `CatalogApi.getEntityByName`
+- 3c2bc73901: Use `setupRequestMockHandlers` from `@backstage/backend-test-utils`
+- Updated dependencies
+ - @backstage/backend-common@0.13.0
+ - @backstage/catalog-model@0.13.0
+ - @backstage/catalog-client@0.9.0
+ - @backstage/plugin-auth-node@0.1.5
+
## 0.12.1-next.0
### Patch Changes
diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json
index 5a1df93c93..acf5a1eac6 100644
--- a/plugins/auth-backend/package.json
+++ b/plugins/auth-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-auth-backend",
"description": "A Backstage backend plugin that handles authentication",
- "version": "0.12.1-next.0",
+ "version": "0.12.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -33,10 +33,10 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/plugin-auth-node": "^0.1.5-next.0",
- "@backstage/backend-common": "^0.13.0-next.0",
- "@backstage/catalog-client": "^0.9.0-next.0",
- "@backstage/catalog-model": "^0.13.0-next.0",
+ "@backstage/plugin-auth-node": "^0.1.5",
+ "@backstage/backend-common": "^0.13.0",
+ "@backstage/catalog-client": "^0.9.0",
+ "@backstage/catalog-model": "^0.13.0",
"@backstage/config": "^0.1.15",
"@backstage/errors": "^0.2.2",
"@backstage/types": "^0.1.3",
@@ -76,8 +76,8 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/backend-test-utils": "^0.1.21-next.0",
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/backend-test-utils": "^0.1.21",
+ "@backstage/cli": "^0.15.2",
"@types/body-parser": "^1.19.0",
"@types/cookie-parser": "^1.4.2",
"@types/express-session": "^1.17.2",
diff --git a/plugins/auth-backend/src/identity/DatabaseKeyStore.test.ts b/plugins/auth-backend/src/identity/DatabaseKeyStore.test.ts
index bb4c129e41..fa7b251780 100644
--- a/plugins/auth-backend/src/identity/DatabaseKeyStore.test.ts
+++ b/plugins/auth-backend/src/identity/DatabaseKeyStore.test.ts
@@ -20,7 +20,7 @@ import { DateTime } from 'luxon';
function createDB() {
const knex = Knex({
- client: 'sqlite3',
+ client: 'better-sqlite3',
connection: ':memory:',
useNullAsDefault: true,
});
diff --git a/plugins/auth-backend/src/identity/KeyStores.test.ts b/plugins/auth-backend/src/identity/KeyStores.test.ts
index f30263e27f..375db4698b 100644
--- a/plugins/auth-backend/src/identity/KeyStores.test.ts
+++ b/plugins/auth-backend/src/identity/KeyStores.test.ts
@@ -49,7 +49,7 @@ describe('KeyStores', () => {
const config = new ConfigReader({
backend: {
database: {
- client: 'sqlite3',
+ client: 'better-sqlite3',
connection: ':memory:',
},
},
diff --git a/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.test.ts b/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.test.ts
index b99c8a7615..587b433ca1 100644
--- a/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.test.ts
+++ b/plugins/auth-backend/src/lib/catalog/CatalogIdentityClient.test.ts
@@ -80,11 +80,6 @@ describe('CatalogIdentityClient', () => {
{
type: RELATION_MEMBER_OF,
targetRef: 'group:default/team-a',
- target: {
- kind: 'group',
- namespace: 'default',
- name: 'team-a',
- },
},
],
},
@@ -102,11 +97,6 @@ describe('CatalogIdentityClient', () => {
{
type: RELATION_MEMBER_OF,
targetRef: 'group:reality/screen-actors-guild',
- target: {
- kind: 'group',
- namespace: 'reality',
- name: 'screen-actors-guild',
- },
},
],
},
diff --git a/plugins/auth-backend/src/service/standaloneServer.ts b/plugins/auth-backend/src/service/standaloneServer.ts
index 4e416e8dc7..16ebbc9345 100644
--- a/plugins/auth-backend/src/service/standaloneServer.ts
+++ b/plugins/auth-backend/src/service/standaloneServer.ts
@@ -39,7 +39,7 @@ export async function startStandaloneServer(
const database = useHotMemoize(module, () => {
const knex = Knex({
- client: 'sqlite3',
+ client: 'better-sqlite3',
connection: ':memory:',
useNullAsDefault: true,
});
diff --git a/plugins/auth-node/CHANGELOG.md b/plugins/auth-node/CHANGELOG.md
index dbb8316cf2..1e0dc95f19 100644
--- a/plugins/auth-node/CHANGELOG.md
+++ b/plugins/auth-node/CHANGELOG.md
@@ -1,5 +1,13 @@
# @backstage/plugin-auth-node
+## 0.1.5
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.13.0
+ - @backstage/catalog-model@0.13.0
+
## 0.1.5-next.0
### Patch Changes
diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json
index a302feca9e..ce4fda9cf0 100644
--- a/plugins/auth-node/package.json
+++ b/plugins/auth-node/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-auth-node",
- "version": "0.1.5-next.0",
+ "version": "0.1.5",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -23,8 +23,8 @@
"start": "backstage-cli package start"
},
"dependencies": {
- "@backstage/backend-common": "^0.13.0-next.0",
- "@backstage/catalog-model": "^0.13.0-next.0",
+ "@backstage/backend-common": "^0.13.0",
+ "@backstage/catalog-model": "^0.13.0",
"@backstage/config": "^0.1.15",
"@backstage/errors": "^0.2.2",
"jose": "^1.27.1",
@@ -32,7 +32,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"msw": "^0.35.0",
"uuid": "^8.0.0"
},
diff --git a/plugins/azure-devops-backend/CHANGELOG.md b/plugins/azure-devops-backend/CHANGELOG.md
index c841ec0e4d..43ab9e2d02 100644
--- a/plugins/azure-devops-backend/CHANGELOG.md
+++ b/plugins/azure-devops-backend/CHANGELOG.md
@@ -1,5 +1,12 @@
# @backstage/plugin-azure-devops-backend
+## 0.3.8
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.13.0
+
## 0.3.8-next.0
### Patch Changes
diff --git a/plugins/azure-devops-backend/README.md b/plugins/azure-devops-backend/README.md
index 79db9f5ff1..e71021471b 100644
--- a/plugins/azure-devops-backend/README.md
+++ b/plugins/azure-devops-backend/README.md
@@ -43,11 +43,13 @@ Here's how to get the backend up and running:
import { Router } from 'express';
import type { PluginEnvironment } from '../types';
- export default function createPlugin({
- logger,
- config,
- }: PluginEnvironment): Promise {
- return createRouter({ logger, config });
+ export default function createPlugin(
+ env: PluginEnvironment,
+ ): Promise {
+ return createRouter({
+ logger: env.logger,
+ config: env.config,
+ });
}
```
diff --git a/plugins/azure-devops-backend/package.json b/plugins/azure-devops-backend/package.json
index 6a94a2b4d3..6ee5e71688 100644
--- a/plugins/azure-devops-backend/package.json
+++ b/plugins/azure-devops-backend/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-azure-devops-backend",
- "version": "0.3.8-next.0",
+ "version": "0.3.8",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -23,7 +23,7 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.13.0-next.0",
+ "@backstage/backend-common": "^0.13.0",
"@backstage/config": "^0.1.15",
"@backstage/plugin-azure-devops-common": "^0.2.2",
"@types/express": "^4.17.6",
@@ -35,7 +35,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@types/supertest": "^2.0.8",
"supertest": "^6.1.6",
"msw": "^0.35.0"
diff --git a/plugins/azure-devops/CHANGELOG.md b/plugins/azure-devops/CHANGELOG.md
index 339539a7ea..1154f40058 100644
--- a/plugins/azure-devops/CHANGELOG.md
+++ b/plugins/azure-devops/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-azure-devops
+## 0.1.18
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.9.0
+ - @backstage/core-components@0.9.1
+ - @backstage/catalog-model@0.13.0
+
## 0.1.18-next.0
### Patch Changes
diff --git a/plugins/azure-devops/README.md b/plugins/azure-devops/README.md
index e4b81fe97c..e06c3c81ec 100644
--- a/plugins/azure-devops/README.md
+++ b/plugins/azure-devops/README.md
@@ -94,7 +94,7 @@ To get the Azure Pipelines component working you'll need to do the following two
```
- 2. If you are using the ``dev.azure.com/project` and `dev.azure.com/build-definition` annotations then you'll want to do this:
+ 2. If you are using the `dev.azure.com/project` and `dev.azure.com/build-definition` annotations then you'll want to do this:
```tsx
// In packages/app/src/components/catalog/EntityPage.tsx
diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json
index fcfc97ce9d..d28efb84cc 100644
--- a/plugins/azure-devops/package.json
+++ b/plugins/azure-devops/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-azure-devops",
- "version": "0.1.18-next.0",
+ "version": "0.1.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -30,12 +30,12 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.13.0-next.0",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/catalog-model": "^0.13.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
"@backstage/errors": "^0.2.2",
"@backstage/plugin-azure-devops-common": "^0.2.2",
- "@backstage/plugin-catalog-react": "^0.9.0-next.0",
+ "@backstage/plugin-catalog-react": "^0.9.0",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -49,12 +49,12 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/dev-utils": "^0.2.25",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
diff --git a/plugins/badges-backend/CHANGELOG.md b/plugins/badges-backend/CHANGELOG.md
index a26b98d2e6..e55338dd68 100644
--- a/plugins/badges-backend/CHANGELOG.md
+++ b/plugins/badges-backend/CHANGELOG.md
@@ -1,5 +1,15 @@
# @backstage/plugin-badges-backend
+## 0.1.23
+
+### Patch Changes
+
+- bf95bb806c: Remove usages of now-removed `CatalogApi.getEntityByName`
+- Updated dependencies
+ - @backstage/backend-common@0.13.0
+ - @backstage/catalog-model@0.13.0
+ - @backstage/catalog-client@0.9.0
+
## 0.1.23-next.0
### Patch Changes
diff --git a/plugins/badges-backend/README.md b/plugins/badges-backend/README.md
index 73f72d32ac..bdbfac3fa5 100644
--- a/plugins/badges-backend/README.md
+++ b/plugins/badges-backend/README.md
@@ -20,15 +20,15 @@ import {
createRouter,
createDefaultBadgeFactories,
} from '@backstage/plugin-badges-backend';
+import { Router } from 'express';
import { PluginEnvironment } from '../types';
-export default async function createPlugin({
- config,
- discovery,
-}: PluginEnvironment) {
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
return await createRouter({
- config,
- discovery,
+ config: env.config,
+ discovery: env.discovery,
badgeFactories: createDefaultBadgeFactories(),
});
}
diff --git a/plugins/badges-backend/package.json b/plugins/badges-backend/package.json
index d5e3fe3dcf..9eaa3f084f 100644
--- a/plugins/badges-backend/package.json
+++ b/plugins/badges-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-badges-backend",
"description": "A Backstage backend plugin that generates README badges for your entities",
- "version": "0.1.23-next.0",
+ "version": "0.1.23",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -34,9 +34,9 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.13.0-next.0",
- "@backstage/catalog-client": "^0.9.0-next.0",
- "@backstage/catalog-model": "^0.13.0-next.0",
+ "@backstage/backend-common": "^0.13.0",
+ "@backstage/catalog-client": "^0.9.0",
+ "@backstage/catalog-model": "^0.13.0",
"@backstage/config": "^0.1.15",
"@backstage/errors": "^0.2.2",
"@types/express": "^4.17.6",
@@ -48,7 +48,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@types/supertest": "^2.0.8",
"supertest": "^6.1.3"
},
diff --git a/plugins/badges-backend/src/types.ts b/plugins/badges-backend/src/types.ts
index 4342a5af40..0467b18155 100644
--- a/plugins/badges-backend/src/types.ts
+++ b/plugins/badges-backend/src/types.ts
@@ -44,7 +44,7 @@ export interface Badge {
link?: string;
/** Badge message */
message: string;
- /** Badge style (apperance). One of "plastic", "flat", "flat-square", "for-the-badge" and "social" */
+ /** Badge style (appearance). One of "plastic", "flat", "flat-square", "for-the-badge" and "social" */
style?: BadgeStyle;
}
diff --git a/plugins/badges/CHANGELOG.md b/plugins/badges/CHANGELOG.md
index df3b511cb7..dd2ffd1747 100644
--- a/plugins/badges/CHANGELOG.md
+++ b/plugins/badges/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-badges
+## 0.2.26
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.9.0
+ - @backstage/core-components@0.9.1
+ - @backstage/catalog-model@0.13.0
+
## 0.2.26-next.0
### Patch Changes
diff --git a/plugins/badges/package.json b/plugins/badges/package.json
index c058989e94..718d38c00a 100644
--- a/plugins/badges/package.json
+++ b/plugins/badges/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-badges",
"description": "A Backstage plugin that generates README badges for your entities",
- "version": "0.2.26-next.0",
+ "version": "0.2.26",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -30,11 +30,11 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.13.0-next.0",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/catalog-model": "^0.13.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
"@backstage/errors": "^0.2.2",
- "@backstage/plugin-catalog-react": "^0.9.0-next.0",
+ "@backstage/plugin-catalog-react": "^0.9.0",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -46,12 +46,12 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/dev-utils": "^0.2.25",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
diff --git a/plugins/bazaar-backend/CHANGELOG.md b/plugins/bazaar-backend/CHANGELOG.md
index e161516d5f..4f4480ab62 100644
--- a/plugins/bazaar-backend/CHANGELOG.md
+++ b/plugins/bazaar-backend/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-bazaar-backend
+## 0.1.13
+
+### Patch Changes
+
+- ab7cd7d70e: Do some groundwork for supporting the `better-sqlite3` driver, to maybe eventually replace `@vscode/sqlite3` (#9912)
+- Updated dependencies
+ - @backstage/backend-common@0.13.0
+ - @backstage/backend-test-utils@0.1.21
+
## 0.1.13-next.0
### Patch Changes
diff --git a/plugins/bazaar-backend/README.md b/plugins/bazaar-backend/README.md
index 82c1376d8b..01b240e0e3 100644
--- a/plugins/bazaar-backend/README.md
+++ b/plugins/bazaar-backend/README.md
@@ -19,13 +19,16 @@ You'll need to add the plugin to the router in your `backend` package. You can d
```tsx
import { PluginEnvironment } from '../types';
import { createRouter } from '@backstage/plugin-bazaar-backend';
+import { Router } from 'express';
-export default async function createPlugin({
- logger,
- database,
- config,
-}: PluginEnvironment) {
- return await createRouter({ logger, config, database });
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
+ return await createRouter({
+ logger: env.logger,
+ config: env.config,
+ database: env.database,
+ });
}
```
diff --git a/plugins/bazaar-backend/package.json b/plugins/bazaar-backend/package.json
index 6224e6d869..2052d52d59 100644
--- a/plugins/bazaar-backend/package.json
+++ b/plugins/bazaar-backend/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-bazaar-backend",
- "version": "0.1.13-next.0",
+ "version": "0.1.13",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -23,8 +23,8 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.13.0-next.0",
- "@backstage/backend-test-utils": "^0.1.21-next.0",
+ "@backstage/backend-common": "^0.13.0",
+ "@backstage/backend-test-utils": "^0.1.21",
"@backstage/config": "^0.1.15",
"@types/express": "^4.17.6",
"express": "^4.17.1",
@@ -34,7 +34,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0"
+ "@backstage/cli": "^0.15.2"
},
"files": [
"dist",
diff --git a/plugins/bazaar-backend/src/service/standaloneServer.ts b/plugins/bazaar-backend/src/service/standaloneServer.ts
index 19b0d68039..e8a49fbf5d 100644
--- a/plugins/bazaar-backend/src/service/standaloneServer.ts
+++ b/plugins/bazaar-backend/src/service/standaloneServer.ts
@@ -38,7 +38,7 @@ export async function startStandaloneServer(
const db = useHotMemoize(module, () => {
const knex = knexFactory({
- client: 'sqlite3',
+ client: 'better-sqlite3',
connection: ':memory:',
useNullAsDefault: true,
});
diff --git a/plugins/bazaar/CHANGELOG.md b/plugins/bazaar/CHANGELOG.md
index 1ad604fd9d..4c139005bf 100644
--- a/plugins/bazaar/CHANGELOG.md
+++ b/plugins/bazaar/CHANGELOG.md
@@ -1,5 +1,17 @@
# @backstage/plugin-bazaar
+## 0.1.17
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/cli@0.15.2
+ - @backstage/plugin-catalog@0.10.0
+ - @backstage/plugin-catalog-react@0.9.0
+ - @backstage/core-components@0.9.1
+ - @backstage/catalog-model@0.13.0
+ - @backstage/catalog-client@0.9.0
+
## 0.1.17-next.0
### Patch Changes
diff --git a/plugins/bazaar/package.json b/plugins/bazaar/package.json
index 6e44067bd7..9bca7c1c6c 100644
--- a/plugins/bazaar/package.json
+++ b/plugins/bazaar/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-bazaar",
- "version": "0.1.17-next.0",
+ "version": "0.1.17",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -24,13 +24,13 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/catalog-client": "^0.9.0-next.0",
- "@backstage/catalog-model": "^0.13.0-next.0",
- "@backstage/cli": "^0.15.2-next.0",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/catalog-client": "^0.9.0",
+ "@backstage/catalog-model": "^0.13.0",
+ "@backstage/cli": "^0.15.2",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
- "@backstage/plugin-catalog": "^0.10.0-next.0",
- "@backstage/plugin-catalog-react": "^0.9.0-next.0",
+ "@backstage/plugin-catalog": "^0.10.0",
+ "@backstage/plugin-catalog-react": "^0.9.0",
"@date-io/luxon": "1.x",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -47,8 +47,8 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/cli": "^0.15.2",
+ "@backstage/dev-utils": "^0.2.25",
"@testing-library/jest-dom": "^5.10.1",
"cross-fetch": "^3.1.5"
},
diff --git a/plugins/bitrise/CHANGELOG.md b/plugins/bitrise/CHANGELOG.md
index 26ce2d20b1..2442a96f5f 100644
--- a/plugins/bitrise/CHANGELOG.md
+++ b/plugins/bitrise/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-bitrise
+## 0.1.29
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.9.0
+ - @backstage/core-components@0.9.1
+ - @backstage/catalog-model@0.13.0
+
## 0.1.29-next.0
### Patch Changes
diff --git a/plugins/bitrise/package.json b/plugins/bitrise/package.json
index 16b58ba129..1f599e3afe 100644
--- a/plugins/bitrise/package.json
+++ b/plugins/bitrise/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-bitrise",
"description": "A Backstage plugin that integrates towards Bitrise",
- "version": "0.1.29-next.0",
+ "version": "0.1.29",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -24,10 +24,10 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.13.0-next.0",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/catalog-model": "^0.13.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
- "@backstage/plugin-catalog-react": "^0.9.0-next.0",
+ "@backstage/plugin-catalog-react": "^0.9.0",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -43,12 +43,12 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/dev-utils": "^0.2.25",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
diff --git a/plugins/catalog-backend-module-aws/CHANGELOG.md b/plugins/catalog-backend-module-aws/CHANGELOG.md
index 8e15c16546..f20bd9fce2 100644
--- a/plugins/catalog-backend-module-aws/CHANGELOG.md
+++ b/plugins/catalog-backend-module-aws/CHANGELOG.md
@@ -1,5 +1,15 @@
# @backstage/plugin-catalog-backend-module-aws
+## 0.1.2
+
+### Patch Changes
+
+- f115a7f8fd: Added `AwsS3DiscoveryProcessor`, which was moved here from `@backstage/plugin-catalog-backend` where it previously resided.
+- Updated dependencies
+ - @backstage/backend-common@0.13.0
+ - @backstage/plugin-catalog-backend@0.24.0
+ - @backstage/catalog-model@0.13.0
+
## 0.1.2-next.0
### Patch Changes
diff --git a/plugins/catalog-backend-module-aws/package.json b/plugins/catalog-backend-module-aws/package.json
index 72324483d9..d49e229b47 100644
--- a/plugins/catalog-backend-module-aws/package.json
+++ b/plugins/catalog-backend-module-aws/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend-module-aws",
"description": "A Backstage catalog backend module that helps integrate towards AWS",
- "version": "0.1.2-next.0",
+ "version": "0.1.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -33,11 +33,11 @@
"start": "backstage-cli package start"
},
"dependencies": {
- "@backstage/backend-common": "^0.13.0-next.0",
- "@backstage/catalog-model": "^0.13.0-next.0",
+ "@backstage/backend-common": "^0.13.0",
+ "@backstage/catalog-model": "^0.13.0",
"@backstage/config": "^0.1.15",
"@backstage/errors": "^0.2.2",
- "@backstage/plugin-catalog-backend": "^0.24.0-next.0",
+ "@backstage/plugin-catalog-backend": "^0.24.0",
"@backstage/types": "^0.1.3",
"aws-sdk": "^2.840.0",
"lodash": "^4.17.21",
@@ -45,7 +45,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@types/lodash": "^4.14.151",
"aws-sdk-mock": "^5.2.1",
"yaml": "^1.9.2"
diff --git a/plugins/catalog-backend-module-azure/.eslintrc.js b/plugins/catalog-backend-module-azure/.eslintrc.js
index 16a033dbc6..e2a53a6ad2 100644
--- a/plugins/catalog-backend-module-azure/.eslintrc.js
+++ b/plugins/catalog-backend-module-azure/.eslintrc.js
@@ -1,3 +1 @@
-module.exports = {
- extends: [require.resolve('@backstage/cli/config/eslint.backend')],
-};
+module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
diff --git a/plugins/catalog-backend-module-azure/CHANGELOG.md b/plugins/catalog-backend-module-azure/CHANGELOG.md
index f6f876ca9f..e5cce00527 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.0
+
+### Minor Changes
+
+- 66ba5d9023: Added package, moving out azure specific functionality from the catalog-backend
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.13.0
+ - @backstage/plugin-catalog-backend@0.24.0
+ - @backstage/catalog-model@0.13.0
+
## 0.1.0-next.0
### Minor Changes
diff --git a/plugins/catalog-backend-module-azure/package.json b/plugins/catalog-backend-module-azure/package.json
index 91e421633d..1a6a70ad5e 100644
--- a/plugins/catalog-backend-module-azure/package.json
+++ b/plugins/catalog-backend-module-azure/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend-module-azure",
"description": "A Backstage catalog backend module that helps integrate towards Azure",
- "version": "0.1.0-next.0",
+ "version": "0.1.0",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -33,12 +33,12 @@
"start": "backstage-cli package start"
},
"dependencies": {
- "@backstage/backend-common": "^0.13.0-next.0",
- "@backstage/catalog-model": "^0.13.0-next.0",
+ "@backstage/backend-common": "^0.13.0",
+ "@backstage/catalog-model": "^0.13.0",
"@backstage/config": "^0.1.15",
"@backstage/errors": "^0.2.2",
"@backstage/integration": "^0.8.0",
- "@backstage/plugin-catalog-backend": "^0.24.0-next.0",
+ "@backstage/plugin-catalog-backend": "^0.24.0",
"@backstage/types": "^0.1.3",
"lodash": "^4.17.21",
"msw": "^0.35.0",
@@ -46,8 +46,8 @@
"winston": "^3.2.1"
},
"devDependencies": {
- "@backstage/backend-test-utils": "^0.1.21-next.0",
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/backend-test-utils": "^0.1.21",
+ "@backstage/cli": "^0.15.2",
"@types/lodash": "^4.14.151"
},
"files": [
diff --git a/plugins/catalog-backend-module-bitbucket/.eslintrc.js b/plugins/catalog-backend-module-bitbucket/.eslintrc.js
new file mode 100644
index 0000000000..e2a53a6ad2
--- /dev/null
+++ b/plugins/catalog-backend-module-bitbucket/.eslintrc.js
@@ -0,0 +1 @@
+module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
diff --git a/plugins/catalog-backend-module-bitbucket/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket/CHANGELOG.md
new file mode 100644
index 0000000000..3852f83063
--- /dev/null
+++ b/plugins/catalog-backend-module-bitbucket/CHANGELOG.md
@@ -0,0 +1,14 @@
+# @backstage/plugin-catalog-backend-module-bitbucket
+
+## 0.1.0
+
+### Minor Changes
+
+- 47a5ae5dd2: Added package, moving out Bitbucket specific functionality from the catalog-backend
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.13.0
+ - @backstage/plugin-catalog-backend@0.24.0
+ - @backstage/catalog-model@0.13.0
diff --git a/plugins/catalog-backend-module-bitbucket/README.md b/plugins/catalog-backend-module-bitbucket/README.md
new file mode 100644
index 0000000000..ae22c7a427
--- /dev/null
+++ b/plugins/catalog-backend-module-bitbucket/README.md
@@ -0,0 +1,8 @@
+# Catalog Backend Module for Bitbucket
+
+This is an extension module to the plugin-catalog-backend plugin, providing extensions targeted at Bitbucket offerings.
+
+## Getting started
+
+See [Backstage documentation](https://backstage.io/docs/integrations/bitbucket/discovery) for details on how to install
+and configure the plugin.
diff --git a/plugins/catalog-backend-module-bitbucket/api-report.md b/plugins/catalog-backend-module-bitbucket/api-report.md
new file mode 100644
index 0000000000..34acd6e76d
--- /dev/null
+++ b/plugins/catalog-backend-module-bitbucket/api-report.md
@@ -0,0 +1,47 @@
+## API Report File for "@backstage/plugin-catalog-backend-module-bitbucket"
+
+> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
+
+```ts
+import { BitbucketIntegration } from '@backstage/integration';
+import { CatalogProcessor } from '@backstage/plugin-catalog-backend';
+import { CatalogProcessorEmit } from '@backstage/plugin-catalog-backend';
+import { CatalogProcessorResult } from '@backstage/plugin-catalog-backend';
+import { Config } from '@backstage/config';
+import { LocationSpec } from '@backstage/plugin-catalog-backend';
+import { Logger } from 'winston';
+import { ScmIntegrationRegistry } from '@backstage/integration';
+
+// @public (undocumented)
+export class BitbucketDiscoveryProcessor implements CatalogProcessor {
+ constructor(options: {
+ integrations: ScmIntegrationRegistry;
+ parser?: BitbucketRepositoryParser;
+ logger: Logger;
+ });
+ // (undocumented)
+ static fromConfig(
+ config: Config,
+ options: {
+ parser?: BitbucketRepositoryParser;
+ logger: Logger;
+ },
+ ): BitbucketDiscoveryProcessor;
+ // (undocumented)
+ getProcessorName(): string;
+ // (undocumented)
+ readLocation(
+ location: LocationSpec,
+ _optional: boolean,
+ emit: CatalogProcessorEmit,
+ ): Promise;
+}
+
+// @public
+export type BitbucketRepositoryParser = (options: {
+ integration: BitbucketIntegration;
+ target: string;
+ presence?: 'optional' | 'required';
+ logger: Logger;
+}) => AsyncIterable;
+```
diff --git a/plugins/catalog-backend-module-bitbucket/package.json b/plugins/catalog-backend-module-bitbucket/package.json
new file mode 100644
index 0000000000..4980eed0fd
--- /dev/null
+++ b/plugins/catalog-backend-module-bitbucket/package.json
@@ -0,0 +1,56 @@
+{
+ "name": "@backstage/plugin-catalog-backend-module-bitbucket",
+ "description": "A Backstage catalog backend module that helps integrate towards Bitbucket",
+ "version": "0.1.0",
+ "main": "src/index.ts",
+ "types": "src/index.ts",
+ "license": "Apache-2.0",
+ "private": false,
+ "publishConfig": {
+ "access": "public",
+ "main": "dist/index.cjs.js",
+ "types": "dist/index.d.ts"
+ },
+ "backstage": {
+ "role": "backend-plugin-module"
+ },
+ "homepage": "https://backstage.io",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/backstage/backstage",
+ "directory": "plugins/catalog-backend-module-bitbucket"
+ },
+ "keywords": [
+ "backstage"
+ ],
+ "scripts": {
+ "build": "backstage-cli package build",
+ "lint": "backstage-cli package lint",
+ "test": "backstage-cli package test",
+ "prepack": "backstage-cli package prepack",
+ "postpack": "backstage-cli package postpack",
+ "clean": "backstage-cli package clean",
+ "start": "backstage-cli package start"
+ },
+ "dependencies": {
+ "@backstage/backend-common": "^0.13.0",
+ "@backstage/catalog-model": "^0.13.0",
+ "@backstage/config": "^0.1.15",
+ "@backstage/errors": "^0.2.2",
+ "@backstage/integration": "^0.8.0",
+ "@backstage/plugin-catalog-backend": "^0.24.0",
+ "@backstage/types": "^0.1.3",
+ "lodash": "^4.17.21",
+ "msw": "^0.35.0",
+ "node-fetch": "^2.6.7",
+ "winston": "^3.2.1"
+ },
+ "devDependencies": {
+ "@backstage/backend-test-utils": "^0.1.21",
+ "@backstage/cli": "^0.15.2",
+ "@types/lodash": "^4.14.151"
+ },
+ "files": [
+ "dist"
+ ]
+}
diff --git a/plugins/catalog-backend/src/modules/bitbucket/BitbucketDiscoveryProcessor.test.ts b/plugins/catalog-backend-module-bitbucket/src/BitbucketDiscoveryProcessor.test.ts
similarity index 99%
rename from plugins/catalog-backend/src/modules/bitbucket/BitbucketDiscoveryProcessor.test.ts
rename to plugins/catalog-backend-module-bitbucket/src/BitbucketDiscoveryProcessor.test.ts
index a25a5da89e..5f441b787c 100644
--- a/plugins/catalog-backend/src/modules/bitbucket/BitbucketDiscoveryProcessor.test.ts
+++ b/plugins/catalog-backend-module-bitbucket/src/BitbucketDiscoveryProcessor.test.ts
@@ -15,12 +15,15 @@
*/
import { getVoidLogger } from '@backstage/backend-common';
-import { BitbucketDiscoveryProcessor } from './BitbucketDiscoveryProcessor';
import { ConfigReader } from '@backstage/config';
+import {
+ LocationSpec,
+ processingResult,
+} from '@backstage/plugin-catalog-backend';
import { RequestHandler, rest } from 'msw';
import { setupServer } from 'msw/node';
+import { BitbucketDiscoveryProcessor } from './BitbucketDiscoveryProcessor';
import { BitbucketRepository20, PagedResponse, PagedResponse20 } from './lib';
-import { LocationSpec, processingResult } from '../../api';
const server = setupServer();
diff --git a/plugins/catalog-backend/src/modules/bitbucket/BitbucketDiscoveryProcessor.ts b/plugins/catalog-backend-module-bitbucket/src/BitbucketDiscoveryProcessor.ts
similarity index 93%
rename from plugins/catalog-backend/src/modules/bitbucket/BitbucketDiscoveryProcessor.ts
rename to plugins/catalog-backend-module-bitbucket/src/BitbucketDiscoveryProcessor.ts
index 49fa05a762..5553de7f02 100644
--- a/plugins/catalog-backend/src/modules/bitbucket/BitbucketDiscoveryProcessor.ts
+++ b/plugins/catalog-backend-module-bitbucket/src/BitbucketDiscoveryProcessor.ts
@@ -14,28 +14,27 @@
* limitations under the License.
*/
-import { Logger } from 'winston';
import { Config } from '@backstage/config';
-
import {
BitbucketIntegration,
ScmIntegrationRegistry,
ScmIntegrations,
} from '@backstage/integration';
+import {
+ CatalogProcessor,
+ CatalogProcessorEmit,
+ LocationSpec,
+} from '@backstage/plugin-catalog-backend';
+import { Logger } from 'winston';
import {
BitbucketClient,
+ BitbucketRepository,
+ BitbucketRepository20,
+ BitbucketRepositoryParser,
defaultRepositoryParser,
paginated,
paginated20,
- BitbucketRepository,
- BitbucketRepository20,
} from './lib';
-import {
- CatalogProcessor,
- CatalogProcessorEmit,
- CatalogProcessorResult,
- LocationSpec,
-} from '../../api';
const DEFAULT_BRANCH = 'master';
const DEFAULT_CATALOG_LOCATION = '/catalog-info.yaml';
@@ -43,23 +42,13 @@ const DEFAULT_CATALOG_LOCATION = '/catalog-info.yaml';
/** @public */
export class BitbucketDiscoveryProcessor implements CatalogProcessor {
private readonly integrations: ScmIntegrationRegistry;
- private readonly parser: (options: {
- integration: BitbucketIntegration;
- target: string;
- presence?: 'optional' | 'required';
- logger: Logger;
- }) => AsyncIterable;
+ private readonly parser: BitbucketRepositoryParser;
private readonly logger: Logger;
static fromConfig(
config: Config,
options: {
- parser?: (options: {
- integration: BitbucketIntegration;
- target: string;
- presence?: 'optional' | 'required';
- logger: Logger;
- }) => AsyncIterable;
+ parser?: BitbucketRepositoryParser;
logger: Logger;
},
) {
@@ -73,12 +62,7 @@ export class BitbucketDiscoveryProcessor implements CatalogProcessor {
constructor(options: {
integrations: ScmIntegrationRegistry;
- parser?: (options: {
- integration: BitbucketIntegration;
- target: string;
- presence?: 'optional' | 'required';
- logger: Logger;
- }) => AsyncIterable;
+ parser?: BitbucketRepositoryParser;
logger: Logger;
}) {
this.integrations = options.integrations;
@@ -123,7 +107,7 @@ export class BitbucketDiscoveryProcessor implements CatalogProcessor {
const { scanned, matches } = isBitbucketCloud
? await this.processCloudRepositories(processOptions)
- : await this.processOrganisationRepositories(processOptions);
+ : await this.processOrganizationRepositories(processOptions);
const duration = ((Date.now() - startTimestamp) / 1000).toFixed(1);
this.logger.debug(
@@ -160,7 +144,7 @@ export class BitbucketDiscoveryProcessor implements CatalogProcessor {
};
}
- private async processOrganisationRepositories(
+ private async processOrganizationRepositories(
options: ProcessOptions,
): Promise {
const { client, location, integration, emit } = options;
diff --git a/plugins/catalog-backend-module-bitbucket/src/index.ts b/plugins/catalog-backend-module-bitbucket/src/index.ts
new file mode 100644
index 0000000000..5bbda25dea
--- /dev/null
+++ b/plugins/catalog-backend-module-bitbucket/src/index.ts
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+/**
+ * A Backstage catalog backend module that helps integrate towards Bitbucket
+ *
+ * @packageDocumentation
+ */
+
+export { BitbucketDiscoveryProcessor } from './BitbucketDiscoveryProcessor';
+export type { BitbucketRepositoryParser } from './lib/BitbucketRepositoryParser';
diff --git a/plugins/catalog-backend/src/modules/bitbucket/lib/BitbucketRepositoryParser.test.ts b/plugins/catalog-backend-module-bitbucket/src/lib/BitbucketRepositoryParser.test.ts
similarity index 95%
rename from plugins/catalog-backend/src/modules/bitbucket/lib/BitbucketRepositoryParser.test.ts
rename to plugins/catalog-backend-module-bitbucket/src/lib/BitbucketRepositoryParser.test.ts
index 9f2d8b2daa..58845fc3d1 100644
--- a/plugins/catalog-backend/src/modules/bitbucket/lib/BitbucketRepositoryParser.test.ts
+++ b/plugins/catalog-backend-module-bitbucket/src/lib/BitbucketRepositoryParser.test.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-import { processingResult } from '../../../api';
+import { processingResult } from '@backstage/plugin-catalog-backend';
import { defaultRepositoryParser } from './BitbucketRepositoryParser';
describe('BitbucketRepositoryParser', () => {
diff --git a/plugins/catalog-backend/src/modules/bitbucket/lib/BitbucketRepositoryParser.ts b/plugins/catalog-backend-module-bitbucket/src/lib/BitbucketRepositoryParser.ts
similarity index 88%
rename from plugins/catalog-backend/src/modules/bitbucket/lib/BitbucketRepositoryParser.ts
rename to plugins/catalog-backend-module-bitbucket/src/lib/BitbucketRepositoryParser.ts
index 8fdcb8f73a..57a162e1e4 100644
--- a/plugins/catalog-backend/src/modules/bitbucket/lib/BitbucketRepositoryParser.ts
+++ b/plugins/catalog-backend-module-bitbucket/src/lib/BitbucketRepositoryParser.ts
@@ -15,12 +15,17 @@
*/
import { BitbucketIntegration } from '@backstage/integration';
+import {
+ CatalogProcessorResult,
+ processingResult,
+} from '@backstage/plugin-catalog-backend';
import { Logger } from 'winston';
-import { CatalogProcessorResult, processingResult } from '../../../api';
/**
+ * A custom callback that reacts to finding a repository by yielding processing
+ * results.
+ *
* @public
- * @deprecated type inlined.
*/
export type BitbucketRepositoryParser = (options: {
integration: BitbucketIntegration;
diff --git a/plugins/catalog-backend/src/modules/bitbucket/lib/client.ts b/plugins/catalog-backend-module-bitbucket/src/lib/client.ts
similarity index 100%
rename from plugins/catalog-backend/src/modules/bitbucket/lib/client.ts
rename to plugins/catalog-backend-module-bitbucket/src/lib/client.ts
index 0ef6558719..a3ee4ab8a6 100644
--- a/plugins/catalog-backend/src/modules/bitbucket/lib/client.ts
+++ b/plugins/catalog-backend-module-bitbucket/src/lib/client.ts
@@ -14,11 +14,11 @@
* limitations under the License.
*/
-import fetch from 'node-fetch';
import {
BitbucketIntegrationConfig,
getBitbucketRequestOptions,
} from '@backstage/integration';
+import fetch from 'node-fetch';
import { BitbucketRepository20 } from './types';
export class BitbucketClient {
diff --git a/plugins/catalog-backend/src/modules/bitbucket/lib/index.ts b/plugins/catalog-backend-module-bitbucket/src/lib/index.ts
similarity index 100%
rename from plugins/catalog-backend/src/modules/bitbucket/lib/index.ts
rename to plugins/catalog-backend-module-bitbucket/src/lib/index.ts
index a819bb3c64..309ec0bce5 100644
--- a/plugins/catalog-backend/src/modules/bitbucket/lib/index.ts
+++ b/plugins/catalog-backend-module-bitbucket/src/lib/index.ts
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-export { BitbucketClient, paginated, paginated20 } from './client';
export { defaultRepositoryParser } from './BitbucketRepositoryParser';
+export type { BitbucketRepositoryParser } from './BitbucketRepositoryParser';
+export { BitbucketClient, paginated, paginated20 } from './client';
export type { PagedResponse, PagedResponse20 } from './client';
export type { BitbucketRepository, BitbucketRepository20 } from './types';
-export type { BitbucketRepositoryParser } from './BitbucketRepositoryParser';
diff --git a/plugins/catalog-backend/src/modules/bitbucket/lib/types.ts b/plugins/catalog-backend-module-bitbucket/src/lib/types.ts
similarity index 100%
rename from plugins/catalog-backend/src/modules/bitbucket/lib/types.ts
rename to plugins/catalog-backend-module-bitbucket/src/lib/types.ts
diff --git a/plugins/catalog-backend/src/util/index.ts b/plugins/catalog-backend-module-bitbucket/src/setupTests.ts
similarity index 94%
rename from plugins/catalog-backend/src/util/index.ts
rename to plugins/catalog-backend-module-bitbucket/src/setupTests.ts
index 0b5a942e0c..d3232290a7 100644
--- a/plugins/catalog-backend/src/util/index.ts
+++ b/plugins/catalog-backend-module-bitbucket/src/setupTests.ts
@@ -14,4 +14,4 @@
* limitations under the License.
*/
-export * from './RecursivePartial';
+export {};
diff --git a/plugins/catalog-backend-module-github/.eslintrc.js b/plugins/catalog-backend-module-github/.eslintrc.js
new file mode 100644
index 0000000000..e2a53a6ad2
--- /dev/null
+++ b/plugins/catalog-backend-module-github/.eslintrc.js
@@ -0,0 +1 @@
+module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
diff --git a/plugins/catalog-backend-module-github/CHANGELOG.md b/plugins/catalog-backend-module-github/CHANGELOG.md
new file mode 100644
index 0000000000..ff15890f73
--- /dev/null
+++ b/plugins/catalog-backend-module-github/CHANGELOG.md
@@ -0,0 +1,14 @@
+# @backstage/plugin-catalog-backend-module-github
+
+## 0.1.0
+
+### Minor Changes
+
+- d4934e19b1: Added package, moving out GitHub specific functionality from the catalog-backend
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.13.0
+ - @backstage/plugin-catalog-backend@0.24.0
+ - @backstage/catalog-model@0.13.0
diff --git a/plugins/catalog-backend-module-github/README.md b/plugins/catalog-backend-module-github/README.md
new file mode 100644
index 0000000000..0d923d992c
--- /dev/null
+++ b/plugins/catalog-backend-module-github/README.md
@@ -0,0 +1,8 @@
+# Catalog Backend Module for GitHub
+
+This is an extension module to the plugin-catalog-backend plugin, providing extensions targeted at GitHub offerings.
+
+## Getting started
+
+See [Backstage documentation](https://backstage.io/docs/integrations/github/discovery) for details on how to install
+and configure the plugin.
diff --git a/plugins/catalog-backend-module-github/api-report.md b/plugins/catalog-backend-module-github/api-report.md
new file mode 100644
index 0000000000..a1b3d34058
--- /dev/null
+++ b/plugins/catalog-backend-module-github/api-report.md
@@ -0,0 +1,126 @@
+## API Report File for "@backstage/plugin-catalog-backend-module-github"
+
+> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
+
+```ts
+import { CatalogProcessor } from '@backstage/plugin-catalog-backend';
+import { CatalogProcessorEmit } from '@backstage/plugin-catalog-backend';
+import { Config } from '@backstage/config';
+import { EntityProvider } from '@backstage/plugin-catalog-backend';
+import { EntityProviderConnection } from '@backstage/plugin-catalog-backend';
+import { GithubCredentialsProvider } from '@backstage/integration';
+import { GitHubIntegrationConfig } from '@backstage/integration';
+import { LocationSpec } from '@backstage/plugin-catalog-backend';
+import { Logger } from 'winston';
+import { ScmIntegrationRegistry } from '@backstage/integration';
+
+// @public
+export class GithubDiscoveryProcessor implements CatalogProcessor {
+ constructor(options: {
+ integrations: ScmIntegrationRegistry;
+ logger: Logger;
+ githubCredentialsProvider?: GithubCredentialsProvider;
+ });
+ // (undocumented)
+ static fromConfig(
+ config: Config,
+ options: {
+ logger: Logger;
+ githubCredentialsProvider?: GithubCredentialsProvider;
+ },
+ ): GithubDiscoveryProcessor;
+ // (undocumented)
+ getProcessorName(): string;
+ // (undocumented)
+ readLocation(
+ location: LocationSpec,
+ _optional: boolean,
+ emit: CatalogProcessorEmit,
+ ): Promise;
+}
+
+// @public
+export type GithubMultiOrgConfig = Array<{
+ name: string;
+ groupNamespace: string;
+ userNamespace: string | undefined;
+}>;
+
+// @public
+export class GithubMultiOrgReaderProcessor implements CatalogProcessor {
+ constructor(options: {
+ integrations: ScmIntegrationRegistry;
+ logger: Logger;
+ orgs: GithubMultiOrgConfig;
+ githubCredentialsProvider?: GithubCredentialsProvider;
+ });
+ // (undocumented)
+ static fromConfig(
+ config: Config,
+ options: {
+ logger: Logger;
+ githubCredentialsProvider?: GithubCredentialsProvider;
+ },
+ ): GithubMultiOrgReaderProcessor;
+ // (undocumented)
+ getProcessorName(): string;
+ // (undocumented)
+ readLocation(
+ location: LocationSpec,
+ _optional: boolean,
+ emit: CatalogProcessorEmit,
+ ): Promise;
+}
+
+// @public (undocumented)
+export class GitHubOrgEntityProvider implements EntityProvider {
+ constructor(options: {
+ id: string;
+ orgUrl: string;
+ gitHubConfig: GitHubIntegrationConfig;
+ logger: Logger;
+ githubCredentialsProvider?: GithubCredentialsProvider;
+ });
+ // (undocumented)
+ connect(connection: EntityProviderConnection): Promise;
+ // (undocumented)
+ static fromConfig(
+ config: Config,
+ options: {
+ id: string;
+ orgUrl: string;
+ logger: Logger;
+ githubCredentialsProvider?: GithubCredentialsProvider;
+ },
+ ): GitHubOrgEntityProvider;
+ // (undocumented)
+ getProviderName(): string;
+ // (undocumented)
+ read(): Promise;
+}
+
+// @public
+export class GithubOrgReaderProcessor implements CatalogProcessor {
+ constructor(options: {
+ integrations: ScmIntegrationRegistry;
+ logger: Logger;
+ githubCredentialsProvider?: GithubCredentialsProvider;
+ });
+ // (undocumented)
+ static fromConfig(
+ config: Config,
+ options: {
+ logger: Logger;
+ githubCredentialsProvider?: GithubCredentialsProvider;
+ },
+ ): GithubOrgReaderProcessor;
+ // (undocumented)
+ getProcessorName(): string;
+ // (undocumented)
+ readLocation(
+ location: LocationSpec,
+ _optional: boolean,
+ emit: CatalogProcessorEmit,
+ ): Promise;
+}
+```
diff --git a/plugins/catalog-backend-module-github/package.json b/plugins/catalog-backend-module-github/package.json
new file mode 100644
index 0000000000..0e63cf9da2
--- /dev/null
+++ b/plugins/catalog-backend-module-github/package.json
@@ -0,0 +1,57 @@
+{
+ "name": "@backstage/plugin-catalog-backend-module-github",
+ "description": "A Backstage catalog backend module that helps integrate towards GitHub",
+ "version": "0.1.0",
+ "main": "src/index.ts",
+ "types": "src/index.ts",
+ "license": "Apache-2.0",
+ "private": false,
+ "publishConfig": {
+ "access": "public",
+ "main": "dist/index.cjs.js",
+ "types": "dist/index.d.ts"
+ },
+ "backstage": {
+ "role": "backend-plugin-module"
+ },
+ "homepage": "https://backstage.io",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/backstage/backstage",
+ "directory": "plugins/catalog-backend-module-github"
+ },
+ "keywords": [
+ "backstage"
+ ],
+ "scripts": {
+ "build": "backstage-cli package build",
+ "lint": "backstage-cli package lint",
+ "test": "backstage-cli package test",
+ "prepack": "backstage-cli package prepack",
+ "postpack": "backstage-cli package postpack",
+ "clean": "backstage-cli package clean",
+ "start": "backstage-cli package start"
+ },
+ "dependencies": {
+ "@backstage/backend-common": "^0.13.0",
+ "@backstage/catalog-model": "^0.13.0",
+ "@backstage/config": "^0.1.15",
+ "@backstage/errors": "^0.2.2",
+ "@backstage/integration": "^0.8.0",
+ "@backstage/plugin-catalog-backend": "^0.24.0",
+ "@backstage/types": "^0.1.3",
+ "@octokit/graphql": "^4.5.8",
+ "lodash": "^4.17.21",
+ "msw": "^0.35.0",
+ "node-fetch": "^2.6.7",
+ "winston": "^3.2.1"
+ },
+ "devDependencies": {
+ "@backstage/backend-test-utils": "^0.1.21",
+ "@backstage/cli": "^0.15.2",
+ "@types/lodash": "^4.14.151"
+ },
+ "files": [
+ "dist"
+ ]
+}
diff --git a/plugins/catalog-backend/src/modules/github/GitHubOrgEntityProvider.test.ts b/plugins/catalog-backend-module-github/src/GitHubOrgEntityProvider.test.ts
similarity index 98%
rename from plugins/catalog-backend/src/modules/github/GitHubOrgEntityProvider.test.ts
rename to plugins/catalog-backend-module-github/src/GitHubOrgEntityProvider.test.ts
index dd3bf490fb..3086386af8 100644
--- a/plugins/catalog-backend/src/modules/github/GitHubOrgEntityProvider.test.ts
+++ b/plugins/catalog-backend-module-github/src/GitHubOrgEntityProvider.test.ts
@@ -20,8 +20,8 @@ import {
GithubCredentialsProvider,
GitHubIntegrationConfig,
} from '@backstage/integration';
+import { EntityProviderConnection } from '@backstage/plugin-catalog-backend';
import { graphql } from '@octokit/graphql';
-import { EntityProviderConnection } from '../../api';
import {
GitHubOrgEntityProvider,
withLocations,
diff --git a/plugins/catalog-backend/src/modules/github/GitHubOrgEntityProvider.ts b/plugins/catalog-backend-module-github/src/GitHubOrgEntityProvider.ts
similarity index 97%
rename from plugins/catalog-backend/src/modules/github/GitHubOrgEntityProvider.ts
rename to plugins/catalog-backend-module-github/src/GitHubOrgEntityProvider.ts
index 76389968ae..5bf501aff0 100644
--- a/plugins/catalog-backend/src/modules/github/GitHubOrgEntityProvider.ts
+++ b/plugins/catalog-backend-module-github/src/GitHubOrgEntityProvider.ts
@@ -27,16 +27,20 @@ import {
ScmIntegrations,
SingleInstanceGithubCredentialsProvider,
} from '@backstage/integration';
+import {
+ EntityProvider,
+ EntityProviderConnection,
+} from '@backstage/plugin-catalog-backend';
import { graphql } from '@octokit/graphql';
import { merge } from 'lodash';
import { Logger } from 'winston';
-import { EntityProvider, EntityProviderConnection } from '../../api';
import {
+ assignGroupsToUsers,
+ buildOrgHierarchy,
getOrganizationTeams,
getOrganizationUsers,
parseGitHubOrgUrl,
} from './lib';
-import { assignGroupsToUsers, buildOrgHierarchy } from '../util/org';
// TODO: Consider supporting an (optional) webhook that reacts on org changes
/** @public */
diff --git a/plugins/catalog-backend/src/modules/github/GithubDiscoveryProcessor.test.ts b/plugins/catalog-backend-module-github/src/GithubDiscoveryProcessor.test.ts
similarity index 99%
rename from plugins/catalog-backend/src/modules/github/GithubDiscoveryProcessor.test.ts
rename to plugins/catalog-backend-module-github/src/GithubDiscoveryProcessor.test.ts
index 5440539b27..b18e3baf75 100644
--- a/plugins/catalog-backend/src/modules/github/GithubDiscoveryProcessor.test.ts
+++ b/plugins/catalog-backend-module-github/src/GithubDiscoveryProcessor.test.ts
@@ -20,7 +20,7 @@ import {
DefaultGithubCredentialsProvider,
ScmIntegrations,
} from '@backstage/integration';
-import { LocationSpec } from '../../api';
+import { LocationSpec } from '@backstage/plugin-catalog-backend';
import { GithubDiscoveryProcessor, parseUrl } from './GithubDiscoveryProcessor';
import { getOrganizationRepositories } from './lib';
diff --git a/plugins/catalog-backend/src/modules/github/GithubDiscoveryProcessor.ts b/plugins/catalog-backend-module-github/src/GithubDiscoveryProcessor.ts
similarity index 99%
rename from plugins/catalog-backend/src/modules/github/GithubDiscoveryProcessor.ts
rename to plugins/catalog-backend-module-github/src/GithubDiscoveryProcessor.ts
index 4aff470f52..78a1bca169 100644
--- a/plugins/catalog-backend/src/modules/github/GithubDiscoveryProcessor.ts
+++ b/plugins/catalog-backend-module-github/src/GithubDiscoveryProcessor.ts
@@ -21,15 +21,15 @@ import {
ScmIntegrationRegistry,
ScmIntegrations,
} from '@backstage/integration';
-import { graphql } from '@octokit/graphql';
-import { Logger } from 'winston';
-import { getOrganizationRepositories } from './lib';
import {
CatalogProcessor,
CatalogProcessorEmit,
LocationSpec,
processingResult,
-} from '../../api';
+} from '@backstage/plugin-catalog-backend';
+import { graphql } from '@octokit/graphql';
+import { Logger } from 'winston';
+import { getOrganizationRepositories } from './lib';
/**
* Extracts repositories out of a GitHub org.
diff --git a/plugins/catalog-backend/src/modules/github/GithubMultiOrgReaderProcessor.ts b/plugins/catalog-backend-module-github/src/GithubMultiOrgReaderProcessor.ts
similarity index 98%
rename from plugins/catalog-backend/src/modules/github/GithubMultiOrgReaderProcessor.ts
rename to plugins/catalog-backend-module-github/src/GithubMultiOrgReaderProcessor.ts
index dbd858fc0d..321e9cc8f8 100644
--- a/plugins/catalog-backend/src/modules/github/GithubMultiOrgReaderProcessor.ts
+++ b/plugins/catalog-backend-module-github/src/GithubMultiOrgReaderProcessor.ts
@@ -23,21 +23,21 @@ import {
ScmIntegrationRegistry,
ScmIntegrations,
} from '@backstage/integration';
-import { graphql } from '@octokit/graphql';
-import { Logger } from 'winston';
-import {
- getOrganizationTeams,
- getOrganizationUsers,
- GithubMultiOrgConfig,
- readGithubMultiOrgConfig,
-} from './lib';
import {
CatalogProcessor,
CatalogProcessorEmit,
LocationSpec,
processingResult,
-} from '../../api';
-import { buildOrgHierarchy } from '../util/org';
+} from '@backstage/plugin-catalog-backend';
+import { graphql } from '@octokit/graphql';
+import { Logger } from 'winston';
+import {
+ buildOrgHierarchy,
+ getOrganizationTeams,
+ getOrganizationUsers,
+ GithubMultiOrgConfig,
+ readGithubMultiOrgConfig,
+} from './lib';
/**
* Extracts teams and users out of a multiple GitHub orgs namespaced per org.
diff --git a/plugins/catalog-backend/src/modules/github/GithubOrgReaderProcessor.test.ts b/plugins/catalog-backend-module-github/src/GithubOrgReaderProcessor.test.ts
similarity index 98%
rename from plugins/catalog-backend/src/modules/github/GithubOrgReaderProcessor.test.ts
rename to plugins/catalog-backend-module-github/src/GithubOrgReaderProcessor.test.ts
index 9ce278ac44..2bb0c538eb 100644
--- a/plugins/catalog-backend/src/modules/github/GithubOrgReaderProcessor.test.ts
+++ b/plugins/catalog-backend-module-github/src/GithubOrgReaderProcessor.test.ts
@@ -17,12 +17,12 @@
import { getVoidLogger } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import {
- ScmIntegrations,
GithubCredentialsProvider,
+ ScmIntegrations,
} from '@backstage/integration';
+import { LocationSpec } from '@backstage/plugin-catalog-backend';
import { graphql } from '@octokit/graphql';
import { GithubOrgReaderProcessor } from './GithubOrgReaderProcessor';
-import { LocationSpec } from '../../api';
jest.mock('@octokit/graphql');
diff --git a/plugins/catalog-backend/src/modules/github/GithubOrgReaderProcessor.ts b/plugins/catalog-backend-module-github/src/GithubOrgReaderProcessor.ts
similarity index 97%
rename from plugins/catalog-backend/src/modules/github/GithubOrgReaderProcessor.ts
rename to plugins/catalog-backend-module-github/src/GithubOrgReaderProcessor.ts
index e85e7b874d..84c12e82ba 100644
--- a/plugins/catalog-backend/src/modules/github/GithubOrgReaderProcessor.ts
+++ b/plugins/catalog-backend-module-github/src/GithubOrgReaderProcessor.ts
@@ -16,26 +16,27 @@
import { Config } from '@backstage/config';
import {
+ DefaultGithubCredentialsProvider,
+ GithubCredentialsProvider,
GithubCredentialType,
ScmIntegrationRegistry,
ScmIntegrations,
- GithubCredentialsProvider,
- DefaultGithubCredentialsProvider,
} from '@backstage/integration';
-import { graphql } from '@octokit/graphql';
-import { Logger } from 'winston';
-import {
- getOrganizationTeams,
- getOrganizationUsers,
- parseGitHubOrgUrl,
-} from './lib';
import {
CatalogProcessor,
CatalogProcessorEmit,
LocationSpec,
processingResult,
-} from '../../api';
-import { assignGroupsToUsers, buildOrgHierarchy } from '../util/org';
+} from '@backstage/plugin-catalog-backend';
+import { graphql } from '@octokit/graphql';
+import { Logger } from 'winston';
+import {
+ assignGroupsToUsers,
+ buildOrgHierarchy,
+ getOrganizationTeams,
+ getOrganizationUsers,
+ parseGitHubOrgUrl,
+} from './lib';
type GraphQL = typeof graphql;
diff --git a/plugins/catalog-backend/src/modules/github/index.ts b/plugins/catalog-backend-module-github/src/index.ts
similarity index 85%
rename from plugins/catalog-backend/src/modules/github/index.ts
rename to plugins/catalog-backend-module-github/src/index.ts
index 7958818096..1394fcd21b 100644
--- a/plugins/catalog-backend/src/modules/github/index.ts
+++ b/plugins/catalog-backend-module-github/src/index.ts
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Backstage Authors
+ * 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.
@@ -14,6 +14,12 @@
* limitations under the License.
*/
+/**
+ * A Backstage catalog backend module that helps integrate towards GitHub
+ *
+ * @packageDocumentation
+ */
+
export { GithubDiscoveryProcessor } from './GithubDiscoveryProcessor';
export { GithubMultiOrgReaderProcessor } from './GithubMultiOrgReaderProcessor';
export { GitHubOrgEntityProvider } from './GitHubOrgEntityProvider';
diff --git a/plugins/catalog-backend/src/modules/github/lib/config.test.ts b/plugins/catalog-backend-module-github/src/lib/config.test.ts
similarity index 100%
rename from plugins/catalog-backend/src/modules/github/lib/config.test.ts
rename to plugins/catalog-backend-module-github/src/lib/config.test.ts
diff --git a/plugins/catalog-backend/src/modules/github/lib/config.ts b/plugins/catalog-backend-module-github/src/lib/config.ts
similarity index 100%
rename from plugins/catalog-backend/src/modules/github/lib/config.ts
rename to plugins/catalog-backend-module-github/src/lib/config.ts
diff --git a/plugins/catalog-backend/src/modules/github/lib/github.test.ts b/plugins/catalog-backend-module-github/src/lib/github.test.ts
similarity index 100%
rename from plugins/catalog-backend/src/modules/github/lib/github.test.ts
rename to plugins/catalog-backend-module-github/src/lib/github.test.ts
diff --git a/plugins/catalog-backend/src/modules/github/lib/github.ts b/plugins/catalog-backend-module-github/src/lib/github.ts
similarity index 100%
rename from plugins/catalog-backend/src/modules/github/lib/github.ts
rename to plugins/catalog-backend-module-github/src/lib/github.ts
diff --git a/plugins/catalog-backend/src/modules/github/lib/index.ts b/plugins/catalog-backend-module-github/src/lib/index.ts
similarity index 93%
rename from plugins/catalog-backend/src/modules/github/lib/index.ts
rename to plugins/catalog-backend-module-github/src/lib/index.ts
index 3e31d9e00c..26ec3e8516 100644
--- a/plugins/catalog-backend/src/modules/github/lib/index.ts
+++ b/plugins/catalog-backend-module-github/src/lib/index.ts
@@ -21,4 +21,5 @@ export {
getOrganizationTeams,
getOrganizationUsers,
} from './github';
+export { assignGroupsToUsers, buildOrgHierarchy } from './org';
export { parseGitHubOrgUrl } from './util';
diff --git a/plugins/catalog-backend/src/modules/util/org.test.ts b/plugins/catalog-backend-module-github/src/lib/org.test.ts
similarity index 100%
rename from plugins/catalog-backend/src/modules/util/org.test.ts
rename to plugins/catalog-backend-module-github/src/lib/org.test.ts
diff --git a/plugins/catalog-backend/src/modules/util/org.ts b/plugins/catalog-backend-module-github/src/lib/org.ts
similarity index 94%
rename from plugins/catalog-backend/src/modules/util/org.ts
rename to plugins/catalog-backend-module-github/src/lib/org.ts
index 3c71f350e6..79a96b5e71 100644
--- a/plugins/catalog-backend/src/modules/util/org.ts
+++ b/plugins/catalog-backend-module-github/src/lib/org.ts
@@ -58,7 +58,10 @@ export function assignGroupsToUsers(
for (const [groupName, userNames] of groupMemberUsers.entries()) {
for (const userName of userNames) {
const user = usersByName.get(userName);
- if (user && !user.spec.memberOf.includes(groupName)) {
+ if (user && !user.spec.memberOf?.includes(groupName)) {
+ if (!user.spec.memberOf) {
+ user.spec.memberOf = [];
+ }
user.spec.memberOf.push(groupName);
}
}
@@ -74,7 +77,7 @@ export function buildMemberOf(groups: GroupEntity[], users: UserEntity[]) {
const transitiveMemberOf = new Set();
const todo = [
- ...user.spec.memberOf,
+ ...(user.spec.memberOf ?? []),
...groups
.filter(g => g.spec.members?.includes(user.metadata.name))
.map(g => g.metadata.name),
diff --git a/plugins/catalog-backend/src/modules/github/lib/util.test.ts b/plugins/catalog-backend-module-github/src/lib/util.test.ts
similarity index 100%
rename from plugins/catalog-backend/src/modules/github/lib/util.test.ts
rename to plugins/catalog-backend-module-github/src/lib/util.test.ts
diff --git a/plugins/catalog-backend/src/modules/github/lib/util.ts b/plugins/catalog-backend-module-github/src/lib/util.ts
similarity index 100%
rename from plugins/catalog-backend/src/modules/github/lib/util.ts
rename to plugins/catalog-backend-module-github/src/lib/util.ts
diff --git a/plugins/catalog-backend-module-github/src/setupTests.ts b/plugins/catalog-backend-module-github/src/setupTests.ts
new file mode 100644
index 0000000000..d3232290a7
--- /dev/null
+++ b/plugins/catalog-backend-module-github/src/setupTests.ts
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+export {};
diff --git a/plugins/catalog-backend-module-gitlab/.eslintrc.js b/plugins/catalog-backend-module-gitlab/.eslintrc.js
index 16a033dbc6..e2a53a6ad2 100644
--- a/plugins/catalog-backend-module-gitlab/.eslintrc.js
+++ b/plugins/catalog-backend-module-gitlab/.eslintrc.js
@@ -1,3 +1 @@
-module.exports = {
- extends: [require.resolve('@backstage/cli/config/eslint.backend')],
-};
+module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
diff --git a/plugins/catalog-backend-module-gitlab/CHANGELOG.md b/plugins/catalog-backend-module-gitlab/CHANGELOG.md
index 09f6df6fe4..75ddcba68b 100644
--- a/plugins/catalog-backend-module-gitlab/CHANGELOG.md
+++ b/plugins/catalog-backend-module-gitlab/CHANGELOG.md
@@ -1,5 +1,18 @@
# @backstage/plugin-catalog-backend-module-gitlab
+## 0.1.0
+
+### Minor Changes
+
+- 66ba5d9023: Added package, moving out GitLab specific functionality from the catalog-backend
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.13.0
+ - @backstage/plugin-catalog-backend@0.24.0
+ - @backstage/catalog-model@0.13.0
+
## 0.1.0-next.0
### Minor Changes
diff --git a/plugins/catalog-backend-module-gitlab/package.json b/plugins/catalog-backend-module-gitlab/package.json
index 7073291d2b..976cee1e69 100644
--- a/plugins/catalog-backend-module-gitlab/package.json
+++ b/plugins/catalog-backend-module-gitlab/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend-module-gitlab",
"description": "A Backstage catalog backend module that helps integrate towards GitLab",
- "version": "0.1.0-next.0",
+ "version": "0.1.0",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -33,12 +33,12 @@
"start": "backstage-cli package start"
},
"dependencies": {
- "@backstage/backend-common": "^0.13.0-next.0",
- "@backstage/catalog-model": "^0.13.0-next.0",
+ "@backstage/backend-common": "^0.13.0",
+ "@backstage/catalog-model": "^0.13.0",
"@backstage/config": "^0.1.15",
"@backstage/errors": "^0.2.2",
"@backstage/integration": "^0.8.0",
- "@backstage/plugin-catalog-backend": "^0.24.0-next.0",
+ "@backstage/plugin-catalog-backend": "^0.24.0",
"@backstage/types": "^0.1.3",
"lodash": "^4.17.21",
"msw": "^0.35.0",
@@ -46,8 +46,8 @@
"winston": "^3.2.1"
},
"devDependencies": {
- "@backstage/backend-test-utils": "^0.1.21-next.0",
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/backend-test-utils": "^0.1.21",
+ "@backstage/cli": "^0.15.2",
"@types/lodash": "^4.14.151"
},
"files": [
diff --git a/plugins/catalog-backend-module-ldap/CHANGELOG.md b/plugins/catalog-backend-module-ldap/CHANGELOG.md
index 6933b4e6c5..e0cf628845 100644
--- a/plugins/catalog-backend-module-ldap/CHANGELOG.md
+++ b/plugins/catalog-backend-module-ldap/CHANGELOG.md
@@ -1,5 +1,44 @@
# @backstage/plugin-catalog-backend-module-ldap
+## 0.4.0
+
+### Minor Changes
+
+- 9461f73643: **BREAKING**: Added a `schedule` field to `LdapOrgEntityProvider.fromConfig`, which is required. If you want to retain the old behavior of scheduling the provider manually, you can set it to the string value `'manual'`. But you may want to leverage the ability to instead pass in the recurring task schedule information directly. This will allow you to simplify your backend setup code to not need an intermediate variable and separate scheduling code at the bottom.
+
+ All things said, a typical setup might now look as follows:
+
+ ```diff
+ // packages/backend/src/plugins/catalog.ts
+ +import { Duration } from 'luxon';
+ +import { LdapOrgEntityProvider } from '@backstage/plugin-catalog-backend-module-ldap';
+ export default async function createPlugin(
+ env: PluginEnvironment,
+ ): Promise {
+ const builder = await CatalogBuilder.create(env);
+ + // The target parameter below needs to match the ldap.providers.target
+ + // value specified in your app-config.
+ + builder.addEntityProvider(
+ + LdapOrgEntityProvider.fromConfig(env.config, {
+ + id: 'our-ldap-master',
+ + target: 'ldaps://ds.example.net',
+ + logger: env.logger,
+ + schedule: env.scheduler.createScheduledTaskRunner({
+ + frequency: Duration.fromObject({ minutes: 60 }),
+ + timeout: Duration.fromObject({ minutes: 15 }),
+ + }),
+ + }),
+ + );
+ ```
+
+### Patch Changes
+
+- f751e84572: Ignore search referrals instead of throwing an error.
+- Updated dependencies
+ - @backstage/backend-tasks@0.2.0
+ - @backstage/plugin-catalog-backend@0.24.0
+ - @backstage/catalog-model@0.13.0
+
## 0.4.0-next.0
### Minor Changes
diff --git a/plugins/catalog-backend-module-ldap/config.d.ts b/plugins/catalog-backend-module-ldap/config.d.ts
index df167bc520..2605eb62f3 100644
--- a/plugins/catalog-backend-module-ldap/config.d.ts
+++ b/plugins/catalog-backend-module-ldap/config.d.ts
@@ -79,6 +79,10 @@ export interface Config {
scope?: 'base' | 'one' | 'sub';
filter?: string;
attributes?: string | string[];
+ sizeLimit?: number;
+ timeLimit?: number;
+ derefAliases?: number;
+ typesOnly?: boolean;
paged?:
| boolean
| {
@@ -159,6 +163,10 @@ export interface Config {
scope?: 'base' | 'one' | 'sub';
filter?: string;
attributes?: string | string[];
+ sizeLimit?: number;
+ timeLimit?: number;
+ derefAliases?: number;
+ typesOnly?: boolean;
paged?:
| boolean
| {
diff --git a/plugins/catalog-backend-module-ldap/package.json b/plugins/catalog-backend-module-ldap/package.json
index a09f93536f..514f8f9e10 100644
--- a/plugins/catalog-backend-module-ldap/package.json
+++ b/plugins/catalog-backend-module-ldap/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend-module-ldap",
"description": "A Backstage catalog backend module that helps integrate towards LDAP",
- "version": "0.4.0-next.0",
+ "version": "0.4.0",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -33,11 +33,11 @@
"start": "backstage-cli package start"
},
"dependencies": {
- "@backstage/backend-tasks": "^0.2.0-next.0",
- "@backstage/catalog-model": "^0.13.0-next.0",
+ "@backstage/backend-tasks": "^0.2.0",
+ "@backstage/catalog-model": "^0.13.0",
"@backstage/config": "^0.1.15",
"@backstage/errors": "^0.2.2",
- "@backstage/plugin-catalog-backend": "^0.24.0-next.0",
+ "@backstage/plugin-catalog-backend": "^0.24.0",
"@backstage/types": "^0.1.3",
"@types/ldapjs": "^2.2.0",
"ldapjs": "^2.2.0",
@@ -46,7 +46,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@types/lodash": "^4.14.151"
},
"files": [
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 06ac24d3ae..292e9a218e 100644
--- a/plugins/catalog-backend-module-ldap/src/ldap/config.test.ts
+++ b/plugins/catalog-backend-module-ldap/src/ldap/config.test.ts
@@ -87,6 +87,10 @@ describe('readLdapConfig', () => {
attributes: ['*'],
filter: 'f',
paged: true,
+ timeLimit: 42,
+ sizeLimit: 100,
+ derefAliases: 0,
+ typesOnly: false,
},
set: { p: 'v' },
map: {
@@ -109,6 +113,10 @@ describe('readLdapConfig', () => {
pageSize: 7,
pagePause: true,
},
+ timeLimit: 42,
+ sizeLimit: 100,
+ derefAliases: 1,
+ typesOnly: true,
},
set: { p: 'v' },
map: {
@@ -138,6 +146,10 @@ describe('readLdapConfig', () => {
attributes: ['*'],
filter: 'f',
paged: true,
+ timeLimit: 42,
+ sizeLimit: 100,
+ derefAliases: 0,
+ typesOnly: false,
},
set: { p: 'v' },
map: {
@@ -160,6 +172,10 @@ describe('readLdapConfig', () => {
pageSize: 7,
pagePause: true,
},
+ timeLimit: 42,
+ sizeLimit: 100,
+ derefAliases: 1,
+ typesOnly: true,
},
set: { p: 'v' },
map: {
diff --git a/plugins/catalog-backend-module-ldap/src/ldap/config.ts b/plugins/catalog-backend-module-ldap/src/ldap/config.ts
index 526467962e..370c9491b3 100644
--- a/plugins/catalog-backend-module-ldap/src/ldap/config.ts
+++ b/plugins/catalog-backend-module-ldap/src/ldap/config.ts
@@ -18,8 +18,8 @@ import { Config } from '@backstage/config';
import { JsonValue } from '@backstage/types';
import { SearchOptions } from 'ldapjs';
import mergeWith from 'lodash/mergeWith';
-import { RecursivePartial } from '@backstage/plugin-catalog-backend';
import { trimEnd } from 'lodash';
+import { RecursivePartial } from './util';
/**
* The configuration parameters for a single LDAP provider.
@@ -208,6 +208,10 @@ export function readLdapConfig(config: Config): LdapProviderConfig[] {
scope: c.getOptionalString('scope') as SearchOptions['scope'],
filter: formatFilter(c.getOptionalString('filter')),
attributes: c.getOptionalStringArray('attributes'),
+ sizeLimit: c.getOptionalNumber('sizeLimit'),
+ timeLimit: c.getOptionalNumber('timeLimit'),
+ derefAliases: c.getOptionalNumber('derefAliases'),
+ typesOnly: c.getOptionalBoolean('typesOnly'),
...(paged !== undefined ? { paged } : undefined),
};
}
diff --git a/plugins/catalog-backend-module-ldap/src/ldap/org.ts b/plugins/catalog-backend-module-ldap/src/ldap/org.ts
index fe59451a9d..28ccbd1d3b 100644
--- a/plugins/catalog-backend-module-ldap/src/ldap/org.ts
+++ b/plugins/catalog-backend-module-ldap/src/ldap/org.ts
@@ -61,7 +61,7 @@ export function buildMemberOf(groups: GroupEntity[], users: UserEntity[]) {
const transitiveMemberOf = new Set();
const todo = [
- ...user.spec.memberOf,
+ ...(user.spec.memberOf ?? []),
...groups
.filter(g => g.spec.members?.includes(user.metadata.name))
.map(g => g.metadata.name),
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 875ffb7029..3ded4635a0 100644
--- a/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts
+++ b/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts
@@ -17,7 +17,6 @@
import { GroupEntity, UserEntity } from '@backstage/catalog-model';
import { SearchEntry } from 'ldapjs';
import merge from 'lodash/merge';
-import { RecursivePartial } from '@backstage/plugin-catalog-backend';
import { LdapClient } from './client';
import { GroupConfig, UserConfig } from './config';
import {
@@ -32,6 +31,7 @@ import {
readLdapUsers,
resolveRelations,
} from './read';
+import { RecursivePartial } from './util';
import { ActiveDirectoryVendor, DefaultLdapVendor } from './vendors';
function user(data: RecursivePartial): UserEntity {
diff --git a/plugins/catalog-backend-module-ldap/src/ldap/util.ts b/plugins/catalog-backend-module-ldap/src/ldap/util.ts
index 21829cef35..0f443c1a86 100644
--- a/plugins/catalog-backend-module-ldap/src/ldap/util.ts
+++ b/plugins/catalog-backend-module-ldap/src/ldap/util.ts
@@ -53,3 +53,11 @@ export function mapStringAttr(
}
}
}
+
+export type RecursivePartial = {
+ [P in keyof T]?: T[P] extends (infer U)[]
+ ? RecursivePartial[]
+ : T[P] extends object
+ ? RecursivePartial
+ : T[P];
+};
diff --git a/plugins/catalog-backend-module-msgraph/CHANGELOG.md b/plugins/catalog-backend-module-msgraph/CHANGELOG.md
index 7b8a358517..859b43813d 100644
--- a/plugins/catalog-backend-module-msgraph/CHANGELOG.md
+++ b/plugins/catalog-backend-module-msgraph/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-catalog-backend-module-msgraph
+## 0.2.19
+
+### Patch Changes
+
+- 3c2bc73901: Use `setupRequestMockHandlers` from `@backstage/backend-test-utils`
+- Updated dependencies
+ - @backstage/plugin-catalog-backend@0.24.0
+ - @backstage/catalog-model@0.13.0
+
## 0.2.19-next.0
### Patch Changes
diff --git a/plugins/catalog-backend-module-msgraph/README.md b/plugins/catalog-backend-module-msgraph/README.md
index a253359471..d9488486ad 100644
--- a/plugins/catalog-backend-module-msgraph/README.md
+++ b/plugins/catalog-backend-module-msgraph/README.md
@@ -35,6 +35,11 @@ catalog:
# the App registration in the Microsoft Azure Portal.
clientId: ${MICROSOFT_GRAPH_CLIENT_ID}
clientSecret: ${MICROSOFT_GRAPH_CLIENT_SECRET_TOKEN}
+ # Optional mode for querying which defaults to "basic".
+ # By default, the Microsoft Graph API only provides the basic feature set
+ # for querying. Certain features are limited to advanced querying capabilities.
+ # (See https://docs.microsoft.com/en-us/graph/aad-advanced-queries)
+ queryMode: basic # basic | advanced
# Optional parameter to include the expanded resource or collection referenced
# by a single relationship (navigation property) in your results.
# Only one relationship can be expanded in a single request.
@@ -117,8 +122,8 @@ useHotCleanup(
```typescript
// packages/backend/src/plugins/catalog.ts
builder.addProcessor(
- MicrosoftGraphOrgReaderProcessor.fromConfig(config, {
- logger,
+ MicrosoftGraphOrgReaderProcessor.fromConfig(env.config, {
+ logger: env.logger,
}),
);
```
@@ -173,8 +178,8 @@ export async function myGroupTransformer(
```ts
builder.addProcessor(
- MicrosoftGraphOrgReaderProcessor.fromConfig(config, {
- logger,
+ MicrosoftGraphOrgReaderProcessor.fromConfig(env.config, {
+ logger: env.logger,
groupTransformer: myGroupTransformer,
}),
);
diff --git a/plugins/catalog-backend-module-msgraph/api-report.md b/plugins/catalog-backend-module-msgraph/api-report.md
index f7d0f112ad..e3840dc6f7 100644
--- a/plugins/catalog-backend-module-msgraph/api-report.md
+++ b/plugins/catalog-backend-module-msgraph/api-report.md
@@ -70,7 +70,10 @@ export class MicrosoftGraphClient {
groupId: string,
maxSize: number,
): Promise;
- getGroups(query?: ODataQuery): AsyncIterable;
+ getGroups(
+ query?: ODataQuery,
+ queryMode?: 'basic' | 'advanced',
+ ): AsyncIterable;
getOrganization(tenantId: string): Promise;
// (undocumented)
getUserPhoto(userId: string, sizeId?: string): Promise;
@@ -82,13 +85,20 @@ export class MicrosoftGraphClient {
userId: string,
query?: ODataQuery,
): Promise;
- getUsers(query?: ODataQuery): AsyncIterable;
+ getUsers(
+ query?: ODataQuery,
+ queryMode?: 'basic' | 'advanced',
+ ): AsyncIterable;
requestApi(
path: string,
query?: ODataQuery,
headers?: Record,
): Promise;
- requestCollection(path: string, query?: ODataQuery): AsyncIterable;
+ requestCollection(
+ path: string,
+ query?: ODataQuery,
+ queryMode?: 'basic' | 'advanced',
+ ): AsyncIterable;
requestRaw(
url: string,
headers?: Record,
@@ -167,6 +177,7 @@ export type MicrosoftGraphProviderConfig = {
groupExpand?: string;
groupFilter?: string;
groupSearch?: string;
+ queryMode?: 'basic' | 'advanced';
};
// @public
@@ -178,6 +189,7 @@ export type ODataQuery = {
filter?: string;
expand?: string;
select?: string[];
+ count?: boolean;
};
// @public
@@ -202,6 +214,7 @@ export function readMicrosoftGraphOrg(
groupExpand?: string;
groupSearch?: string;
groupFilter?: string;
+ queryMode?: 'basic' | 'advanced';
userTransformer?: UserTransformer;
groupTransformer?: GroupTransformer;
organizationTransformer?: OrganizationTransformer;
diff --git a/plugins/catalog-backend-module-msgraph/config.d.ts b/plugins/catalog-backend-module-msgraph/config.d.ts
index d47abf60bb..db5ab81c4b 100644
--- a/plugins/catalog-backend-module-msgraph/config.d.ts
+++ b/plugins/catalog-backend-module-msgraph/config.d.ts
@@ -58,7 +58,7 @@ export interface Config {
clientSecret: string;
// TODO: Consider not making these config options and pass them in the
- // constructor instead. They are probably not environment specifc, so
+ // constructor instead. They are probably not environment specific, so
// they could also be configured "in code".
/**
diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json
index 5de78b3ec4..58ff3b2b3d 100644
--- a/plugins/catalog-backend-module-msgraph/package.json
+++ b/plugins/catalog-backend-module-msgraph/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend-module-msgraph",
"description": "A Backstage catalog backend module that helps integrate towards Microsoft Graph",
- "version": "0.2.19-next.0",
+ "version": "0.2.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -34,9 +34,9 @@
},
"dependencies": {
"@azure/msal-node": "^1.1.0",
- "@backstage/catalog-model": "^0.13.0-next.0",
+ "@backstage/catalog-model": "^0.13.0",
"@backstage/config": "^0.1.15",
- "@backstage/plugin-catalog-backend": "^0.24.0-next.0",
+ "@backstage/plugin-catalog-backend": "^0.24.0",
"@microsoft/microsoft-graph-types": "^2.6.0",
"@types/node-fetch": "^2.5.12",
"lodash": "^4.17.21",
@@ -46,9 +46,9 @@
"qs": "^6.9.4"
},
"devDependencies": {
- "@backstage/backend-common": "^0.13.0-next.0",
- "@backstage/backend-test-utils": "^0.1.21-next.0",
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/backend-common": "^0.13.0",
+ "@backstage/backend-test-utils": "^0.1.21",
+ "@backstage/cli": "^0.15.2",
"@types/lodash": "^4.14.151",
"msw": "^0.35.0"
},
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 467b03733e..5ff4fa4e0e 100644
--- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.test.ts
+++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.test.ts
@@ -157,7 +157,7 @@ describe('MicrosoftGraphClient', () => {
expect(userProfile).toEqual({ surname: 'Example' });
});
- it('should throw expection if load user profile fails', async () => {
+ it('should throw exception if load user profile fails', async () => {
worker.use(
rest.get('https://example.com/users/user-id', (_, res, ctx) =>
res(ctx.status(404)),
diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.ts
index cba5d9f640..20e791c5d5 100644
--- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.ts
+++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.ts
@@ -24,6 +24,7 @@ import { MicrosoftGraphProviderConfig } from './config';
* OData (Open Data Protocol) Query
*
* {@link https://docs.microsoft.com/en-us/odata/concepts/queryoptions-overview}
+ * {@link https://docs.microsoft.com/en-us/graph/query-parameters}
* @public
*/
export type ODataQuery = {
@@ -43,6 +44,10 @@ export type ODataQuery = {
* request a specific set of properties for each entity or complex type
*/
select?: string[];
+ /**
+ * Retrieves the total count of matching resources.
+ */
+ count?: boolean;
};
/**
@@ -100,19 +105,34 @@ export class MicrosoftGraphClient {
* @public
* @param path - Resource in Microsoft Graph
* @param query - OData Query {@link ODataQuery}
- *
+ * @param queryMode - Mode to use while querying. Some features are only available at "advanced".
*/
async *requestCollection(
path: string,
query?: ODataQuery,
+ queryMode?: 'basic' | 'advanced',
): AsyncIterable {
- const headers: Record = query?.search
- ? {
- // Eventual consistency is required to use $search.
- // If a new user/group is not found, it'll eventually be imported on a subsequent read
- ConsistencyLevel: 'eventual',
- }
- : {};
+ // upgrade to advanced query mode transparently when "search" is used
+ // to stay backwards compatible.
+ const appliedQueryMode = query?.search ? 'advanced' : queryMode ?? 'basic';
+
+ // not needed for "search"
+ // as of https://docs.microsoft.com/en-us/graph/aad-advanced-queries?tabs=http
+ // even though a few other places say the opposite
+ // - https://docs.microsoft.com/en-us/graph/api/user-list?view=graph-rest-1.0&tabs=http#request-headers
+ // - https://docs.microsoft.com/en-us/graph/api/resources/group?view=graph-rest-1.0#properties
+ if (appliedQueryMode === 'advanced' && (query?.filter || query?.select)) {
+ query.count = true;
+ }
+ const headers: Record =
+ appliedQueryMode === 'advanced'
+ ? {
+ // Eventual consistency is required for advanced querying capabilities
+ // like "$search" or parts of "$filter".
+ // If a new user/group is not found, it'll eventually be imported on a subsequent read
+ ConsistencyLevel: 'eventual',
+ }
+ : {};
let response = await this.requestApi(path, query, headers);
@@ -156,6 +176,7 @@ export class MicrosoftGraphClient {
$filter: query?.filter,
$select: query?.select?.join(','),
$expand: query?.expand,
+ $count: query?.count,
},
{
addQueryPrefix: true,
@@ -248,10 +269,17 @@ export class MicrosoftGraphClient {
*
* @public
* @param query - OData Query {@link ODataQuery}
- *
+ * @param queryMode - Mode to use while querying. Some features are only available at "advanced".
*/
- async *getUsers(query?: ODataQuery): AsyncIterable {
- yield* this.requestCollection(`users`, query);
+ async *getUsers(
+ query?: ODataQuery,
+ queryMode?: 'basic' | 'advanced',
+ ): AsyncIterable {
+ yield* this.requestCollection(
+ `users`,
+ query,
+ queryMode,
+ );
}
/**
@@ -280,12 +308,20 @@ export class MicrosoftGraphClient {
* Get a collection of
* {@link https://docs.microsoft.com/en-us/graph/api/resources/group | Group}
* from Graph API and return as `AsyncIterable`
+ *
* @public
* @param query - OData Query {@link ODataQuery}
- *
+ * @param queryMode - Mode to use while querying. Some features are only available at "advanced".
*/
- async *getGroups(query?: ODataQuery): AsyncIterable {
- yield* this.requestCollection(`groups`, query);
+ async *getGroups(
+ query?: ODataQuery,
+ queryMode?: 'basic' | 'advanced',
+ ): AsyncIterable {
+ yield* this.requestCollection(
+ `groups`,
+ query,
+ queryMode,
+ );
}
/**
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 cfc5c1cbb0..34796fb29a 100644
--- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/config.test.ts
+++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/config.test.ts
@@ -93,4 +93,21 @@ describe('readMicrosoftGraphConfig', () => {
};
expect(() => readMicrosoftGraphConfig(new ConfigReader(config))).toThrow();
});
+
+ it('should fail if both userFilter and userGroupMemberSearch are set', () => {
+ const config = {
+ providers: [
+ {
+ target: 'target',
+ tenantId: 'tenantId',
+ clientId: 'clientId',
+ clientSecret: 'clientSecret',
+ authority: 'https://login.example.com/',
+ userFilter: 'accountEnabled eq true',
+ userGroupMemberSearch: 'any',
+ },
+ ],
+ };
+ expect(() => readMicrosoftGraphConfig(new ConfigReader(config))).toThrow();
+ });
});
diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/config.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/config.ts
index b7fbcfb8a9..441892531a 100644
--- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/config.ts
+++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/config.ts
@@ -53,7 +53,7 @@ export type MicrosoftGraphProviderConfig = {
*/
userFilter?: string;
/**
- * The expand argument to apply to users.
+ * The "expand" argument to apply to users.
*
* E.g. "manager"
*/
@@ -88,6 +88,15 @@ export type MicrosoftGraphProviderConfig = {
* E.g. "\"displayName:-team\"" would only match groups which contain '-team'
*/
groupSearch?: string;
+ /**
+ * By default, the Microsoft Graph API only provides the basic feature set
+ * for querying. Certain features are limited to advanced query capabilities
+ * (see https://docs.microsoft.com/en-us/graph/aad-advanced-queries)
+ * and need to be enabled.
+ *
+ * Some features like `$expand` are not available for advanced queries, though.
+ */
+ queryMode?: 'basic' | 'advanced';
};
/**
@@ -136,6 +145,15 @@ export function readMicrosoftGraphConfig(
);
}
+ const queryMode = providerConfig.getOptionalString('queryMode');
+ if (
+ queryMode !== undefined &&
+ queryMode !== 'basic' &&
+ queryMode !== 'advanced'
+ ) {
+ throw new Error(`queryMode must be one of: basic, advanced`);
+ }
+
providers.push({
target,
authority,
@@ -149,6 +167,7 @@ export function readMicrosoftGraphConfig(
groupExpand,
groupFilter,
groupSearch,
+ queryMode,
});
}
diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/org.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/org.ts
index fe59451a9d..28ccbd1d3b 100644
--- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/org.ts
+++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/org.ts
@@ -61,7 +61,7 @@ export function buildMemberOf(groups: GroupEntity[], users: UserEntity[]) {
const transitiveMemberOf = new Set();
const todo = [
- ...user.spec.memberOf,
+ ...(user.spec.memberOf ?? []),
...groups
.filter(g => g.spec.members?.includes(user.metadata.name))
.map(g => g.metadata.name),
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 e3d6897d66..1fc4904b74 100644
--- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.test.ts
+++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.test.ts
@@ -111,9 +111,62 @@ describe('read microsoft graph', () => {
]);
expect(client.getUsers).toBeCalledTimes(1);
- expect(client.getUsers).toBeCalledWith({
- filter: 'accountEnabled eq true',
+ expect(client.getUsers).toBeCalledWith(
+ {
+ filter: 'accountEnabled eq true',
+ },
+ undefined,
+ );
+ expect(client.getUserPhotoWithSizeLimit).toBeCalledTimes(1);
+ expect(client.getUserPhotoWithSizeLimit).toBeCalledWith('userid', 120);
+ });
+
+ it('should read users with advanced query mode', async () => {
+ async function* getExampleUsers() {
+ yield {
+ id: 'userid',
+ displayName: 'User Name',
+ mail: 'user.name@example.com',
+ };
+ }
+
+ client.getUsers.mockImplementation(getExampleUsers);
+ client.getUserPhotoWithSizeLimit.mockResolvedValue(
+ 'data:image/jpeg;base64,...',
+ );
+
+ const { users } = await readMicrosoftGraphUsers(client, {
+ queryMode: 'advanced',
+ userFilter: 'accountEnabled eq true',
+ logger: getVoidLogger(),
});
+
+ expect(users).toEqual([
+ user({
+ metadata: {
+ annotations: {
+ 'graph.microsoft.com/user-id': 'userid',
+ },
+ name: 'user.name_example.com',
+ },
+ spec: {
+ profile: {
+ displayName: 'User Name',
+ email: 'user.name@example.com',
+ picture: 'data:image/jpeg;base64,...',
+ },
+ memberOf: [],
+ },
+ }),
+ ]);
+
+ expect(client.getUsers).toBeCalledTimes(1);
+ expect(client.getUsers).toBeCalledWith(
+ {
+ filter: 'accountEnabled eq true',
+ },
+ 'advanced',
+ );
expect(client.getUserPhotoWithSizeLimit).toBeCalledTimes(1);
expect(client.getUserPhotoWithSizeLimit).toBeCalledWith('userid', 120);
});
@@ -154,10 +207,13 @@ describe('read microsoft graph', () => {
]);
expect(client.getUsers).toBeCalledTimes(1);
- expect(client.getUsers).toBeCalledWith({
- expand: 'manager',
- filter: 'accountEnabled eq true',
- });
+ expect(client.getUsers).toBeCalledWith(
+ {
+ expand: 'manager',
+ filter: 'accountEnabled eq true',
+ },
+ undefined,
+ );
expect(client.getUserPhotoWithSizeLimit).toBeCalledTimes(1);
expect(client.getUserPhotoWithSizeLimit).toBeCalledWith('userid', 120);
});
@@ -222,9 +278,88 @@ describe('read microsoft graph', () => {
]);
expect(client.getGroups).toBeCalledTimes(1);
- expect(client.getGroups).toBeCalledWith({
- filter: 'securityEnabled eq true',
+ expect(client.getGroups).toBeCalledWith(
+ {
+ filter: 'securityEnabled eq true',
+ },
+ undefined,
+ );
+ expect(client.getGroupMembers).toBeCalledTimes(1);
+ expect(client.getGroupMembers).toBeCalledWith('groupid');
+
+ expect(client.getUserProfile).toBeCalledTimes(1);
+ expect(client.getUserProfile).toBeCalledWith('userid', {
+ expand: undefined,
});
+ expect(client.getUserPhotoWithSizeLimit).toBeCalledTimes(1);
+ expect(client.getUserPhotoWithSizeLimit).toBeCalledWith('userid', 120);
+ });
+
+ it('should read users from Groups with advanced query mode', async () => {
+ async function* getExampleGroups() {
+ yield {
+ id: 'groupid',
+ displayName: 'Group Name',
+ description: 'Group Description',
+ mail: 'group@example.com',
+ };
+ }
+
+ async function* getExampleGroupMembers(): AsyncIterable {
+ yield {
+ '@odata.type': '#microsoft.graph.group',
+ id: 'childgroupid',
+ };
+ yield {
+ '@odata.type': '#microsoft.graph.user',
+ id: 'userid',
+ };
+ }
+
+ client.getGroups.mockImplementation(getExampleGroups);
+ client.getGroupMembers.mockImplementation(getExampleGroupMembers);
+
+ client.getUserProfile.mockResolvedValue({
+ id: 'userid',
+ displayName: 'User Name',
+ mail: 'user.name@example.com',
+ });
+ client.getUserPhotoWithSizeLimit.mockResolvedValue(
+ 'data:image/jpeg;base64,...',
+ );
+
+ const { users } = await readMicrosoftGraphUsersInGroups(client, {
+ queryMode: 'advanced',
+ userGroupMemberFilter: 'securityEnabled eq true',
+ logger: getVoidLogger(),
+ });
+
+ expect(users).toEqual([
+ user({
+ metadata: {
+ annotations: {
+ 'graph.microsoft.com/user-id': 'userid',
+ },
+ name: 'user.name_example.com',
+ },
+ spec: {
+ profile: {
+ displayName: 'User Name',
+ email: 'user.name@example.com',
+ picture: 'data:image/jpeg;base64,...',
+ },
+ memberOf: [],
+ },
+ }),
+ ]);
+
+ expect(client.getGroups).toBeCalledTimes(1);
+ expect(client.getGroups).toBeCalledWith(
+ {
+ filter: 'securityEnabled eq true',
+ },
+ 'advanced',
+ );
expect(client.getGroupMembers).toBeCalledTimes(1);
expect(client.getGroupMembers).toBeCalledWith('groupid');
@@ -292,10 +427,13 @@ describe('read microsoft graph', () => {
]);
expect(client.getGroups).toBeCalledTimes(1);
- expect(client.getGroups).toBeCalledWith({
- expand: 'member',
- filter: 'securityEnabled eq true',
- });
+ expect(client.getGroups).toBeCalledWith(
+ {
+ expand: 'member',
+ filter: 'securityEnabled eq true',
+ },
+ undefined,
+ );
expect(client.getGroupMembers).toBeCalledTimes(1);
expect(client.getGroupMembers).toBeCalledWith('groupid');
@@ -444,9 +582,108 @@ describe('read microsoft graph', () => {
expect(groupMember.get('organization_name')).toEqual(new Set());
expect(client.getGroups).toBeCalledTimes(1);
- expect(client.getGroups).toBeCalledWith({
- filter: 'securityEnabled eq false',
+ expect(client.getGroups).toBeCalledWith(
+ {
+ filter: 'securityEnabled eq false',
+ },
+ undefined,
+ );
+ expect(client.getGroupMembers).toBeCalledTimes(1);
+ expect(client.getGroupMembers).toBeCalledWith('groupid');
+ // 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);
+ });
+
+ it('should read groups with advanced query mode', async () => {
+ async function* getExampleGroups() {
+ yield {
+ id: 'groupid',
+ displayName: 'Group Name',
+ description: 'Group Description',
+ mail: 'group@example.com',
+ };
+ }
+
+ async function* getExampleGroupMembers(): AsyncIterable {
+ yield {
+ '@odata.type': '#microsoft.graph.group',
+ id: 'childgroupid',
+ };
+ yield {
+ '@odata.type': '#microsoft.graph.user',
+ id: 'userid',
+ };
+ }
+
+ client.getGroups.mockImplementation(getExampleGroups);
+ client.getGroupMembers.mockImplementation(getExampleGroupMembers);
+ client.getOrganization.mockResolvedValue({
+ id: 'tenantid',
+ displayName: 'Organization Name',
});
+ client.getGroupPhotoWithSizeLimit.mockResolvedValue(
+ 'data:image/jpeg;base64,...',
+ );
+
+ const { groups, groupMember, groupMemberOf, rootGroup } =
+ await readMicrosoftGraphGroups(client, 'tenantid', {
+ queryMode: 'advanced',
+ groupFilter: 'securityEnabled eq false',
+ });
+
+ 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': '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(groupMember.get('organization_name')).toEqual(new Set());
+
+ expect(client.getGroups).toBeCalledTimes(1);
+ expect(client.getGroups).toBeCalledWith(
+ {
+ filter: 'securityEnabled eq false',
+ },
+ 'advanced',
+ );
expect(client.getGroupMembers).toBeCalledTimes(1);
expect(client.getGroupMembers).toBeCalledWith('groupid');
// TODO: Loading groups photos doesn't work right now as Microsoft Graph
@@ -537,10 +774,13 @@ describe('read microsoft graph', () => {
expect(groupMember.get('organization_name')).toEqual(new Set());
expect(client.getGroups).toBeCalledTimes(1);
- expect(client.getGroups).toBeCalledWith({
- expand: 'member',
- filter: 'securityEnabled eq false',
- });
+ expect(client.getGroups).toBeCalledWith(
+ {
+ expand: 'member',
+ filter: 'securityEnabled eq false',
+ },
+ undefined,
+ );
expect(client.getGroupMembers).toBeCalledTimes(1);
expect(client.getGroupMembers).toBeCalledWith('groupid');
// TODO: Loading groups photos doesn't work right now as Microsoft Graph
@@ -628,9 +868,12 @@ describe('read microsoft graph', () => {
}),
]);
expect(rootGroup).toEqual(expectedRootGroup);
- expect(client.getGroups).toBeCalledWith({
- filter: 'securityEnabled eq true',
- });
+ expect(client.getGroups).toBeCalledWith(
+ {
+ filter: 'securityEnabled eq true',
+ },
+ undefined,
+ );
expect(client.getGroupMembers).toBeCalledTimes(1);
expect(client.getGroupMembers).toBeCalledWith('groupid');
});
@@ -788,13 +1031,19 @@ describe('read microsoft graph', () => {
});
expect(client.getUsers).toBeCalledTimes(1);
- expect(client.getUsers).toBeCalledWith({
- filter: undefined,
- });
+ expect(client.getUsers).toBeCalledWith(
+ {
+ filter: undefined,
+ },
+ undefined,
+ );
expect(client.getGroups).toBeCalledTimes(1);
- expect(client.getGroups).toBeCalledWith({
- filter: 'securityEnabled eq false',
- });
+ expect(client.getGroups).toBeCalledWith(
+ {
+ filter: 'securityEnabled eq false',
+ },
+ undefined,
+ );
});
it('should read users using userExpand and userFilter', async () => {
@@ -822,14 +1071,20 @@ describe('read microsoft graph', () => {
});
expect(client.getUsers).toBeCalledTimes(1);
- expect(client.getUsers).toBeCalledWith({
- expand: 'manager',
- filter: 'accountEnabled eq true',
- });
+ expect(client.getUsers).toBeCalledWith(
+ {
+ expand: 'manager',
+ filter: 'accountEnabled eq true',
+ },
+ undefined,
+ );
expect(client.getGroups).toBeCalledTimes(1);
- expect(client.getGroups).toBeCalledWith({
- filter: 'securityEnabled eq false',
- });
+ expect(client.getGroups).toBeCalledWith(
+ {
+ filter: 'securityEnabled eq false',
+ },
+ undefined,
+ );
});
it('should read users using userExpand and userGroupMemberFilter', async () => {
@@ -858,12 +1113,18 @@ describe('read microsoft graph', () => {
expect(client.getUsers).toBeCalledTimes(0);
expect(client.getGroups).toBeCalledTimes(2);
- expect(client.getGroups).toBeCalledWith({
- filter: 'name eq backstage-group',
- });
- expect(client.getGroups).toBeCalledWith({
- filter: 'securityEnabled eq false',
- });
+ expect(client.getGroups).toBeCalledWith(
+ {
+ filter: 'name eq backstage-group',
+ },
+ undefined,
+ );
+ expect(client.getGroups).toBeCalledWith(
+ {
+ filter: 'securityEnabled eq false',
+ },
+ undefined,
+ );
expect(client.getUserProfile).toBeCalledTimes(1);
expect(client.getUserPhotoWithSizeLimit).toBeCalledTimes(1);
});
diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts
index ed6ca76e68..e9760f7698 100644
--- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts
+++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/read.ts
@@ -84,6 +84,7 @@ export async function defaultUserTransformer(
export async function readMicrosoftGraphUsers(
client: MicrosoftGraphClient,
options: {
+ queryMode?: 'basic' | 'advanced';
userFilter?: string;
userExpand?: string;
transformer?: UserTransformer;
@@ -95,13 +96,16 @@ export async function readMicrosoftGraphUsers(
const users: UserEntity[] = [];
const limiter = limiterFactory(10);
- const transformer = options?.transformer ?? defaultUserTransformer;
+ const transformer = options.transformer ?? defaultUserTransformer;
const promises: Promise[] = [];
- for await (const user of client.getUsers({
- filter: options.userFilter,
- expand: options.userExpand,
- })) {
+ for await (const user of client.getUsers(
+ {
+ filter: options.userFilter,
+ expand: options.userExpand,
+ },
+ options.queryMode,
+ )) {
// Process all users in parallel, otherwise it can take quite some time
promises.push(
limiter(async () => {
@@ -137,6 +141,7 @@ export async function readMicrosoftGraphUsers(
export async function readMicrosoftGraphUsersInGroups(
client: MicrosoftGraphClient,
options: {
+ queryMode?: 'basic' | 'advanced';
userExpand?: string;
userGroupMemberSearch?: string;
userGroupMemberFilter?: string;
@@ -157,11 +162,14 @@ export async function readMicrosoftGraphUsersInGroups(
const groupMemberUsers: Set = new Set();
- for await (const group of client.getGroups({
- expand: options.groupExpand,
- search: options.userGroupMemberSearch,
- filter: options.userGroupMemberFilter,
- })) {
+ for await (const group of client.getGroups(
+ {
+ expand: options.groupExpand,
+ search: options.userGroupMemberSearch,
+ filter: options.userGroupMemberFilter,
+ },
+ options.queryMode,
+ )) {
// Process all groups in parallel, otherwise it can take quite some time
userGroupMemberPromises.push(
limiter(async () => {
@@ -331,6 +339,7 @@ export async function readMicrosoftGraphGroups(
client: MicrosoftGraphClient,
tenantId: string,
options?: {
+ queryMode?: 'basic' | 'advanced';
groupExpand?: string;
groupFilter?: string;
groupSearch?: string;
@@ -359,11 +368,14 @@ export async function readMicrosoftGraphGroups(
const transformer = options?.groupTransformer ?? defaultGroupTransformer;
const promises: Promise[] = [];
- for await (const group of client.getGroups({
- expand: options?.groupExpand,
- search: options?.groupSearch,
- filter: options?.groupFilter,
- })) {
+ for await (const group of client.getGroups(
+ {
+ expand: options?.groupExpand,
+ search: options?.groupSearch,
+ filter: options?.groupFilter,
+ },
+ options?.queryMode,
+ )) {
// Process all groups in parallel, otherwise it can take quite some time
promises.push(
limiter(async () => {
@@ -495,6 +507,9 @@ export function resolveRelations(
retrieveItems(groupMemberOf, id).forEach(p => {
const parentGroup = groupMap.get(p);
if (parentGroup) {
+ if (!user.spec.memberOf) {
+ user.spec.memberOf = [];
+ }
user.spec.memberOf.push(stringifyEntityRef(parentGroup));
}
});
@@ -520,6 +535,7 @@ export async function readMicrosoftGraphOrg(
groupExpand?: string;
groupSearch?: string;
groupFilter?: string;
+ queryMode?: 'basic' | 'advanced';
userTransformer?: UserTransformer;
groupTransformer?: GroupTransformer;
organizationTransformer?: OrganizationTransformer;
@@ -528,10 +544,11 @@ export async function readMicrosoftGraphOrg(
): Promise<{ users: UserEntity[]; groups: GroupEntity[] }> {
const users: UserEntity[] = [];
- if (options.userGroupMemberFilter) {
+ if (options.userGroupMemberFilter || options.userGroupMemberSearch) {
const { users: usersInGroups } = await readMicrosoftGraphUsersInGroups(
client,
{
+ queryMode: options.queryMode,
userGroupMemberFilter: options.userGroupMemberFilter,
userGroupMemberSearch: options.userGroupMemberSearch,
transformer: options.userTransformer,
@@ -541,6 +558,7 @@ export async function readMicrosoftGraphOrg(
users.push(...usersInGroups);
} else {
const { users: usersWithFilter } = await readMicrosoftGraphUsers(client, {
+ queryMode: options.queryMode,
userFilter: options.userFilter,
userExpand: options.userExpand,
transformer: options.userTransformer,
@@ -550,10 +568,11 @@ export async function readMicrosoftGraphOrg(
}
const { groups, rootGroup, groupMember, groupMemberOf } =
await readMicrosoftGraphGroups(client, tenantId, {
- groupSearch: options?.groupSearch,
- groupFilter: options?.groupFilter,
- groupTransformer: options?.groupTransformer,
- organizationTransformer: options?.organizationTransformer,
+ queryMode: options.queryMode,
+ groupSearch: options.groupSearch,
+ groupFilter: options.groupFilter,
+ groupTransformer: options.groupTransformer,
+ organizationTransformer: options.organizationTransformer,
});
resolveRelations(rootGroup, groups, users, groupMember, groupMemberOf);
diff --git a/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgEntityProvider.ts b/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgEntityProvider.ts
index 7d27e87d73..71aabaeef2 100644
--- a/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgEntityProvider.ts
+++ b/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgEntityProvider.ts
@@ -126,6 +126,7 @@ export class MicrosoftGraphOrgEntityProvider implements EntityProvider {
userGroupMemberSearch: provider.userGroupMemberSearch,
groupFilter: provider.groupFilter,
groupSearch: provider.groupSearch,
+ queryMode: provider.queryMode,
groupTransformer: this.options.groupTransformer,
userTransformer: this.options.userTransformer,
organizationTransformer: this.options.organizationTransformer,
diff --git a/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgReaderProcessor.ts b/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgReaderProcessor.ts
index 9037bd8728..5d8619e874 100644
--- a/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgReaderProcessor.ts
+++ b/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgReaderProcessor.ts
@@ -73,6 +73,7 @@ export class MicrosoftGraphOrgReaderProcessor implements CatalogProcessor {
this.groupTransformer = options.groupTransformer;
this.organizationTransformer = options.organizationTransformer;
}
+
getProcessorName(): string {
return 'MicrosoftGraphOrgReaderProcessor';
}
@@ -95,7 +96,7 @@ export class MicrosoftGraphOrgReaderProcessor implements CatalogProcessor {
);
}
- // Read out all of the raw data
+ // Read out all the raw data
const startTimestamp = Date.now();
this.logger.info('Reading Microsoft Graph users and groups');
@@ -112,6 +113,7 @@ export class MicrosoftGraphOrgReaderProcessor implements CatalogProcessor {
groupExpand: provider.groupExpand,
groupFilter: provider.groupFilter,
groupSearch: provider.groupSearch,
+ queryMode: provider.queryMode,
userTransformer: this.userTransformer,
groupTransformer: this.groupTransformer,
organizationTransformer: this.organizationTransformer,
diff --git a/plugins/catalog-backend/.snyk b/plugins/catalog-backend/.snyk
deleted file mode 100644
index ad62599e66..0000000000
--- a/plugins/catalog-backend/.snyk
+++ /dev/null
@@ -1,47 +0,0 @@
-# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
-version: v1.22.1
-# ignores vulnerabilities until expiry date; change duration by modifying expiry date
-ignore:
- SNYK-JS-TAR-1579155:
- - 'sqlite3 > node-gyp > tar':
- reason: >-
- The only usage is via node-gyp; there is no unpacking of untrusted tar
- files
- expires: 2022-11-11T14:30:05.581Z
- created: 2021-11-11T14:30:05.582Z
- SNYK-JS-TAR-1579152:
- - 'sqlite3 > node-gyp > tar':
- reason: >-
- The only usage is via node-gyp; there is no unpacking of untrusted tar
- files
- expires: 2022-11-11T14:30:05.581Z
- created: 2021-11-11T14:30:05.582Z
- SNYK-JS-TAR-1579147:
- - 'sqlite3 > node-gyp > tar':
- reason: >-
- The only usage is via node-gyp; there is no unpacking of untrusted tar
- files
- expires: 2022-11-11T14:30:05.581Z
- created: 2021-11-11T14:30:05.582Z
- SNYK-JS-TAR-1536758:
- - 'sqlite3 > node-gyp > tar':
- reason: >-
- The only usage is via node-gyp; there is no unpacking of untrusted tar
- files
- expires: 2022-11-11T14:30:05.581Z
- created: 2021-11-11T14:30:05.582Z
- SNYK-JS-TAR-1536531:
- - 'sqlite3 > node-gyp > tar':
- reason: >-
- The only usage is via node-gyp; there is no unpacking of untrusted tar
- files
- expires: 2022-11-11T14:30:05.581Z
- created: 2021-11-11T14:30:05.582Z
- SNYK-JS-TAR-1536528:
- - 'sqlite3 > node-gyp > tar':
- reason: >-
- The only usage is via node-gyp; there is no unpacking of untrusted tar
- files
- expires: 2022-11-11T14:30:05.581Z
- created: 2021-11-11T14:30:05.582Z
-patch: {}
diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md
index 664f58ffe5..b0b7403311 100644
--- a/plugins/catalog-backend/CHANGELOG.md
+++ b/plugins/catalog-backend/CHANGELOG.md
@@ -1,5 +1,103 @@
# @backstage/plugin-catalog-backend
+## 0.24.0
+
+### Minor Changes
+
+- 66ba5d9023: **BREAKING**: Removed `GithubDiscoveryProcessor`, `GithubMultiOrgReaderProcessor`, `GitHubOrgEntityProvider`, `GithubOrgReaderProcessor`, and `GithubMultiOrgConfig` which now instead should be imported from `@backstage/plugin-catalog-backend-module-github`. NOTE THAT the `GithubDiscoveryProcessor` and `GithubOrgReaderProcessor` were part of the default set of processors in the catalog backend, and if you are a user of discovery or location based org ingestion on GitLab, you MUST now add them manually in the catalog initialization code of your backend.
+
+ ```diff
+ // In packages/backend/src/plugins/catalog.ts
+ +import {
+ + GithubDiscoveryProcessor,
+ + GithubOrgReaderProcessor,
+ +} from '@backstage/plugin-catalog-backend-module-github';
+ +import {
+ + ScmIntegrations,
+ + DefaultGithubCredentialsProvider
+ +} from '@backstage/integration';
+
+ export default async function createPlugin(
+ env: PluginEnvironment,
+ ): Promise {
+ const builder = await CatalogBuilder.create(env);
+ + const integrations = ScmIntegrations.fromConfig(config);
+ + const githubCredentialsProvider =
+ + DefaultGithubCredentialsProvider.fromIntegrations(integrations);
+ + builder.addProcessor(
+ + GithubDiscoveryProcessor.fromConfig(config, {
+ + logger,
+ + githubCredentialsProvider,
+ + }),
+ + GithubOrgReaderProcessor.fromConfig(config, {
+ + logger,
+ + githubCredentialsProvider,
+ + }),
+ + );
+ ```
+
+ **BREAKING**: Removed `GitLabDiscoveryProcessor`, which now instead should be imported from `@backstage/plugin-catalog-backend-module-gitlab`. NOTE THAT this processor was part of the default set of processors in the catalog backend, and if you are a user of discovery on GitLab, you MUST now add it manually in the catalog initialization code of your backend.
+
+ ```diff
+ // In packages/backend/src/plugins/catalog.ts
+ +import { GitLabDiscoveryProcessor } from '@backstage/plugin-catalog-backend-module-gitlab';
+
+ export default async function createPlugin(
+ env: PluginEnvironment,
+ ): Promise {
+ const builder = await CatalogBuilder.create(env);
+ + builder.addProcessor(
+ + GitLabDiscoveryProcessor.fromConfig(env.config, { logger: env.logger })
+ + );
+ ```
+
+ **BREAKING**: Removed `BitbucketDiscoveryProcessor`, which now instead should be imported from `@backstage/plugin-catalog-backend-module-bitbucket`. NOTE THAT this processor was part of the default set of processors in the catalog backend, and if you are a user of discovery on Bitbucket, you MUST now add it manually in the catalog initialization code of your backend.
+
+ ```diff
+ // In packages/backend/src/plugins/catalog.ts
+ +import { BitbucketDiscoveryProcessor } from '@backstage/plugin-catalog-backend-module-bitbucket';
+
+ export default async function createPlugin(
+ env: PluginEnvironment,
+ ): Promise {
+ const builder = await CatalogBuilder.create(env);
+ + builder.addProcessor(
+ + BitbucketDiscoveryProcessor.fromConfig(env.config, { logger: env.logger })
+ + );
+ ```
+
+ **BREAKING**: Removed `AzureDevOpsDiscoveryProcessor`, which now instead should be imported from `@backstage/plugin-catalog-backend-module-azure`. This processor was not part of the set of default processors. If you were using it, you should already have a reference to it in your backend code and only need to update the import.
+
+ **BREAKING**: Removed the formerly deprecated type `BitbucketRepositoryParser`, which is instead reintroduced in `@backstage/plugin-catalog-backend-module-bitbucket`.
+
+- f115a7f8fd: **BREAKING**: Removed `AwsS3DiscoveryProcessor`, which now instead should be imported from `@backstage/plugin-catalog-backend-module-aws`.
+- 55150919ed: - **BREAKING**: Support for `backstage.io/v1beta2` Software Templates has been removed. Please migrate your legacy templates to the new `scaffolder.backstage.io/v1beta3` `apiVersion` by following the [migration guide](https://backstage.io/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3)
+
+### Patch Changes
+
+- ab7cd7d70e: Do some groundwork for supporting the `better-sqlite3` driver, to maybe eventually replace `@vscode/sqlite3` (#9912)
+- e0a69ba49f: build(deps): bump `fs-extra` from 9.1.0 to 10.0.1
+- 616f02ade2: support Bitbucket Cloud's code search to discover catalog files (multiple per repo, Location entities for existing files only)
+- e421d77536: **BREAKING**:
+
+ - Removed the previously deprecated `runPeriodically` export. Please use the `@backstage/backend-tasks` package instead, or copy [the actual implementation](https://github.com/backstage/backstage/blob/02875d4d56708c60f86f6b0a5b3da82e24988354/plugins/catalog-backend/src/util/runPeriodically.ts#L29) into your own code if you explicitly do not want coordination of task runs across your worker nodes.
+ - Removed the previously deprecated `CatalogProcessorLocationResult.optional` field. Please set the corresponding `LocationSpec.presence` field to `'optional'` instead.
+ - Related to the previous point, the `processingResult.location` function no longer has a second boolean `optional` argument. Please set the corresponding `LocationSpec.presence` field to `'optional'` instead.
+ - Removed the previously deprecated `StaticLocationProcessor`. It has not been in use for some time; its functionality is covered by `ConfigLocationEntityProvider` instead.
+
+- 3c2bc73901: Use `setupRequestMockHandlers` from `@backstage/backend-test-utils`
+- c1168bb440: Fixed display of the location in the log message that is printed when entity envelope validation fails.
+- b1aacbf96a: Applied the fix for the `/alpha` entry point resolution that was part of the `v0.70.1` release of Backstage.
+- 3e54f6c436: Use `@backstage/plugin-search-common` package instead of `@backstage/search-common`.
+- Updated dependencies
+ - @backstage/backend-common@0.13.0
+ - @backstage/plugin-scaffolder-common@0.3.0
+ - @backstage/catalog-model@0.13.0
+ - @backstage/plugin-catalog-common@0.2.2
+ - @backstage/plugin-search-common@0.3.1
+ - @backstage/catalog-client@0.9.0
+ - @backstage/plugin-permission-node@0.5.4
+
## 0.24.0-next.0
### Minor Changes
diff --git a/plugins/catalog-backend/api-report.md b/plugins/catalog-backend/api-report.md
index 2a007fc52c..ad80e36232 100644
--- a/plugins/catalog-backend/api-report.md
+++ b/plugins/catalog-backend/api-report.md
@@ -5,9 +5,8 @@
```ts
///
-import { BitbucketIntegration } from '@backstage/integration';
import { CatalogApi } from '@backstage/catalog-client';
-import { CatalogEntityDocument as CatalogEntityDocument_2 } from '@backstage/plugin-catalog-common';
+import { CatalogEntityDocument } from '@backstage/plugin-catalog-common';
import { CompoundEntityRef } from '@backstage/catalog-model';
import { ConditionalPolicyDecision } from '@backstage/plugin-permission-node';
import { Conditions } from '@backstage/plugin-permission-node';
@@ -15,13 +14,8 @@ import { Config } from '@backstage/config';
import { DocumentCollatorFactory } from '@backstage/plugin-search-common';
import { Entity } from '@backstage/catalog-model';
import { EntityPolicy } from '@backstage/catalog-model';
-import express from 'express';
import { GetEntitiesRequest } from '@backstage/catalog-client';
-import { GithubCredentialsProvider } from '@backstage/integration';
-import { GitHubIntegrationConfig } from '@backstage/integration';
-import { JsonObject } from '@backstage/types';
import { JsonValue } from '@backstage/types';
-import { Location as Location_2 } from '@backstage/catalog-client';
import { Logger } from 'winston';
import { Permission } from '@backstage/plugin-permission-common';
import { PermissionAuthorizer } from '@backstage/plugin-permission-common';
@@ -97,49 +91,6 @@ export class AnnotateScmSlugEntityProcessor implements CatalogProcessor {
preProcessEntity(entity: Entity, location: LocationSpec): Promise;
}
-// @public (undocumented)
-export class BitbucketDiscoveryProcessor implements CatalogProcessor {
- constructor(options: {
- integrations: ScmIntegrationRegistry;
- parser?: (options: {
- integration: BitbucketIntegration;
- target: string;
- presence?: 'optional' | 'required';
- logger: Logger;
- }) => AsyncIterable;
- logger: Logger;
- });
- // (undocumented)
- static fromConfig(
- config: Config,
- options: {
- parser?: (options: {
- integration: BitbucketIntegration;
- target: string;
- presence?: 'optional' | 'required';
- logger: Logger;
- }) => AsyncIterable;
- logger: Logger;
- },
- ): BitbucketDiscoveryProcessor;
- // (undocumented)
- getProcessorName(): string;
- // (undocumented)
- readLocation(
- location: LocationSpec,
- _optional: boolean,
- emit: CatalogProcessorEmit,
- ): Promise;
-}
-
-// @public @deprecated (undocumented)
-export type BitbucketRepositoryParser = (options: {
- integration: BitbucketIntegration;
- target: string;
- presence?: 'optional' | 'required';
- logger: Logger;
-}) => AsyncIterable;
-
// @public (undocumented)
export class BuiltinKindsEntityProcessor implements CatalogProcessor {
// (undocumented)
@@ -167,10 +118,7 @@ export class CatalogBuilder {
): void;
addProcessor(...processors: CatalogProcessor[]): CatalogBuilder;
build(): Promise<{
- entitiesCatalog: EntitiesCatalog;
- locationAnalyzer: LocationAnalyzer;
processingEngine: CatalogProcessingEngine;
- locationService: LocationService;
router: Router;
}>;
static create(env: CatalogEnvironment): CatalogBuilder;
@@ -188,10 +136,6 @@ export class CatalogBuilder {
processingInterval: ProcessingIntervalFunction,
): CatalogBuilder;
setProcessingIntervalSeconds(seconds: number): CatalogBuilder;
- // @deprecated
- setRefreshInterval(refreshInterval: RefreshIntervalFunction): CatalogBuilder;
- // @deprecated
- setRefreshIntervalSeconds(seconds: number): CatalogBuilder;
}
// @alpha
@@ -220,9 +164,6 @@ export const catalogConditions: Conditions<{
>;
}>;
-// @public @deprecated (undocumented)
-export type CatalogEntityDocument = CatalogEntityDocument_2;
-
// @public (undocumented)
export type CatalogEnvironment = {
logger: Logger;
@@ -240,12 +181,6 @@ export interface CatalogProcessingEngine {
stop(): Promise;
}
-// @public
-export interface CatalogProcessingOrchestrator {
- // (undocumented)
- process(request: EntityProcessingRequest): Promise;
-}
-
// @public (undocumented)
export type CatalogProcessor = {
getProcessorName(): string;
@@ -320,22 +255,6 @@ export type CatalogProcessorResult =
| CatalogProcessorRelationResult
| CatalogProcessorErrorResult;
-// @public
-export type CatalogRule = {
- allow: Array<{
- kind: string;
- }>;
- locations?: Array<{
- target?: string;
- type: string;
- }>;
-};
-
-// @public
-export type CatalogRulesEnforcer = {
- isAllowed(entity: Entity, location: LocationSpec): boolean;
-};
-
// @public (undocumented)
export class CodeOwnersProcessor implements CatalogProcessor {
constructor(options: {
@@ -373,15 +292,6 @@ export function createRandomProcessingInterval(options: {
maxSeconds: number;
}): ProcessingIntervalFunction;
-// @public @deprecated
-export function createRandomRefreshInterval(options: {
- minSeconds: number;
- maxSeconds: number;
-}): RefreshIntervalFunction;
-
-// @public
-export function createRouter(options: RouterOptions): Promise;
-
// @public @deprecated (undocumented)
export class DefaultCatalogCollator {
constructor(options: {
@@ -401,7 +311,7 @@ export class DefaultCatalogCollator {
// (undocumented)
protected discovery: PluginEndpointDiscovery;
// (undocumented)
- execute(): Promise;
+ execute(): Promise;
// (undocumented)
protected filter?: GetEntitiesRequest['filter'];
// (undocumented)
@@ -448,107 +358,18 @@ export type DefaultCatalogCollatorFactoryOptions = {
catalogClient?: CatalogApi;
};
-// @public (undocumented)
-export class DefaultCatalogProcessingOrchestrator
- implements CatalogProcessingOrchestrator
-{
- constructor(options: {
- processors: CatalogProcessor[];
- integrations: ScmIntegrationRegistry;
- logger: Logger;
- parser: CatalogProcessorParser;
- policy: EntityPolicy;
- rulesEnforcer: CatalogRulesEnforcer;
- });
- // (undocumented)
- process(request: EntityProcessingRequest): Promise;
-}
-
-// @public
-export class DefaultCatalogRulesEnforcer implements CatalogRulesEnforcer {
- constructor(rules: CatalogRule[]);
- static readonly defaultRules: CatalogRule[];
- static fromConfig(config: Config): DefaultCatalogRulesEnforcer;
- isAllowed(entity: Entity, location: LocationSpec): boolean;
-}
-
// @public
export type DeferredEntity = {
entity: Entity;
locationKey?: string;
};
-// @public (undocumented)
-export type EntitiesCatalog = {
- entities(request?: EntitiesRequest): Promise;
- removeEntityByUid(
- uid: string,
- options?: {
- authorizationToken?: string;
- },
- ): Promise;
- entityAncestry(
- entityRef: string,
- options?: {
- authorizationToken?: string;
- },
- ): Promise;
- facets(request: EntityFacetsRequest): Promise;
-};
-
-// @public (undocumented)
-export type EntitiesRequest = {
- filter?: EntityFilter;
- fields?: (entity: Entity) => Entity;
- pagination?: EntityPagination;
- authorizationToken?: string;
-};
-
-// @public (undocumented)
-export type EntitiesResponse = {
- entities: Entity[];
- pageInfo: PageInfo;
-};
-
// @public
export type EntitiesSearchFilter = {
key: string;
values?: string[];
};
-// @public @deprecated (undocumented)
-function entity(
- atLocation: LocationSpec,
- newEntity: Entity,
-): CatalogProcessorResult;
-
-// @public (undocumented)
-export type EntityAncestryResponse = {
- rootEntityRef: string;
- items: Array<{
- entity: Entity;
- parentEntityRefs: string[];
- }>;
-};
-
-// @public
-export interface EntityFacetsRequest {
- authorizationToken?: string;
- facets: string[];
- filter?: EntityFilter;
-}
-
-// @public
-export interface EntityFacetsResponse {
- facets: Record<
- string,
- Array<{
- value: string;
- count: number;
- }>
- >;
-}
-
// @public
export type EntityFilter =
| {
@@ -562,34 +383,6 @@ export type EntityFilter =
}
| EntitiesSearchFilter;
-// @public
-export type EntityPagination = {
- limit?: number;
- offset?: number;
- after?: string;
-};
-
-// @public
-export type EntityProcessingRequest = {
- entity: Entity;
- state?: JsonObject;
-};
-
-// @public
-export type EntityProcessingResult =
- | {
- ok: true;
- state: JsonObject;
- completedEntity: Entity;
- deferredEntities: DeferredEntity[];
- relations: EntityRelationSpec[];
- errors: Error[];
- }
- | {
- ok: false;
- errors: Error[];
- };
-
// @public
export interface EntityProvider {
connect(connection: EntityProviderConnection): Promise;
@@ -633,134 +426,6 @@ export class FileReaderProcessor implements CatalogProcessor {
): Promise;
}
-// @public @deprecated (undocumented)
-function generalError(
- atLocation: LocationSpec,
- message: string,
-): CatalogProcessorResult;
-
-// @public
-export class GithubDiscoveryProcessor implements CatalogProcessor {
- constructor(options: {
- integrations: ScmIntegrationRegistry;
- logger: Logger;
- githubCredentialsProvider?: GithubCredentialsProvider;
- });
- // (undocumented)
- static fromConfig(
- config: Config,
- options: {
- logger: Logger;
- githubCredentialsProvider?: GithubCredentialsProvider;
- },
- ): GithubDiscoveryProcessor;
- // (undocumented)
- getProcessorName(): string;
- // (undocumented)
- readLocation(
- location: LocationSpec,
- _optional: boolean,
- emit: CatalogProcessorEmit,
- ): Promise;
-}
-
-// @public
-export type GithubMultiOrgConfig = Array<{
- name: string;
- groupNamespace: string;
- userNamespace: string | undefined;
-}>;
-
-// @public
-export class GithubMultiOrgReaderProcessor implements CatalogProcessor {
- constructor(options: {
- integrations: ScmIntegrationRegistry;
- logger: Logger;
- orgs: GithubMultiOrgConfig;
- githubCredentialsProvider?: GithubCredentialsProvider;
- });
- // (undocumented)
- static fromConfig(
- config: Config,
- options: {
- logger: Logger;
- githubCredentialsProvider?: GithubCredentialsProvider;
- },
- ): GithubMultiOrgReaderProcessor;
- // (undocumented)
- getProcessorName(): string;
- // (undocumented)
- readLocation(
- location: LocationSpec,
- _optional: boolean,
- emit: CatalogProcessorEmit,
- ): Promise;
-}
-
-// @public (undocumented)
-export class GitHubOrgEntityProvider implements EntityProvider {
- constructor(options: {
- id: string;
- orgUrl: string;
- gitHubConfig: GitHubIntegrationConfig;
- logger: Logger;
- githubCredentialsProvider?: GithubCredentialsProvider;
- });
- // (undocumented)
- connect(connection: EntityProviderConnection): Promise;
- // (undocumented)
- static fromConfig(
- config: Config,
- options: {
- id: string;
- orgUrl: string;
- logger: Logger;
- githubCredentialsProvider?: GithubCredentialsProvider;
- },
- ): GitHubOrgEntityProvider;
- // (undocumented)
- getProviderName(): string;
- // (undocumented)
- read(): Promise;
-}
-
-// @public
-export class GithubOrgReaderProcessor implements CatalogProcessor {
- constructor(options: {
- integrations: ScmIntegrationRegistry;
- logger: Logger;
- githubCredentialsProvider?: GithubCredentialsProvider;
- });
- // (undocumented)
- static fromConfig(
- config: Config,
- options: {
- logger: Logger;
- githubCredentialsProvider?: GithubCredentialsProvider;
- },
- ): GithubOrgReaderProcessor;
- // (undocumented)
- getProcessorName(): string;
- // (undocumented)
- readLocation(
- location: LocationSpec,
- _optional: boolean,
- emit: CatalogProcessorEmit,
- ): Promise;
-}
-
-// @public @deprecated (undocumented)
-function inputError(
- atLocation: LocationSpec,
- message: string,
-): CatalogProcessorResult;
-
-// @public @deprecated (undocumented)
-function location_2(
- newLocation: LocationSpec,
- _optional?: boolean,
-): CatalogProcessorResult;
-
// @public (undocumented)
export type LocationAnalyzer = {
analyzeLocation(
@@ -786,50 +451,6 @@ export type LocationEntityProcessorOptions = {
integrations: ScmIntegrationRegistry;
};
-// @public
-export interface LocationInput {
- // @deprecated (undocumented)
- presence?: 'optional' | 'required';
- // (undocumented)
- target: string;
- // (undocumented)
- type: string;
-}
-
-// @public
-export interface LocationService {
- // (undocumented)
- createLocation(
- location: LocationInput,
- dryRun: boolean,
- options?: {
- authorizationToken?: string;
- },
- ): Promise<{
- location: Location_2;
- entities: Entity[];
- exists?: boolean;
- }>;
- // (undocumented)
- deleteLocation(
- id: string,
- options?: {
- authorizationToken?: string;
- },
- ): Promise;
- // (undocumented)
- getLocation(
- id: string,
- options?: {
- authorizationToken?: string;
- },
- ): Promise;
- // (undocumented)
- listLocations(options?: {
- authorizationToken?: string;
- }): Promise;
-}
-
// @public
export type LocationSpec = {
type: string;
@@ -837,34 +458,6 @@ export type LocationSpec = {
presence?: 'optional' | 'required';
};
-// @public
-export interface LocationStore {
- // (undocumented)
- createLocation(location: LocationInput): Promise;
- // (undocumented)
- deleteLocation(id: string): Promise;
- // (undocumented)
- getLocation(id: string): Promise;
- // (undocumented)
- listLocations(): Promise;
-}
-
-// @public @deprecated (undocumented)
-function notFoundError(
- atLocation: LocationSpec,
- message: string,
-): CatalogProcessorResult;
-
-// @public (undocumented)
-export type PageInfo =
- | {
- hasNextPage: false;
- }
- | {
- hasNextPage: true;
- endCursor: string;
- };
-
// @public (undocumented)
export function parseEntityYaml(
data: Buffer,
@@ -961,62 +554,6 @@ export const processingResult: Readonly<{
readonly relation: (spec: EntityRelationSpec) => CatalogProcessorResult;
}>;
-// @public
-export type RecursivePartial = {
- [P in keyof T]?: T[P] extends (infer U)[]
- ? RecursivePartial[]
- : T[P] extends object
- ? RecursivePartial
- : T[P];
-};
-
-// @public @deprecated
-export type RefreshIntervalFunction = () => number;
-
-// @public
-export type RefreshOptions = {
- entityRef: string;
- authorizationToken?: string;
-};
-
-// @public
-export interface RefreshService {
- refresh(options: RefreshOptions): Promise;
-}
-
-// @public @deprecated (undocumented)
-function relation(spec: EntityRelationSpec): CatalogProcessorResult;
-
-declare namespace results {
- export {
- notFoundError,
- inputError,
- generalError,
- location_2 as location,
- entity,
- relation,
- };
-}
-export { results };
-
-// @public
-export interface RouterOptions {
- // (undocumented)
- config: Config;
- // (undocumented)
- entitiesCatalog?: EntitiesCatalog;
- // (undocumented)
- locationAnalyzer?: LocationAnalyzer;
- // (undocumented)
- locationService: LocationService;
- // (undocumented)
- logger: Logger;
- // (undocumented)
- permissionIntegrationRouter?: express.Router;
- // (undocumented)
- refreshService?: RefreshService;
-}
-
// @public (undocumented)
export class UrlReaderProcessor implements CatalogProcessor {
constructor(options: { reader: UrlReader; logger: Logger });
diff --git a/plugins/catalog-backend/knexfile.js b/plugins/catalog-backend/knexfile.js
index 4c8be42673..4cf9ef77c3 100644
--- a/plugins/catalog-backend/knexfile.js
+++ b/plugins/catalog-backend/knexfile.js
@@ -17,7 +17,7 @@
// This file makes it possible to run "yarn knex migrate:make some_file_name"
// to assist in making new migrations
module.exports = {
- client: 'sqlite3',
+ client: 'better-sqlite3',
connection: ':memory:',
useNullAsDefault: true,
migrations: {
diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json
index 700141fb94..54b19f5269 100644
--- a/plugins/catalog-backend/package.json
+++ b/plugins/catalog-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend",
"description": "The Backstage backend plugin that provides the Backstage catalog",
- "version": "0.24.0-next.0",
+ "version": "0.24.0",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -34,19 +34,18 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.13.0-next.0",
- "@backstage/catalog-client": "^0.9.0-next.0",
- "@backstage/catalog-model": "^0.13.0-next.0",
+ "@backstage/backend-common": "^0.13.0",
+ "@backstage/catalog-client": "^0.9.0",
+ "@backstage/catalog-model": "^0.13.0",
"@backstage/config": "^0.1.15",
"@backstage/errors": "^0.2.2",
"@backstage/integration": "^0.8.0",
- "@backstage/plugin-catalog-common": "^0.2.2-next.0",
+ "@backstage/plugin-catalog-common": "^0.2.2",
"@backstage/plugin-permission-common": "^0.5.2",
- "@backstage/plugin-permission-node": "^0.5.4-next.0",
- "@backstage/plugin-scaffolder-common": "^0.3.0-next.0",
- "@backstage/plugin-search-common": "^0.3.1-next.0",
+ "@backstage/plugin-permission-node": "^0.5.4",
+ "@backstage/plugin-scaffolder-common": "^0.3.0",
+ "@backstage/plugin-search-common": "^0.3.1",
"@backstage/types": "^0.1.3",
- "@octokit/graphql": "^4.5.8",
"@types/express": "^4.17.6",
"codeowners-utils": "^1.0.2",
"core-js": "^3.6.5",
@@ -69,16 +68,16 @@
"zod": "^3.11.6"
},
"devDependencies": {
- "@backstage/backend-test-utils": "^0.1.21-next.0",
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/backend-test-utils": "^0.1.21",
+ "@backstage/cli": "^0.15.2",
"@backstage/plugin-permission-common": "^0.5.2",
- "@backstage/plugin-search-backend-node": "0.5.1-next.0",
+ "@backstage/plugin-search-backend-node": "0.5.1",
"@types/core-js": "^2.5.4",
"@types/git-url-parse": "^9.0.0",
"@types/lodash": "^4.14.151",
"@types/supertest": "^2.0.8",
"@types/uuid": "^8.0.0",
- "@vscode/sqlite3": "^5.0.7",
+ "better-sqlite3": "^7.5.0",
"msw": "^0.35.0",
"supertest": "^6.1.3",
"wait-for-expect": "^3.0.2",
diff --git a/plugins/catalog-backend/src/api/deprecatedResult.ts b/plugins/catalog-backend/src/api/deprecatedResult.ts
deleted file mode 100644
index e616f3cf7d..0000000000
--- a/plugins/catalog-backend/src/api/deprecatedResult.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2020 The Backstage Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import { InputError, NotFoundError } from '@backstage/errors';
-import { Entity } from '@backstage/catalog-model';
-import { CatalogProcessorResult } from './processor';
-import { EntityRelationSpec, LocationSpec } from './common';
-
-// NOTE: This entire file is deprecated and should be eventually removed along with the `result` export
-
-/**
- * @public
- * @deprecated import the processingResult symbol instead and use its fields
- */
-export function notFoundError(
- atLocation: LocationSpec,
- message: string,
-): CatalogProcessorResult {
- return {
- type: 'error',
- location: atLocation,
- error: new NotFoundError(message),
- };
-}
-
-/**
- * @public
- * @deprecated import the processingResult symbol instead and use its fields
- */
-export function inputError(
- atLocation: LocationSpec,
- message: string,
-): CatalogProcessorResult {
- return {
- type: 'error',
- location: atLocation,
- error: new InputError(message),
- };
-}
-
-/**
- * @public
- * @deprecated import the processingResult symbol instead and use its fields
- */
-export function generalError(
- atLocation: LocationSpec,
- message: string,
-): CatalogProcessorResult {
- return { type: 'error', location: atLocation, error: new Error(message) };
-}
-
-/**
- * @public
- * @deprecated import the processingResult symbol instead and use its fields
- */
-export function location(
- newLocation: LocationSpec,
- _optional?: boolean,
-): CatalogProcessorResult {
- return { type: 'location', location: newLocation };
-}
-
-/**
- * @public
- * @deprecated import the processingResult symbol instead and use its fields
- */
-export function entity(
- atLocation: LocationSpec,
- newEntity: Entity,
-): CatalogProcessorResult {
- return { type: 'entity', location: atLocation, entity: newEntity };
-}
-
-/**
- * @public
- * @deprecated import the processingResult symbol instead and use its fields
- */
-export function relation(spec: EntityRelationSpec): CatalogProcessorResult {
- return { type: 'relation', relation: spec };
-}
diff --git a/plugins/catalog-backend/src/api/index.ts b/plugins/catalog-backend/src/api/index.ts
index 3f1c627743..1cb4b71aa3 100644
--- a/plugins/catalog-backend/src/api/index.ts
+++ b/plugins/catalog-backend/src/api/index.ts
@@ -14,10 +14,6 @@
* limitations under the License.
*/
-import * as results from './deprecatedResult';
-
-export { results };
-
export { processingResult } from './processingResult';
export type { EntityRelationSpec, LocationSpec } from './common';
export type {
diff --git a/plugins/catalog-backend/src/catalog/index.ts b/plugins/catalog-backend/src/catalog/index.ts
index 59f67b2f52..ba34673bba 100644
--- a/plugins/catalog-backend/src/catalog/index.ts
+++ b/plugins/catalog-backend/src/catalog/index.ts
@@ -14,15 +14,4 @@
* limitations under the License.
*/
-export type {
- EntitiesCatalog,
- EntitiesRequest,
- EntitiesResponse,
- EntitiesSearchFilter,
- EntityAncestryResponse,
- EntityFacetsRequest,
- EntityFacetsResponse,
- EntityFilter,
- EntityPagination,
- PageInfo,
-} from './types';
+export type { EntitiesSearchFilter, EntityFilter } from './types';
diff --git a/plugins/catalog-backend/src/catalog/types.ts b/plugins/catalog-backend/src/catalog/types.ts
index b575b96c6c..34060814aa 100644
--- a/plugins/catalog-backend/src/catalog/types.ts
+++ b/plugins/catalog-backend/src/catalog/types.ts
@@ -31,7 +31,6 @@ export type EntityFilter =
/**
* A pagination rule for entities.
- * @public
*/
export type EntityPagination = {
limit?: number;
@@ -60,7 +59,6 @@ export type EntitiesSearchFilter = {
values?: string[];
};
-/** @public */
export type PageInfo =
| {
hasNextPage: false;
@@ -70,7 +68,6 @@ export type PageInfo =
endCursor: string;
};
-/** @public */
export type EntitiesRequest = {
filter?: EntityFilter;
fields?: (entity: Entity) => Entity;
@@ -78,13 +75,11 @@ export type EntitiesRequest = {
authorizationToken?: string;
};
-/** @public */
export type EntitiesResponse = {
entities: Entity[];
pageInfo: PageInfo;
};
-/** @public */
export type EntityAncestryResponse = {
rootEntityRef: string;
items: Array<{
@@ -95,8 +90,6 @@ export type EntityAncestryResponse = {
/**
* The request shape for {@link EntitiesCatalog.facets}.
- *
- * @public
*/
export interface EntityFacetsRequest {
/**
@@ -121,8 +114,6 @@ export interface EntityFacetsRequest {
/**
* The response shape for {@link EntitiesCatalog.facets}.
- *
- * @public
*/
export interface EntityFacetsResponse {
/**
@@ -131,8 +122,7 @@ export interface EntityFacetsResponse {
facets: Record>;
}
-/** @public */
-export type EntitiesCatalog = {
+export interface EntitiesCatalog {
/**
* Fetch entities.
*
@@ -167,4 +157,4 @@ export type EntitiesCatalog = {
* @param request - Request options
*/
facets(request: EntityFacetsRequest): Promise;
-};
+}
diff --git a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts
index 6ffd054435..061be0a767 100644
--- a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts
+++ b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts
@@ -35,7 +35,7 @@ import {
ListParentsResult,
} from './types';
import { DeferredEntity } from '../processing/types';
-import { RefreshIntervalFunction } from '../processing/refresh';
+import { ProcessingIntervalFunction } from '../processing/refresh';
import { rethrowError, timestampToDateTime } from './conversion';
import { initDatabaseMetrics } from './metrics';
import {
@@ -59,7 +59,7 @@ export class DefaultProcessingDatabase implements ProcessingDatabase {
private readonly options: {
database: Knex;
logger: Logger;
- refreshInterval: RefreshIntervalFunction;
+ refreshInterval: ProcessingIntervalFunction;
},
) {
initDatabaseMetrics(options.database);
diff --git a/plugins/catalog-backend/src/database/conversion.ts b/plugins/catalog-backend/src/database/conversion.ts
index 54b642f3ff..827ae9b367 100644
--- a/plugins/catalog-backend/src/database/conversion.ts
+++ b/plugins/catalog-backend/src/database/conversion.ts
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import { isDatabaseConflictError } from '@backstage/backend-common';
import { ConflictError, InputError } from '@backstage/errors';
import { DateTime } from 'luxon';
@@ -47,10 +48,7 @@ export function timestampToDateTime(input: Date | string): DateTime {
* Rethrows an error, possibly translating it to a more precise error type.
*/
export function rethrowError(e: any): never {
- if (
- /SQLITE_CONSTRAINT: UNIQUE/.test(e.message) ||
- /unique constraint/.test(e.message)
- ) {
+ if (isDatabaseConflictError(e)) {
throw new ConflictError(`Rejected due to a conflicting entity`, e);
}
diff --git a/plugins/catalog-backend/src/index.ts b/plugins/catalog-backend/src/index.ts
index 4c1e753300..437c1f4598 100644
--- a/plugins/catalog-backend/src/index.ts
+++ b/plugins/catalog-backend/src/index.ts
@@ -25,7 +25,6 @@ export * from './catalog';
export * from './ingestion';
export * from './modules';
export * from './search';
-export * from './util';
export * from './processing';
export * from './service';
export * from './permissions';
diff --git a/plugins/catalog-backend/src/ingestion/CatalogRules.ts b/plugins/catalog-backend/src/ingestion/CatalogRules.ts
index e4bfdb8d0f..587a0bd7d5 100644
--- a/plugins/catalog-backend/src/ingestion/CatalogRules.ts
+++ b/plugins/catalog-backend/src/ingestion/CatalogRules.ts
@@ -23,8 +23,6 @@ import { LocationSpec } from '../api';
* Rules to apply to catalog entities.
*
* An undefined list of matchers means match all, an empty list of matchers means match none.
- *
- * @public
*/
export type CatalogRule = {
allow: Array<{
@@ -39,8 +37,6 @@ export type CatalogRule = {
/**
* Decides whether an entity from a given location is allowed to enter the
* catalog, according to some rule set.
- *
- * @public
*/
export type CatalogRulesEnforcer = {
isAllowed(entity: Entity, location: LocationSpec): boolean;
@@ -49,8 +45,6 @@ export type CatalogRulesEnforcer = {
/**
* Implements the default catalog rule set, consuming the config keys
* `catalog.rules` and `catalog.locations.[].rules`.
- *
- * @public
*/
export class DefaultCatalogRulesEnforcer implements CatalogRulesEnforcer {
/**
@@ -131,7 +125,7 @@ export class DefaultCatalogRulesEnforcer implements CatalogRulesEnforcer {
constructor(private readonly rules: CatalogRule[]) {}
/**
- * Checks wether a specific entity/location combination is allowed
+ * Checks whether a specific entity/location combination is allowed
* according to the configured rules.
*/
isAllowed(entity: Entity, location: LocationSpec) {
diff --git a/plugins/catalog-backend/src/ingestion/index.ts b/plugins/catalog-backend/src/ingestion/index.ts
index 1f4729b041..c97d029b5c 100644
--- a/plugins/catalog-backend/src/ingestion/index.ts
+++ b/plugins/catalog-backend/src/ingestion/index.ts
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-export { DefaultCatalogRulesEnforcer } from './CatalogRules';
-export type { CatalogRule, CatalogRulesEnforcer } from './CatalogRules';
export type {
AnalyzeLocationEntityField,
AnalyzeLocationExistingEntity,
diff --git a/plugins/catalog-backend/src/modules/codeowners/CodeOwnersProcessor.test.ts b/plugins/catalog-backend/src/modules/codeowners/CodeOwnersProcessor.test.ts
index 8cf250de2a..ac4415549e 100644
--- a/plugins/catalog-backend/src/modules/codeowners/CodeOwnersProcessor.test.ts
+++ b/plugins/catalog-backend/src/modules/codeowners/CodeOwnersProcessor.test.ts
@@ -76,7 +76,7 @@ describe('CodeOwnersProcessor', () => {
expect(result).toEqual(entity);
});
- it('should ingore invalid locations type', async () => {
+ it('should ignore invalid locations type', async () => {
const { entity, processor } = setupTest();
const result = await processor.preProcessEntity(
diff --git a/plugins/catalog-backend/src/modules/core/DefaultLocationStore.ts b/plugins/catalog-backend/src/modules/core/DefaultLocationStore.ts
index d637f4eda0..0d4bedabbb 100644
--- a/plugins/catalog-backend/src/modules/core/DefaultLocationStore.ts
+++ b/plugins/catalog-backend/src/modules/core/DefaultLocationStore.ts
@@ -22,7 +22,7 @@ import { DbLocationsRow } from '../../database/tables';
import { getEntityLocationRef } from '../../processing/util';
import { EntityProvider, EntityProviderConnection } from '../../api';
import { locationSpecToLocationEntity } from '../../util/conversion';
-import { LocationInput, LocationStore } from '../../service';
+import { LocationInput, LocationStore } from '../../service/types';
export class DefaultLocationStore implements LocationStore, EntityProvider {
private _connection: EntityProviderConnection | undefined;
diff --git a/plugins/catalog-backend/src/modules/index.ts b/plugins/catalog-backend/src/modules/index.ts
index c541250c46..10ebf65fed 100644
--- a/plugins/catalog-backend/src/modules/index.ts
+++ b/plugins/catalog-backend/src/modules/index.ts
@@ -14,7 +14,5 @@
* limitations under the License.
*/
-export * from './bitbucket';
export * from './codeowners';
export * from './core';
-export * from './github';
diff --git a/plugins/catalog-backend/src/permissions/rules/isEntityOwner.test.ts b/plugins/catalog-backend/src/permissions/rules/isEntityOwner.test.ts
index 8e20655393..11304c768c 100644
--- a/plugins/catalog-backend/src/permissions/rules/isEntityOwner.test.ts
+++ b/plugins/catalog-backend/src/permissions/rules/isEntityOwner.test.ts
@@ -30,11 +30,6 @@ describe('isEntityOwner', () => {
{
type: 'ownedBy',
targetRef: 'user:default/spiderman',
- target: {
- kind: 'user',
- namespace: 'default',
- name: 'spiderman',
- },
},
],
};
@@ -54,11 +49,6 @@ describe('isEntityOwner', () => {
{
type: 'ownedBy',
targetRef: 'user:default/green-goblin',
- target: {
- kind: 'user',
- namespace: 'default',
- name: 'green-goblin',
- },
},
],
};
diff --git a/plugins/catalog-backend/src/processing/index.ts b/plugins/catalog-backend/src/processing/index.ts
index aec6a5d71c..b392c3aa76 100644
--- a/plugins/catalog-backend/src/processing/index.ts
+++ b/plugins/catalog-backend/src/processing/index.ts
@@ -14,20 +14,7 @@
* limitations under the License.
*/
-export type {
- CatalogProcessingOrchestrator,
- CatalogProcessingEngine,
- EntityProcessingRequest,
- EntityProcessingResult,
- DeferredEntity,
-} from './types';
-export { DefaultCatalogProcessingOrchestrator } from './DefaultCatalogProcessingOrchestrator';
+export type { CatalogProcessingEngine, DeferredEntity } from './types';
-export {
- createRandomRefreshInterval,
- createRandomProcessingInterval,
-} from './refresh';
-export type {
- RefreshIntervalFunction,
- ProcessingIntervalFunction,
-} from './refresh';
+export { createRandomProcessingInterval } from './refresh';
+export type { ProcessingIntervalFunction } from './refresh';
diff --git a/plugins/catalog-backend/src/processing/refresh.ts b/plugins/catalog-backend/src/processing/refresh.ts
index 941c338912..f9f596cdb9 100644
--- a/plugins/catalog-backend/src/processing/refresh.ts
+++ b/plugins/catalog-backend/src/processing/refresh.ts
@@ -14,35 +14,12 @@
* limitations under the License.
*/
-/**
- * Function that returns the catalog refresh interval in seconds.
- * @deprecated use {@link ProcessingIntervalFunction} instead
- * @public
- */
-export type RefreshIntervalFunction = () => number;
-
/**
* Function that returns the catalog processing interval in seconds.
* @public
*/
export type ProcessingIntervalFunction = () => number;
-/**
- * Creates a function that returns a random refresh interval between minSeconds and maxSeconds.
- * @returns A {@link RefreshIntervalFunction} that provides the next refresh interval
- * @deprecated use {@link createRandomProcessingInterval} instead
- * @public
- */
-export function createRandomRefreshInterval(options: {
- minSeconds: number;
- maxSeconds: number;
-}): RefreshIntervalFunction {
- const { minSeconds, maxSeconds } = options;
- return () => {
- return Math.random() * (maxSeconds - minSeconds) + minSeconds;
- };
-}
-
/**
* Creates a function that returns a random processing interval between minSeconds and maxSeconds.
* @returns A {@link ProcessingIntervalFunction} that provides the next processing interval
diff --git a/plugins/catalog-backend/src/search/index.ts b/plugins/catalog-backend/src/search/index.ts
index eb5b1e7c22..2602f0fada 100644
--- a/plugins/catalog-backend/src/search/index.ts
+++ b/plugins/catalog-backend/src/search/index.ts
@@ -17,14 +17,6 @@
export { DefaultCatalogCollatorFactory } from './DefaultCatalogCollatorFactory';
export type { DefaultCatalogCollatorFactoryOptions } from './DefaultCatalogCollatorFactory';
-import { CatalogEntityDocument as CatalogEntityDocumentType } from '@backstage/plugin-catalog-common';
-
-/**
- * @deprecated import from `@backstage/plugin-catalog-common` instead
- * @public
- */
-export type CatalogEntityDocument = CatalogEntityDocumentType;
-
/**
* todo(backstage/techdocs-core): stop exporting this in a future release.
*/
diff --git a/plugins/catalog-backend/src/service/CatalogBuilder.ts b/plugins/catalog-backend/src/service/CatalogBuilder.ts
index 768118404e..fb4ed6086f 100644
--- a/plugins/catalog-backend/src/service/CatalogBuilder.ts
+++ b/plugins/catalog-backend/src/service/CatalogBuilder.ts
@@ -28,15 +28,11 @@ import {
stringifyEntityRef,
Validators,
} from '@backstage/catalog-model';
-import {
- GithubCredentialsProvider,
- ScmIntegrations,
- DefaultGithubCredentialsProvider,
-} from '@backstage/integration';
+import { ScmIntegrations } from '@backstage/integration';
import { createHash } from 'crypto';
import { Router } from 'express';
import lodash, { keyBy } from 'lodash';
-import { EntitiesCatalog, EntitiesSearchFilter } from '../catalog';
+import { EntitiesSearchFilter } from '../catalog';
import {
CatalogProcessor,
@@ -45,12 +41,9 @@ import {
} from '../api';
import {
AnnotateLocationEntityProcessor,
- BitbucketDiscoveryProcessor,
BuiltinKindsEntityProcessor,
CodeOwnersProcessor,
FileReaderProcessor,
- GithubDiscoveryProcessor,
- GithubOrgReaderProcessor,
PlaceholderProcessor,
PlaceholderResolver,
UrlReaderProcessor,
@@ -75,7 +68,6 @@ import { DefaultCatalogProcessingOrchestrator } from '../processing/DefaultCatal
import { Stitcher } from '../stitching/Stitcher';
import {
createRandomProcessingInterval,
- RefreshIntervalFunction,
ProcessingIntervalFunction,
} from '../processing/refresh';
import { createRouter } from './createRouter';
@@ -84,7 +76,6 @@ import { AuthorizedRefreshService } from './AuthorizedRefreshService';
import { DefaultCatalogRulesEnforcer } from '../ingestion/CatalogRules';
import { Config } from '@backstage/config';
import { Logger } from 'winston';
-import { LocationService } from './types';
import { connectEntityProviders } from '../processing/connectEntityProviders';
import { permissionRules as catalogPermissionRules } from '../permissions/rules';
import { PermissionAuthorizer } from '@backstage/plugin-permission-common';
@@ -186,25 +177,6 @@ export class CatalogBuilder {
return this;
}
- /**
- * Refresh interval determines how often entities should be refreshed.
- * Seconds provided will be multiplied by 1.5
- * The default refresh duration is 100-150 seconds.
- * setting this too low will potentially deplete request quotas to upstream services.
- *
- * @deprecated use {@link CatalogBuilder#setProcessingIntervalSeconds} instead
- */
- setRefreshIntervalSeconds(seconds: number): CatalogBuilder {
- this.env.logger.warn(
- '[DEPRECATION] - CatalogBuilder.setRefreshIntervalSeconds is deprecated. Use CatalogBuilder.setProcessingIntervalSeconds instead.',
- );
- this.processingInterval = createRandomProcessingInterval({
- minSeconds: seconds,
- maxSeconds: seconds * 1.5,
- });
- return this;
- }
-
/**
* Processing interval determines how often entities should be processed.
* Seconds provided will be multiplied by 1.5
@@ -219,20 +191,6 @@ export class CatalogBuilder {
return this;
}
- /**
- * Overwrites the default refresh interval function used to spread
- * entity updates in the catalog.
- *
- * @deprecated use {@link CatalogBuilder#setProcessingInterval} instead
- */
- setRefreshInterval(refreshInterval: RefreshIntervalFunction): CatalogBuilder {
- this.env.logger.warn(
- '[DEPRECATION] - CatalogBuilder.setRefreshInterval is deprecated. Use CatalogBuilder.setProcessingInterval instead.',
- );
- this.processingInterval = refreshInterval;
- return this;
- }
-
/**
* Overwrites the default processing interval function used to spread
* entity updates in the catalog.
@@ -352,20 +310,9 @@ export class CatalogBuilder {
getDefaultProcessors(): CatalogProcessor[] {
const { config, logger, reader } = this.env;
const integrations = ScmIntegrations.fromConfig(config);
- const githubCredentialsProvider: GithubCredentialsProvider =
- DefaultGithubCredentialsProvider.fromIntegrations(integrations);
return [
new FileReaderProcessor(),
- BitbucketDiscoveryProcessor.fromConfig(config, { logger }),
- GithubDiscoveryProcessor.fromConfig(config, {
- logger,
- githubCredentialsProvider,
- }),
- GithubOrgReaderProcessor.fromConfig(config, {
- logger,
- githubCredentialsProvider,
- }),
new UrlReaderProcessor({ reader, logger }),
CodeOwnersProcessor.fromConfig(config, { logger, reader }),
new AnnotateLocationEntityProcessor({ integrations }),
@@ -407,10 +354,7 @@ export class CatalogBuilder {
* Wires up and returns all of the component parts of the catalog
*/
async build(): Promise<{
- entitiesCatalog: EntitiesCatalog;
- locationAnalyzer: LocationAnalyzer;
processingEngine: CatalogProcessingEngine;
- locationService: LocationService;
router: Router;
}> {
const { config, database, logger, permissions } = this.env;
@@ -512,10 +456,7 @@ export class CatalogBuilder {
await connectEntityProviders(processingDatabase, entityProviders);
return {
- entitiesCatalog,
- locationAnalyzer,
processingEngine,
- locationService,
router,
};
}
@@ -567,6 +508,8 @@ export class CatalogBuilder {
// Add the ones (if any) that the user added
processors.push(...this.processors);
+ this.checkMissingExternalProcessors(processors);
+
return processors;
}
@@ -595,4 +538,88 @@ export class CatalogBuilder {
);
}
}
+
+ // TODO(freben): This can be removed no sooner than June 2022, after adopters have had some time to adapt to the new package structure
+ private checkMissingExternalProcessors(processors: CatalogProcessor[]) {
+ const skipCheckVarName = 'BACKSTAGE_CATALOG_SKIP_MISSING_PROCESSORS_CHECK';
+ if (process.env[skipCheckVarName]) {
+ return;
+ }
+
+ const locationTypes = new Set(
+ this.env.config
+ .getOptionalConfigArray('catalog.locations')
+ ?.map(l => l.getString('type')) ?? [],
+ );
+ const processorNames = new Set(processors.map(p => p.getProcessorName()));
+
+ function check(
+ locationType: string,
+ processorName: string,
+ installationUrl: string,
+ ) {
+ if (
+ locationTypes.has(locationType) &&
+ !processorNames.has(processorName)
+ ) {
+ throw new Error(
+ [
+ `Your config contains a "catalog.locations" entry of type ${locationType},`,
+ `but does not have the corresponding catalog processor ${processorName} installed.`,
+ `This processor used to be built into the catalog itself, but is now moved to an`,
+ `external module that has to be installed manually. Please follow the installation`,
+ `instructions at ${installationUrl} if you are using this ability, or remove the`,
+ `location from your app config if you do not. You can also silence this check entirely`,
+ `by setting the environment variable ${skipCheckVarName} to 'true'.`,
+ ].join(' '),
+ );
+ }
+ }
+
+ check(
+ 'aws-cloud-accounts',
+ 'AwsOrganizationCloudAccountProcessor',
+ 'https://backstage.io/docs/integrations',
+ );
+ check(
+ 's3-discovery',
+ 'AwsS3DiscoveryProcessor',
+ 'https://backstage.io/docs/integrations/aws-s3/discovery',
+ );
+ check(
+ 'azure-discovery',
+ 'AzureDevOpsDiscoveryProcessor',
+ 'https://backstage.io/docs/integrations/azure/discovery',
+ );
+ check(
+ 'bitbucket-discovery',
+ 'BitbucketDiscoveryProcessor',
+ 'https://backstage.io/docs/integrations/bitbucket/discovery',
+ );
+ check(
+ 'github-discovery',
+ 'GithubDiscoveryProcessor',
+ 'https://backstage.io/docs/integrations/github/discovery',
+ );
+ check(
+ 'github-org',
+ 'GithubOrgReaderProcessor',
+ 'https://backstage.io/docs/integrations/github/org',
+ );
+ check(
+ 'gitlab-discovery',
+ 'GitLabDiscoveryProcessor',
+ 'https://backstage.io/docs/integrations/gitlab/discovery',
+ );
+ check(
+ 'ldap-org',
+ 'LdapOrgReaderProcessor',
+ 'https://backstage.io/docs/integrations/ldap/org',
+ );
+ check(
+ 'microsoft-graph-org',
+ 'MicrosoftGraphOrgReaderProcessor',
+ 'https://backstage.io/docs/integrations/azure/org',
+ );
+ }
}
diff --git a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts
index f8b68bebc5..eaa0ce0189 100644
--- a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts
+++ b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts
@@ -208,9 +208,10 @@ export class DefaultEntitiesCatalog implements EntitiesCatalog {
// sure that all adopters have re-stitched their entities so that the new
// targetRef field is present on them, and that they have stopped consuming
// the now-removed old field
+ // TODO(jhaals): Remove this in April 2022
for (const entity of entities) {
if (entity.relations) {
- for (const relation of entity.relations) {
+ for (const relation of entity.relations as any) {
if (!relation.targetRef && relation.target) {
// This is the case where an old-form entity, not yet stitched with
// the updated code, was in the database
diff --git a/plugins/catalog-backend/src/service/createRouter.test.ts b/plugins/catalog-backend/src/service/createRouter.test.ts
index 8db15cb4a1..1602d07d28 100644
--- a/plugins/catalog-backend/src/service/createRouter.test.ts
+++ b/plugins/catalog-backend/src/service/createRouter.test.ts
@@ -21,7 +21,7 @@ import type { Location } from '@backstage/catalog-client';
import type { Entity } from '@backstage/catalog-model';
import express from 'express';
import request from 'supertest';
-import { EntitiesCatalog } from '../catalog';
+import { EntitiesCatalog } from '../catalog/types';
import { LocationInput, LocationService, RefreshService } from './types';
import { basicEntityFilter } from './request';
import { createRouter } from './createRouter';
diff --git a/plugins/catalog-backend/src/service/createRouter.ts b/plugins/catalog-backend/src/service/createRouter.ts
index 56121f4155..a35309035f 100644
--- a/plugins/catalog-backend/src/service/createRouter.ts
+++ b/plugins/catalog-backend/src/service/createRouter.ts
@@ -22,7 +22,7 @@ import express from 'express';
import Router from 'express-promise-router';
import { Logger } from 'winston';
import yn from 'yn';
-import { EntitiesCatalog } from '../catalog';
+import { EntitiesCatalog } from '../catalog/types';
import { LocationAnalyzer } from '../ingestion/types';
import {
basicEntityFilter,
@@ -158,7 +158,9 @@ export async function createRouter(
async (req, res) => {
const { kind, namespace, name } = req.params;
const entityRef = stringifyEntityRef({ kind, namespace, name });
- const response = await entitiesCatalog.entityAncestry(entityRef);
+ const response = await entitiesCatalog.entityAncestry(entityRef, {
+ authorizationToken: getBearerToken(req.header('authorization')),
+ });
res.status(200).json(response);
},
)
diff --git a/plugins/catalog-backend/src/service/index.ts b/plugins/catalog-backend/src/service/index.ts
index e1c7f54475..b1e91e4382 100644
--- a/plugins/catalog-backend/src/service/index.ts
+++ b/plugins/catalog-backend/src/service/index.ts
@@ -14,14 +14,5 @@
* limitations under the License.
*/
-export type {
- LocationService,
- RefreshService,
- RefreshOptions,
- LocationStore,
- LocationInput,
-} from './types';
-export { createRouter } from './createRouter';
-export type { RouterOptions } from './createRouter';
export type { CatalogEnvironment } from './CatalogBuilder';
export { CatalogBuilder } from './CatalogBuilder';
diff --git a/plugins/catalog-backend/src/service/request/parseEntityPaginationParams.ts b/plugins/catalog-backend/src/service/request/parseEntityPaginationParams.ts
index c91c0b0214..87b19e13de 100644
--- a/plugins/catalog-backend/src/service/request/parseEntityPaginationParams.ts
+++ b/plugins/catalog-backend/src/service/request/parseEntityPaginationParams.ts
@@ -15,7 +15,7 @@
*/
import { InputError } from '@backstage/errors';
-import { EntityPagination } from '../../catalog';
+import { EntityPagination } from '../../catalog/types';
import { parseIntegerParam, parseStringParam } from './common';
/**
diff --git a/plugins/catalog-backend/src/service/request/parseEntityTransformParams.ts b/plugins/catalog-backend/src/service/request/parseEntityTransformParams.ts
index 7474b12c11..9935da07a8 100644
--- a/plugins/catalog-backend/src/service/request/parseEntityTransformParams.ts
+++ b/plugins/catalog-backend/src/service/request/parseEntityTransformParams.ts
@@ -17,7 +17,7 @@
import { Entity } from '@backstage/catalog-model';
import { InputError } from '@backstage/errors';
import lodash from 'lodash';
-import { RecursivePartial } from '../../util';
+import { RecursivePartial } from '../../util/RecursivePartial';
import { parseStringsParam } from './common';
export function parseEntityTransformParams(
diff --git a/plugins/catalog-backend/src/service/standaloneServer.ts b/plugins/catalog-backend/src/service/standaloneServer.ts
index ba5604a561..e48515fb8b 100644
--- a/plugins/catalog-backend/src/service/standaloneServer.ts
+++ b/plugins/catalog-backend/src/service/standaloneServer.ts
@@ -46,7 +46,9 @@ export async function startStandaloneServer(
const database = useHotMemoize(module, () => {
const manager = DatabaseManager.fromConfig(
new ConfigReader({
- backend: { database: { client: 'sqlite3', connection: ':memory:' } },
+ backend: {
+ database: { client: 'better-sqlite3', connection: ':memory:' },
+ },
}),
);
return manager.forPlugin('catalog');
diff --git a/plugins/catalog-backend/src/service/types.ts b/plugins/catalog-backend/src/service/types.ts
index fc315b9d89..f6cfa2e783 100644
--- a/plugins/catalog-backend/src/service/types.ts
+++ b/plugins/catalog-backend/src/service/types.ts
@@ -25,8 +25,6 @@ import { Location } from '@backstage/catalog-client';
export interface LocationInput {
type: string;
target: string;
- /** @deprecated This field is ignored and will be removed */
- presence?: 'optional' | 'required';
}
/**
diff --git a/plugins/catalog-backend/src/stitching/Stitcher.test.ts b/plugins/catalog-backend/src/stitching/Stitcher.test.ts
index 9df4bedd60..9accebf1fc 100644
--- a/plugins/catalog-backend/src/stitching/Stitcher.test.ts
+++ b/plugins/catalog-backend/src/stitching/Stitcher.test.ts
@@ -94,11 +94,6 @@ describe('Stitcher', () => {
{
type: 'looksAt',
targetRef: 'k:ns/other',
- target: {
- kind: 'k',
- namespace: 'ns',
- name: 'other',
- },
},
],
apiVersion: 'a',
@@ -107,7 +102,6 @@ describe('Stitcher', () => {
name: 'n',
namespace: 'ns',
etag: expect.any(String),
- generation: 1,
uid: 'my-id',
},
spec: {
@@ -161,20 +155,10 @@ describe('Stitcher', () => {
{
type: 'looksAt',
targetRef: 'k:ns/other',
- target: {
- kind: 'k',
- namespace: 'ns',
- name: 'other',
- },
},
{
type: 'looksAt',
targetRef: 'k:ns/third',
- target: {
- kind: 'k',
- namespace: 'ns',
- name: 'third',
- },
},
]),
apiVersion: 'a',
@@ -183,7 +167,6 @@ describe('Stitcher', () => {
name: 'n',
namespace: 'ns',
etag: expect.any(String),
- generation: 1,
uid: 'my-id',
},
spec: {
diff --git a/plugins/catalog-backend/src/stitching/Stitcher.ts b/plugins/catalog-backend/src/stitching/Stitcher.ts
index 37b86fef46..c31052c01e 100644
--- a/plugins/catalog-backend/src/stitching/Stitcher.ts
+++ b/plugins/catalog-backend/src/stitching/Stitcher.ts
@@ -17,7 +17,6 @@
import { ENTITY_STATUS_CATALOG_PROCESSING_TYPE } from '@backstage/catalog-client';
import {
AlphaEntity,
- parseEntityRef,
EntityRelation,
EntityStatusItem,
} from '@backstage/catalog-model';
@@ -186,8 +185,6 @@ export class Stitcher {
.filter(row => row.relationType /* exclude null row, if relevant */)
.map(row => ({
type: row.relationType!,
- // TODO(freben): This field is deprecated and should be removed in a future release
- target: parseEntityRef(row.relationTarget!),
targetRef: row.relationTarget!,
}));
if (statusItems.length) {
@@ -205,7 +202,6 @@ export class Stitcher {
}
entity.metadata.uid = entityId;
- entity.metadata.generation = 1;
if (!entity.metadata.etag) {
// If the original data source did not have its own etag handling,
// use the hash as a good-quality etag
diff --git a/plugins/catalog-backend/src/stitching/buildEntitySearch.test.ts b/plugins/catalog-backend/src/stitching/buildEntitySearch.test.ts
index 52e3392676..e18f1c0c48 100644
--- a/plugins/catalog-backend/src/stitching/buildEntitySearch.test.ts
+++ b/plugins/catalog-backend/src/stitching/buildEntitySearch.test.ts
@@ -62,7 +62,6 @@ describe('buildEntitySearch', () => {
namespace: 'namespace',
uid: 'uid',
etag: 'etag',
- generation: 'generation',
c: 'c',
},
d: 'd',
@@ -144,12 +143,10 @@ describe('buildEntitySearch', () => {
{
type: 't1',
targetRef: 'k:ns/a',
- target: { kind: 'k', namespace: 'ns', name: 'a' },
},
{
type: 't2',
targetRef: 'k:ns/b',
- target: { kind: 'k', namespace: 'ns', name: 'b' },
},
],
apiVersion: 'a',
@@ -193,12 +190,10 @@ describe('buildEntitySearch', () => {
{
type: 'dup',
targetRef: 'k:ns/a',
- target: { kind: 'k', namespace: 'ns', name: 'a' },
},
{
type: 'DUP',
targetRef: 'k:ns/b',
- target: { kind: 'k', namespace: 'ns', name: 'b' },
},
],
apiVersion: 'a',
diff --git a/plugins/catalog-backend/src/stitching/buildEntitySearch.ts b/plugins/catalog-backend/src/stitching/buildEntitySearch.ts
index cd8a3735de..54e5ffa738 100644
--- a/plugins/catalog-backend/src/stitching/buildEntitySearch.ts
+++ b/plugins/catalog-backend/src/stitching/buildEntitySearch.ts
@@ -29,7 +29,6 @@ const SPECIAL_KEYS = [
'metadata.namespace',
'metadata.uid',
'metadata.etag',
- 'metadata.generation',
];
// The maximum length allowed for search values. These columns are indexed, and
diff --git a/plugins/catalog-backend/src/util/RecursivePartial.ts b/plugins/catalog-backend/src/util/RecursivePartial.ts
index 92e1ab9296..c452836f34 100644
--- a/plugins/catalog-backend/src/util/RecursivePartial.ts
+++ b/plugins/catalog-backend/src/util/RecursivePartial.ts
@@ -16,7 +16,7 @@
/**
* Makes all keys of an entire hierarchy optional.
- * @public
+ * @ignore
*/
export type RecursivePartial = {
[P in keyof T]?: T[P] extends (infer U)[]
diff --git a/plugins/catalog-common/CHANGELOG.md b/plugins/catalog-common/CHANGELOG.md
index be795cc898..4e5bb6571a 100644
--- a/plugins/catalog-common/CHANGELOG.md
+++ b/plugins/catalog-common/CHANGELOG.md
@@ -1,5 +1,13 @@
# @backstage/plugin-catalog-common
+## 0.2.2
+
+### Patch Changes
+
+- b1aacbf96a: Applied the fix for the `/alpha` entry point resolution that was part of the `v0.70.1` release of Backstage.
+- Updated dependencies
+ - @backstage/search-common@0.3.1
+
## 0.2.2-next.0
### Patch Changes
diff --git a/plugins/catalog-common/package.json b/plugins/catalog-common/package.json
index 9a6b11e517..fe131bd22f 100644
--- a/plugins/catalog-common/package.json
+++ b/plugins/catalog-common/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-common",
"description": "Common functionalities for the catalog plugin",
- "version": "0.2.2-next.0",
+ "version": "0.2.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -35,10 +35,10 @@
},
"dependencies": {
"@backstage/plugin-permission-common": "^0.5.2",
- "@backstage/search-common": "^0.3.1-next.0"
+ "@backstage/search-common": "^0.3.1"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0"
+ "@backstage/cli": "^0.15.2"
},
"files": [
"dist",
diff --git a/plugins/catalog-graph/CHANGELOG.md b/plugins/catalog-graph/CHANGELOG.md
index 84006ba4de..5a22ee83b8 100644
--- a/plugins/catalog-graph/CHANGELOG.md
+++ b/plugins/catalog-graph/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/plugin-catalog-graph
+## 0.2.14
+
+### Patch Changes
+
+- bf95bb806c: Remove usages of now-removed `CatalogApi.getEntityByName`
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.9.0
+ - @backstage/core-components@0.9.1
+ - @backstage/catalog-model@0.13.0
+ - @backstage/catalog-client@0.9.0
+
## 0.2.14-next.0
### Patch Changes
diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json
index d3b65d1151..d86df7d56c 100644
--- a/plugins/catalog-graph/package.json
+++ b/plugins/catalog-graph/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-catalog-graph",
- "version": "0.2.14-next.0",
+ "version": "0.2.14",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -24,11 +24,11 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/catalog-client": "^0.9.0-next.0",
- "@backstage/catalog-model": "^0.13.0-next.0",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/catalog-client": "^0.9.0",
+ "@backstage/catalog-model": "^0.13.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
- "@backstage/plugin-catalog-react": "^0.9.0-next.0",
+ "@backstage/plugin-catalog-react": "^0.9.0",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -45,13 +45,13 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
- "@backstage/plugin-catalog": "^0.10.0-next.0",
+ "@backstage/cli": "^0.15.2",
+ "@backstage/plugin-catalog": "^0.10.0",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/dev-utils": "^0.2.25",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/react-hooks": "^7.0.2",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7"
diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityRelationsGraph.test.tsx b/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityRelationsGraph.test.tsx
index e8c9239739..2bf303bb92 100644
--- a/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityRelationsGraph.test.tsx
+++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityRelationsGraph.test.tsx
@@ -49,20 +49,10 @@ describe('', () => {
},
relations: [
{
- target: {
- kind: 'k',
- name: 'a1',
- namespace: 'd',
- },
targetRef: 'k:d/a1',
type: RELATION_OWNER_OF,
},
{
- target: {
- kind: 'b',
- name: 'c1',
- namespace: 'd',
- },
targetRef: 'b:d/c1',
type: RELATION_HAS_PART,
},
@@ -77,20 +67,10 @@ describe('', () => {
},
relations: [
{
- target: {
- kind: 'b',
- name: 'c',
- namespace: 'd',
- },
targetRef: 'b:d/c',
type: RELATION_OWNED_BY,
},
{
- target: {
- kind: 'b',
- name: 'c1',
- namespace: 'd',
- },
targetRef: 'b:d/c1',
type: RELATION_OWNED_BY,
},
@@ -105,29 +85,14 @@ describe('', () => {
},
relations: [
{
- target: {
- kind: 'b',
- name: 'c',
- namespace: 'd',
- },
targetRef: 'b:d/c',
type: RELATION_PART_OF,
},
{
- target: {
- kind: 'k',
- name: 'a1',
- namespace: 'd',
- },
targetRef: 'k:d/a1',
type: RELATION_OWNER_OF,
},
{
- target: {
- kind: 'b',
- name: 'c2',
- namespace: 'd',
- },
targetRef: 'b:d/c2',
type: RELATION_HAS_PART,
},
@@ -142,11 +107,6 @@ describe('', () => {
},
relations: [
{
- target: {
- kind: 'b',
- name: 'c1',
- namespace: 'd',
- },
targetRef: 'b:d/c1',
type: RELATION_PART_OF,
},
diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/relations.ts b/plugins/catalog-graph/src/components/EntityRelationsGraph/relations.ts
index ed847d7143..44352040ae 100644
--- a/plugins/catalog-graph/src/components/EntityRelationsGraph/relations.ts
+++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/relations.ts
@@ -38,7 +38,7 @@ import {
*/
export type RelationPairs = [string, string][];
-// TODO: This file only contains the pairs for the build-in relations.
+// TODO: This file only contains the pairs for the built-in relations.
// How to implement this when custom relations are used? Right now you can pass
// the relations everywhere.
// Another option is to move this into @backstage/catalog-model
diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/useEntityRelationNodesAndEdges.test.ts b/plugins/catalog-graph/src/components/EntityRelationsGraph/useEntityRelationNodesAndEdges.test.ts
index 4715cb106a..c2ee918e5b 100644
--- a/plugins/catalog-graph/src/components/EntityRelationsGraph/useEntityRelationNodesAndEdges.test.ts
+++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/useEntityRelationNodesAndEdges.test.ts
@@ -44,20 +44,10 @@ describe('useEntityRelationNodesAndEdges', () => {
},
relations: [
{
- target: {
- kind: 'k',
- name: 'a1',
- namespace: 'd',
- },
targetRef: 'k:d/a1',
type: RELATION_OWNER_OF,
},
{
- target: {
- kind: 'b',
- name: 'c1',
- namespace: 'd',
- },
targetRef: 'b:d/c1',
type: RELATION_HAS_PART,
},
@@ -72,20 +62,10 @@ describe('useEntityRelationNodesAndEdges', () => {
},
relations: [
{
- target: {
- kind: 'b',
- name: 'c',
- namespace: 'd',
- },
targetRef: 'b:d/c',
type: RELATION_OWNED_BY,
},
{
- target: {
- kind: 'b',
- name: 'c1',
- namespace: 'd',
- },
targetRef: 'b:d/c1',
type: RELATION_OWNED_BY,
},
@@ -100,29 +80,14 @@ describe('useEntityRelationNodesAndEdges', () => {
},
relations: [
{
- target: {
- kind: 'b',
- name: 'c',
- namespace: 'd',
- },
targetRef: 'b:d/c',
type: RELATION_PART_OF,
},
{
- target: {
- kind: 'k',
- name: 'a1',
- namespace: 'd',
- },
targetRef: 'k:d/a1',
type: RELATION_OWNER_OF,
},
{
- target: {
- kind: 'b',
- name: 'c2',
- namespace: 'd',
- },
targetRef: 'b:d/c2',
type: RELATION_HAS_PART,
},
@@ -137,11 +102,6 @@ describe('useEntityRelationNodesAndEdges', () => {
},
relations: [
{
- target: {
- kind: 'b',
- name: 'c1',
- namespace: 'd',
- },
targetRef: 'b:d/c1',
type: RELATION_PART_OF,
},
diff --git a/plugins/catalog-graphql/CHANGELOG.md b/plugins/catalog-graphql/CHANGELOG.md
index 542b272a02..b74a422512 100644
--- a/plugins/catalog-graphql/CHANGELOG.md
+++ b/plugins/catalog-graphql/CHANGELOG.md
@@ -1,5 +1,12 @@
# @backstage/plugin-catalog-graphql
+## 0.3.6
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/catalog-model@0.13.0
+
## 0.3.6-next.0
### Patch Changes
diff --git a/plugins/catalog-graphql/package.json b/plugins/catalog-graphql/package.json
index 7afbab0698..564d3ed9a6 100644
--- a/plugins/catalog-graphql/package.json
+++ b/plugins/catalog-graphql/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-graphql",
"description": "An experimental Backstage catalog GraphQL module",
- "version": "0.3.6-next.0",
+ "version": "0.3.6",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -34,7 +34,7 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.13.0-next.0",
+ "@backstage/catalog-model": "^0.13.0",
"@backstage/config": "^0.1.15",
"@backstage/types": "^0.1.3",
"graphql-modules": "^2.0.0",
@@ -46,7 +46,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/test-utils": "^0.3.0",
"@graphql-codegen/cli": "^2.3.1",
"@graphql-codegen/typescript": "^2.4.2",
diff --git a/plugins/catalog-graphql/src/graphql/module.test.ts b/plugins/catalog-graphql/src/graphql/module.test.ts
index 605e9d9aed..5490c2030a 100644
--- a/plugins/catalog-graphql/src/graphql/module.test.ts
+++ b/plugins/catalog-graphql/src/graphql/module.test.ts
@@ -59,7 +59,6 @@ describe('Catalog Module', () => {
metadata: {
annotations: {},
etag: '123',
- generation: 1,
labels: {},
name: 'Ben',
namespace: 'Blames',
@@ -118,7 +117,6 @@ describe('Catalog Module', () => {
metadata: {
annotations: null as any,
etag: '123',
- generation: 1,
labels: {},
name: 'Ben',
namespace: 'Blames',
@@ -170,7 +168,6 @@ describe('Catalog Module', () => {
metadata: {
annotations: {},
etag: '123',
- generation: 1,
labels: null as any,
name: 'Ben',
namespace: 'Blames',
@@ -221,7 +218,6 @@ describe('Catalog Module', () => {
metadata: {
annotations: { lob: 'bloben' },
etag: '123',
- generation: 1,
labels: {},
name: 'Ben',
namespace: 'Blames',
@@ -272,7 +268,6 @@ describe('Catalog Module', () => {
metadata: {
annotations: {},
etag: '123',
- generation: 1,
labels: { lob2: 'bloben' },
name: 'Ben',
namespace: 'Blames',
diff --git a/plugins/catalog-graphql/src/graphql/types.ts b/plugins/catalog-graphql/src/graphql/types.ts
index 4dc5a3522b..aecf2a1cd1 100644
--- a/plugins/catalog-graphql/src/graphql/types.ts
+++ b/plugins/catalog-graphql/src/graphql/types.ts
@@ -70,7 +70,6 @@ export type ComponentMetadata = EntityMetadata & {
annotation?: Maybe;
annotations: Scalars['JSONObject'];
etag: Scalars['String'];
- generation: Scalars['Int'];
label?: Maybe;
labels: Scalars['JSONObject'];
name: Scalars['String'];
@@ -91,7 +90,6 @@ export type DefaultEntityMetadata = EntityMetadata & {
annotation?: Maybe;
annotations: Scalars['JSONObject'];
etag: Scalars['String'];
- generation: Scalars['Int'];
label?: Maybe;
labels: Scalars['JSONObject'];
name: Scalars['String'];
@@ -115,7 +113,6 @@ export type EntityMetadata = {
annotation?: Maybe;
annotations: Scalars['JSONObject'];
etag: Scalars['String'];
- generation: Scalars['Int'];
label?: Maybe;
labels: Scalars['JSONObject'];
name: Scalars['String'];
@@ -153,7 +150,6 @@ export type TemplateMetadata = EntityMetadata & {
annotation?: Maybe;
annotations: Scalars['JSONObject'];
etag: Scalars['String'];
- generation: Scalars['Int'];
label?: Maybe;
labels: Scalars['JSONObject'];
name: Scalars['String'];
@@ -386,7 +382,6 @@ export type ComponentMetadataResolvers<
>;
annotations?: Resolver;
etag?: Resolver;
- generation?: Resolver;
label?: Resolver<
Maybe,
ParentType,
@@ -416,7 +411,6 @@ export type DefaultEntityMetadataResolvers<
>;
annotations?: Resolver;
etag?: Resolver;
- generation?: Resolver;
label?: Resolver<
Maybe,
ParentType,
@@ -454,7 +448,6 @@ export type EntityMetadataResolvers<
>;
annotations?: Resolver;
etag?: Resolver;
- generation?: Resolver;
label?: Resolver<
Maybe,
ParentType,
@@ -517,7 +510,6 @@ export type TemplateMetadataResolvers<
>;
annotations?: Resolver;
etag?: Resolver;
- generation?: Resolver;
label?: Resolver<
Maybe,
ParentType,
diff --git a/plugins/catalog-graphql/src/schema.js b/plugins/catalog-graphql/src/schema.js
index 6690f34da6..cf6ccf3017 100644
--- a/plugins/catalog-graphql/src/schema.js
+++ b/plugins/catalog-graphql/src/schema.js
@@ -26,7 +26,6 @@ const schema = /* GraphQL */ `
label(name: String!): JSON
uid: String!
etag: String!
- generation: Int!
}
type DefaultEntityMetadata implements EntityMetadata {
@@ -37,7 +36,6 @@ const schema = /* GraphQL */ `
label(name: String!): JSON
uid: String!
etag: String!
- generation: Int!
}
type ComponentMetadata implements EntityMetadata {
@@ -48,7 +46,6 @@ const schema = /* GraphQL */ `
label(name: String!): JSON
uid: String!
etag: String!
- generation: Int!
# mock field to prove extensions working
relationships: String
}
@@ -61,7 +58,6 @@ const schema = /* GraphQL */ `
label(name: String!): JSON
uid: String!
etag: String!
- generation: Int!
# mock field to prove extensions working
updatedBy: String
}
diff --git a/plugins/catalog-graphql/src/service/client.ts b/plugins/catalog-graphql/src/service/client.ts
index eaf2e63bc1..c6a5cff140 100644
--- a/plugins/catalog-graphql/src/service/client.ts
+++ b/plugins/catalog-graphql/src/service/client.ts
@@ -20,7 +20,6 @@ import fetch from 'node-fetch';
export interface ReaderEntityMeta extends EntityMeta {
uid: string;
etag: string;
- generation: number;
namespace: string;
annotations: Record;
labels: Record;
diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md
index db8d59eb51..6b512ef5d1 100644
--- a/plugins/catalog-import/CHANGELOG.md
+++ b/plugins/catalog-import/CHANGELOG.md
@@ -1,5 +1,17 @@
# @backstage/plugin-catalog-import
+## 0.8.5
+
+### Patch Changes
+
+- bf95bb806c: Remove usages of now-removed `CatalogApi.getEntityByName`
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.9.0
+ - @backstage/core-components@0.9.1
+ - @backstage/catalog-model@0.13.0
+ - @backstage/catalog-client@0.9.0
+ - @backstage/integration-react@0.1.25
+
## 0.8.5-next.0
### Patch Changes
diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json
index 566602f5ba..29e471f50b 100644
--- a/plugins/catalog-import/package.json
+++ b/plugins/catalog-import/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-import",
"description": "A Backstage plugin the helps you import entities into your catalog",
- "version": "0.8.5-next.0",
+ "version": "0.8.5",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -34,15 +34,15 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/catalog-client": "^0.9.0-next.0",
- "@backstage/catalog-model": "^0.13.0-next.0",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/catalog-client": "^0.9.0",
+ "@backstage/catalog-model": "^0.13.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/config": "^0.1.15",
"@backstage/core-plugin-api": "^0.8.0",
"@backstage/errors": "^0.2.2",
"@backstage/integration": "^0.8.0",
- "@backstage/integration-react": "^0.1.25-next.0",
- "@backstage/plugin-catalog-react": "^0.9.0-next.0",
+ "@backstage/integration-react": "^0.1.25",
+ "@backstage/plugin-catalog-react": "^0.9.0",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.57",
@@ -60,12 +60,12 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/dev-utils": "^0.2.25",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/react-hooks": "^7.0.2",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
diff --git a/plugins/catalog-import/src/components/StepReviewLocation/StepReviewLocation.tsx b/plugins/catalog-import/src/components/StepReviewLocation/StepReviewLocation.tsx
index 5c4f9b9594..7943b6e3b8 100644
--- a/plugins/catalog-import/src/components/StepReviewLocation/StepReviewLocation.tsx
+++ b/plugins/catalog-import/src/components/StepReviewLocation/StepReviewLocation.tsx
@@ -73,8 +73,6 @@ export const StepReviewLocation = ({
const result = await catalogApi.addLocation({
type: 'url',
target: l.target,
- presence:
- prepareResult.type === 'repository' ? 'optional' : 'required',
});
return {
target: result.location.target,
diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md
index 3bffeeef99..7b181efc93 100644
--- a/plugins/catalog-react/CHANGELOG.md
+++ b/plugins/catalog-react/CHANGELOG.md
@@ -1,5 +1,34 @@
# @backstage/plugin-catalog-react
+## 0.9.0
+
+### Minor Changes
+
+- b0af81726d: **BREAKING**: Removed `reduceCatalogFilters` and `reduceEntityFilters` due to low external utility value.
+- 7ffb2c73c9: **BREAKING**: Removed the deprecated `loadCatalogOwnerRefs` function. Usages of this function can be directly replaced with `ownershipEntityRefs` from `identityApi.getBackstageIdentity()`.
+
+ This also affects the `useEntityOwnership` hook in that it no longer uses `loadCatalogOwnerRefs`, meaning it will no longer load in additional relations and instead only rely on the `ownershipEntityRefs` from the `IdentityApi`.
+
+- dd88d1e3ac: **BREAKING**: Removed `useEntityFromUrl`.
+- 9844d4d2bd: **BREAKING**: Removed `useEntityCompoundName`, use `useRouteRefParams(entityRouteRef)` instead.
+- 2b8c986ce0: **BREAKING**: Removed `useEntityListProvider` use `useEntityList` instead.
+- f3a7a9de6d: **BREAKING**: Removed `useOwnedEntities` and moved its usage internally to the scaffolder-backend where it's used.
+
+ **BREAKING**: Removed `EntityTypeReturn` type which is now inlined.
+
+- cf1ff5b438: **BREAKING**: Removed the `useEntityKinds` hook, use `catalogApi.getEntityFacets({ facets: ['kind'] })` instead.
+- fc6290a76d: **BREAKING**: Removed the deprecated `useOwnUser` hook. Existing usage can be replaced with `identityApi.getBackstageIdentity()`, followed by a call to `catalogClient.getEntityByRef(identity.userEntityRef)`.
+
+### Patch Changes
+
+- b1aacbf96a: Applied the fix for the `/alpha` entry point resolution that was part of the `v0.70.1` release of Backstage.
+- 2986f8e09d: Fixed EntityOwnerPicker and OwnershipCard url filter issue with more than 21 owners
+- f3a7a9de6d: Internalized usage of `useOwnedEntities` hook.
+- Updated dependencies
+ - @backstage/core-components@0.9.1
+ - @backstage/catalog-model@0.13.0
+ - @backstage/catalog-client@0.9.0
+
## 0.9.0-next.0
### Minor Changes
diff --git a/plugins/catalog-react/api-report.md b/plugins/catalog-react/api-report.md
index 4912c857cf..265fce417d 100644
--- a/plugins/catalog-react/api-report.md
+++ b/plugins/catalog-react/api-report.md
@@ -388,28 +388,11 @@ export interface EntityTypePickerProps {
// @public
export const FavoriteEntity: (props: FavoriteEntityProps) => JSX.Element;
-// @public @deprecated (undocumented)
-export const favoriteEntityIcon: (isStarred: boolean) => JSX.Element;
-
// @public (undocumented)
export type FavoriteEntityProps = ComponentProps & {
entity: Entity;
};
-// @public @deprecated (undocumented)
-export const favoriteEntityTooltip: (
- isStarred: boolean,
-) => 'Remove from favorites' | 'Add to favorites';
-
-// @public @deprecated (undocumented)
-export const formatEntityRefTitle: typeof humanizeEntityRef;
-
-// @public @deprecated (undocumented)
-export function getEntityMetadataEditUrl(entity: Entity): string | undefined;
-
-// @public @deprecated (undocumented)
-export function getEntityMetadataViewUrl(entity: Entity): string | undefined;
-
// @public
export function getEntityRelations(
entity: Entity | undefined,
@@ -489,9 +472,6 @@ export function useAsyncEntity<
// @public
export function useEntity(): {
entity: TEntity;
- loading: boolean;
- error?: Error;
- refresh?: VoidFunction;
};
// @public
diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json
index f7c17d74ac..5ba52e8ac7 100644
--- a/plugins/catalog-react/package.json
+++ b/plugins/catalog-react/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-react",
"description": "A frontend library that helps other Backstage plugins interact with the catalog",
- "version": "0.9.0-next.0",
+ "version": "0.9.0",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -34,9 +34,9 @@
"start": "backstage-cli package start"
},
"dependencies": {
- "@backstage/catalog-client": "^0.9.0-next.0",
- "@backstage/catalog-model": "^0.13.0-next.0",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/catalog-client": "^0.9.0",
+ "@backstage/catalog-model": "^0.13.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
"@backstage/errors": "^0.2.2",
"@backstage/integration": "^0.8.0",
@@ -61,13 +61,13 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/plugin-catalog-common": "^0.2.2-next.0",
- "@backstage/plugin-scaffolder-common": "^0.3.0-next.0",
+ "@backstage/plugin-catalog-common": "^0.2.2",
+ "@backstage/plugin-scaffolder-common": "^0.3.0",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/react-hooks": "^7.0.2",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
diff --git a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.test.tsx b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.test.tsx
index de21bfeee3..f648b51456 100644
--- a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.test.tsx
+++ b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.test.tsx
@@ -32,20 +32,10 @@ const sampleEntities: Entity[] = [
{
type: 'ownedBy',
targetRef: 'group:default/some-owner',
- target: {
- name: 'some-owner',
- namespace: 'default',
- kind: 'Group',
- },
},
{
type: 'ownedBy',
targetRef: 'group:default/some-owner-2',
- target: {
- name: 'some-owner-2',
- namespace: 'default',
- kind: 'Group',
- },
},
],
},
@@ -59,11 +49,6 @@ const sampleEntities: Entity[] = [
{
type: 'ownedBy',
targetRef: 'group:default/another-owner',
- target: {
- name: 'another-owner',
- namespace: 'default',
- kind: 'Group',
- },
},
],
},
@@ -77,11 +62,6 @@ const sampleEntities: Entity[] = [
{
type: 'ownedBy',
targetRef: 'group:default/some-owner',
- target: {
- name: 'some-owner',
- namespace: 'default',
- kind: 'Group',
- },
},
],
},
diff --git a/plugins/catalog-react/src/components/EntityRefLink/humanize.test.ts b/plugins/catalog-react/src/components/EntityRefLink/humanize.test.ts
index b541946ece..d41d3c6635 100644
--- a/plugins/catalog-react/src/components/EntityRefLink/humanize.test.ts
+++ b/plugins/catalog-react/src/components/EntityRefLink/humanize.test.ts
@@ -16,7 +16,7 @@
import { humanizeEntityRef } from './humanize';
-describe('formatEntityRefTitle', () => {
+describe('humanizeEntityRef', () => {
it('formats entity in default namespace', () => {
const entity = {
apiVersion: 'v1',
diff --git a/plugins/catalog-react/src/components/EntityRefLink/humanize.ts b/plugins/catalog-react/src/components/EntityRefLink/humanize.ts
index 0ade1da0b9..2f72a7ee3b 100644
--- a/plugins/catalog-react/src/components/EntityRefLink/humanize.ts
+++ b/plugins/catalog-react/src/components/EntityRefLink/humanize.ts
@@ -20,9 +20,6 @@ import {
DEFAULT_NAMESPACE,
} from '@backstage/catalog-model';
-/** @public @deprecated please use {@link humanizeEntityRef} instead */
-export const formatEntityRefTitle = humanizeEntityRef;
-
/** @public */
export function humanizeEntityRef(
entityRef: Entity | CompoundEntityRef,
diff --git a/plugins/catalog-react/src/components/EntityRefLink/index.ts b/plugins/catalog-react/src/components/EntityRefLink/index.ts
index 50394547a0..50ac3d4534 100644
--- a/plugins/catalog-react/src/components/EntityRefLink/index.ts
+++ b/plugins/catalog-react/src/components/EntityRefLink/index.ts
@@ -18,4 +18,4 @@ export { EntityRefLink } from './EntityRefLink';
export type { EntityRefLinkProps } from './EntityRefLink';
export { EntityRefLinks } from './EntityRefLinks';
export type { EntityRefLinksProps } from './EntityRefLinks';
-export { humanizeEntityRef, formatEntityRefTitle } from './humanize';
+export { humanizeEntityRef } from './humanize';
diff --git a/plugins/catalog-react/src/components/EntityTable/presets.test.tsx b/plugins/catalog-react/src/components/EntityTable/presets.test.tsx
index f2fcd016f0..cca9c7d494 100644
--- a/plugins/catalog-react/src/components/EntityTable/presets.test.tsx
+++ b/plugins/catalog-react/src/components/EntityTable/presets.test.tsx
@@ -45,20 +45,10 @@ describe('systemEntityColumns', () => {
{
type: RELATION_PART_OF,
targetRef: 'domain:my-namespace/my-domain',
- target: {
- kind: 'domain',
- name: 'my-domain',
- namespace: 'my-namespace',
- },
},
{
type: RELATION_OWNED_BY,
targetRef: 'group:default/test',
- target: {
- kind: 'group',
- name: 'test',
- namespace: 'default',
- },
},
],
},
@@ -107,20 +97,10 @@ describe('componentEntityColumns', () => {
{
type: RELATION_PART_OF,
targetRef: 'system:my-namespace/my-system',
- target: {
- kind: 'system',
- name: 'my-system',
- namespace: 'my-namespace',
- },
},
{
type: RELATION_OWNED_BY,
targetRef: 'group:default/test',
- target: {
- kind: 'group',
- name: 'test',
- namespace: 'default',
- },
},
],
},
diff --git a/plugins/catalog-react/src/components/FavoriteEntity/FavoriteEntity.tsx b/plugins/catalog-react/src/components/FavoriteEntity/FavoriteEntity.tsx
index eaa2821448..e055f4056f 100644
--- a/plugins/catalog-react/src/components/FavoriteEntity/FavoriteEntity.tsx
+++ b/plugins/catalog-react/src/components/FavoriteEntity/FavoriteEntity.tsx
@@ -32,20 +32,6 @@ const YellowStar = withStyles({
},
})(Star);
-/**
- * @public
- * @deprecated due to low utility value.
- */
-export const favoriteEntityTooltip = (isStarred: boolean) =>
- isStarred ? 'Remove from favorites' : 'Add to favorites';
-
-/**
- * @public
- * @deprecated due to low utility value.
- */
-export const favoriteEntityIcon = (isStarred: boolean) =>
- isStarred ? : ;
-
/**
* IconButton for showing if a current entity is starred and adding/removing it from the favorite entities
* @param props - MaterialUI IconButton props extended by required `entity` prop
diff --git a/plugins/catalog-react/src/components/FavoriteEntity/index.ts b/plugins/catalog-react/src/components/FavoriteEntity/index.ts
index a46d04b6c7..3f54e29da9 100644
--- a/plugins/catalog-react/src/components/FavoriteEntity/index.ts
+++ b/plugins/catalog-react/src/components/FavoriteEntity/index.ts
@@ -14,9 +14,5 @@
* limitations under the License.
*/
-export {
- favoriteEntityTooltip,
- favoriteEntityIcon,
- FavoriteEntity,
-} from './FavoriteEntity';
+export { FavoriteEntity } from './FavoriteEntity';
export type { FavoriteEntityProps } from './FavoriteEntity';
diff --git a/plugins/catalog-react/src/components/UserListPicker/UserListPicker.test.tsx b/plugins/catalog-react/src/components/UserListPicker/UserListPicker.test.tsx
index 310deabbb7..db3ce7cf5d 100644
--- a/plugins/catalog-react/src/components/UserListPicker/UserListPicker.test.tsx
+++ b/plugins/catalog-react/src/components/UserListPicker/UserListPicker.test.tsx
@@ -104,7 +104,6 @@ const backendEntities: Entity[] = [
{
type: RELATION_OWNED_BY,
targetRef: 'user:default/testuser',
- target: { kind: 'User', namespace: 'default', name: 'testUser' },
},
],
},
@@ -138,7 +137,6 @@ const backendEntities: Entity[] = [
{
type: RELATION_OWNED_BY,
targetRef: 'user:default/testuser',
- target: { kind: 'User', namespace: 'default', name: 'testUser' },
},
],
},
diff --git a/plugins/catalog-react/src/hooks/useEntity.test.tsx b/plugins/catalog-react/src/hooks/useEntity.test.tsx
index f61283f2cf..5e86a94180 100644
--- a/plugins/catalog-react/src/hooks/useEntity.test.tsx
+++ b/plugins/catalog-react/src/hooks/useEntity.test.tsx
@@ -16,19 +16,21 @@
import React from 'react';
import { renderHook } from '@testing-library/react-hooks';
-import { useEntity, EntityProvider, AsyncEntityProvider } from './useEntity';
+import {
+ useEntity,
+ useAsyncEntity,
+ EntityProvider,
+ AsyncEntityProvider,
+} from './useEntity';
import { Entity } from '@backstage/catalog-model';
-describe('EntityProvider', () => {
- it('should provide no entity', async () => {
+describe('useEntity', () => {
+ it('should throw if no entity is provided', async () => {
const { result } = renderHook(() => useEntity(), {
wrapper: ({ children }) => ,
});
- expect(result.current.entity).toBe(undefined);
- expect(result.current.loading).toBe(true);
- expect(result.current.error).toBe(undefined);
- expect(result.current.refresh).toBe(undefined);
+ expect(result.error?.message).toMatch(/entity has not been loaded/);
});
it('should provide an entity', async () => {
@@ -40,15 +42,12 @@ describe('EntityProvider', () => {
});
expect(result.current.entity).toBe(entity);
- expect(result.current.loading).toBe(false);
- expect(result.current.error).toBe(undefined);
- expect(result.current.refresh).toBe(undefined);
});
});
-describe('AsyncEntityProvider', () => {
+describe('useAsyncEntity', () => {
it('should provide no entity', async () => {
- const { result } = renderHook(() => useEntity(), {
+ const { result } = renderHook(() => useAsyncEntity(), {
wrapper: ({ children }) => (
),
@@ -63,7 +62,7 @@ describe('AsyncEntityProvider', () => {
it('should provide an entity', async () => {
const entity = { kind: 'MyEntity' } as Entity;
const refresh = () => {};
- const { result } = renderHook(() => useEntity(), {
+ const { result } = renderHook(() => useAsyncEntity(), {
wrapper: ({ children }) => (
{
it('should provide an error', async () => {
const error = new Error('oh no');
- const { result } = renderHook(() => useEntity(), {
+ const { result } = renderHook(() => useAsyncEntity(), {
wrapper: ({ children }) => (
(
*/
export function useEntity(): {
entity: TEntity;
- /** @deprecated use {@link useAsyncEntity} instead */
- loading: boolean;
- /** @deprecated use {@link useAsyncEntity} instead */
- error?: Error;
- /** @deprecated use {@link useAsyncEntity} instead */
- refresh?: VoidFunction;
} {
const versionedHolder =
useVersionedContext<{ 1: EntityLoadingStatus }>('entity-context');
@@ -123,18 +117,12 @@ export function useEntity(): {
}
if (!value.entity) {
- // Once we have removed the additional fields from being returned we can drop this deprecation
- // and move to the error instead.
- // throw new Error('useEntity hook is being called outside of an EntityLayout where the entity has not been loaded. If this is intentional, please use useAsyncEntity instead.');
-
- // eslint-disable-next-line no-console
- console.warn(
- 'DEPRECATION: useEntity hook is being called outside of an EntityLayout where the entity has not been loaded. If this is intentional, please use useAsyncEntity instead. This warning will be replaced with an error in future releases.',
+ throw new Error(
+ 'useEntity hook is being called outside of an EntityLayout where the entity has not been loaded. If this is intentional, please use useAsyncEntity instead.',
);
}
- const { entity, loading, error, refresh } = value;
- return { entity: entity as TEntity, loading, error, refresh };
+ return { entity: value.entity as TEntity };
}
/**
diff --git a/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx b/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx
index e3ab09f081..3353312955 100644
--- a/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx
+++ b/plugins/catalog-react/src/hooks/useEntityListProvider.test.tsx
@@ -46,11 +46,6 @@ const entities: Entity[] = [
{
type: 'ownedBy',
targetRef: 'user:default/guest',
- target: {
- name: 'guest',
- namespace: 'default',
- kind: 'User',
- },
},
],
},
diff --git a/plugins/catalog-react/src/hooks/useEntityOwnership.test.tsx b/plugins/catalog-react/src/hooks/useEntityOwnership.test.tsx
index d4d80203d3..616e4949c1 100644
--- a/plugins/catalog-react/src/hooks/useEntityOwnership.test.tsx
+++ b/plugins/catalog-react/src/hooks/useEntityOwnership.test.tsx
@@ -62,12 +62,10 @@ describe('useEntityOwnership', () => {
{
type: RELATION_OWNED_BY,
targetRef: 'user:default/user1',
- target: { kind: 'User', namespace: 'default', name: 'user1' },
},
{
type: RELATION_OWNED_BY,
targetRef: 'group:default/group1',
- target: { kind: 'Group', namespace: 'default', name: 'group1' },
},
],
};
diff --git a/plugins/catalog-react/src/hooks/useEntityPermission.test.tsx b/plugins/catalog-react/src/hooks/useEntityPermission.test.tsx
index 553d999b61..766b587da3 100644
--- a/plugins/catalog-react/src/hooks/useEntityPermission.test.tsx
+++ b/plugins/catalog-react/src/hooks/useEntityPermission.test.tsx
@@ -17,18 +17,18 @@
import { catalogEntityDeletePermission } from '@backstage/plugin-catalog-common';
import { renderHook } from '@testing-library/react-hooks';
import { useEntityPermission } from './useEntityPermission';
-import { useEntity } from './useEntity';
+import { useAsyncEntity } from './useEntity';
import { usePermission } from '@backstage/plugin-permission-react';
jest.mock('./useEntity', () => ({
...jest.requireActual('./useEntity'),
- useEntity: jest.fn(),
+ useAsyncEntity: jest.fn(),
}));
jest.mock('@backstage/plugin-permission-react', () => ({
...jest.requireActual('@backstage/plugin-permission-react'),
usePermission: jest.fn(),
}));
-const useEntityMock = useEntity as jest.Mock;
+const useEntityMock = useAsyncEntity as jest.Mock;
const usePermissionMock = usePermission as jest.Mock;
describe('useEntityPermission', () => {
diff --git a/plugins/catalog-react/src/hooks/useEntityPermission.ts b/plugins/catalog-react/src/hooks/useEntityPermission.ts
index 092114936a..55d863726e 100644
--- a/plugins/catalog-react/src/hooks/useEntityPermission.ts
+++ b/plugins/catalog-react/src/hooks/useEntityPermission.ts
@@ -17,7 +17,7 @@
import { stringifyEntityRef } from '@backstage/catalog-model';
import { Permission } from '@backstage/plugin-permission-common';
import { usePermission } from '@backstage/plugin-permission-react';
-import { useEntity } from './useEntity';
+import { useAsyncEntity } from './useEntity';
/**
* A thin wrapper around the
@@ -35,7 +35,11 @@ export function useEntityPermission(permission: Permission): {
allowed: boolean;
error?: Error;
} {
- const { entity, loading: loadingEntity, error: entityError } = useEntity();
+ const {
+ entity,
+ loading: loadingEntity,
+ error: entityError,
+ } = useAsyncEntity();
const {
allowed,
loading: loadingPermission,
diff --git a/plugins/catalog-react/src/index.ts b/plugins/catalog-react/src/index.ts
index 6d5a5ad204..2ca7d67d59 100644
--- a/plugins/catalog-react/src/index.ts
+++ b/plugins/catalog-react/src/index.ts
@@ -32,8 +32,6 @@ export * from './testUtils';
export * from './types';
export * from './overridableComponents';
export {
- getEntityMetadataEditUrl,
- getEntityMetadataViewUrl,
getEntityRelations,
getEntitySourceLocation,
isOwnerOf,
diff --git a/plugins/catalog-react/src/utils/getEntityMetadataUrl.ts b/plugins/catalog-react/src/utils/getEntityMetadataUrl.ts
deleted file mode 100644
index 6037fc3c4d..0000000000
--- a/plugins/catalog-react/src/utils/getEntityMetadataUrl.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2020 The Backstage Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import {
- ANNOTATION_EDIT_URL,
- ANNOTATION_VIEW_URL,
- Entity,
-} from '@backstage/catalog-model';
-
-/**
- * @public
- * @deprecated use entity.metadata.annotations?.[ANNOTATION_VIEW_URL] instead. */
-export function getEntityMetadataViewUrl(entity: Entity): string | undefined {
- return entity.metadata.annotations?.[ANNOTATION_VIEW_URL];
-}
-
-/**
- * @public
- * @deprecated use entity.metadata.annotations?.[ANNOTATION_EDIT_URL] instead.
- */
-export function getEntityMetadataEditUrl(entity: Entity): string | undefined {
- return entity.metadata.annotations?.[ANNOTATION_EDIT_URL];
-}
diff --git a/plugins/catalog-react/src/utils/getEntityRelations.test.ts b/plugins/catalog-react/src/utils/getEntityRelations.test.ts
index ea0ba59399..f602e8dcc9 100644
--- a/plugins/catalog-react/src/utils/getEntityRelations.test.ts
+++ b/plugins/catalog-react/src/utils/getEntityRelations.test.ts
@@ -32,7 +32,6 @@ describe('getEntityRelations', () => {
{
type: RELATION_MEMBER_OF,
targetRef: 'group:default/member',
- target: { kind: 'group', namespace: 'default', name: 'member' },
},
{
type: RELATION_CHILD_OF,
@@ -53,7 +52,6 @@ describe('getEntityRelations', () => {
{
type: RELATION_MEMBER_OF,
targetRef: 'group:default/member',
- target: { kind: 'group', namespace: 'default', name: 'member' },
},
{
type: RELATION_MEMBER_OF,
diff --git a/plugins/catalog-react/src/utils/index.ts b/plugins/catalog-react/src/utils/index.ts
index 2672664ef8..5afc32af63 100644
--- a/plugins/catalog-react/src/utils/index.ts
+++ b/plugins/catalog-react/src/utils/index.ts
@@ -14,10 +14,6 @@
* limitations under the License.
*/
export * from './filters';
-export {
- getEntityMetadataEditUrl,
- getEntityMetadataViewUrl,
-} from './getEntityMetadataUrl';
export { getEntityRelations } from './getEntityRelations';
export { getEntitySourceLocation } from './getEntitySourceLocation';
export type { EntitySourceLocation } from './getEntitySourceLocation';
diff --git a/plugins/catalog-react/src/utils/isOwnerOf.test.ts b/plugins/catalog-react/src/utils/isOwnerOf.test.ts
index d3053646d8..224550d479 100644
--- a/plugins/catalog-react/src/utils/isOwnerOf.test.ts
+++ b/plugins/catalog-react/src/utils/isOwnerOf.test.ts
@@ -32,7 +32,6 @@ describe('isOwnerOf', () => {
{
type: RELATION_OWNED_BY,
targetRef: 'user:default/user',
- target: { kind: 'user', namespace: 'default', name: 'user' },
},
],
} as Entity;
@@ -48,7 +47,6 @@ describe('isOwnerOf', () => {
{
type: RELATION_MEMBER_OF,
targetRef: 'group:default/group',
- target: { kind: 'group', namespace: 'default', name: 'group' },
},
],
} as Entity;
@@ -57,7 +55,6 @@ describe('isOwnerOf', () => {
{
type: RELATION_OWNED_BY,
targetRef: 'group:default/group',
- target: { kind: 'group', namespace: 'default', name: 'group' },
},
],
} as Entity;
diff --git a/plugins/catalog/CHANGELOG.md b/plugins/catalog/CHANGELOG.md
index ed10e6723b..4c9c292518 100644
--- a/plugins/catalog/CHANGELOG.md
+++ b/plugins/catalog/CHANGELOG.md
@@ -1,5 +1,27 @@
# @backstage/plugin-catalog
+## 0.10.0
+
+### Minor Changes
+
+- 51856359bf: **BREAKING**: Removed the `AboutCard` component which has been replaced by `EntityAboutCard`.
+- 5ea9509e6a: **BREAKING**: Removed `CatalogResultListItemProps` and `CatalogResultListItem`, replaced by `CatalogSearchResultListItemProps` and `CatalogSearchResultListItem`.
+
+### Patch Changes
+
+- 9a06d18385: Added an `allowedKinds` option to `CatalogKindHeader` to limit entity kinds available in the dropdown.
+- 251688a75e: Updated `CatalogKindHeader` to respond to external changes to query parameters in the URL, such as two sidebar links that apply different catalog filters.
+- 9844d4d2bd: Removed usage of removed hook.
+- 3e54f6c436: Use `@backstage/plugin-search-common` package instead of `@backstage/search-common`.
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.9.0
+ - @backstage/core-components@0.9.1
+ - @backstage/catalog-model@0.13.0
+ - @backstage/plugin-catalog-common@0.2.2
+ - @backstage/plugin-search-common@0.3.1
+ - @backstage/catalog-client@0.9.0
+ - @backstage/integration-react@0.1.25
+
## 0.10.0-next.0
### Minor Changes
diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json
index 971152a08d..bdc3e64fcc 100644
--- a/plugins/catalog/package.json
+++ b/plugins/catalog/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog",
"description": "The Backstage plugin for browsing the Backstage catalog",
- "version": "0.10.0-next.0",
+ "version": "0.10.0",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -34,15 +34,15 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/catalog-client": "^0.9.0-next.0",
- "@backstage/catalog-model": "^0.13.0-next.0",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/catalog-client": "^0.9.0",
+ "@backstage/catalog-model": "^0.13.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
"@backstage/errors": "^0.2.2",
- "@backstage/integration-react": "^0.1.25-next.0",
- "@backstage/plugin-catalog-common": "^0.2.2-next.0",
- "@backstage/plugin-catalog-react": "^0.9.0-next.0",
- "@backstage/plugin-search-common": "^0.3.1-next.0",
+ "@backstage/integration-react": "^0.1.25",
+ "@backstage/plugin-catalog-common": "^0.2.2",
+ "@backstage/plugin-catalog-react": "^0.9.0",
+ "@backstage/plugin-search-common": "^0.3.1",
"@backstage/theme": "^0.2.15",
"@backstage/types": "^0.1.2",
"@material-ui/core": "^4.12.2",
@@ -60,13 +60,13 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/dev-utils": "^0.2.25",
"@backstage/plugin-permission-react": "^0.3.3",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"cross-fetch": "^3.1.5"
diff --git a/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx b/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx
index 9a878e3b60..563ccd0cd7 100644
--- a/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx
+++ b/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx
@@ -448,7 +448,7 @@ describe('', () => {
expect(getByText('View TechDocs').closest('a')).not.toHaveAttribute('href');
});
- it('renders disbaled techdocs link when route is not bound', async () => {
+ it('renders disabled techdocs link when route is not bound', async () => {
const entity = {
apiVersion: 'v1',
kind: 'Component',
diff --git a/plugins/catalog/src/components/AboutCard/AboutContent.test.tsx b/plugins/catalog/src/components/AboutCard/AboutContent.test.tsx
index cf9673eeeb..87ee8cc6ec 100644
--- a/plugins/catalog/src/components/AboutCard/AboutContent.test.tsx
+++ b/plugins/catalog/src/components/AboutCard/AboutContent.test.tsx
@@ -48,29 +48,14 @@ describe('', () => {
{
type: RELATION_OWNED_BY,
targetRef: 'user:default/o',
- target: {
- kind: 'user',
- name: 'o',
- namespace: 'default',
- },
},
{
type: RELATION_PART_OF,
targetRef: 'system:default/s',
- target: {
- kind: 'system',
- name: 's',
- namespace: 'default',
- },
},
{
type: RELATION_PART_OF,
targetRef: 'domain:default/d',
- target: {
- kind: 'domain',
- name: 'd',
- namespace: 'default',
- },
},
],
};
@@ -156,20 +141,10 @@ describe('', () => {
{
type: RELATION_OWNED_BY,
targetRef: 'user:default/guest',
- target: {
- kind: 'user',
- name: 'guest',
- namespace: 'default',
- },
},
{
type: RELATION_PART_OF,
targetRef: 'system:default/system',
- target: {
- kind: 'system',
- name: 'system',
- namespace: 'default',
- },
},
],
};
@@ -263,29 +238,14 @@ describe('', () => {
{
type: RELATION_OWNED_BY,
targetRef: 'user:default/guest',
- target: {
- kind: 'user',
- name: 'guest',
- namespace: 'default',
- },
},
{
type: RELATION_PART_OF,
targetRef: 'system:default/system',
- target: {
- kind: 'system',
- name: 'system',
- namespace: 'default',
- },
},
{
type: RELATION_PART_OF,
targetRef: 'component:default/parent-software',
- target: {
- kind: 'component',
- name: 'parent-software',
- namespace: 'default',
- },
},
],
};
@@ -378,11 +338,6 @@ describe('', () => {
{
type: RELATION_OWNED_BY,
targetRef: 'user:default/guest',
- target: {
- kind: 'user',
- name: 'guest',
- namespace: 'default',
- },
},
],
};
@@ -538,20 +493,10 @@ describe('', () => {
{
type: RELATION_OWNED_BY,
targetRef: 'user:default/guest',
- target: {
- kind: 'user',
- name: 'guest',
- namespace: 'default',
- },
},
{
type: RELATION_PART_OF,
targetRef: 'system:default/system',
- target: {
- kind: 'system',
- name: 'system',
- namespace: 'default',
- },
},
],
};
@@ -637,20 +582,10 @@ describe('', () => {
{
type: RELATION_OWNED_BY,
targetRef: 'user:default/guest',
- target: {
- kind: 'user',
- name: 'guest',
- namespace: 'default',
- },
},
{
type: RELATION_PART_OF,
targetRef: 'domain:default/domain',
- target: {
- kind: 'domain',
- name: 'domain',
- namespace: 'default',
- },
},
],
};
diff --git a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx
index 07bd81b287..c3135e5697 100644
--- a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx
+++ b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx
@@ -75,7 +75,6 @@ describe('DefaultCatalogPage', () => {
{
type: RELATION_OWNED_BY,
targetRef: 'group:default/tools',
- target: { kind: 'group', name: 'tools', namespace: 'default' },
},
],
},
diff --git a/plugins/catalog/src/components/DependencyOfComponentsCard/DependencyOfComponentsCard.test.tsx b/plugins/catalog/src/components/DependencyOfComponentsCard/DependencyOfComponentsCard.test.tsx
index 05d836870f..b3f8262076 100644
--- a/plugins/catalog/src/components/DependencyOfComponentsCard/DependencyOfComponentsCard.test.tsx
+++ b/plugins/catalog/src/components/DependencyOfComponentsCard/DependencyOfComponentsCard.test.tsx
@@ -80,11 +80,6 @@ describe('', () => {
},
relations: [
{
- target: {
- kind: 'component',
- namespace: 'my-namespace',
- name: 'target-name',
- },
targetRef: 'component:my-namespace/target-name',
type: RELATION_DEPENDENCY_OF,
},
diff --git a/plugins/catalog/src/components/DependsOnComponentsCard/DependsOnComponentsCard.test.tsx b/plugins/catalog/src/components/DependsOnComponentsCard/DependsOnComponentsCard.test.tsx
index b7ef594522..57106015b2 100644
--- a/plugins/catalog/src/components/DependsOnComponentsCard/DependsOnComponentsCard.test.tsx
+++ b/plugins/catalog/src/components/DependsOnComponentsCard/DependsOnComponentsCard.test.tsx
@@ -80,11 +80,6 @@ describe('', () => {
},
relations: [
{
- target: {
- kind: 'component',
- namespace: 'my-namespace',
- name: 'target-name',
- },
targetRef: 'component:my-namespace/target-name',
type: RELATION_DEPENDS_ON,
},
diff --git a/plugins/catalog/src/components/DependsOnResourcesCard/DependsOnResourcesCard.test.tsx b/plugins/catalog/src/components/DependsOnResourcesCard/DependsOnResourcesCard.test.tsx
index b8d2801e48..bd52bfeeb8 100644
--- a/plugins/catalog/src/components/DependsOnResourcesCard/DependsOnResourcesCard.test.tsx
+++ b/plugins/catalog/src/components/DependsOnResourcesCard/DependsOnResourcesCard.test.tsx
@@ -80,11 +80,6 @@ describe('', () => {
},
relations: [
{
- target: {
- kind: 'resource',
- namespace: 'my-namespace',
- name: 'target-name',
- },
targetRef: 'resource:my-namespace/target-name',
type: RELATION_DEPENDS_ON,
},
diff --git a/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.test.tsx b/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.test.tsx
index fbb474825f..77fdb74f2f 100644
--- a/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.test.tsx
+++ b/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.test.tsx
@@ -80,11 +80,6 @@ describe('', () => {
},
relations: [
{
- target: {
- kind: 'component',
- namespace: 'my-namespace',
- name: 'target-name',
- },
targetRef: 'component:my-namespace/target-name',
type: RELATION_HAS_PART,
},
diff --git a/plugins/catalog/src/components/HasResourcesCard/HasResourcesCard.test.tsx b/plugins/catalog/src/components/HasResourcesCard/HasResourcesCard.test.tsx
index c75273e484..20830d2ccd 100644
--- a/plugins/catalog/src/components/HasResourcesCard/HasResourcesCard.test.tsx
+++ b/plugins/catalog/src/components/HasResourcesCard/HasResourcesCard.test.tsx
@@ -75,11 +75,6 @@ describe('', () => {
},
relations: [
{
- target: {
- kind: 'resource',
- namespace: 'my-namespace',
- name: 'target-name',
- },
targetRef: 'resource:my-namespace/target-name',
type: RELATION_HAS_PART,
},
diff --git a/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.test.tsx b/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.test.tsx
index e021fea2f3..7fd0273939 100644
--- a/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.test.tsx
+++ b/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.test.tsx
@@ -80,11 +80,6 @@ describe('', () => {
},
relations: [
{
- target: {
- kind: 'component',
- namespace: 'my-namespace',
- name: 'target-name',
- },
targetRef: 'component:my-namespace/target-name',
type: RELATION_HAS_PART,
},
diff --git a/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.test.tsx b/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.test.tsx
index 6a2e2a0b7f..cd11e4d3f3 100644
--- a/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.test.tsx
+++ b/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.test.tsx
@@ -78,11 +78,6 @@ describe('', () => {
},
relations: [
{
- target: {
- kind: 'system',
- namespace: 'my-namespace',
- name: 'target-name',
- },
targetRef: 'system:my-namespace/target-name',
type: RELATION_HAS_PART,
},
diff --git a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx
index eb6b71c47e..18b45a84d4 100644
--- a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx
+++ b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx
@@ -102,11 +102,6 @@ describe('', () => {
},
relations: [
{
- target: {
- kind: 'domain',
- namespace: 'namespace',
- name: 'domain',
- },
targetRef: 'domain:namespace/domain',
type: RELATION_PART_OF,
},
@@ -162,11 +157,6 @@ describe('', () => {
},
relations: [
{
- target: {
- kind: 'Domain',
- namespace: 'namespace',
- name: 'alongdomainthatshouldgettruncated',
- },
targetRef: 'domain:namespace/alongdomainthatshouldgettruncated',
type: RELATION_PART_OF,
},
diff --git a/plugins/cicd-statistics/CHANGELOG.md b/plugins/cicd-statistics/CHANGELOG.md
index fac9b6413e..253e3d60bf 100644
--- a/plugins/cicd-statistics/CHANGELOG.md
+++ b/plugins/cicd-statistics/CHANGELOG.md
@@ -1,5 +1,13 @@
# @backstage/plugin-cicd-statistics
+## 0.1.4
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.9.0
+ - @backstage/catalog-model@0.13.0
+
## 0.1.4-next.0
### Patch Changes
diff --git a/plugins/cicd-statistics/package.json b/plugins/cicd-statistics/package.json
index 05ddd95544..08cffaeba6 100644
--- a/plugins/cicd-statistics/package.json
+++ b/plugins/cicd-statistics/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-cicd-statistics",
"description": "A frontend plugin visualizing CI/CD pipeline statistics (build time)",
- "version": "0.1.4-next.0",
+ "version": "0.1.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -37,9 +37,9 @@
"@types/luxon": "^2.0.5"
},
"dependencies": {
- "@backstage/catalog-model": "^0.13.0-next.0",
+ "@backstage/catalog-model": "^0.13.0",
"@backstage/core-plugin-api": "^0.8.0",
- "@backstage/plugin-catalog-react": "^0.9.0-next.0",
+ "@backstage/plugin-catalog-react": "^0.9.0",
"@date-io/luxon": "^1.3.13",
"@material-ui/core": "^4.9.13",
"@material-ui/icons": "^4.11.2",
diff --git a/plugins/cicd-statistics/src/apis/types.ts b/plugins/cicd-statistics/src/apis/types.ts
index 0a87b40fc2..32d9d3f2df 100644
--- a/plugins/cicd-statistics/src/apis/types.ts
+++ b/plugins/cicd-statistics/src/apis/types.ts
@@ -47,7 +47,7 @@ export const statusTypes: Array = [
/**
* The branch enum of either 'master' or 'branch' (or possibly the meta 'all').
*
- * The concept of what constitues a master branch is generic. It might be called
+ * The concept of what constitutes a master branch is generic. It might be called
* something like 'release' or 'main' or 'trunk' in the underlying CI/CD system,
* which is then up to the Api to map accordingly.
*/
diff --git a/plugins/circleci/CHANGELOG.md b/plugins/circleci/CHANGELOG.md
index 13a0211758..e44eb0c8cb 100644
--- a/plugins/circleci/CHANGELOG.md
+++ b/plugins/circleci/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-circleci
+## 0.3.2
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.9.0
+ - @backstage/core-components@0.9.1
+ - @backstage/catalog-model@0.13.0
+
## 0.3.2-next.0
### Patch Changes
diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json
index 44d6378082..d315c9a161 100644
--- a/plugins/circleci/package.json
+++ b/plugins/circleci/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-circleci",
"description": "A Backstage plugin that integrates towards Circle CI",
- "version": "0.3.2-next.0",
+ "version": "0.3.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -35,10 +35,10 @@
"postpack": "backstage-cli package postpack"
},
"dependencies": {
- "@backstage/catalog-model": "^0.13.0-next.0",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/catalog-model": "^0.13.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
- "@backstage/plugin-catalog-react": "^0.9.0-next.0",
+ "@backstage/plugin-catalog-react": "^0.9.0",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -55,12 +55,12 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/dev-utils": "^0.2.25",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"@types/humanize-duration": "^3.25.1",
"@types/jest": "^26.0.7",
diff --git a/plugins/cloudbuild/CHANGELOG.md b/plugins/cloudbuild/CHANGELOG.md
index 3d6170a1c9..6c2378d472 100644
--- a/plugins/cloudbuild/CHANGELOG.md
+++ b/plugins/cloudbuild/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-cloudbuild
+## 0.3.2
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.9.0
+ - @backstage/core-components@0.9.1
+ - @backstage/catalog-model@0.13.0
+
## 0.3.2-next.0
### Patch Changes
diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json
index 9febaf010f..bf4a65bd07 100644
--- a/plugins/cloudbuild/package.json
+++ b/plugins/cloudbuild/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-cloudbuild",
"description": "A Backstage plugin that integrates towards Google Cloud Build",
- "version": "0.3.2-next.0",
+ "version": "0.3.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -34,10 +34,10 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.13.0-next.0",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/catalog-model": "^0.13.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
- "@backstage/plugin-catalog-react": "^0.9.0-next.0",
+ "@backstage/plugin-catalog-react": "^0.9.0",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -52,12 +52,12 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/dev-utils": "^0.2.25",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
diff --git a/plugins/code-climate/CHANGELOG.md b/plugins/code-climate/CHANGELOG.md
index c74d695448..33a4c4e4d5 100644
--- a/plugins/code-climate/CHANGELOG.md
+++ b/plugins/code-climate/CHANGELOG.md
@@ -1,5 +1,15 @@
# @backstage/plugin-code-climate
+## 0.1.2
+
+### Patch Changes
+
+- 4f79204c47: Added `backstage.role` to `package.json`
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.9.0
+ - @backstage/core-components@0.9.1
+ - @backstage/catalog-model@0.13.0
+
## 0.1.2-next.0
### Patch Changes
diff --git a/plugins/code-climate/package.json b/plugins/code-climate/package.json
index 5da58648f3..4913939be4 100644
--- a/plugins/code-climate/package.json
+++ b/plugins/code-climate/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-code-climate",
- "version": "0.1.2-next.0",
+ "version": "0.1.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -23,10 +23,10 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.13.0-next.0",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/catalog-model": "^0.13.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
- "@backstage/plugin-catalog-react": "^0.9.0-next.0",
+ "@backstage/plugin-catalog-react": "^0.9.0",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -40,11 +40,11 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/cli": "^0.15.2",
+ "@backstage/dev-utils": "^0.2.25",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"@types/humanize-duration": "^3.27.1",
"@types/jest": "^26.0.7",
diff --git a/plugins/code-coverage-backend/CHANGELOG.md b/plugins/code-coverage-backend/CHANGELOG.md
index 382cf61863..7bb82bf483 100644
--- a/plugins/code-coverage-backend/CHANGELOG.md
+++ b/plugins/code-coverage-backend/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-code-coverage-backend
+## 0.1.27
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.13.0
+ - @backstage/catalog-model@0.13.0
+ - @backstage/catalog-client@0.9.0
+
## 0.1.27-next.0
### Patch Changes
diff --git a/plugins/code-coverage-backend/package.json b/plugins/code-coverage-backend/package.json
index 3070b190b9..e4b9032f78 100644
--- a/plugins/code-coverage-backend/package.json
+++ b/plugins/code-coverage-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-code-coverage-backend",
"description": "A Backstage backend plugin that helps you keep track of your code coverage",
- "version": "0.1.27-next.0",
+ "version": "0.1.27",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -23,9 +23,9 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.13.0-next.0",
- "@backstage/catalog-client": "^0.9.0-next.0",
- "@backstage/catalog-model": "^0.13.0-next.0",
+ "@backstage/backend-common": "^0.13.0",
+ "@backstage/catalog-client": "^0.9.0",
+ "@backstage/catalog-model": "^0.13.0",
"@backstage/config": "^0.1.15",
"@backstage/errors": "^0.2.2",
"@backstage/integration": "^0.8.0",
@@ -39,7 +39,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@types/express-xml-bodyparser": "^0.3.2",
"@types/supertest": "^2.0.8",
"msw": "^0.35.0",
diff --git a/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.test.ts b/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.test.ts
index 15028a76fd..635debca02 100644
--- a/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.test.ts
+++ b/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.test.ts
@@ -26,7 +26,7 @@ const db = DatabaseManager.fromConfig(
new ConfigReader({
backend: {
database: {
- client: 'sqlite3',
+ client: 'better-sqlite3',
connection: ':memory:',
},
},
diff --git a/plugins/code-coverage-backend/src/service/converter/cobertura.ts b/plugins/code-coverage-backend/src/service/converter/cobertura.ts
index e7f7490304..025d40a4f6 100644
--- a/plugins/code-coverage-backend/src/service/converter/cobertura.ts
+++ b/plugins/code-coverage-backend/src/service/converter/cobertura.ts
@@ -27,7 +27,7 @@ export class Cobertura implements Converter {
* convert cobertura into shared json coverage format
*
* @param xml - cobertura xml object
- * @param scmFiles - list of files that are commited to SCM
+ * @param scmFiles - list of files that are committed to SCM
*/
convert(xml: CoberturaXML, scmFiles: string[]): FileEntry[] {
const ppc = xml.coverage.packages
diff --git a/plugins/code-coverage-backend/src/service/router.test.ts b/plugins/code-coverage-backend/src/service/router.test.ts
index 4e6a66fdd8..7d1825c25f 100644
--- a/plugins/code-coverage-backend/src/service/router.test.ts
+++ b/plugins/code-coverage-backend/src/service/router.test.ts
@@ -31,7 +31,7 @@ function createDatabase(): PluginDatabaseManager {
new ConfigReader({
backend: {
database: {
- client: 'sqlite3',
+ client: 'better-sqlite3',
connection: ':memory:',
},
},
diff --git a/plugins/code-coverage-backend/src/service/standaloneServer.ts b/plugins/code-coverage-backend/src/service/standaloneServer.ts
index 291f78ffc5..c4ced6baeb 100644
--- a/plugins/code-coverage-backend/src/service/standaloneServer.ts
+++ b/plugins/code-coverage-backend/src/service/standaloneServer.ts
@@ -40,7 +40,7 @@ export async function startStandaloneServer(
const db = useHotMemoize(module, () => {
const knex = knexFactory({
- client: 'sqlite3',
+ client: 'better-sqlite3',
connection: ':memory:',
useNullAsDefault: true,
});
diff --git a/plugins/code-coverage/CHANGELOG.md b/plugins/code-coverage/CHANGELOG.md
index 2689d3ba08..8dd1a067a8 100644
--- a/plugins/code-coverage/CHANGELOG.md
+++ b/plugins/code-coverage/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-code-coverage
+## 0.1.29
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.9.0
+ - @backstage/core-components@0.9.1
+ - @backstage/catalog-model@0.13.0
+
## 0.1.29-next.0
### Patch Changes
diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json
index d387429d58..f0b115fd18 100644
--- a/plugins/code-coverage/package.json
+++ b/plugins/code-coverage/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-code-coverage",
"description": "A Backstage plugin that helps you keep track of your code coverage",
- "version": "0.1.29-next.0",
+ "version": "0.1.29",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -24,12 +24,12 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.13.0-next.0",
+ "@backstage/catalog-model": "^0.13.0",
"@backstage/config": "^0.1.15",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
"@backstage/errors": "^0.2.2",
- "@backstage/plugin-catalog-react": "^0.9.0-next.0",
+ "@backstage/plugin-catalog-react": "^0.9.0",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -46,12 +46,12 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/dev-utils": "^0.2.25",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"@types/highlightjs": "^10.1.0",
"@types/jest": "^26.0.7",
diff --git a/plugins/config-schema/CHANGELOG.md b/plugins/config-schema/CHANGELOG.md
index 56fc017920..98d3099c0e 100644
--- a/plugins/config-schema/CHANGELOG.md
+++ b/plugins/config-schema/CHANGELOG.md
@@ -1,5 +1,12 @@
# @backstage/plugin-config-schema
+## 0.1.25
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.9.1
+
## 0.1.25-next.0
### Patch Changes
diff --git a/plugins/config-schema/dev/example-schema.json b/plugins/config-schema/dev/example-schema.json
index be297aaa8d..86f05d500d 100644
--- a/plugins/config-schema/dev/example-schema.json
+++ b/plugins/config-schema/dev/example-schema.json
@@ -346,7 +346,7 @@
"properties": {
"client": {
"type": "string",
- "enum": ["sqlite3"]
+ "enum": ["sqlite3", "better-sqlite3"]
},
"connection": {
"type": "string"
diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json
index 9a16050142..a521e0b35c 100644
--- a/plugins/config-schema/package.json
+++ b/plugins/config-schema/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-config-schema",
"description": "A Backstage plugin that lets you browse the configuration schema of your app",
- "version": "0.1.25-next.0",
+ "version": "0.1.25",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -25,7 +25,7 @@
},
"dependencies": {
"@backstage/config": "^0.1.15",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
"@backstage/errors": "^0.2.2",
"@backstage/theme": "^0.2.15",
@@ -41,12 +41,12 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/dev-utils": "^0.2.25",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
diff --git a/plugins/cost-insights/CHANGELOG.md b/plugins/cost-insights/CHANGELOG.md
index 6ceff3112f..4f8139df31 100644
--- a/plugins/cost-insights/CHANGELOG.md
+++ b/plugins/cost-insights/CHANGELOG.md
@@ -1,5 +1,13 @@
# @backstage/plugin-cost-insights
+## 0.11.24
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.9.1
+ - @backstage/catalog-model@0.13.0
+
## 0.11.24-next.0
### Patch Changes
diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json
index 44cbfb84b3..9034fe85b5 100644
--- a/plugins/cost-insights/package.json
+++ b/plugins/cost-insights/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-cost-insights",
"description": "A Backstage plugin that helps you keep track of your cloud spend",
- "version": "0.11.24-next.0",
+ "version": "0.11.24",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -34,9 +34,9 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.13.0-next.0",
+ "@backstage/catalog-model": "^0.13.0",
"@backstage/config": "^0.1.15",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
@@ -60,12 +60,12 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/dev-utils": "^0.2.25",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
diff --git a/plugins/cost-insights/src/components/BarChart/BarChart.tsx b/plugins/cost-insights/src/components/BarChart/BarChart.tsx
index 98a2410b7b..27ef69db7a 100644
--- a/plugins/cost-insights/src/components/BarChart/BarChart.tsx
+++ b/plugins/cost-insights/src/components/BarChart/BarChart.tsx
@@ -104,7 +104,7 @@ export const BarChart = ({
.slice(stepStart, stepEnd);
// Pin the domain to the largest value in the series.
- // Intentially redundant - This could simply be derived from the first element in the already sorted list,
+ // Intentionally redundant - This could simply be derived from the first element in the already sorted list,
// but that may not be the case in the future when custom sorting is implemented.
const globalResourcesMax = resources.reduce(
(max, r: ResourceData) => Math.max(max, r.current, r.previous),
diff --git a/plugins/cost-insights/src/utils/scroll.tsx b/plugins/cost-insights/src/utils/scroll.tsx
index 1cf824aeda..65fce35174 100644
--- a/plugins/cost-insights/src/utils/scroll.tsx
+++ b/plugins/cost-insights/src/utils/scroll.tsx
@@ -17,7 +17,7 @@ import React, { useEffect, useRef } from 'react';
import { ScrollTo, useScroll } from '../hooks/useScroll';
/*
- Utility component use in conjuction with useScroll that allows scrollable components to control behavior and offset.
+ Utility component use in conjunction with useScroll that allows scrollable components to control behavior and offset.
1. ScrollAnchor must be a direct child of a scrollable component.
2. ScrollAnchor's parent position must be relative.
3. ScrollAnchor's id must be unique.
diff --git a/plugins/explore-react/package.json b/plugins/explore-react/package.json
index 3de867f965..650ec24660 100644
--- a/plugins/explore-react/package.json
+++ b/plugins/explore-react/package.json
@@ -40,7 +40,7 @@
"@backstage/dev-utils": "^0.2.25-next.0",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
diff --git a/plugins/explore/CHANGELOG.md b/plugins/explore/CHANGELOG.md
index 829946a3ce..2f7da4efa6 100644
--- a/plugins/explore/CHANGELOG.md
+++ b/plugins/explore/CHANGELOG.md
@@ -1,5 +1,15 @@
# @backstage/plugin-explore
+## 0.3.33
+
+### Patch Changes
+
+- bf95bb806c: Remove usages of now-removed `CatalogApi.getEntityByName`
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.9.0
+ - @backstage/core-components@0.9.1
+ - @backstage/catalog-model@0.13.0
+
## 0.3.33-next.0
### Patch Changes
diff --git a/plugins/explore/package.json b/plugins/explore/package.json
index 5491c8c379..43de4f12b0 100644
--- a/plugins/explore/package.json
+++ b/plugins/explore/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-explore",
"description": "A Backstage plugin for building an exploration page of your software ecosystem",
- "version": "0.3.33-next.0",
+ "version": "0.3.33",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -34,10 +34,10 @@
"start": "backstage-cli package start"
},
"dependencies": {
- "@backstage/catalog-model": "^0.13.0-next.0",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/catalog-model": "^0.13.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
- "@backstage/plugin-catalog-react": "^0.9.0-next.0",
+ "@backstage/plugin-catalog-react": "^0.9.0",
"@backstage/plugin-explore-react": "^0.0.14",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
@@ -53,12 +53,12 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/dev-utils": "^0.2.25",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
diff --git a/plugins/firehydrant/CHANGELOG.md b/plugins/firehydrant/CHANGELOG.md
index cc0f46d7ff..17f5fcca21 100644
--- a/plugins/firehydrant/CHANGELOG.md
+++ b/plugins/firehydrant/CHANGELOG.md
@@ -1,5 +1,13 @@
# @backstage/plugin-firehydrant
+## 0.1.19
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.9.0
+ - @backstage/core-components@0.9.1
+
## 0.1.19-next.0
### Patch Changes
diff --git a/plugins/firehydrant/package.json b/plugins/firehydrant/package.json
index bd869de57f..5956acdec9 100644
--- a/plugins/firehydrant/package.json
+++ b/plugins/firehydrant/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-firehydrant",
"description": "A Backstage plugin that integrates towards FireHydrant",
- "version": "0.1.19-next.0",
+ "version": "0.1.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -25,9 +25,9 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
- "@backstage/plugin-catalog-react": "^0.9.0-next.0",
+ "@backstage/plugin-catalog-react": "^0.9.0",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -39,12 +39,12 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/dev-utils": "^0.2.25",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
diff --git a/plugins/fossa/CHANGELOG.md b/plugins/fossa/CHANGELOG.md
index cfa1046581..f8e0bbf1cf 100644
--- a/plugins/fossa/CHANGELOG.md
+++ b/plugins/fossa/CHANGELOG.md
@@ -1,5 +1,15 @@
# @backstage/plugin-fossa
+## 0.2.34
+
+### Patch Changes
+
+- bf95bb806c: Remove usages of now-removed `CatalogApi.getEntityByName`
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.9.0
+ - @backstage/core-components@0.9.1
+ - @backstage/catalog-model@0.13.0
+
## 0.2.34-next.0
### Patch Changes
diff --git a/plugins/fossa/dev/index.tsx b/plugins/fossa/dev/index.tsx
index 1ce9ec58b2..78c0ad380b 100644
--- a/plugins/fossa/dev/index.tsx
+++ b/plugins/fossa/dev/index.tsx
@@ -43,7 +43,6 @@ const entity = (name?: string) =>
{
type: RELATION_OWNED_BY,
targetRef: `group:default/${name}`,
- target: { kind: 'group', namespace: 'default', name },
},
],
} as Entity);
diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json
index 5cd8aa4eff..a63bf02b2f 100644
--- a/plugins/fossa/package.json
+++ b/plugins/fossa/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-fossa",
"description": "A Backstage plugin that integrates towards FOSSA",
- "version": "0.2.34-next.0",
+ "version": "0.2.34",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -35,11 +35,11 @@
"clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/catalog-model": "^0.13.0-next.0",
- "@backstage/core-components": "^0.9.1-next.0",
+ "@backstage/catalog-model": "^0.13.0",
+ "@backstage/core-components": "^0.9.1",
"@backstage/core-plugin-api": "^0.8.0",
"@backstage/errors": "^0.2.2",
- "@backstage/plugin-catalog-react": "^0.9.0-next.0",
+ "@backstage/plugin-catalog-react": "^0.9.0",
"@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -53,12 +53,12 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.15.2-next.0",
+ "@backstage/cli": "^0.15.2",
"@backstage/core-app-api": "^0.6.0",
- "@backstage/dev-utils": "^0.2.25-next.0",
+ "@backstage/dev-utils": "^0.2.25",
"@backstage/test-utils": "^0.3.0",
"@testing-library/jest-dom": "^5.10.1",
- "@testing-library/react": "^11.2.5",
+ "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
diff --git a/plugins/gcalendar/.eslintrc.js b/plugins/gcalendar/.eslintrc.js
new file mode 100644
index 0000000000..e2a53a6ad2
--- /dev/null
+++ b/plugins/gcalendar/.eslintrc.js
@@ -0,0 +1 @@
+module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
diff --git a/plugins/gcalendar/README.md b/plugins/gcalendar/README.md
new file mode 100644
index 0000000000..ccfcf9c4eb
--- /dev/null
+++ b/plugins/gcalendar/README.md
@@ -0,0 +1,28 @@
+# Google calendar plugin
+
+Plugin displays events from google calendar
+
+## Getting started
+
+The plugin exports `HomePageCalendar` widget for the Homepage.
+If your homepage is not static JSX add `gcalendarApiRef` to the App's `apis.ts`:
+
+```ts
+import {
+ GCalendarApiClient,
+ gcalendarApiRef,
+} from '@backstage/plugin-gcalendar';
+
+export const apis = [
+ // ...
+ createApiFactory({
+ api: gcalendarApiRef,
+ deps: { authApi: googleAuthApiRef, fetchApi: fetchApiRef },
+ factory: deps => new GCalendarApiClient(deps),
+ }),
+];
+```
+
+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.
diff --git a/plugins/gcalendar/api-report.md b/plugins/gcalendar/api-report.md
new file mode 100644
index 0000000000..276c144400
--- /dev/null
+++ b/plugins/gcalendar/api-report.md
@@ -0,0 +1,88 @@
+## API Report File for "@backstage/plugin-gcalendar"
+
+> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
+
+```ts
+///
+///
+
+import { ApiRef } from '@backstage/core-plugin-api';
+import { BackstagePlugin } from '@backstage/core-plugin-api';
+import { FetchApi } from '@backstage/core-plugin-api';
+import { OAuthApi } from '@backstage/core-plugin-api';
+import { RouteRef } from '@backstage/core-plugin-api';
+
+// Warning: (ae-missing-release-tag) "EventAttendee" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
+//
+// @public (undocumented)
+export type EventAttendee = gapi.client.calendar.EventAttendee;
+
+// Warning: (ae-missing-release-tag) "GCalendar" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
+//
+// @public (undocumented)
+export type GCalendar = gapi.client.calendar.CalendarListEntry;
+
+// Warning: (ae-missing-release-tag) "GCalendarApiClient" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
+//
+// @public (undocumented)
+export class GCalendarApiClient {
+ // Warning: (ae-forgotten-export) The symbol "Options" needs to be exported by the entry point index.d.ts
+ constructor(options: Options);
+ // (undocumented)
+ getCalendars(params?: any): Promise<{
+ items: GCalendar[];
+ }>;
+ // (undocumented)
+ getEvents(
+ calendarId: string,
+ params?: any,
+ ): Promise<{
+ items: GCalendarEvent[];
+ }>;
+}
+
+// Warning: (ae-missing-release-tag) "gcalendarApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
+//
+// @public (undocumented)
+export const gcalendarApiRef: ApiRef;
+
+// Warning: (ae-missing-release-tag) "GCalendarEvent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
+//
+// @public (undocumented)
+export type GCalendarEvent = gapi.client.calendar.Event &
+ Pick &
+ Pick & {
+ calendarId?: string;
+ };
+
+// Warning: (ae-missing-release-tag) "gcalendarPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
+//
+// @public (undocumented)
+export const gcalendarPlugin: BackstagePlugin<
+ {
+ root: RouteRef;
+ },
+ {}
+>;
+
+// Warning: (ae-missing-release-tag) "HomePageCalendar" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
+//
+// @public (undocumented)
+export const HomePageCalendar: () => JSX.Element;
+
+// Warning: (ae-missing-release-tag) "ResponseStatus" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
+//
+// @public (undocumented)
+export enum ResponseStatus {
+ // (undocumented)
+ accepted = 'accepted',
+ // (undocumented)
+ declined = 'declined',
+ // (undocumented)
+ maybe = 'tentative',
+ // (undocumented)
+ needsAction = 'needsAction',
+}
+
+// (No @packageDocumentation comment for this package)
+```
diff --git a/plugins/gcalendar/dev/index.tsx b/plugins/gcalendar/dev/index.tsx
new file mode 100644
index 0000000000..807c2b4d77
--- /dev/null
+++ b/plugins/gcalendar/dev/index.tsx
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React from 'react';
+import { Content, Page } from '@backstage/core-components';
+import { googleAuthApiRef } from '@backstage/core-plugin-api';
+import { createDevApp } from '@backstage/dev-utils';
+import { calendarListMock, eventsMock } from './mocks';
+import { gcalendarPlugin, HomePageCalendar } from '../src/plugin';
+import { gcalendarApiRef } from '../src';
+
+createDevApp()
+ .registerPlugin(gcalendarPlugin)
+ .registerApi({
+ api: googleAuthApiRef,
+ deps: {},
+ factory: () =>
+ ({
+ async getAccessToken() {
+ return Promise.resolve('token');
+ },
+ } as unknown as typeof googleAuthApiRef.T),
+ })
+ .registerApi({
+ api: gcalendarApiRef,
+ deps: {},
+ factory: () =>
+ ({
+ async getCalendars() {
+ return Promise.resolve(calendarListMock);
+ },
+ async getEvents() {
+ return Promise.resolve({
+ items: eventsMock,
+ });
+ },
+ } as unknown as typeof gcalendarApiRef.T),
+ })
+ .addPage({
+ element: (
+
+
+
+
+
+ ),
+ title: 'Root Page',
+ })
+ .render();
diff --git a/plugins/gcalendar/dev/mocks.ts b/plugins/gcalendar/dev/mocks.ts
new file mode 100644
index 0000000000..c566527590
--- /dev/null
+++ b/plugins/gcalendar/dev/mocks.ts
@@ -0,0 +1,57 @@
+/*
+ * 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 { DateTime } from 'luxon';
+import { GCalendar, GCalendarEvent } from '../src/api';
+
+const primaryCalendar: GCalendar = {
+ id: 'calendar-1',
+ summary: 'test-1@test.com',
+ primary: true,
+};
+const nonPrimaryCalendar: GCalendar = {
+ id: 'calendar-2',
+ summary: 'test-2@test.com',
+ primary: false,
+ backgroundColor: '#9BF0E1',
+};
+
+export const calendarListMock = {
+ items: [primaryCalendar, nonPrimaryCalendar],
+};
+
+export const eventsMock: GCalendarEvent[] = [...Array(3).keys()].map(i => ({
+ id: i.toString(),
+ summary: `Meeting ${i + 1}`,
+ start: {
+ dateTime: DateTime.now()
+ .minus({ hour: i + 1 })
+ .toISO(),
+ timeZone: 'Europe/London',
+ },
+ end: {
+ dateTime: DateTime.now().minus({ hour: i }).toISO(),
+ timeZone: 'Europe/London',
+ },
+ description: '
Dummy title
Dummy description
',
+ conferenceData: {
+ entryPoints: [
+ {
+ entryPointType: 'video',
+ uri: 'https://zoom.us/',
+ },
+ ],
+ },
+}));
diff --git a/plugins/gcalendar/package.json b/plugins/gcalendar/package.json
new file mode 100644
index 0000000000..d5fb6765e3
--- /dev/null
+++ b/plugins/gcalendar/package.json
@@ -0,0 +1,65 @@
+{
+ "name": "@backstage/plugin-gcalendar",
+ "version": "0.1.0",
+ "main": "src/index.ts",
+ "types": "src/index.ts",
+ "license": "Apache-2.0",
+ "publishConfig": {
+ "access": "public",
+ "main": "dist/index.esm.js",
+ "types": "dist/index.d.ts"
+ },
+ "backstage": {
+ "role": "frontend-plugin"
+ },
+ "scripts": {
+ "start": "backstage-cli package start",
+ "build": "backstage-cli package build",
+ "clean": "backstage-cli package clean",
+ "test": "backstage-cli package test",
+ "lint": "backstage-cli package lint",
+ "prepack": "backstage-cli package prepack",
+ "postpack": "backstage-cli package postpack"
+ },
+ "dependencies": {
+ "@backstage/core-components": "^0.9.1",
+ "@backstage/core-plugin-api": "^0.8.0",
+ "@backstage/errors": "^0.2.2",
+ "@backstage/theme": "^0.2.15",
+ "@material-ui/core": "^4.12.2",
+ "@material-ui/icons": "^4.9.1",
+ "@material-ui/lab": "4.0.0-alpha.57",
+ "classnames": "^2.3.1",
+ "cross-fetch": "^3.1.5",
+ "dompurify": "^2.3.6",
+ "lodash": "^4.17.21",
+ "luxon": "^2.3.0",
+ "material-ui-popup-state": "^1.9.3",
+ "react-query": "^3.34.16",
+ "react-use": "^17.2.4"
+ },
+ "peerDependencies": {
+ "react": "^16.13.1 || ^17.0.0"
+ },
+ "devDependencies": {
+ "@backstage/cli": "^0.15.2",
+ "@backstage/core-app-api": "^0.6.0",
+ "@backstage/dev-utils": "^0.2.25",
+ "@backstage/test-utils": "^0.3.0",
+ "@testing-library/jest-dom": "^5.10.1",
+ "@testing-library/react": "^12.1.3",
+ "@testing-library/user-event": "^13.1.8",
+ "@types/dompurify": "^2.3.3",
+ "@types/gapi": "^0.0.41",
+ "@types/gapi.auth2": "^0.0.56",
+ "@types/gapi.client.calendar": "^3.0.10",
+ "@types/jest": "^26.0.7",
+ "@types/node": "^14.14.32",
+ "@types/sanitize-html": "^2.6.2",
+ "cross-fetch": "^3.1.5",
+ "msw": "^0.35.0"
+ },
+ "files": [
+ "dist"
+ ]
+}
diff --git a/plugins/gcalendar/src/api/client.ts b/plugins/gcalendar/src/api/client.ts
new file mode 100644
index 0000000000..5b6ea96339
--- /dev/null
+++ b/plugins/gcalendar/src/api/client.ts
@@ -0,0 +1,73 @@
+/*
+ * 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 { OAuthApi, createApiRef, FetchApi } from '@backstage/core-plugin-api';
+
+import { GCalendar, GCalendarEvent } from './types';
+import { ResponseError } from '@backstage/errors';
+
+type Options = {
+ authApi: OAuthApi;
+ fetchApi: FetchApi;
+};
+
+export const gcalendarApiRef = createApiRef({
+ id: 'plugin.gcalendar.service',
+});
+
+export class GCalendarApiClient {
+ private readonly authApi: OAuthApi;
+ private readonly fetchApi: FetchApi;
+
+ constructor(options: Options) {
+ this.authApi = options.authApi;
+ this.fetchApi = options.fetchApi;
+ }
+
+ private async get(
+ path: string,
+ params: { [key in string]: any },
+ ): Promise {
+ const query = new URLSearchParams(params);
+ const url = new URL(
+ `${path}?${query.toString()}`,
+ 'https://www.googleapis.com',
+ );
+ const token = await this.authApi.getAccessToken();
+ const response = await this.fetchApi.fetch(url.toString(), {
+ headers: token ? { Authorization: `Bearer ${token}` } : {},
+ });
+
+ if (!response.ok) {
+ throw await ResponseError.fromResponse(response);
+ }
+
+ return response.json() as Promise;
+ }
+
+ public async getCalendars(params?: any) {
+ return this.get<{ items: GCalendar[] }>(
+ '/calendar/v3/users/me/calendarList',
+ params,
+ );
+ }
+
+ public async getEvents(calendarId: string, params?: any) {
+ return this.get<{ items: GCalendarEvent[] }>(
+ `/calendar/v3/calendars/${encodeURIComponent(calendarId)}/events`,
+ params,
+ );
+ }
+}
diff --git a/plugins/gcalendar/src/api/index.ts b/plugins/gcalendar/src/api/index.ts
new file mode 100644
index 0000000000..4c195158d3
--- /dev/null
+++ b/plugins/gcalendar/src/api/index.ts
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+export * from './client';
+export * from './types';
diff --git a/plugins/gcalendar/src/api/types.ts b/plugins/gcalendar/src/api/types.ts
new file mode 100644
index 0000000000..1423b91aca
--- /dev/null
+++ b/plugins/gcalendar/src/api/types.ts
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+///
+///
+
+export type GCalendar = gapi.client.calendar.CalendarListEntry;
+
+export type EventAttendee = gapi.client.calendar.EventAttendee;
+
+export type GCalendarEvent = gapi.client.calendar.Event &
+ Pick &
+ Pick & {
+ calendarId?: string;
+ };
+
+export enum ResponseStatus {
+ needsAction = 'needsAction',
+ accepted = 'accepted',
+ declined = 'declined',
+ maybe = 'tentative',
+}
diff --git a/plugins/gcalendar/src/components/CalendarCard/AttendeeChip.test.tsx b/plugins/gcalendar/src/components/CalendarCard/AttendeeChip.test.tsx
new file mode 100644
index 0000000000..64485e74ab
--- /dev/null
+++ b/plugins/gcalendar/src/components/CalendarCard/AttendeeChip.test.tsx
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React from 'react';
+
+import { renderInTestApp } from '@backstage/test-utils';
+
+import { AttendeeChip } from './AttendeeChip';
+import { EventAttendee, ResponseStatus } from '../../api';
+
+describe('', () => {
+ it('renders attendee email', async () => {
+ const email = 'test@test.com';
+ const user: EventAttendee = {
+ email,
+ responseStatus: ResponseStatus.needsAction,
+ };
+ const { queryByText } = await renderInTestApp();
+ expect(queryByText(email)).toBeInTheDocument();
+ });
+
+ it('renders accepted icon', async () => {
+ const email = 'test@test.com';
+ const user: EventAttendee = {
+ email,
+ responseStatus: ResponseStatus.accepted,
+ };
+ const { getByTestId } = await renderInTestApp();
+ expect(getByTestId('accepted-icon')).toBeInTheDocument();
+ });
+
+ it('renders declined icon', async () => {
+ const email = 'test@test.com';
+ const user: EventAttendee = {
+ email,
+ responseStatus: ResponseStatus.declined,
+ };
+ const { getByTestId } = await renderInTestApp();
+ expect(getByTestId('declined-icon')).toBeInTheDocument();
+ });
+});
diff --git a/plugins/gcalendar/src/components/CalendarCard/AttendeeChip.tsx b/plugins/gcalendar/src/components/CalendarCard/AttendeeChip.tsx
new file mode 100644
index 0000000000..dd4d743572
--- /dev/null
+++ b/plugins/gcalendar/src/components/CalendarCard/AttendeeChip.tsx
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React from 'react';
+
+import { BackstageTheme } from '@backstage/theme';
+
+import { Badge, Chip, makeStyles } from '@material-ui/core';
+import CancelIcon from '@material-ui/icons/Cancel';
+import CheckIcon from '@material-ui/icons/CheckCircle';
+
+import { EventAttendee, ResponseStatus } from '../../api';
+
+const useStyles = makeStyles((theme: BackstageTheme) => {
+ const getIconColor = (responseStatus?: string) => {
+ if (!responseStatus) return theme.palette.primary.light;
+
+ return {
+ [ResponseStatus.accepted]: theme.palette.status.ok,
+ [ResponseStatus.declined]: theme.palette.status.error,
+ }[responseStatus];
+ };
+
+ return {
+ responseStatus: {
+ color: ({ responseStatus }: { responseStatus?: string }) =>
+ getIconColor(responseStatus),
+ },
+ badge: {
+ right: 10,
+ top: 5,
+ '& svg': {
+ height: 16,
+ width: 16,
+ background: '#fff',
+ },
+ },
+ };
+});
+
+const ResponseIcon = ({ responseStatus }: any) => {
+ if (responseStatus === ResponseStatus.accepted) {
+ return ;
+ }
+ if (responseStatus === ResponseStatus.declined) {
+ return ;
+ }
+
+ return null;
+};
+
+type AttendeeChipProps = {
+ user: EventAttendee;
+};
+
+export const AttendeeChip = ({ user }: AttendeeChipProps) => {
+ const classes = useStyles({ responseStatus: user.responseStatus });
+
+ return (
+ }
+ >
+
+
+ );
+};
diff --git a/plugins/gcalendar/src/components/CalendarCard/CalendarCard.tsx b/plugins/gcalendar/src/components/CalendarCard/CalendarCard.tsx
new file mode 100644
index 0000000000..7b7c02b883
--- /dev/null
+++ b/plugins/gcalendar/src/components/CalendarCard/CalendarCard.tsx
@@ -0,0 +1,146 @@
+/*
+ * 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 { sortBy } from 'lodash';
+import { DateTime } from 'luxon';
+import React, { useEffect, useMemo, useState } from 'react';
+
+import { InfoCard, Progress } from '@backstage/core-components';
+import { useAnalytics } from '@backstage/core-plugin-api';
+
+import { Box, IconButton, Typography } from '@material-ui/core';
+import PrevIcon from '@material-ui/icons/NavigateBefore';
+import NextIcon from '@material-ui/icons/NavigateNext';
+
+import {
+ useCalendarsQuery,
+ useEventsQuery,
+ useSignIn,
+ useStoredCalendars,
+} from '../../hooks';
+import calendarCardIcon from '../../icons/calendarIcon.svg';
+import { CalendarEvent } from './CalendarEvent';
+import { CalendarSelect } from './CalendarSelect';
+import { SignInContent } from './SignInContent';
+import { getStartDate } from './util';
+
+export const CalendarCard = () => {
+ const [date, setDate] = useState(DateTime.now());
+ const analytics = useAnalytics();
+
+ const changeDay = (offset = 1) => {
+ setDate(prev => prev.plus({ day: offset }));
+ analytics.captureEvent('click', 'change date');
+ };
+
+ const { isSignedIn, isInitialized, signIn } = useSignIn();
+
+ useEffect(() => {
+ signIn(true);
+ }, [signIn]);
+
+ const { isLoading: isCalendarLoading, data } = useCalendarsQuery({
+ enabled: isSignedIn,
+ });
+ const calendars = useMemo(() => data?.items || [], [data]);
+ const primaryCalendarId = calendars.find(c => c.primary === true)?.id;
+ const defaultSelectedCalendars = primaryCalendarId ? [primaryCalendarId] : [];
+ const [storedCalendars, setStoredCalendars] = useStoredCalendars(
+ defaultSelectedCalendars,
+ );
+
+ const { events, isLoading: isEventLoading } = useEventsQuery({
+ calendars,
+ selectedCalendars: storedCalendars,
+ enabled: isSignedIn && calendars.length > 0,
+ timeMin: date.startOf('day').toISO(),
+ timeMax: date.endOf('day').toISO(),
+ timeZone: date.zoneName,
+ });
+
+ return (
+
+
+
+
+ {isSignedIn ? (
+ <>
+ changeDay(-1)} size="small">
+
+
+ changeDay(1)} size="small">
+
+
+
+
+ {date.toLocaleString({
+ weekday: 'short',
+ month: 'short',
+ day: 'numeric',
+ })}
+
+
+
+
+
+ >
+ ) : (
+ Agenda
+ )}
+
+ }
+ deepLink={{
+ link: 'https://calendar.google.com/',
+ title: 'Go to Calendar',
+ }}
+ >
+
+ {(isCalendarLoading || isEventLoading || !isInitialized) && (
+
+