diff --git a/.changeset/clever-tomatoes-change.md b/.changeset/clever-tomatoes-change.md deleted file mode 100644 index c57953efb9..0000000000 --- a/.changeset/clever-tomatoes-change.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch -'@backstage/plugin-scaffolder-backend': minor ---- - -# Stateless scaffolding - -The scaffolder has been redesigned to be horizontally scalable and to persistently store task state and execution logs in the database. - -Each scaffolder task is given a unique task ID which is persisted in the database. -Tasks are then picked up by a `TaskWorker` which performs the scaffolding steps. -Execution logs are also persisted in the database meaning you can now refresh the scaffolder task status page without losing information. - -The task status page is now dynamically created based on the step information stored in the database. -This allows for custom steps to be displayed once the next version of the scaffolder template schema is available. - -The task page is updated to display links to both the git repository and to the newly created catalog entity. - -Component registration has moved from the frontend into a separate registration step executed by the `TaskWorker`. This requires that a `CatalogClient` is passed to the scaffolder backend instead of the old `CatalogEntityClient`. - -Make sure to update `plugins/scaffolder.ts` - -```diff - import { - CookieCutter, - createRouter, - Preparers, - Publishers, - CreateReactAppTemplater, - Templaters, -- CatalogEntityClient, - } from '@backstage/plugin-scaffolder-backend'; - -+import { CatalogClient } from '@backstage/catalog-client'; - - const discovery = SingleHostDiscovery.fromConfig(config); --const entityClient = new CatalogEntityClient({ discovery }); -+const catalogClient = new CatalogClient({ discoveryApi: discovery }) - - return await createRouter({ - preparers, - templaters, - publishers, - logger, - config, - dockerClient, -- entityClient, - database, -+ catalogClient, - }); -``` - -As well as adding the `@backstage/catalog-client` packages as a dependency of your backend package. diff --git a/.changeset/curly-poems-boil.md b/.changeset/curly-poems-boil.md deleted file mode 100644 index 22d5df4665..0000000000 --- a/.changeset/curly-poems-boil.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Update messages that process during loading, error, and no templates found. -Remove unused dependencies. diff --git a/.changeset/cyan-dingos-watch.md b/.changeset/cyan-dingos-watch.md deleted file mode 100644 index 7b15d30112..0000000000 --- a/.changeset/cyan-dingos-watch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/test-utils': patch ---- - -Allow `ExternalRouteRef` instances to be passed as a route ref to `mountedRoutes`. diff --git a/.changeset/cyan-feet-hide.md b/.changeset/cyan-feet-hide.md deleted file mode 100644 index a1d58d8252..0000000000 --- a/.changeset/cyan-feet-hide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-org': patch ---- - -Use the `pageTheme` to colour the OwnershipCard boxes with their respective theme colours. diff --git a/.changeset/dingo-dongo.md b/.changeset/dingo-dongo.md deleted file mode 100644 index 424c88f61c..0000000000 --- a/.changeset/dingo-dongo.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -'@backstage/plugin-catalog': minor -'@backstage/plugin-scaffolder': minor ---- - -The Scaffolder and Catalog plugins have been migrated to partially require use of the [new composability API](https://backstage.io/docs/plugins/composability). The Scaffolder used to register its pages using the deprecated route registration plugin API, but those registrations have been removed. This means you now need to add the Scaffolder plugin page to the app directly. - -The page is imported from the Scaffolder plugin and added to the `` component: - -```tsx -} /> -``` - -The Catalog plugin has also been migrated to use an [external route reference](https://backstage.io/docs/plugins/composability#binding-external-routes-in-the-app) to dynamically link to the create component page. This means you need to migrate the catalog plugin to use the new extension components, as well as bind the external route. - -To use the new extension components, replace existing usage of the `CatalogRouter` with the following: - -```tsx -} /> -}> - - -``` - -And to bind the external route from the catalog plugin to the scaffolder template index page, make sure you have the appropriate imports and add the following to the `createApp` call: - -```ts -import { catalogPlugin } from '@backstage/plugin-catalog'; -import { scaffolderPlugin } from '@backstage/plugin-scaffolder'; - -const app = createApp({ - // ... - bindRoutes({ bind }) { - bind(catalogPlugin.externalRoutes, { - createComponent: scaffolderPlugin.routes.root, - }); - }, -}); -``` diff --git a/.changeset/dry-ads-matter.md b/.changeset/dry-ads-matter.md deleted file mode 100644 index fc0a412d1e..0000000000 --- a/.changeset/dry-ads-matter.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch -'@backstage/plugin-techdocs-backend': patch ---- - -Got rid of some `attr` and cleaned up a bit in the TechDocs config schema. diff --git a/.changeset/eight-chefs-reply.md b/.changeset/eight-chefs-reply.md deleted file mode 100644 index 9e133e2722..0000000000 --- a/.changeset/eight-chefs-reply.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-explore': patch ---- - -Display the owner of a domain on the domain card. diff --git a/.changeset/gentle-buses-exist.md b/.changeset/gentle-buses-exist.md deleted file mode 100644 index a32f0bf8f0..0000000000 --- a/.changeset/gentle-buses-exist.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/core-api': patch -'@backstage/core': patch ---- - -More informative error message for missing ApiContext. diff --git a/.changeset/itchy-rivers-judge.md b/.changeset/itchy-rivers-judge.md deleted file mode 100644 index 711becd33b..0000000000 --- a/.changeset/itchy-rivers-judge.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': minor ---- - -Adding Search and Filter features to Scaffolder/Templates Grid diff --git a/.changeset/kind-eels-run.md b/.changeset/kind-eels-run.md deleted file mode 100644 index 0d890b0478..0000000000 --- a/.changeset/kind-eels-run.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/core': patch -'@backstage/plugin-catalog-react': patch ---- - -Forward link styling of `EntityRefLink` and `EnriryRefLinks` into the underling -`Link`. diff --git a/.changeset/popular-donuts-fetch.md b/.changeset/popular-donuts-fetch.md deleted file mode 100644 index 9681bdb875..0000000000 --- a/.changeset/popular-donuts-fetch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-tech-radar': patch ---- - -Added a dialog box that will show up when a you click on link on the radar and display the description if provided. diff --git a/.changeset/popular-nails-agree.md b/.changeset/popular-nails-agree.md deleted file mode 100644 index 361ff4745d..0000000000 --- a/.changeset/popular-nails-agree.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/core': patch ---- - -Deprecate `type` of `ItemCard` and introduce new `subtitle` which allows passing -react nodes. diff --git a/.changeset/seven-kangaroos-work.md b/.changeset/seven-kangaroos-work.md deleted file mode 100644 index 6e4ac95c9d..0000000000 --- a/.changeset/seven-kangaroos-work.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-app-backend': patch ---- - -Clarify troubleshooting steps for schema serialization issues. diff --git a/.changeset/small-bikes-enjoy.md b/.changeset/small-bikes-enjoy.md deleted file mode 100644 index 2b624ece2f..0000000000 --- a/.changeset/small-bikes-enjoy.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-api-docs': patch -'@backstage/plugin-catalog': patch ---- - -Changes made in CatalogTable and ApiExplorerTable for using the OverflowTooltip component for truncating large description and showing tooltip on hover-over. diff --git a/.changeset/techdocs-wild-zoos-do.md b/.changeset/techdocs-wild-zoos-do.md deleted file mode 100644 index 42a2a6f1c4..0000000000 --- a/.changeset/techdocs-wild-zoos-do.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/techdocs-common': patch ---- - -Fix AWS, GCS and Azure publisher to work on Windows. diff --git a/.changeset/three-pumpkins-watch.md b/.changeset/three-pumpkins-watch.md new file mode 100644 index 0000000000..cb059a5381 --- /dev/null +++ b/.changeset/three-pumpkins-watch.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-jenkins': patch +--- + +- Add Jenkins logo to project page. +- Move to new Backstage breadcrumb component. +- Change references of deprecated "Job" terminology to "Project" per [Jenkins Glossary](https://www.jenkins.io/doc/book/glossary/). diff --git a/.changeset/tricky-birds-appear.md b/.changeset/tricky-birds-appear.md deleted file mode 100644 index ce1792c5da..0000000000 --- a/.changeset/tricky-birds-appear.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core': patch ---- - -Introduced generic OverflowTooltip component for cases where longer text needs to be truncated with ellipsis and show hover tooltip with full text. This is particularly useful in the cases where longer description text is rendered in table. e.g. CatalogTable and ApiExplorerTable. diff --git a/.changeset/twenty-pandas-crash.md b/.changeset/twenty-pandas-crash.md new file mode 100644 index 0000000000..95ff389406 --- /dev/null +++ b/.changeset/twenty-pandas-crash.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Fixed EntityProvider setting 'loading' bool erroneously to true diff --git a/.changeset/weak-foxes-explain.md b/.changeset/weak-foxes-explain.md deleted file mode 100644 index 5536e1982c..0000000000 --- a/.changeset/weak-foxes-explain.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -**BREAKING CHANGE** - -The Scaffolder and Catalog plugins have been migrated to partially require use of the [new composability API](https://backstage.io/docs/plugins/composability). The Scaffolder used to register its pages using the deprecated route registration plugin API, but those registrations have been removed. This means you now need to add the Scaffolder plugin page to the app directly. - -The Catalog plugin has also been migrated to use an [external route reference](https://backstage.io/docs/plugins/composability#binding-external-routes-in-the-app) to dynamically link to the create component page. This means you need to migrate the catalog plugin to use the new extension components, as well as bind the external route. - -Apply the following changes to `packages/app/src/App.tsx`: - -```diff --import { Router as CatalogRouter } from '@backstage/plugin-catalog'; -+import { -+ catalogPlugin, -+ CatalogIndexPage, -+ CatalogEntityPage, -+} from '@backstage/plugin-catalog'; -+import { scaffolderPlugin, ScaffolderPage } from '@backstage/plugin-scaffolder'; - -# The following addition to the app config allows the catalog plugin to link to the -# component creation page, i.e. the scaffolder. You can chose a different target if you want to. - const app = createApp({ - apis, - plugins: Object.values(plugins), -+ bindRoutes({ bind }) { -+ bind(catalogPlugin.externalRoutes, { -+ createComponent: scaffolderPlugin.routes.root, -+ }); -+ } - }); - -# Apply these changes within FlatRoutes. It is important to have migrated to using FlatRoutes -# for this to work, if you haven't done that yet, see the previous entries in this changelog. -- } -- /> -+ } /> -+ } -+ > -+ -+ - } /> -+ } /> -``` - -The scaffolder has been redesigned to be horizontally scalable and to persistently store task state and execution logs in the database. Component registration has moved from the frontend into a separate registration step executed by the `TaskWorker`. This requires that a `CatalogClient` is passed to the scaffolder backend instead of the old `CatalogEntityClient`. - -The default catalog client comes from the `@backstage/catalog-client`, which you need to add as a dependency in `packages/backend/package.json`. - -Once the dependency has been added, apply the following changes to`packages/backend/src/plugins/scaffolder.ts`: - -```diff - import { - CookieCutter, - createRouter, - Preparers, - Publishers, - CreateReactAppTemplater, - Templaters, -- CatalogEntityClient, - } from '@backstage/plugin-scaffolder-backend'; -+import { CatalogClient } from '@backstage/catalog-client'; - - const discovery = SingleHostDiscovery.fromConfig(config); --const entityClient = new CatalogEntityClient({ discovery }); -+const catalogClient = new CatalogClient({ discoveryApi: discovery }) - - return await createRouter({ - preparers, - templaters, - publishers, - logger, - config, - dockerClient, -- entityClient, - database, -+ catalogClient, - }); -``` - -See the `@backstage/scaffolder-backend` changelog for more information about this change. diff --git a/.github/styles/vocab.txt b/.github/styles/vocab.txt index 41ec95e9aa..2e0bd13962 100644 --- a/.github/styles/vocab.txt +++ b/.github/styles/vocab.txt @@ -94,6 +94,7 @@ Zalando Zhou Zolotusky abc +accessors adamdmharvey andrewthauer api @@ -166,6 +167,7 @@ interop jq js json +jsonnet jsx kubectl kubernetes @@ -203,6 +205,7 @@ octokit oidc onboarding pagerduty +pageview parallelization plantuml postgres diff --git a/docs/cli/commands.md b/docs/cli/commands.md index ea72f7e050..5a68690615 100644 --- a/docs/cli/commands.md +++ b/docs/cli/commands.md @@ -24,7 +24,6 @@ Below is a cleaned up output of `yarn backstage-cli --help`. ```text app:build Build an app for a production release -app:diff Diff an existing app with the creation template app:serve Serve an app for local development backend:build Build a backend plugin @@ -112,25 +111,6 @@ Options: -h, --help display help for command ``` -## app:diff - -Scope: `app` - -Diff an existing app with the template used in `@backstage/create-app`. This -will verify that your app package has not diverged from the template, and can be -useful to run after updating the version of `@backstage/cli` in your app. - -This command is experimental and may be removed in the future. - -```text -Usage: backstage-cli app:diff - -Options: - --check Fail if changes are required - --yes Apply all changes - -h, --help display help for command -``` - ## app:serve Scope: `app` diff --git a/docs/features/software-catalog/well-known-annotations.md b/docs/features/software-catalog/well-known-annotations.md index 2cbb829554..8ec4813799 100644 --- a/docs/features/software-catalog/well-known-annotations.md +++ b/docs/features/software-catalog/well-known-annotations.md @@ -70,6 +70,35 @@ The value of this annotation is a location reference string (see above). If this annotation is specified, it is expected to point to a repository that the TechDocs system can read and generate docs from. +### backstage.io/view-url, backstage.io/edit-url + +```yaml +# Example: +metadata: + annotations: + backstage.io/view-url: https://some.website/catalog-info.yaml + backstage.io/edit-url: https://github.com/my-org/catalog/edit/master/my-service.jsonnet +``` + +These annotations allow customising links from the catalog pages. The view URL +should point to the canonical metadata YAML that governs this entity. The edit +URL should point to the source file for the metadata. In the example above, +`my-org` generates its catalog data from Jsonnet files in a monorepo, so the +view and edit links need changing. + +### backstage.io/source-location + +```yaml +# Example: +metadata: + annotations: + backstage.io/source-location: github:https://github.com/my-org/my-service +``` + +A `Location` reference that points to the source code of the entity (typically a +`Component`). Useful when catalog files do not get ingested from the source code +repository itself. + ### jenkins.io/github-folder ```yaml diff --git a/docs/features/techdocs/using-cloud-storage.md b/docs/features/techdocs/using-cloud-storage.md index 32c44e9595..cd4b058644 100644 --- a/docs/features/techdocs/using-cloud-storage.md +++ b/docs/features/techdocs/using-cloud-storage.md @@ -191,6 +191,27 @@ techdocs: Refer to the [official AWS documentation for obtaining the credentials](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/getting-your-credentials.html). +**3c. Authentication using an assumed role** Users with multiple AWS accounts +may want to use a role for S3 storage that is in a different AWS account. Using +the `roleArn` parameter as seen below, you can instruct the TechDocs publisher +to assume a role before accessing S3. + +```yaml +techdocs: + publisher: + type: 'awsS3' + awsS3: + bucketName: 'name-of-techdocs-storage-bucket' + region: + $env: AWS_REGION + credentials: + roleArn: arn:aws:iam::123456789012:role/my-backstage-role +``` + +Note: Assuming a role requires that primary credentials are already configured +at `AWS.config.credentials`. Read more about +[assuming roles in AWS](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html). + **4. That's it!** Your Backstage app is now ready to use AWS S3 for TechDocs, to store and read diff --git a/docs/integrations/google-analytics/installation.md b/docs/integrations/google-analytics/installation.md new file mode 100644 index 0000000000..a0e6f69d13 --- /dev/null +++ b/docs/integrations/google-analytics/installation.md @@ -0,0 +1,24 @@ +--- +id: installation +title: Google Analytics Installation +sidebar_label: Installation +# prettier-ignore +description: Adding Google Analytics to Your App +--- + +There is a basic Google Analytics integration built into Backstage. You can +enable it by adding the following to your app configuration: + +```yaml +app: + googleAnalyticsTrackingId: UA-000000-0 +``` + +Replace the tracking ID with your own. + +For more information, learn about Google Analytics +[here](https://marketingplatform.google.com/about/analytics/). + +The default behavior is only to send a pageview hit to Google Analytics. To +record more, look at the developer documentation +[here](https://developers.google.com/analytics/devguides/collection/gtagjs). diff --git a/docs/plugins/observability.md b/docs/plugins/observability.md index 8b6668606f..de6f4bf988 100644 --- a/docs/plugins/observability.md +++ b/docs/plugins/observability.md @@ -10,18 +10,8 @@ Backstage integrator. ## Google Analytics -There is a basic Google Analytics integration built into Backstage. You can -enable it by adding the following to your app configuration: - -```yaml -app: - googleAnalyticsTrackingId: UA-000000-0 -``` - -Replace the tracking ID with your own. - -For more information, learn about Google Analytics -[here](https://marketingplatform.google.com/about/analytics/). +See how to install Google Analytics in your app +[here](../integrations/google-analytics/installation.md) ## Logging diff --git a/microsite/pages/en/demos.js b/microsite/pages/en/demos.js index 47ea1ee9ee..86cb6c786d 100644 --- a/microsite/pages/en/demos.js +++ b/microsite/pages/en/demos.js @@ -21,6 +21,8 @@ const Background = props => { To explore the UI and basic features of Backstage firsthand, go to: demo.backstage.io. + (Tip: click “All” to view all the example components in the + service catalog.) Watch the videos below to get an introduction to Backstage and to diff --git a/microsite/sidebars.json b/microsite/sidebars.json index 0b3c8f5915..799433b8ef 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -112,6 +112,11 @@ "type": "subcategory", "label": "LDAP", "ids": ["integrations/ldap/org"] + }, + { + "type": "subcategory", + "label": "Google Analytics", + "ids": ["integrations/google-analytics/installation"] } ], "Plugins": [ diff --git a/mkdocs.yml b/mkdocs.yml index 00824392a7..6b1971ce03 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -70,6 +70,8 @@ nav: - Org Data: 'integrations/github/org.md' - LDAP: - Org Data: 'integrations/ldap/org.md' + - Google Analytics: + - Installation: 'integrations/google-analytics/installation.md' - Plugins: - Overview: 'plugins/index.md' - Existing plugins: 'plugins/existing-plugins.md' diff --git a/package.json b/package.json index 6c39cf2953..527304b4f3 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "docker-build": "yarn tsc && yarn workspace example-backend build --build-dependencies && yarn workspace example-backend build-image", "create-plugin": "backstage-cli create-plugin --scope backstage --no-private", "remove-plugin": "backstage-cli remove-plugin", - "release": "changeset version && yarn diff --yes && yarn prettier --write '{packages,plugins}/*/{package.json,CHANGELOG.md}' && yarn install --frozen-lockfile", + "release": "changeset version && yarn diff --yes && yarn prettier --write '{packages,plugins}/*/{package.json,CHANGELOG.md}' && yarn install", "prettier:check": "prettier --check .", "lerna": "lerna", "storybook": "yarn workspace storybook start", diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index b85ffd3ae1..f9166939c6 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,64 @@ # example-app +## 0.2.17 + +### Patch Changes + +- Updated dependencies [3a58084b6] +- Updated dependencies [a5f42cf66] +- Updated dependencies [38205492a] +- Updated dependencies [e488f0502] +- Updated dependencies [e799e74d4] +- Updated dependencies [e3bc5aad7] +- Updated dependencies [a5f42cf66] +- Updated dependencies [a8953a9c9] +- Updated dependencies [f37992797] +- Updated dependencies [347137ccf] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [d6593abe6] +- Updated dependencies [bad21a085] +- Updated dependencies [e8e35fb5f] +- Updated dependencies [9615e68fb] +- Updated dependencies [e780e119c] +- Updated dependencies [437bac549] +- Updated dependencies [9f2b3a26e] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [968b588f7] +- Updated dependencies [3a58084b6] +- Updated dependencies [2499f6cde] +- Updated dependencies [5469a9761] +- Updated dependencies [60d1bc3e7] +- Updated dependencies [2c1f2a7c2] +- Updated dependencies [6266ddd11] + - @backstage/core@0.6.3 + - @backstage/plugin-scaffolder@0.6.0 + - @backstage/plugin-cost-insights@0.8.2 + - @backstage/plugin-org@0.3.8 + - @backstage/plugin-catalog@0.4.0 + - @backstage/plugin-catalog-import@0.4.2 + - @backstage/plugin-techdocs@0.5.8 + - @backstage/plugin-explore@0.2.7 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/plugin-api-docs@0.4.7 + - @backstage/catalog-model@0.7.2 + - @backstage/cli@0.6.2 + - @backstage/plugin-tech-radar@0.3.6 + - @backstage/plugin-circleci@0.2.10 + - @backstage/plugin-cloudbuild@0.2.11 + - @backstage/plugin-github-actions@0.3.4 + - @backstage/plugin-jenkins@0.3.11 + - @backstage/plugin-kafka@0.2.4 + - @backstage/plugin-kubernetes@0.3.11 + - @backstage/plugin-lighthouse@0.2.12 + - @backstage/plugin-pagerduty@0.3.1 + - @backstage/plugin-register-component@0.2.11 + - @backstage/plugin-rollbar@0.3.2 + - @backstage/plugin-search@0.3.2 + - @backstage/plugin-sentry@0.3.7 + ## 0.2.16 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index c7c517b9ff..76a087a4fd 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,38 +1,38 @@ { "name": "example-app", - "version": "0.2.16", + "version": "0.2.17", "private": true, "bundled": true, "dependencies": { - "@backstage/catalog-model": "^0.7.1", - "@backstage/cli": "^0.6.1", - "@backstage/core": "^0.6.2", - "@backstage/plugin-api-docs": "^0.4.6", - "@backstage/plugin-catalog": "^0.3.2", - "@backstage/plugin-catalog-react": "^0.0.4", - "@backstage/plugin-catalog-import": "^0.4.1", - "@backstage/plugin-circleci": "^0.2.9", - "@backstage/plugin-cloudbuild": "^0.2.10", - "@backstage/plugin-cost-insights": "^0.8.1", - "@backstage/plugin-explore": "^0.2.6", + "@backstage/catalog-model": "^0.7.2", + "@backstage/cli": "^0.6.2", + "@backstage/core": "^0.6.3", + "@backstage/plugin-api-docs": "^0.4.7", + "@backstage/plugin-catalog": "^0.4.0", + "@backstage/plugin-catalog-react": "^0.1.0", + "@backstage/plugin-catalog-import": "^0.4.2", + "@backstage/plugin-circleci": "^0.2.10", + "@backstage/plugin-cloudbuild": "^0.2.11", + "@backstage/plugin-cost-insights": "^0.8.2", + "@backstage/plugin-explore": "^0.2.7", "@backstage/plugin-gcp-projects": "^0.2.4", - "@backstage/plugin-github-actions": "^0.3.3", + "@backstage/plugin-github-actions": "^0.3.4", "@backstage/plugin-gitops-profiles": "^0.2.5", "@backstage/plugin-graphiql": "^0.2.7", - "@backstage/plugin-org": "^0.3.7", - "@backstage/plugin-jenkins": "^0.3.10", - "@backstage/plugin-kafka": "^0.2.3", - "@backstage/plugin-kubernetes": "^0.3.10", - "@backstage/plugin-lighthouse": "^0.2.11", + "@backstage/plugin-org": "^0.3.8", + "@backstage/plugin-jenkins": "^0.3.11", + "@backstage/plugin-kafka": "^0.2.4", + "@backstage/plugin-kubernetes": "^0.3.11", + "@backstage/plugin-lighthouse": "^0.2.12", "@backstage/plugin-newrelic": "^0.2.5", - "@backstage/plugin-pagerduty": "0.3.0", - "@backstage/plugin-register-component": "^0.2.10", - "@backstage/plugin-rollbar": "^0.3.1", - "@backstage/plugin-scaffolder": "^0.5.1", - "@backstage/plugin-sentry": "^0.3.6", - "@backstage/plugin-search": "^0.3.1", - "@backstage/plugin-tech-radar": "^0.3.5", - "@backstage/plugin-techdocs": "^0.5.7", + "@backstage/plugin-pagerduty": "0.3.1", + "@backstage/plugin-register-component": "^0.2.11", + "@backstage/plugin-rollbar": "^0.3.2", + "@backstage/plugin-scaffolder": "^0.6.0", + "@backstage/plugin-sentry": "^0.3.7", + "@backstage/plugin-search": "^0.3.2", + "@backstage/plugin-tech-radar": "^0.3.6", + "@backstage/plugin-techdocs": "^0.5.8", "@backstage/plugin-user-settings": "^0.2.6", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", @@ -53,7 +53,7 @@ "zen-observable": "^0.8.15" }, "devDependencies": { - "@backstage/test-utils": "^0.1.7", + "@backstage/test-utils": "^0.1.8", "@testing-library/cypress": "^7.0.1", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index 05549b2085..84e51d6bcf 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,27 @@ # example-backend +## 0.2.17 + +### Patch Changes + +- Updated dependencies [a70af22a2] +- Updated dependencies [ec504e7b4] +- Updated dependencies [a5f42cf66] +- Updated dependencies [f37992797] +- Updated dependencies [bad21a085] +- Updated dependencies [1c06cb312] +- Updated dependencies [2499f6cde] +- Updated dependencies [a1f5e6545] + - @backstage/plugin-kubernetes-backend@0.2.7 + - @backstage/plugin-auth-backend@0.3.2 + - @backstage/plugin-scaffolder-backend@0.8.0 + - @backstage/plugin-techdocs-backend@0.6.2 + - @backstage/catalog-model@0.7.2 + - @backstage/plugin-app-backend@0.3.8 + - @backstage/plugin-catalog-backend@0.6.3 + - @backstage/config@0.1.3 + - example-app@0.2.17 + ## 0.2.15 ### Patch Changes diff --git a/packages/backend/package.json b/packages/backend/package.json index 413d157c2d..9220b71866 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.2.15", + "version": "0.2.17", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,23 +29,23 @@ "dependencies": { "@backstage/backend-common": "^0.5.3", "@backstage/catalog-client": "^0.3.6", - "@backstage/catalog-model": "^0.7.1", - "@backstage/config": "^0.1.2", - "@backstage/plugin-app-backend": "^0.3.7", - "@backstage/plugin-auth-backend": "^0.3.0", - "@backstage/plugin-catalog-backend": "^0.6.1", + "@backstage/catalog-model": "^0.7.2", + "@backstage/config": "^0.1.3", + "@backstage/plugin-app-backend": "^0.3.8", + "@backstage/plugin-auth-backend": "^0.3.2", + "@backstage/plugin-catalog-backend": "^0.6.3", "@backstage/plugin-graphql-backend": "^0.1.5", - "@backstage/plugin-kubernetes-backend": "^0.2.6", + "@backstage/plugin-kubernetes-backend": "^0.2.7", "@backstage/plugin-kafka-backend": "^0.2.0", "@backstage/plugin-proxy-backend": "^0.2.4", "@backstage/plugin-rollbar-backend": "^0.1.7", - "@backstage/plugin-scaffolder-backend": "^0.7.0", - "@backstage/plugin-techdocs-backend": "^0.6.0", + "@backstage/plugin-scaffolder-backend": "^0.8.0", + "@backstage/plugin-techdocs-backend": "^0.6.2", "@gitbeaker/node": "^28.0.2", "@octokit/rest": "^18.0.12", "azure-devops-node-api": "^10.1.1", "dockerode": "^3.2.1", - "example-app": "^0.2.15", + "example-app": "^0.2.17", "express": "^4.17.1", "express-promise-router": "^3.0.3", "knex": "^0.21.6", @@ -55,7 +55,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.6.0", + "@backstage/cli": "^0.6.2", "@types/dockerode": "^3.2.1", "@types/express": "^4.17.6", "@types/express-serve-static-core": "^4.17.5" diff --git a/packages/catalog-model/CHANGELOG.md b/packages/catalog-model/CHANGELOG.md index 8d581dcb0c..3351ed317a 100644 --- a/packages/catalog-model/CHANGELOG.md +++ b/packages/catalog-model/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/catalog-model +## 0.7.2 + +### Patch Changes + +- bad21a085: Implement annotations for customising Entity URLs in the Catalog pages. +- Updated dependencies [a1f5e6545] + - @backstage/config@0.1.3 + ## 0.7.1 ### Patch Changes diff --git a/packages/catalog-model/examples/components/petstore-component.yaml b/packages/catalog-model/examples/components/petstore-component.yaml index 48286f9b74..878fabd551 100644 --- a/packages/catalog-model/examples/components/petstore-component.yaml +++ b/packages/catalog-model/examples/components/petstore-component.yaml @@ -2,7 +2,8 @@ apiVersion: backstage.io/v1alpha1 kind: Component metadata: name: petstore - description: Petstore + # This is an extra long description + description: The Petstore is an example API used to show features of the OpenAPI spec. links: - url: https://github.com/swagger-api/swagger-petstore title: GitHub Repo diff --git a/packages/catalog-model/package.json b/packages/catalog-model/package.json index af74b78a08..554eea0937 100644 --- a/packages/catalog-model/package.json +++ b/packages/catalog-model/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/catalog-model", - "version": "0.7.1", + "version": "0.7.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,7 +29,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/config": "^0.1.2", + "@backstage/config": "^0.1.3", "@types/json-schema": "^7.0.5", "@types/yup": "^0.29.8", "ajv": "^7.0.3", @@ -39,7 +39,7 @@ "yup": "^0.29.3" }, "devDependencies": { - "@backstage/cli": "^0.6.0", + "@backstage/cli": "^0.6.2", "@types/express": "^4.17.6", "@types/jest": "^26.0.7", "@types/lodash": "^4.14.151", diff --git a/packages/catalog-model/src/entity/constants.ts b/packages/catalog-model/src/entity/constants.ts index 42ea2ae8ba..c8f88e3b0c 100644 --- a/packages/catalog-model/src/entity/constants.ts +++ b/packages/catalog-model/src/entity/constants.ts @@ -27,3 +27,9 @@ export const ENTITY_META_GENERATED_FIELDS = [ 'etag', 'generation', ] as const; + +/** + * Annotations for linking to entity from catalog pages. + */ +export const VIEW_URL_ANNOTATION = 'backstage.io/view-url'; +export const EDIT_URL_ANNOTATION = 'backstage.io/edit-url'; diff --git a/packages/catalog-model/src/entity/index.ts b/packages/catalog-model/src/entity/index.ts index e80e14f7a4..e267c607e1 100644 --- a/packages/catalog-model/src/entity/index.ts +++ b/packages/catalog-model/src/entity/index.ts @@ -17,6 +17,8 @@ export { ENTITY_DEFAULT_NAMESPACE, ENTITY_META_GENERATED_FIELDS, + VIEW_URL_ANNOTATION, + EDIT_URL_ANNOTATION, } from './constants'; export type { Entity, diff --git a/packages/catalog-model/src/location/annotation.ts b/packages/catalog-model/src/location/annotation.ts index 93f2fabea4..ba875c3edf 100644 --- a/packages/catalog-model/src/location/annotation.ts +++ b/packages/catalog-model/src/location/annotation.ts @@ -17,3 +17,5 @@ export const LOCATION_ANNOTATION = 'backstage.io/managed-by-location'; export const ORIGIN_LOCATION_ANNOTATION = 'backstage.io/managed-by-origin-location'; + +export const SOURCE_LOCATION_ANNOTATION = 'backstage.io/source-location'; diff --git a/packages/catalog-model/src/location/index.ts b/packages/catalog-model/src/location/index.ts index 8fd516120a..6cfb074613 100644 --- a/packages/catalog-model/src/location/index.ts +++ b/packages/catalog-model/src/location/index.ts @@ -20,4 +20,8 @@ export { locationSpecSchema, analyzeLocationSchema, } from './validation'; -export { LOCATION_ANNOTATION, ORIGIN_LOCATION_ANNOTATION } from './annotation'; +export { + LOCATION_ANNOTATION, + ORIGIN_LOCATION_ANNOTATION, + SOURCE_LOCATION_ANNOTATION, +} from './annotation'; diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index f8c09d45b9..148af6fa8a 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/cli +## 0.6.2 + +### Patch Changes + +- e780e119c: Add missing `file-loader` dependency which could cause issues with loading images and other assets. +- 6266ddd11: The `yarn backstage-cli app:diff` has been broken since a couple of months. The command to perform updates `yarn backstage-cli versions:bump` prints change logs which seems to be a good replacement for this command. +- Updated dependencies [a1f5e6545] + - @backstage/config@0.1.3 + ## 0.6.1 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 5be3a2c695..4a95df0f38 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.6.1", + "version": "0.6.2", "private": false, "publishConfig": { "access": "public" @@ -31,7 +31,7 @@ "@babel/core": "^7.4.4", "@babel/plugin-transform-modules-commonjs": "^7.4.4", "@backstage/cli-common": "^0.1.1", - "@backstage/config": "^0.1.2", + "@backstage/config": "^0.1.3", "@backstage/config-loader": "^0.5.1", "@hot-loader/react-dom": "^16.13.0", "@lerna/package-graph": "^4.0.0", @@ -74,6 +74,7 @@ "eslint-plugin-react": "^7.12.4", "eslint-plugin-react-hooks": "^4.0.0", "express": "^4.17.1", + "file-loader": "^6.2.0", "fork-ts-checker-webpack-plugin": "^4.0.5", "fs-extra": "^9.0.0", "handlebars": "^4.7.3", @@ -116,10 +117,10 @@ }, "devDependencies": { "@backstage/backend-common": "^0.5.4", - "@backstage/config": "^0.1.2", - "@backstage/core": "^0.6.2", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.6", + "@backstage/config": "^0.1.3", + "@backstage/core": "^0.6.3", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@backstage/theme": "^0.2.3", "@types/diff": "^4.0.2", "@types/express": "^4.17.6", diff --git a/packages/cli/src/commands/app/diff.ts b/packages/cli/src/commands/app/diff.ts deleted file mode 100644 index a667407f23..0000000000 --- a/packages/cli/src/commands/app/diff.ts +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * 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 { Command } from 'commander'; -import { - diffTemplateFiles, - handlers, - handleAllFiles, - inquirerPromptFunc, - makeCheckPromptFunc, - yesPromptFunc, -} from '../../lib/diff'; -import { version } from '../../lib/version'; - -const fileHandlers = [ - { - patterns: ['packages/app/package.json'], - handler: handlers.appPackageJson, - }, - { - patterns: [/tsconfig\.json$/], - handler: handlers.exactMatch, - }, - { - patterns: [ - /README\.md$/, - /\.eslintrc\.js$/, - // make sure files in 1st level of src/ and dev/ exist - /^packages\/app\/(src|dev)\/[^/]+$/, - ], - handler: handlers.exists, - }, - { - patterns: [ - 'lerna.json', - /^src\//, - /^patches\//, - /^packages\/app\/public\//, - /^packages\/app\/cypress/, - // Let plugin:diff take care of the plugins - /^plugins/, - /package\.json$/, - ], - handler: handlers.skip, - }, -]; - -export default async (cmd: Command) => { - let promptFunc = inquirerPromptFunc; - let finalize = () => {}; - - if (cmd.check) { - [promptFunc, finalize] = makeCheckPromptFunc(); - } else if (cmd.yes) { - promptFunc = yesPromptFunc; - } - - const templateFiles = await diffTemplateFiles('default-app', { version }); - await handleAllFiles(fileHandlers, templateFiles, promptFunc); - await finalize(); -}; diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index 1d267c6889..e058aaf696 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -76,13 +76,6 @@ export function registerCommands(program: CommanderStatic) { .option(...configOption) .action(lazy(() => import('./backend/dev').then(m => m.default))); - program - .command('app:diff') - .option('--check', 'Fail if changes are required') - .option('--yes', 'Apply all changes') - .description('Diff an existing app with the creation template') - .action(lazy(() => import('./app/diff').then(m => m.default))); - program .command('create-plugin') .option( diff --git a/packages/config/CHANGELOG.md b/packages/config/CHANGELOG.md index 06a9d8e4f1..cfc48fe21a 100644 --- a/packages/config/CHANGELOG.md +++ b/packages/config/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/config +## 0.1.3 + +### Patch Changes + +- a1f5e6545: Adds an optional type to `config.get` & `config.getOptional`. This avoids the need for casting. For example: + + ```ts + const config = useApi(configApiRef); + + const myConfig = config.get('myPlugin.complexConfig'); + // vs + const myConfig config.get('myPlugin.complexConfig') as SomeTypeDefinition; + ``` + ## 0.1.2 ### Patch Changes diff --git a/packages/config/package.json b/packages/config/package.json index 4e6c2f7157..1eadb5d4e5 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/config", "description": "Config API used by Backstage core, backend, and CLI", - "version": "0.1.2", + "version": "0.1.3", "private": false, "publishConfig": { "access": "public", diff --git a/packages/config/src/reader.ts b/packages/config/src/reader.ts index c690e0bbc9..99977d19cd 100644 --- a/packages/config/src/reader.ts +++ b/packages/config/src/reader.ts @@ -88,22 +88,22 @@ export class ConfigReader implements Config { return [...new Set([...localKeys, ...fallbackKeys])]; } - get(key?: string): JsonValue { + get(key?: string): T { const value = this.getOptional(key); if (value === undefined) { throw new Error(errors.missing(this.fullKey(key ?? ''))); } - return value; + return value as T; } - getOptional(key?: string): JsonValue | undefined { + getOptional(key?: string): T | undefined { const value = this.readValue(key); - const fallbackValue = this.fallback?.getOptional(key); + const fallbackValue = this.fallback?.getOptional(key); if (value === undefined) { return fallbackValue; } else if (fallbackValue === undefined) { - return value; + return value as T; } // Avoid merging arrays and primitive values, since that's how merging works for other @@ -113,7 +113,7 @@ export class ConfigReader implements Config { { value: cloneDeep(fallbackValue) }, { value }, (into, from) => (!isObject(from) || !isObject(into) ? from : undefined), - ).value; + ).value as T; } getConfig(key: string): ConfigReader { diff --git a/packages/config/src/types.ts b/packages/config/src/types.ts index 840cc36173..92293a3f26 100644 --- a/packages/config/src/types.ts +++ b/packages/config/src/types.ts @@ -34,8 +34,8 @@ export type Config = { keys(): string[]; - get(key?: string): JsonValue; - getOptional(key?: string): JsonValue | undefined; + get(key?: string): T; + getOptional(key?: string): T | undefined; getConfig(key: string): Config; getOptionalConfig(key: string): Config | undefined; diff --git a/packages/core-api/CHANGELOG.md b/packages/core-api/CHANGELOG.md index 14a5aa899d..7fa7e71828 100644 --- a/packages/core-api/CHANGELOG.md +++ b/packages/core-api/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/core-api +## 0.2.11 + +### Patch Changes + +- 3a58084b6: The `FlatRoutes` components now renders the not found page of the app if no routes are matched. +- 1407b34c6: More informative error message for missing ApiContext. +- b6c4f485d: Fix error when querying Backstage Identity with SAML authentication +- 3a58084b6: Created separate `AppContext` type to be returned from `useApp` rather than the `BackstageApp` itself. The `AppContext` type includes but deprecates `getPlugins`, `getProvider`, `getRouter`, and `getRoutes`. In addition, the `AppContext` adds a new `getComponents` method which providers access to the app components. +- Updated dependencies [a1f5e6545] + - @backstage/config@0.1.3 + ## 0.2.10 ### Patch Changes diff --git a/packages/core-api/package.json b/packages/core-api/package.json index cfe90ebb34..d3eb0d7791 100644 --- a/packages/core-api/package.json +++ b/packages/core-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-api", "description": "Internal Core API used by Backstage plugins and apps", - "version": "0.2.10", + "version": "0.2.11", "private": false, "publishConfig": { "access": "public", @@ -29,7 +29,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/config": "^0.1.2", + "@backstage/config": "^0.1.3", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -42,8 +42,8 @@ "zen-observable": "^0.8.15" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/test-utils": "^0.1.6", + "@backstage/cli": "^0.6.2", + "@backstage/test-utils": "^0.1.8", "@backstage/test-utils-core": "^0.1.1", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", diff --git a/packages/core-api/src/apis/implementations/auth/saml/SamlAuth.ts b/packages/core-api/src/apis/implementations/auth/saml/SamlAuth.ts index e05f6266d6..af97ad8f36 100644 --- a/packages/core-api/src/apis/implementations/auth/saml/SamlAuth.ts +++ b/packages/core-api/src/apis/implementations/auth/saml/SamlAuth.ts @@ -83,7 +83,7 @@ class SamlAuth implements ProfileInfoApi, BackstageIdentityApi, SessionApi { } async getBackstageIdentity( - options: AuthRequestOptions, + options: AuthRequestOptions = {}, ): Promise { const session = await this.sessionManager.getSession(options); return session?.backstageIdentity; diff --git a/packages/core-api/src/app/App.tsx b/packages/core-api/src/app/App.tsx index f50bcdd015..3cf5abdb44 100644 --- a/packages/core-api/src/app/App.tsx +++ b/packages/core-api/src/app/App.tsx @@ -64,6 +64,7 @@ import { AppThemeProvider } from './AppThemeProvider'; import { AppComponents, AppConfigLoader, + AppContext, AppOptions, AppRouteBinder, BackstageApp, @@ -139,6 +140,42 @@ function useConfigLoader( return { api: configReader }; } +class AppContextImpl implements AppContext { + constructor(private readonly app: PrivateAppImpl) {} + + getPlugins(): BackstagePlugin[] { + // eslint-disable-next-line no-console + console.warn('appContext.getPlugins() is deprecated and will be removed'); + return this.app.getPlugins(); + } + + getSystemIcon(key: string): IconComponent { + return this.app.getSystemIcon(key); + } + + getComponents(): AppComponents { + return this.app.getComponents(); + } + + getProvider(): React.ComponentType<{}> { + // eslint-disable-next-line no-console + console.warn('appContext.getProvider() is deprecated and will be removed'); + return this.app.getProvider(); + } + + getRouter(): React.ComponentType<{}> { + // eslint-disable-next-line no-console + console.warn('appContext.getRouter() is deprecated and will be removed'); + return this.app.getRouter(); + } + + getRoutes(): JSX.Element[] { + // eslint-disable-next-line no-console + console.warn('appContext.getRoutes() is deprecated and will be removed'); + return this.app.getRoutes(); + } +} + export class PrivateAppImpl implements BackstageApp { private apiHolder?: ApiHolder; private configApi?: ConfigApi; @@ -173,11 +210,13 @@ export class PrivateAppImpl implements BackstageApp { return this.icons[key]; } + getComponents(): AppComponents { + return this.components; + } + getRoutes(): JSX.Element[] { const routes = new Array(); - const featureFlagsApi = this.getApiHolder().get(featureFlagsApiRef)!; - const { NotFoundErrorPage } = this.components; for (const plugin of this.plugins.values()) { @@ -211,13 +250,6 @@ export class PrivateAppImpl implements BackstageApp { routes.push(); break; } - case 'feature-flag': { - featureFlagsApi.registerFlag({ - name: output.name, - pluginId: plugin.getId(), - }); - break; - } default: break; } @@ -236,6 +268,27 @@ export class PrivateAppImpl implements BackstageApp { } getProvider(): ComponentType<{}> { + const appContext = new AppContextImpl(this); + const apiHolder = this.getApiHolder(); + + const featureFlagsApi = this.getApiHolder().get(featureFlagsApiRef)!; + + for (const plugin of this.plugins.values()) { + for (const output of plugin.output()) { + switch (output.type) { + case 'feature-flag': { + featureFlagsApi.registerFlag({ + name: output.name, + pluginId: plugin.getId(), + }); + break; + } + default: + break; + } + } + } + const Provider = ({ children }: PropsWithChildren<{}>) => { const appThemeApi = useMemo( () => AppThemeSelector.createWithStorage(this.themes), @@ -272,8 +325,8 @@ export class PrivateAppImpl implements BackstageApp { this.configApi = loadedConfig.api; return ( - - + + (undefined); +const Context = createContext(undefined); type Props = { - app: BackstageApp; + appContext: AppContext; }; export const AppContextProvider = ({ - app, + appContext, children, }: PropsWithChildren) => ( - + ); -export const useApp = (): BackstageApp => { - const app = useContext(Context); - if (!app) { +export const useApp = (): AppContext => { + const appContext = useContext(Context); + if (!appContext) { throw new Error('No app context available'); } - return app; + return appContext; }; diff --git a/packages/core-api/src/app/types.ts b/packages/core-api/src/app/types.ts index 1970868ca6..69eb7f7189 100644 --- a/packages/core-api/src/app/types.ts +++ b/packages/core-api/src/app/types.ts @@ -187,6 +187,40 @@ export type BackstageApp = { /** * Routes component that contains all routes for plugin pages in the app. + * + * @deprecated Registering routes in plugins is deprecated and this method will be removed. + */ + getRoutes(): JSX.Element[]; +}; + +export type AppContext = { + /** + * @deprecated Will be removed + */ + getPlugins(): BackstagePlugin[]; + + /** + * Get a common or custom icon for this app. + */ + getSystemIcon(key: IconKey): IconComponent; + + /** + * Get the components registered for various purposes in the app. + */ + getComponents(): AppComponents; + + /** + * @deprecated Will be removed + */ + getProvider(): ComponentType<{}>; + + /** + * @deprecated Will be removed + */ + getRouter(): ComponentType<{}>; + + /** + * @deprecated Will be removed */ getRoutes(): JSX.Element[]; }; diff --git a/packages/core-api/src/routing/FlatRoutes.tsx b/packages/core-api/src/routing/FlatRoutes.tsx index cefb347290..3702442811 100644 --- a/packages/core-api/src/routing/FlatRoutes.tsx +++ b/packages/core-api/src/routing/FlatRoutes.tsx @@ -14,8 +14,9 @@ * limitations under the License. */ -import { ReactNode, Children, isValidElement, Fragment } from 'react'; +import React, { ReactNode, Children, isValidElement, Fragment } from 'react'; import { useRoutes } from 'react-router-dom'; +import { useApp } from '../app'; type RouteObject = { path: string; @@ -71,6 +72,15 @@ type FlatRoutesProps = { }; export const FlatRoutes = (props: FlatRoutesProps): JSX.Element | null => { + const app = useApp(); + const { NotFoundErrorPage } = app.getComponents(); const routes = createRoutesFromChildren(props.children); + + // TODO(Rugvip): Possibly add a way to skip this, like a noNotFoundPage prop + routes.push({ + element: , + path: '/*', + }); + return useRoutes(routes); }; diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index bd800e8d63..81fe728101 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/core +## 0.6.3 + +### Patch Changes + +- 3a58084b6: The `FlatRoutes` components now renders the not found page of the app if no routes are matched. +- e799e74d4: Fix `OverflowTooltip` cutting off the bottom of letters like "g" and "y". +- 1407b34c6: More informative error message for missing ApiContext. +- 9615e68fb: Forward link styling of `EntityRefLink` and `EnriryRefLinks` into the underling + `Link`. +- 49f9b7346: Deprecate `type` of `ItemCard` and introduce new `subtitle` which allows passing + react nodes. +- 3a58084b6: Created separate `AppContext` type to be returned from `useApp` rather than the `BackstageApp` itself. The `AppContext` type includes but deprecates `getPlugins`, `getProvider`, `getRouter`, and `getRoutes`. In addition, the `AppContext` adds a new `getComponents` method which providers access to the app components. +- 2c1f2a7c2: Introduced generic OverflowTooltip component for cases where longer text needs to be truncated with ellipsis and show hover tooltip with full text. This is particularly useful in the cases where longer description text is rendered in table. e.g. CatalogTable and ApiExplorerTable. +- Updated dependencies [3a58084b6] +- Updated dependencies [1407b34c6] +- Updated dependencies [b6c4f485d] +- Updated dependencies [3a58084b6] +- Updated dependencies [a1f5e6545] + - @backstage/core-api@0.2.11 + - @backstage/config@0.1.3 + ## 0.6.2 ### Patch Changes diff --git a/packages/core/package.json b/packages/core/package.json index f6afa76b7f..c2fae32d6c 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core", "description": "Core API used by Backstage plugins and apps", - "version": "0.6.2", + "version": "0.6.3", "private": false, "publishConfig": { "access": "public", @@ -29,8 +29,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/config": "^0.1.2", - "@backstage/core-api": "^0.2.10", + "@backstage/config": "^0.1.3", + "@backstage/core-api": "^0.2.11", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -68,8 +68,8 @@ "zen-observable": "^0.8.15" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/packages/core/src/components/OverflowTooltip/OverflowTooltip.tsx b/packages/core/src/components/OverflowTooltip/OverflowTooltip.tsx index 9bbe7aeb81..faf064f9f4 100644 --- a/packages/core/src/components/OverflowTooltip/OverflowTooltip.tsx +++ b/packages/core/src/components/OverflowTooltip/OverflowTooltip.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { Tooltip, TooltipProps } from '@material-ui/core'; +import { makeStyles, Tooltip, TooltipProps } from '@material-ui/core'; import React, { useState } from 'react'; import TextTruncate, { TextTruncateProps } from 'react-text-truncate'; @@ -26,8 +26,15 @@ type Props = { placement?: TooltipProps['placement']; }; +const useStyles = makeStyles({ + container: { + overflow: 'visible !important', + }, +}); + export const OverflowTooltip = (props: Props) => { const [hover, setHover] = useState(false); + const classes = useStyles(); const handleToggled = (truncated: boolean) => { setHover(truncated); @@ -43,6 +50,7 @@ export const OverflowTooltip = (props: Props) => { text={props.text} line={props.line} onToggled={handleToggled} + containerClassName={classes.container} /> ); diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index 1735d0c1a0..de59a343ed 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,169 @@ # @backstage/create-app +## 0.3.11 + +### Patch Changes + +- 4594f7efc: Add the google analytics scripts in the `index.html` template for new applications. + + To apply this change to an existing application, change the following in `packages\app\public\index.html`: + + ```diff + <%= app.title %> + + + <% if (app.googleAnalyticsTrackingId && typeof app.googleAnalyticsTrackingId + + === 'string') { %> + + + + + + <% } %> + + ``` + +- 08fa2176a: **BREAKING CHANGE** + + The Scaffolder and Catalog plugins have been migrated to partially require use of the [new composability API](https://backstage.io/docs/plugins/composability). The Scaffolder used to register its pages using the deprecated route registration plugin API, but those registrations have been removed. This means you now need to add the Scaffolder plugin page to the app directly. + + The Catalog plugin has also been migrated to use an [external route reference](https://backstage.io/docs/plugins/composability#binding-external-routes-in-the-app) to dynamically link to the create component page. This means you need to migrate the catalog plugin to use the new extension components, as well as bind the external route. + + Apply the following changes to `packages/app/src/App.tsx`: + + ```diff + -import { Router as CatalogRouter } from '@backstage/plugin-catalog'; + +import { + + catalogPlugin, + + CatalogIndexPage, + + CatalogEntityPage, + +} from '@backstage/plugin-catalog'; + +import { scaffolderPlugin, ScaffolderPage } from '@backstage/plugin-scaffolder'; + + # The following addition to the app config allows the catalog plugin to link to the + # component creation page, i.e. the scaffolder. You can chose a different target if you want to. + const app = createApp({ + apis, + plugins: Object.values(plugins), + + bindRoutes({ bind }) { + + bind(catalogPlugin.externalRoutes, { + + createComponent: scaffolderPlugin.routes.root, + + }); + + } + }); + + # Apply these changes within FlatRoutes. It is important to have migrated to using FlatRoutes + # for this to work, if you haven't done that yet, see the previous entries in this changelog. + - } + - /> + + } /> + + } + + > + + + + + } /> + + } /> + ``` + + The scaffolder has been redesigned to be horizontally scalable and to persistently store task state and execution logs in the database. Component registration has moved from the frontend into a separate registration step executed by the `TaskWorker`. This requires that a `CatalogClient` is passed to the scaffolder backend instead of the old `CatalogEntityClient`. + + The default catalog client comes from the `@backstage/catalog-client`, which you need to add as a dependency in `packages/backend/package.json`. + + Once the dependency has been added, apply the following changes to`packages/backend/src/plugins/scaffolder.ts`: + + ```diff + import { + CookieCutter, + createRouter, + Preparers, + Publishers, + CreateReactAppTemplater, + Templaters, + - CatalogEntityClient, + } from '@backstage/plugin-scaffolder-backend'; + +import { CatalogClient } from '@backstage/catalog-client'; + + const discovery = SingleHostDiscovery.fromConfig(config); + -const entityClient = new CatalogEntityClient({ discovery }); + +const catalogClient = new CatalogClient({ discoveryApi: discovery }) + + return await createRouter({ + preparers, + templaters, + publishers, + logger, + config, + dockerClient, + - entityClient, + database, + + catalogClient, + }); + ``` + + See the `@backstage/scaffolder-backend` changelog for more information about this change. + +- Updated dependencies [ec504e7b4] +- Updated dependencies [3a58084b6] +- Updated dependencies [a5f42cf66] +- Updated dependencies [e488f0502] +- Updated dependencies [e799e74d4] +- Updated dependencies [dc12852c9] +- Updated dependencies [a5f42cf66] +- Updated dependencies [a8953a9c9] +- Updated dependencies [f37992797] +- Updated dependencies [347137ccf] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [d6593abe6] +- Updated dependencies [bad21a085] +- Updated dependencies [e8e35fb5f] +- Updated dependencies [9615e68fb] +- Updated dependencies [e780e119c] +- Updated dependencies [437bac549] +- Updated dependencies [9f2b3a26e] +- Updated dependencies [49f9b7346] +- Updated dependencies [1c06cb312] +- Updated dependencies [968b588f7] +- Updated dependencies [3a58084b6] +- Updated dependencies [2499f6cde] +- Updated dependencies [5469a9761] +- Updated dependencies [a1f5e6545] +- Updated dependencies [60d1bc3e7] +- Updated dependencies [2c1f2a7c2] +- Updated dependencies [6266ddd11] + - @backstage/plugin-auth-backend@0.3.2 + - @backstage/core@0.6.3 + - @backstage/plugin-scaffolder@0.6.0 + - @backstage/plugin-scaffolder-backend@0.8.0 + - @backstage/test-utils@0.1.8 + - @backstage/plugin-catalog@0.4.0 + - @backstage/plugin-catalog-import@0.4.2 + - @backstage/plugin-techdocs@0.5.8 + - @backstage/plugin-techdocs-backend@0.6.2 + - @backstage/plugin-explore@0.2.7 + - @backstage/plugin-api-docs@0.4.7 + - @backstage/catalog-model@0.7.2 + - @backstage/cli@0.6.2 + - @backstage/plugin-tech-radar@0.3.6 + - @backstage/plugin-app-backend@0.3.8 + - @backstage/plugin-catalog-backend@0.6.3 + - @backstage/config@0.1.3 + - @backstage/plugin-circleci@0.2.10 + - @backstage/plugin-github-actions@0.3.4 + - @backstage/plugin-lighthouse@0.2.12 + - @backstage/plugin-search@0.3.2 + ## 0.3.10 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index b427b1e2ed..05615cc78d 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/create-app", "description": "Create app package for Backstage", - "version": "0.3.10", + "version": "0.3.11", "private": false, "publishConfig": { "access": "public" @@ -44,33 +44,33 @@ "ts-node": "^8.6.2" }, "peerDependencies": { - "@backstage/backend-common": "^0.5.4", - "@backstage/catalog-client": "^0.3.6", - "@backstage/catalog-model": "^0.7.1", - "@backstage/cli": "^0.6.1", - "@backstage/config": "^0.1.2", - "@backstage/core": "^0.6.2", - "@backstage/plugin-api-docs": "^0.4.6", - "@backstage/plugin-app-backend": "^0.3.7", - "@backstage/plugin-auth-backend": "^0.3.1", - "@backstage/plugin-catalog": "^0.3.2", - "@backstage/plugin-catalog-backend": "^0.6.2", - "@backstage/plugin-catalog-import": "^0.4.1", - "@backstage/plugin-circleci": "^0.2.9", - "@backstage/plugin-explore": "^0.2.6", - "@backstage/plugin-github-actions": "^0.3.3", - "@backstage/plugin-lighthouse": "^0.2.11", - "@backstage/plugin-proxy-backend": "^0.2.4", - "@backstage/plugin-rollbar-backend": "^0.1.7", - "@backstage/plugin-scaffolder": "^0.5.1", - "@backstage/plugin-search": "^0.3.1", - "@backstage/plugin-scaffolder-backend": "^0.7.1", - "@backstage/plugin-tech-radar": "^0.3.5", - "@backstage/plugin-techdocs": "^0.5.7", - "@backstage/plugin-techdocs-backend": "^0.6.1", - "@backstage/plugin-user-settings": "^0.2.6", - "@backstage/test-utils": "^0.1.7", - "@backstage/theme": "^0.2.3" + "@backstage/backend-common": "*", + "@backstage/catalog-client": "*", + "@backstage/catalog-model": "*", + "@backstage/cli": "*", + "@backstage/config": "*", + "@backstage/core": "*", + "@backstage/plugin-api-docs": "*", + "@backstage/plugin-app-backend": "*", + "@backstage/plugin-auth-backend": "*", + "@backstage/plugin-catalog": "*", + "@backstage/plugin-catalog-backend": "*", + "@backstage/plugin-catalog-import": "*", + "@backstage/plugin-circleci": "*", + "@backstage/plugin-explore": "*", + "@backstage/plugin-github-actions": "*", + "@backstage/plugin-lighthouse": "*", + "@backstage/plugin-proxy-backend": "*", + "@backstage/plugin-rollbar-backend": "*", + "@backstage/plugin-scaffolder": "*", + "@backstage/plugin-search": "*", + "@backstage/plugin-scaffolder-backend": "*", + "@backstage/plugin-tech-radar": "*", + "@backstage/plugin-techdocs": "*", + "@backstage/plugin-techdocs-backend": "*", + "@backstage/plugin-user-settings": "*", + "@backstage/test-utils": "*", + "@backstage/theme": "*" }, "nodemonConfig": { "watch": "./src", diff --git a/packages/create-app/templates/default-app/packages/app/public/index.html b/packages/create-app/templates/default-app/packages/app/public/index.html index ea9208ca57..5653173480 100644 --- a/packages/create-app/templates/default-app/packages/app/public/index.html +++ b/packages/create-app/templates/default-app/packages/app/public/index.html @@ -48,6 +48,22 @@ } <%= app.title %> + <% if (app.googleAnalyticsTrackingId && typeof app.googleAnalyticsTrackingId + === 'string') { %> + + + <% } %> diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index 52de79ca58..f02ce3ae23 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/dev-utils +## 0.1.12 + +### Patch Changes + +- 5aa4ceea6: Make sure to provide dummy routes for all external routes of plugins given to DevApp +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [dc12852c9] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/test-utils@0.1.8 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + ## 0.1.11 ### Patch Changes diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index abe21fe0f1..0d2af1bc69 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.1.11", + "version": "0.1.12", "private": false, "publishConfig": { "access": "public", @@ -29,10 +29,10 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.6.2", - "@backstage/catalog-model": "^0.7.1", - "@backstage/plugin-catalog-react": "^0.0.4", - "@backstage/test-utils": "^0.1.7", + "@backstage/core": "^0.6.3", + "@backstage/catalog-model": "^0.7.2", + "@backstage/plugin-catalog-react": "^0.1.0", + "@backstage/test-utils": "^0.1.8", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -47,7 +47,7 @@ "react-router-dom": "6.0.0-beta.0" }, "devDependencies": { - "@backstage/cli": "^0.6.1", + "@backstage/cli": "^0.6.2", "@types/jest": "^26.0.7", "@types/node": "^12.0.0" }, diff --git a/packages/dev-utils/src/devApp/render.tsx b/packages/dev-utils/src/devApp/render.tsx index e1bdf4d0e9..0c3a1395a6 100644 --- a/packages/dev-utils/src/devApp/render.tsx +++ b/packages/dev-utils/src/devApp/render.tsx @@ -14,26 +14,30 @@ * limitations under the License. */ -import { hot } from 'react-hot-loader'; -import React, { ComponentType, ReactNode } from 'react'; -import ReactDOM from 'react-dom'; -import BookmarkIcon from '@material-ui/icons/Bookmark'; import { + AlertDisplay, + AnyApiFactory, + ApiFactory, + attachComponentData, createApp, - SidebarPage, + createPlugin, + createRouteRef, + FlatRoutes, + IconComponent, + OAuthRequestDialog, + RouteRef, Sidebar, SidebarItem, + SidebarPage, SidebarSpacer, - ApiFactory, - createPlugin, - AlertDisplay, - OAuthRequestDialog, - AnyApiFactory, - IconComponent, - FlatRoutes, - attachComponentData, } from '@backstage/core'; +import { Box } from '@material-ui/core'; +import BookmarkIcon from '@material-ui/icons/Bookmark'; import SentimentDissatisfiedIcon from '@material-ui/icons/SentimentDissatisfied'; +import React, { ComponentType, ReactNode } from 'react'; +import ReactDOM from 'react-dom'; +import { hot } from 'react-hot-loader'; +import { Route } from 'react-router'; const GatheringRoute: (props: { path: string; @@ -128,9 +132,22 @@ class DevAppBuilder { * Build a DevApp component using the resources registered so far */ build(): ComponentType<{}> { + const dummyRouteRef = createRouteRef({ title: 'Page of another plugin' }); + const DummyPage = () => Page belonging to another plugin.; + attachComponentData(DummyPage, 'core.mountPoint', dummyRouteRef); + const app = createApp({ apis: this.apis, plugins: this.plugins, + bindRoutes: ({ bind }) => { + for (const plugin of this.plugins ?? []) { + const targets: Record> = {}; + for (const routeKey of Object.keys(plugin.externalRoutes)) { + targets[routeKey] = dummyRouteRef; + } + bind(plugin.externalRoutes, targets); + } + }, }); const AppProvider = app.getProvider(); @@ -145,13 +162,13 @@ class DevAppBuilder { {this.rootChildren} - {sidebar} {this.routes} {deprecatedAppRoutes} + } /> diff --git a/packages/techdocs-common/CHANGELOG.md b/packages/techdocs-common/CHANGELOG.md index caaa9f5e2f..60a10c924e 100644 --- a/packages/techdocs-common/CHANGELOG.md +++ b/packages/techdocs-common/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/techdocs-common +## 0.4.2 + +### Patch Changes + +- 2499f6cde: Add support for assuming role in AWS integrations +- 1e4ddd71d: Fix AWS, GCS and Azure publisher to work on Windows. +- Updated dependencies [bad21a085] +- Updated dependencies [a1f5e6545] + - @backstage/catalog-model@0.7.2 + - @backstage/config@0.1.3 + ## 0.4.1 ### Patch Changes diff --git a/packages/techdocs-common/package.json b/packages/techdocs-common/package.json index 9363334641..c8ae633c97 100644 --- a/packages/techdocs-common/package.json +++ b/packages/techdocs-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/techdocs-common", "description": "Common functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", - "version": "0.4.1", + "version": "0.4.2", "main": "src/index.ts", "types": "src/index.ts", "private": false, @@ -39,8 +39,8 @@ "@azure/identity": "^1.2.2", "@azure/storage-blob": "^12.4.0", "@backstage/backend-common": "^0.5.4", - "@backstage/catalog-model": "^0.7.1", - "@backstage/config": "^0.1.2", + "@backstage/catalog-model": "^0.7.2", + "@backstage/config": "^0.1.3", "@backstage/integration": "^0.5.0", "@google-cloud/storage": "^5.6.0", "@types/dockerode": "^3.2.1", @@ -60,7 +60,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.6.1", + "@backstage/cli": "^0.6.2", "@types/fs-extra": "^9.0.5", "@types/git-url-parse": "^9.0.0", "@types/js-yaml": "^3.12.5", diff --git a/packages/techdocs-common/src/stages/publish/awsS3.ts b/packages/techdocs-common/src/stages/publish/awsS3.ts index 96cce331ec..fc45a2d5cd 100644 --- a/packages/techdocs-common/src/stages/publish/awsS3.ts +++ b/packages/techdocs-common/src/stages/publish/awsS3.ts @@ -15,12 +15,13 @@ */ import { Entity, EntityName } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; -import aws from 'aws-sdk'; +import aws, { Credentials } from 'aws-sdk'; import { ManagedUpload } from 'aws-sdk/clients/s3'; import express from 'express'; import fs from 'fs-extra'; import JSON5 from 'json5'; import createLimiter from 'p-limit'; +import { CredentialsOptions } from 'aws-sdk/lib/credentials'; import path from 'path'; import { Readable } from 'stream'; import { Logger } from 'winston'; @@ -59,14 +60,34 @@ export class AwsS3Publish implements PublisherBase { // https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/loading-node-credentials-shared.html // 3. IAM Roles for EC2 // https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/loading-node-credentials-iam.html - const credentials = config.getOptionalConfig( + const credentialsConfig = config.getOptionalConfig( 'techdocs.publisher.awsS3.credentials', ); let accessKeyId = undefined; let secretAccessKey = undefined; - if (credentials) { - accessKeyId = credentials.getOptionalString('accessKeyId'); - secretAccessKey = credentials.getOptionalString('secretAccessKey'); + let credentials: Credentials | CredentialsOptions | undefined = undefined; + if (credentialsConfig) { + const roleArn = credentialsConfig.getOptionalString('roleArn'); + if (roleArn && aws.config.credentials instanceof Credentials) { + credentials = new aws.ChainableTemporaryCredentials({ + masterCredentials: aws.config.credentials as Credentials, + params: { + RoleSessionName: 'backstage-aws-techdocs-s3-publisher', + RoleArn: roleArn, + }, + }); + } else { + accessKeyId = credentialsConfig.getOptionalString('accessKeyId'); + secretAccessKey = credentialsConfig.getOptionalString( + 'secretAccessKey', + ); + if (accessKeyId && secretAccessKey) { + credentials = { + accessKeyId, + secretAccessKey, + }; + } + } } // AWS Region is an optional config. If missing, default AWS env variable AWS_REGION @@ -74,14 +95,7 @@ export class AwsS3Publish implements PublisherBase { const region = config.getOptionalString('techdocs.publisher.awsS3.region'); const storageClient = new aws.S3({ - ...(credentials && - accessKeyId && - secretAccessKey && { - credentials: { - accessKeyId, - secretAccessKey, - }, - }), + credentials, ...(region && { region, }), diff --git a/packages/test-utils/CHANGELOG.md b/packages/test-utils/CHANGELOG.md index a30b2b3f6a..50f656ec67 100644 --- a/packages/test-utils/CHANGELOG.md +++ b/packages/test-utils/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/test-utils +## 0.1.8 + +### Patch Changes + +- dc12852c9: Allow `ExternalRouteRef` instances to be passed as a route ref to `mountedRoutes`. +- Updated dependencies [3a58084b6] +- Updated dependencies [1407b34c6] +- Updated dependencies [b6c4f485d] +- Updated dependencies [3a58084b6] + - @backstage/core-api@0.2.11 + ## 0.1.7 ### Patch Changes diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 5a4ad2b4a4..fbbd4f9eca 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/test-utils", "description": "Utilities to test Backstage plugins and apps.", - "version": "0.1.7", + "version": "0.1.8", "private": false, "publishConfig": { "access": "public", @@ -29,7 +29,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-api": "^0.2.7", + "@backstage/core-api": "^0.2.11", "@backstage/test-utils-core": "^0.1.1", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", @@ -45,7 +45,7 @@ "zen-observable": "^0.8.15" }, "devDependencies": { - "@backstage/cli": "^0.6.0", + "@backstage/cli": "^0.6.2", "@types/jest": "^26.0.7", "@types/node": "^12.0.0" }, diff --git a/plugins/api-docs/CHANGELOG.md b/plugins/api-docs/CHANGELOG.md index a6aa6c1e2d..480beeff16 100644 --- a/plugins/api-docs/CHANGELOG.md +++ b/plugins/api-docs/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-api-docs +## 0.4.7 + +### Patch Changes + +- d6593abe6: Remove domain column from `HasSystemsCard` and system from `HasComponentsCard`, + `HasSubcomponentsCard`, and `HasApisCard`. +- 437bac549: Make the description column in the catalog table and api-docs table use up as + much space as possible before hiding overflowing text. +- 5469a9761: Changes made in CatalogTable and ApiExplorerTable for using the OverflowTooltip component for truncating large description and showing tooltip on hover-over. +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + ## 0.4.6 ### Patch Changes diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 4182ccbe14..bdf6ccf47c 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-api-docs", - "version": "0.4.6", + "version": "0.4.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,9 +30,9 @@ }, "dependencies": { "@asyncapi/react-component": "^0.18.2", - "@backstage/catalog-model": "^0.7.1", - "@backstage/core": "^0.6.2", - "@backstage/plugin-catalog-react": "^0.0.4", + "@backstage/catalog-model": "^0.7.2", + "@backstage/core": "^0.6.3", + "@backstage/plugin-catalog-react": "^0.1.0", "@backstage/theme": "^0.2.3", "@material-icons/font": "^1.0.2", "@material-ui/core": "^4.11.0", @@ -49,9 +49,9 @@ "swagger-ui-react": "^3.37.2" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/api-docs/src/components/ApiExplorerTable/ApiExplorerTable.tsx b/plugins/api-docs/src/components/ApiExplorerTable/ApiExplorerTable.tsx index 729f659b56..5b9808e26d 100644 --- a/plugins/api-docs/src/components/ApiExplorerTable/ApiExplorerTable.tsx +++ b/plugins/api-docs/src/components/ApiExplorerTable/ApiExplorerTable.tsx @@ -99,6 +99,7 @@ const columns: TableColumn[] = [ placement="bottom-start" /> ), + width: 'auto', }, { title: 'Tags', diff --git a/plugins/api-docs/src/components/ApisCards/HasApisCard.tsx b/plugins/api-docs/src/components/ApisCards/HasApisCard.tsx index 9f1d487b65..c3e636b1f1 100644 --- a/plugins/api-docs/src/components/ApisCards/HasApisCard.tsx +++ b/plugins/api-docs/src/components/ApisCards/HasApisCard.tsx @@ -20,6 +20,7 @@ import { InfoCard, Link, Progress, + TableColumn, WarningPanel, } from '@backstage/core'; import { @@ -28,12 +29,20 @@ import { useRelatedEntities, } from '@backstage/plugin-catalog-react'; import React from 'react'; -import { apiEntityColumns } from './presets'; +import { createSpecApiTypeColumn } from './presets'; type Props = { variant?: 'gridItem'; }; +const columns: TableColumn[] = [ + EntityTable.columns.createEntityRefColumn({ defaultKind: 'API' }), + EntityTable.columns.createOwnerColumn(), + EntityTable.columns.createSpecLifecycleColumn(), + createSpecApiTypeColumn(), + EntityTable.columns.createMetadataDescriptionColumn(), +]; + export const HasApisCard = ({ variant = 'gridItem' }: Props) => { const { entity } = useEntity(); const { entities, loading, error } = useRelatedEntities(entity, { @@ -73,7 +82,7 @@ export const HasApisCard = ({ variant = 'gridItem' }: Props) => { } - columns={apiEntityColumns} + columns={columns} entities={entities as ApiEntity[]} /> ); diff --git a/plugins/app-backend/CHANGELOG.md b/plugins/app-backend/CHANGELOG.md index f39dad2eb9..06ec3e150f 100644 --- a/plugins/app-backend/CHANGELOG.md +++ b/plugins/app-backend/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-app-backend +## 0.3.8 + +### Patch Changes + +- 1c06cb312: Clarify troubleshooting steps for schema serialization issues. +- Updated dependencies [a1f5e6545] + - @backstage/config@0.1.3 + ## 0.3.7 ### Patch Changes diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json index 52ebab520d..af5a1e2f3d 100644 --- a/plugins/app-backend/package.json +++ b/plugins/app-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-app-backend", - "version": "0.3.7", + "version": "0.3.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,7 +31,7 @@ "dependencies": { "@backstage/backend-common": "^0.5.3", "@backstage/config-loader": "^0.5.1", - "@backstage/config": "^0.1.2", + "@backstage/config": "^0.1.3", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^3.0.3", @@ -40,7 +40,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.6.0", + "@backstage/cli": "^0.6.2", "@types/supertest": "^2.0.8", "msw": "^0.20.5", "supertest": "^4.0.2" diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md index 3d69afee37..14d70ba1f5 100644 --- a/plugins/auth-backend/CHANGELOG.md +++ b/plugins/auth-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend +## 0.3.2 + +### Patch Changes + +- ec504e7b4: Fix for refresh token being lost during Microsoft login. +- Updated dependencies [bad21a085] +- Updated dependencies [a1f5e6545] + - @backstage/catalog-model@0.7.2 + - @backstage/config@0.1.3 + ## 0.3.1 ### Patch Changes diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index f206c0046d..f9dfdd5215 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend", - "version": "0.3.1", + "version": "0.3.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,8 +31,8 @@ "dependencies": { "@backstage/backend-common": "^0.5.4", "@backstage/catalog-client": "^0.3.6", - "@backstage/catalog-model": "^0.7.1", - "@backstage/config": "^0.1.2", + "@backstage/catalog-model": "^0.7.2", + "@backstage/config": "^0.1.3", "@types/express": "^4.17.6", "@types/passport": "^1.0.3", "compression": "^1.7.4", @@ -66,7 +66,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.6.1", + "@backstage/cli": "^0.6.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/providers/github/provider.ts b/plugins/auth-backend/src/providers/github/provider.ts index 438cbca07b..2b0db9c2d9 100644 --- a/plugins/auth-backend/src/providers/github/provider.ts +++ b/plugins/auth-backend/src/providers/github/provider.ts @@ -54,12 +54,12 @@ export class GithubAuthProvider implements OAuthHandlers { }, ( accessToken: any, - refreshToken: any, + _refreshToken: any, params: any, fullProfile: any, done: PassportDoneCallback, ) => { - done(undefined, { fullProfile, params, accessToken, refreshToken }); + done(undefined, { fullProfile, params, accessToken }); }, ); } diff --git a/plugins/auth-backend/src/providers/gitlab/provider.ts b/plugins/auth-backend/src/providers/gitlab/provider.ts index 7c24757833..630cad0554 100644 --- a/plugins/auth-backend/src/providers/gitlab/provider.ts +++ b/plugins/auth-backend/src/providers/gitlab/provider.ts @@ -51,12 +51,12 @@ export class GitlabAuthProvider implements OAuthHandlers { }, ( accessToken: any, - refreshToken: any, + _refreshToken: any, params: any, fullProfile: any, done: PassportDoneCallback, ) => { - done(undefined, { fullProfile, params, accessToken, refreshToken }); + done(undefined, { fullProfile, params, accessToken }); }, ); } diff --git a/plugins/auth-backend/src/providers/microsoft/provider.ts b/plugins/auth-backend/src/providers/microsoft/provider.ts index 4dee90d4c6..e6157c1a83 100644 --- a/plugins/auth-backend/src/providers/microsoft/provider.ts +++ b/plugins/auth-backend/src/providers/microsoft/provider.ts @@ -72,7 +72,7 @@ export class MicrosoftAuthProvider implements OAuthHandlers { fullProfile: passport.Profile, done: PassportDoneCallback, ) => { - done(undefined, { fullProfile, accessToken, refreshToken, params }); + done(undefined, { fullProfile, accessToken, params }, { refreshToken }); }, ); } diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md index dce76b57a3..42315b3802 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-catalog-backend +## 0.6.3 + +### Patch Changes + +- 2499f6cde: Add support for assuming role in AWS integrations +- Updated dependencies [bad21a085] +- Updated dependencies [a1f5e6545] + - @backstage/catalog-model@0.7.2 + - @backstage/config@0.1.3 + ## 0.6.2 ### Patch Changes diff --git a/plugins/catalog-backend/config.d.ts b/plugins/catalog-backend/config.d.ts index 7877f34dcf..32ff44457c 100644 --- a/plugins/catalog-backend/config.d.ts +++ b/plugins/catalog-backend/config.d.ts @@ -334,6 +334,19 @@ export interface Config { }>; }; + /** + * AwsOrganizationCloudAccountProcessor configuration + */ + awsOrganization?: { + provider: { + /** + * The role to be assumed by this processor + * + */ + roleArn?: string; + }; + }; + /** * MicrosoftGraphOrgReaderProcessor configuration */ diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index bc087a3017..0925870506 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend", - "version": "0.6.2", + "version": "0.6.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,8 +31,8 @@ "dependencies": { "@azure/msal-node": "^1.0.0-beta.3", "@backstage/backend-common": "^0.5.4", - "@backstage/catalog-model": "^0.7.1", - "@backstage/config": "^0.1.2", + "@backstage/catalog-model": "^0.7.2", + "@backstage/config": "^0.1.3", "@backstage/integration": "^0.5.0", "@octokit/graphql": "^4.5.8", "@types/express": "^4.17.6", @@ -59,8 +59,8 @@ "yup": "^0.29.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/test-utils": "^0.1.8", "@types/core-js": "^2.5.4", "@types/git-url-parse": "^9.0.0", "@types/lodash": "^4.14.151", diff --git a/plugins/catalog-backend/src/ingestion/processors/AwsOrganizationCloudAccountProcessor.test.ts b/plugins/catalog-backend/src/ingestion/processors/AwsOrganizationCloudAccountProcessor.test.ts index ba163fa0c3..292564dc4f 100644 --- a/plugins/catalog-backend/src/ingestion/processors/AwsOrganizationCloudAccountProcessor.test.ts +++ b/plugins/catalog-backend/src/ingestion/processors/AwsOrganizationCloudAccountProcessor.test.ts @@ -15,10 +15,14 @@ */ import { AwsOrganizationCloudAccountProcessor } from './AwsOrganizationCloudAccountProcessor'; +import * as winston from 'winston'; describe('AwsOrganizationCloudAccountProcessor', () => { describe('readLocation', () => { - const processor = new AwsOrganizationCloudAccountProcessor(); + const processor = new AwsOrganizationCloudAccountProcessor({ + provider: {}, + logger: winston.createLogger(), + }); const location = { type: 'aws-cloud-accounts', target: '' }; const emit = jest.fn(); const listAccounts = jest.fn(); diff --git a/plugins/catalog-backend/src/ingestion/processors/AwsOrganizationCloudAccountProcessor.ts b/plugins/catalog-backend/src/ingestion/processors/AwsOrganizationCloudAccountProcessor.ts index 0e988e7307..7964541840 100644 --- a/plugins/catalog-backend/src/ingestion/processors/AwsOrganizationCloudAccountProcessor.ts +++ b/plugins/catalog-backend/src/ingestion/processors/AwsOrganizationCloudAccountProcessor.ts @@ -14,11 +14,17 @@ * limitations under the License. */ import { LocationSpec, ResourceEntityV1alpha1 } from '@backstage/catalog-model'; -import AWS, { Organizations } from 'aws-sdk'; +import AWS, { Credentials, Organizations } from 'aws-sdk'; import { Account, ListAccountsResponse } from 'aws-sdk/clients/organizations'; import * as results from './results'; import { CatalogProcessor, CatalogProcessorEmit } from './types'; +import { Config } from '@backstage/config'; +import { Logger } from 'winston'; +import { + AwsOrganizationProviderConfig, + readAwsOrganizationConfig, +} from './awsOrganization/config'; const AWS_ORGANIZATION_REGION = 'us-east-1'; const LOCATION_TYPE = 'aws-cloud-accounts'; @@ -33,9 +39,39 @@ const ORGANIZATION_ANNOTATION: string = 'amazonaws.com/organization-id'; * If custom authentication is needed, it can be achieved by configuring the global AWS.credentials object. */ export class AwsOrganizationCloudAccountProcessor implements CatalogProcessor { + logger: Logger; organizations: Organizations; - constructor() { + provider: AwsOrganizationProviderConfig; + + static fromConfig(config: Config, options: { logger: Logger }) { + const c = config.getOptionalConfig('catalog.processors.awsOrganization'); + return new AwsOrganizationCloudAccountProcessor({ + ...options, + provider: c ? readAwsOrganizationConfig(c) : {}, + }); + } + + constructor(options: { + provider: AwsOrganizationProviderConfig; + logger: Logger; + }) { + this.provider = options.provider; + this.logger = options.logger; + let credentials = undefined; + if ( + this.provider.roleArn !== undefined && + AWS.config.credentials instanceof Credentials + ) { + credentials = new AWS.ChainableTemporaryCredentials({ + masterCredentials: AWS.config.credentials as Credentials, + params: { + RoleSessionName: 'backstage-aws-organization-processor', + RoleArn: this.provider.roleArn, + }, + }); + } this.organizations = new AWS.Organizations({ + credentials, region: AWS_ORGANIZATION_REGION, }); // Only available in us-east-1 } diff --git a/plugins/catalog-backend/src/ingestion/processors/awsOrganization/config.test.ts b/plugins/catalog-backend/src/ingestion/processors/awsOrganization/config.test.ts new file mode 100644 index 0000000000..09d95b479d --- /dev/null +++ b/plugins/catalog-backend/src/ingestion/processors/awsOrganization/config.test.ts @@ -0,0 +1,33 @@ +/* + * Copyright 2020 Spotify AB + * + * 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 { readAwsOrganizationConfig } from './config'; + +describe('readAwsOrganizationConfig', () => { + it('applies all of the defaults', () => { + const config = { + provider: { + roleArn: 'aws::arn::foo', + }, + }; + const actual = readAwsOrganizationConfig(new ConfigReader(config)); + const expected = { + roleArn: 'aws::arn::foo', + }; + expect(actual).toEqual(expected); + }); +}); diff --git a/plugins/scaffolder/src/components/ScaffolderFilter/AllServicesCount.tsx b/plugins/catalog-backend/src/ingestion/processors/awsOrganization/config.ts similarity index 52% rename from plugins/scaffolder/src/components/ScaffolderFilter/AllServicesCount.tsx rename to plugins/catalog-backend/src/ingestion/processors/awsOrganization/config.ts index efacfa4320..90206f504c 100644 --- a/plugins/scaffolder/src/components/ScaffolderFilter/AllServicesCount.tsx +++ b/plugins/catalog-backend/src/ingestion/processors/awsOrganization/config.ts @@ -14,20 +14,25 @@ * limitations under the License. */ -import { useApi } from '@backstage/core'; -import { catalogApiRef } from '@backstage/plugin-catalog-react'; -import { CircularProgress, useTheme } from '@material-ui/core'; -import React from 'react'; -import { useAsync } from 'react-use'; +import { Config } from '@backstage/config'; -export const AllServicesCount = () => { - const theme = useTheme(); - const catalogApi = useApi(catalogApiRef); - const { value, loading } = useAsync(() => catalogApi.getEntities()); - - if (loading) { - return ; - } - - return {value ?? length ?? '-'}; +/** + * The configuration parameters for a single AWS Organization Processor + */ +export type AwsOrganizationProviderConfig = { + /** + * The role to assume for the processor. + */ + roleArn?: string; }; + +export function readAwsOrganizationConfig( + config: Config, +): AwsOrganizationProviderConfig { + const providerConfig = config.getOptionalConfig('provider'); + + const roleArn = providerConfig?.getOptionalString('roleArn'); + return { + roleArn, + }; +} diff --git a/plugins/catalog-backend/src/service/router.ts b/plugins/catalog-backend/src/service/router.ts index 17cfc77d8b..5936e3a747 100644 --- a/plugins/catalog-backend/src/service/router.ts +++ b/plugins/catalog-backend/src/service/router.ts @@ -60,6 +60,16 @@ export async function createRouter( res.status(200).json(entities.map(fieldMapper)); }) .post('/entities', async (req, res) => { + /* + * NOTE: THIS METHOD IS DEPRECATED AND NOT RECOMMENDED TO USE + * + * Posting entities to this method has unclear semantics and will not + * properly subject them to limitations, processing, or resolution of + * relations. + * + * It stays around in the service for the time being, but may be + * removed or change semantics at any time without prior notice. + */ const body = await requireRequestBody(req); const [result] = await entitiesCatalog.batchAddOrUpdateEntities([ { entity: body as Entity, relations: [] }, diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md index e12718bc96..fce40aacfc 100644 --- a/plugins/catalog-import/CHANGELOG.md +++ b/plugins/catalog-import/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-catalog-import +## 0.4.2 + +### Patch Changes + +- a8953a9c9: This updates the `catalog-import` plugin to omit the default metadata namespace + field and also use the short form entity reference format for selected group owners. +- 968b588f7: Allows the CodeOwnersProcessor to set the owner automatically within the catalog-import plugin. This adds an additional checkbox that overrides the group selector and will omit the owner option in the generated catalog file yaml. +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + ## 0.4.1 ### Patch Changes diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index ad196e4f1f..a427a0e884 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-import", - "version": "0.4.1", + "version": "0.4.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,11 +30,11 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.7.1", + "@backstage/catalog-model": "^0.7.2", "@backstage/catalog-client": "^0.3.6", - "@backstage/core": "^0.6.2", + "@backstage/core": "^0.6.3", "@backstage/integration": "^0.5.0", - "@backstage/plugin-catalog-react": "^0.0.4", + "@backstage/plugin-catalog-react": "^0.1.0", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -51,9 +51,9 @@ "yaml": "^1.10.0" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/react-hooks": "^3.3.0", diff --git a/plugins/catalog-import/src/components/ImportStepper/defaults.tsx b/plugins/catalog-import/src/components/ImportStepper/defaults.tsx index f2dd1d62f4..dff2136aaa 100644 --- a/plugins/catalog-import/src/components/ImportStepper/defaults.tsx +++ b/plugins/catalog-import/src/components/ImportStepper/defaults.tsx @@ -15,7 +15,15 @@ */ import { ConfigApi } from '@backstage/core'; -import { Box, StepLabel, TextField, Typography } from '@material-ui/core'; +import { + Box, + Checkbox, + FormControlLabel, + FormHelperText, + StepLabel, + TextField, + Typography, +} from '@material-ui/core'; import React from 'react'; import { BackButton } from '../Buttons'; import { StepFinishImportLocation } from '../StepFinishImportLocation'; @@ -167,6 +175,7 @@ export function defaultGenerateStepper( defaultTitle={title} defaultBody={body} renderFormFields={({ + values, control, errors, groupsLoading, @@ -219,22 +228,47 @@ export function defaultGenerateStepper( required /> - + )} + + { + if (value) { + control.setValue('owner', ''); + } + }} + /> + } + label={ + <> + Use CODEOWNERS file as Entity Owner + + } /> + + WARNING: This may fail is no CODEOWNERS file is found at + the target location. + )} /> diff --git a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.test.tsx b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.test.tsx index 0b38fdaf58..606f9ff88e 100644 --- a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.test.tsx +++ b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.test.tsx @@ -21,7 +21,10 @@ import { act, render, RenderResult } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; import { AnalyzeResult, catalogImportApiRef } from '../../api'; -import { StepPrepareCreatePullRequest } from './StepPrepareCreatePullRequest'; +import { + generateEntities, + StepPrepareCreatePullRequest, +} from './StepPrepareCreatePullRequest'; describe('', () => { const catalogImportApi: jest.Mocked = { @@ -60,6 +63,7 @@ describe('', () => { kind: 'Component', metadata: { name: 'my-component', + namespace: 'default', }, spec: { owner: 'my-owner', @@ -282,6 +286,46 @@ spec: renderFormFieldsFn.mock.calls[ renderFormFieldsFn.mock.calls.length - 1 ][0], - ).toMatchObject({ groups: ['Group:my-group'], groupsLoading: false }); + ).toMatchObject({ groups: ['my-group'], groupsLoading: false }); + }); + + describe('generateEntities', () => { + it.each([[undefined], [null]])( + 'should not include blank namespace for %s', + namespace => { + expect( + generateEntities( + [{ metadata: { namespace: namespace as any } }], + 'my-component', + 'group-1', + ), + ).toEqual([ + expect.objectContaining({ + metadata: expect.not.objectContaining({ + namespace: 'default', + }), + }), + ]); + }, + ); + + it.each([['default'], ['my-namespace']])( + 'should include explicit namespace %s', + namespace => { + expect( + generateEntities( + [{ metadata: { namespace } }], + 'my-component', + 'group-1', + ), + ).toEqual([ + expect.objectContaining({ + metadata: expect.objectContaining({ + namespace, + }), + }), + ]); + }, + ); }); }); diff --git a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.tsx b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.tsx index d9e7b962ab..c34d5f374b 100644 --- a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.tsx +++ b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.tsx @@ -14,13 +14,16 @@ * limitations under the License. */ -import { Entity, serializeEntityRef } from '@backstage/catalog-model'; +import { Entity } from '@backstage/catalog-model'; import { useApi } from '@backstage/core'; -import { catalogApiRef } from '@backstage/plugin-catalog-react'; +import { + catalogApiRef, + formatEntityRefTitle, +} from '@backstage/plugin-catalog-react'; import { Box, FormHelperText, Grid, Typography } from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; import React, { useCallback, useState } from 'react'; -import { UseFormMethods } from 'react-hook-form'; +import { UnpackNestedValue, UseFormMethods } from 'react-hook-form'; import { useAsync } from 'react-use'; import YAML from 'yaml'; import { AnalyzeResult, catalogImportApiRef } from '../../api'; @@ -45,6 +48,7 @@ type FormData = { body: string; componentName: string; owner: string; + useCodeowners: boolean; }; type Props = { @@ -60,16 +64,17 @@ type Props = { renderFormFields: ( props: Pick, 'errors' | 'register' | 'control'> & { + values: UnpackNestedValue; groups: string[]; groupsLoading: boolean; }, ) => React.ReactNode; }; -function generateEntities( +export function generateEntities( entities: PartialEntity[], componentName: string, - owner: string, + owner?: string, ): Entity[] { return entities.map(e => ({ ...e, @@ -78,11 +83,10 @@ function generateEntities( metadata: { ...e.metadata, name: componentName, - namespace: e.metadata?.namespace ?? 'default', }, spec: { ...e.spec, - owner, + ...(owner ? { owner } : {}), }, })); } @@ -107,8 +111,9 @@ export const StepPrepareCreatePullRequest = ({ filter: { kind: 'group' }, }); - // TODO: defaultKind (=group), defaultNamespace (=same as entity) - return groupEntities.items.map(e => serializeEntityRef(e) as string).sort(); + return groupEntities.items + .map(e => formatEntityRefTitle(e, { defaultKind: 'group' })) + .sort(); }); const handleResult = useCallback( @@ -186,10 +191,12 @@ export const StepPrepareCreatePullRequest = ({ (analyzeResult.generatedEntities[0]?.spec?.owner as string) || '', componentName: analyzeResult.generatedEntities[0]?.metadata?.name || '', + useCodeowners: false, }} render={({ values, errors, control, register }) => ( <> {renderFormFields({ + values, errors, register, control, diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md index 07898af872..85035880eb 100644 --- a/plugins/catalog-react/CHANGELOG.md +++ b/plugins/catalog-react/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-catalog-react +## 0.1.0 + +### Minor Changes + +- d0760ecdf: Moved common useStarredEntities hook to plugin-catalog-react + +### Patch Changes + +- 88f1f1b60: Truncate and show ellipsis with tooltip if content of + `createMetadataDescriptionColumn` is too wide. +- 9615e68fb: Forward link styling of `EntityRefLink` and `EnriryRefLinks` into the underling + `Link`. +- 5c2e2863f: Added the proper type parameters to entityRouteRef. +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [1407b34c6] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [3a58084b6] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/catalog-model@0.7.2 + ## 0.0.4 ### Patch Changes diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index 432c59ef3b..7408e1d596 100644 --- a/plugins/catalog-react/package.json +++ b/plugins/catalog-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-react", - "version": "0.0.4", + "version": "0.1.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,8 +29,8 @@ }, "dependencies": { "@backstage/catalog-client": "^0.3.6", - "@backstage/catalog-model": "^0.7.1", - "@backstage/core": "^0.6.2", + "@backstage/catalog-model": "^0.7.2", + "@backstage/core": "^0.6.3", "@material-ui/core": "^4.11.0", "@types/react": "^16.9", "react": "^16.13.1", @@ -39,9 +39,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/react-hooks": "^3.3.0", diff --git a/plugins/catalog-react/src/components/EntityProvider/EntityProvider.tsx b/plugins/catalog-react/src/components/EntityProvider/EntityProvider.tsx index 45cdd56d04..861fe3d9e7 100644 --- a/plugins/catalog-react/src/components/EntityProvider/EntityProvider.tsx +++ b/plugins/catalog-react/src/components/EntityProvider/EntityProvider.tsx @@ -26,7 +26,7 @@ export const EntityProvider = ({ entity, children }: EntityProviderProps) => ( diff --git a/plugins/catalog-react/src/components/EntityTable/columns.tsx b/plugins/catalog-react/src/components/EntityTable/columns.tsx index 7ca99b1100..7f5417df4e 100644 --- a/plugins/catalog-react/src/components/EntityTable/columns.tsx +++ b/plugins/catalog-react/src/components/EntityTable/columns.tsx @@ -20,7 +20,7 @@ import { RELATION_OWNED_BY, RELATION_PART_OF, } from '@backstage/catalog-model'; -import { TableColumn } from '@backstage/core'; +import { OverflowTooltip, TableColumn } from '@backstage/core'; import React from 'react'; import { getEntityRelations } from '../../utils'; import { @@ -139,6 +139,12 @@ export function createMetadataDescriptionColumn< return { title: 'Description', field: 'metadata.description', + render: entity => ( + + ), width: 'auto', }; } diff --git a/plugins/catalog-react/src/components/EntityTable/presets.test.tsx b/plugins/catalog-react/src/components/EntityTable/presets.test.tsx index b6b8c26e37..0f87c4132f 100644 --- a/plugins/catalog-react/src/components/EntityTable/presets.test.tsx +++ b/plugins/catalog-react/src/components/EntityTable/presets.test.tsx @@ -74,7 +74,7 @@ describe('systemEntityColumns', () => { expect(getByText('my-namespace/my-system')).toBeInTheDocument(); expect(getByText('my-namespace/my-domain')).toBeInTheDocument(); expect(getByText('Test')).toBeInTheDocument(); - expect(getByText('Some description')).toBeInTheDocument(); + expect(getByText(/Some/)).toBeInTheDocument(); }); }); }); @@ -131,7 +131,7 @@ describe('componentEntityColumns', () => { expect(getByText('Test')).toBeInTheDocument(); expect(getByText('production')).toBeInTheDocument(); expect(getByText('service')).toBeInTheDocument(); - expect(getByText('Some description')).toBeInTheDocument(); + expect(getByText(/Some/)).toBeInTheDocument(); }); }); }); diff --git a/plugins/catalog-react/src/hooks/index.ts b/plugins/catalog-react/src/hooks/index.ts index 2ecf6e9a90..d964c22a3b 100644 --- a/plugins/catalog-react/src/hooks/index.ts +++ b/plugins/catalog-react/src/hooks/index.ts @@ -16,3 +16,4 @@ export { EntityContext, useEntity, useEntityFromUrl } from './useEntity'; export { useEntityCompoundName } from './useEntityCompoundName'; export { useRelatedEntities } from './useRelatedEntities'; +export { useStarredEntities } from './useStarredEntities'; diff --git a/plugins/scaffolder/src/hooks/useStarredEntities.test.tsx b/plugins/catalog-react/src/hooks/useStarredEntities.test.tsx similarity index 100% rename from plugins/scaffolder/src/hooks/useStarredEntities.test.tsx rename to plugins/catalog-react/src/hooks/useStarredEntities.test.tsx diff --git a/plugins/catalog/src/hooks/useStarredEntities.ts b/plugins/catalog-react/src/hooks/useStarredEntities.ts similarity index 100% rename from plugins/catalog/src/hooks/useStarredEntities.ts rename to plugins/catalog-react/src/hooks/useStarredEntities.ts diff --git a/plugins/catalog-react/src/routes.ts b/plugins/catalog-react/src/routes.ts index 0fced32f59..7470b8030e 100644 --- a/plugins/catalog-react/src/routes.ts +++ b/plugins/catalog-react/src/routes.ts @@ -31,6 +31,7 @@ export const entityRoute = createRouteRef({ icon: NoIcon, path: ':namespace/:kind/:name/*', title: 'Entity', + params: ['namespace', 'kind', 'name'], }); export const entityRouteRef = entityRoute; diff --git a/plugins/catalog/CHANGELOG.md b/plugins/catalog/CHANGELOG.md index 6dc2913b60..129bb98346 100644 --- a/plugins/catalog/CHANGELOG.md +++ b/plugins/catalog/CHANGELOG.md @@ -1,5 +1,70 @@ # @backstage/plugin-catalog +## 0.4.0 + +### Minor Changes + +- a5f42cf66: The Scaffolder and Catalog plugins have been migrated to partially require use of the [new composability API](https://backstage.io/docs/plugins/composability). The Scaffolder used to register its pages using the deprecated route registration plugin API, but those registrations have been removed. This means you now need to add the Scaffolder plugin page to the app directly. + + The page is imported from the Scaffolder plugin and added to the `` component: + + ```tsx + } /> + ``` + + The Catalog plugin has also been migrated to use an [external route reference](https://backstage.io/docs/plugins/composability#binding-external-routes-in-the-app) to dynamically link to the create component page. This means you need to migrate the catalog plugin to use the new extension components, as well as bind the external route. + + To use the new extension components, replace existing usage of the `CatalogRouter` with the following: + + ```tsx + } /> + }> + + + ``` + + And to bind the external route from the catalog plugin to the scaffolder template index page, make sure you have the appropriate imports and add the following to the `createApp` call: + + ```ts + import { catalogPlugin } from '@backstage/plugin-catalog'; + import { scaffolderPlugin } from '@backstage/plugin-scaffolder'; + + const app = createApp({ + // ... + bindRoutes({ bind }) { + bind(catalogPlugin.externalRoutes, { + createComponent: scaffolderPlugin.routes.root, + }); + }, + }); + ``` + +- d0760ecdf: Moved common useStarredEntities hook to plugin-catalog-react + +### Patch Changes + +- d6593abe6: Remove domain column from `HasSystemsCard` and system from `HasComponentsCard`, + `HasSubcomponentsCard`, and `HasApisCard`. +- bad21a085: Implement annotations for customising Entity URLs in the Catalog pages. +- 437bac549: Make the description column in the catalog table and api-docs table use up as + much space as possible before hiding overflowing text. +- 5469a9761: Changes made in CatalogTable and ApiExplorerTable for using the OverflowTooltip component for truncating large description and showing tooltip on hover-over. +- 60d1bc3e7: Fix Japanese Good Morning +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + ## 0.3.2 ### Patch Changes diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index 6efb450597..d6dfc8da5a 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog", - "version": "0.3.2", + "version": "0.4.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,9 +31,9 @@ }, "dependencies": { "@backstage/catalog-client": "^0.3.6", - "@backstage/catalog-model": "^0.7.1", - "@backstage/core": "^0.6.2", - "@backstage/plugin-catalog-react": "^0.0.4", + "@backstage/catalog-model": "^0.7.2", + "@backstage/core": "^0.6.3", + "@backstage/plugin-catalog-react": "^0.1.0", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -50,9 +50,9 @@ "swr": "^0.3.0" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@microsoft/microsoft-graph-types": "^1.25.0", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", diff --git a/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx b/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx index ada827115d..449d3c1fc9 100644 --- a/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx +++ b/plugins/catalog/src/components/AboutCard/AboutCard.test.tsx @@ -15,6 +15,10 @@ */ import { EntityProvider } from '@backstage/plugin-catalog-react'; +import { + SOURCE_LOCATION_ANNOTATION, + EDIT_URL_ANNOTATION, +} from '@backstage/catalog-model'; import { render } from '@testing-library/react'; import React from 'react'; import { AboutCard } from './AboutCard'; @@ -123,3 +127,41 @@ describe(' BitBucket', () => { ); }); }); + +describe(' custom links', () => { + it('renders info and "view source" link', () => { + const entity = { + apiVersion: 'v1', + kind: 'Component', + metadata: { + name: 'software', + annotations: { + 'backstage.io/managed-by-location': + 'bitbucket:https://bitbucket.org/backstage/backstage/src/master/software.yaml', + [EDIT_URL_ANNOTATION]: 'https://another.place', + [SOURCE_LOCATION_ANNOTATION]: + 'url:https://another.place/backstage.git', + }, + }, + spec: { + owner: 'guest', + type: 'service', + lifecycle: 'production', + }, + }; + const { getByText } = render( + + + , + ); + expect(getByText('service')).toBeInTheDocument(); + expect(getByText('View Source').closest('a')).toHaveAttribute( + 'href', + 'https://another.place/backstage.git', + ); + expect(getByText('View Source').closest('a')).toHaveAttribute( + 'edithref', + 'https://another.place', + ); + }); +}); diff --git a/plugins/catalog/src/components/AboutCard/AboutCard.tsx b/plugins/catalog/src/components/AboutCard/AboutCard.tsx index 2d6cd6bca8..64564f5ec4 100644 --- a/plugins/catalog/src/components/AboutCard/AboutCard.tsx +++ b/plugins/catalog/src/components/AboutCard/AboutCard.tsx @@ -16,7 +16,9 @@ import { Entity, + LocationSpec, ENTITY_DEFAULT_NAMESPACE, + SOURCE_LOCATION_ANNOTATION, RELATION_PROVIDES_API, } from '@backstage/catalog-model'; import { HeaderIconLinkRow } from '@backstage/core'; @@ -34,8 +36,8 @@ import EditIcon from '@material-ui/icons/Edit'; import ExtensionIcon from '@material-ui/icons/Extension'; import GitHubIcon from '@material-ui/icons/GitHub'; import React from 'react'; -import { findLocationForEntityMeta } from '../../data/utils'; -import { createEditLink, determineUrlType } from '../createEditLink'; +import { findLocationForEntityMeta, parseLocation } from '../../data/utils'; +import { findEditUrl, determineUrlType } from '../actions'; import { AboutContent } from './AboutContent'; const useStyles = makeStyles({ @@ -60,20 +62,35 @@ type CodeLinkInfo = { href?: string; }; +function getSourceLocationForEntity( + entity: Entity, + location?: LocationSpec, +): LocationSpec | undefined { + const annotation = entity.metadata?.annotations?.[SOURCE_LOCATION_ANNOTATION]; + const parsed = annotation && parseLocation(annotation); + + return parsed || location; +} + function getCodeLinkInfo(entity: Entity): CodeLinkInfo { const location = findLocationForEntityMeta(entity?.metadata); + const editUrl = findEditUrl(entity); + let sourceLocation = getSourceLocationForEntity(entity, location); + if (location) { + sourceLocation = sourceLocation || location; const type = - location.type === 'url' - ? determineUrlType(location.target) - : location.type; + sourceLocation.type === 'url' + ? determineUrlType(sourceLocation.target) + : sourceLocation.type; return { + edithref: editUrl, icon: iconMap[type], - edithref: createEditLink(location), - href: location.target, + href: sourceLocation.target, }; } - return {}; + + return { edithref: editUrl, href: sourceLocation?.target }; } type AboutCardProps = { diff --git a/plugins/catalog/src/components/CatalogPage/CatalogPage.tsx b/plugins/catalog/src/components/CatalogPage/CatalogPage.tsx index ed51316dcd..327bc2e472 100644 --- a/plugins/catalog/src/components/CatalogPage/CatalogPage.tsx +++ b/plugins/catalog/src/components/CatalogPage/CatalogPage.tsx @@ -23,14 +23,18 @@ import { useApi, useRouteRef, } from '@backstage/core'; -import { catalogApiRef, isOwnerOf } from '@backstage/plugin-catalog-react'; +import { + catalogApiRef, + isOwnerOf, + useStarredEntities, +} from '@backstage/plugin-catalog-react'; + import { Button, makeStyles } from '@material-ui/core'; import SettingsIcon from '@material-ui/icons/Settings'; import StarIcon from '@material-ui/icons/Star'; import React, { useCallback, useMemo, useState } from 'react'; import { Link as RouterLink } from 'react-router-dom'; import { EntityFilterGroupsProvider, useFilteredEntities } from '../../filter'; -import { useStarredEntities } from '../../hooks/useStarredEntities'; import { createComponentRouteRef } from '../../routes'; import { ButtonGroup, diff --git a/plugins/catalog/src/components/CatalogPage/utils/locales/goodMorning.locales.json b/plugins/catalog/src/components/CatalogPage/utils/locales/goodMorning.locales.json index a67c292d83..febbc32c49 100644 --- a/plugins/catalog/src/components/CatalogPage/utils/locales/goodMorning.locales.json +++ b/plugins/catalog/src/components/CatalogPage/utils/locales/goodMorning.locales.json @@ -27,7 +27,7 @@ "Indonesian": "Selamat pagi", "Irish": "Dia dhuit", "Italian": "Buongiorno", - "Japanese": "お早う", + "Japanese": "おはよう", "Korean": "안녕하세요", "Kazakh": "Kayırlı tan", "Kurdish": "Beyanî baş", diff --git a/plugins/catalog/src/components/CatalogTable/CatalogTable.test.tsx b/plugins/catalog/src/components/CatalogTable/CatalogTable.test.tsx index 16c91c0d6c..ffd5f3d190 100644 --- a/plugins/catalog/src/components/CatalogTable/CatalogTable.test.tsx +++ b/plugins/catalog/src/components/CatalogTable/CatalogTable.test.tsx @@ -14,7 +14,12 @@ * limitations under the License. */ -import { Entity } from '@backstage/catalog-model'; +import { + Entity, + VIEW_URL_ANNOTATION, + EDIT_URL_ANNOTATION, +} from '@backstage/catalog-model'; +import { act, fireEvent } from '@testing-library/react'; import { renderWithEffects, wrapInTestApp } from '@backstage/test-utils'; import * as React from 'react'; import { CatalogTable } from './CatalogTable'; @@ -38,6 +43,14 @@ const entities: Entity[] = [ ]; describe('CatalogTable component', () => { + beforeEach(() => { + window.open = jest.fn(); + }); + + afterEach(() => { + jest.resetAllMocks(); + }); + it('should render error message when error is passed in props', async () => { const rendered = await renderWithEffects( wrapInTestApp( @@ -70,4 +83,62 @@ describe('CatalogTable component', () => { expect(rendered.getByText(/component2/)).toBeInTheDocument(); expect(rendered.getByText(/component3/)).toBeInTheDocument(); }); + + it('should use specified edit URL if in annotation', async () => { + const entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'component1', + annotations: { [EDIT_URL_ANNOTATION]: 'https://other.place' }, + }, + }; + + const { getByTitle } = await renderWithEffects( + wrapInTestApp( + , + ), + ); + + const editButton = getByTitle('Edit'); + + await act(async () => { + fireEvent.click(editButton); + }); + + expect(window.open).toHaveBeenCalledWith('https://other.place', '_blank'); + }); + + it('should use specified view URL if in annotation', async () => { + const entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'component1', + annotations: { [VIEW_URL_ANNOTATION]: 'https://other.place' }, + }, + }; + + const { getByTitle } = await renderWithEffects( + wrapInTestApp( + , + ), + ); + + const viewButton = getByTitle('View'); + + await act(async () => { + fireEvent.click(viewButton); + }); + + expect(window.open).toHaveBeenCalledWith('https://other.place', '_blank'); + }); }); diff --git a/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx b/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx index 91f187855a..5a8040cd5b 100644 --- a/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx +++ b/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx @@ -32,14 +32,13 @@ import { EntityRefLinks, formatEntityRefTitle, getEntityRelations, + useStarredEntities, } from '@backstage/plugin-catalog-react'; import { Chip } from '@material-ui/core'; import Edit from '@material-ui/icons/Edit'; import OpenInNew from '@material-ui/icons/OpenInNew'; import React from 'react'; -import { findLocationForEntityMeta } from '../../data/utils'; -import { useStarredEntities } from '../../hooks/useStarredEntities'; -import { createEditLink } from '../createEditLink'; +import { findViewUrl, findEditUrl } from '../actions'; import { favouriteEntityIcon, favouriteEntityTooltip, @@ -98,6 +97,7 @@ const columns: TableColumn[] = [ placement="bottom-start" /> ), + width: 'auto', }, { title: 'Tags', @@ -152,24 +152,24 @@ export const CatalogTable = ({ const actions: TableProps['actions'] = [ ({ entity }) => { - const location = findLocationForEntityMeta(entity.metadata); + const url = findViewUrl(entity); return { icon: () => , tooltip: 'View', onClick: () => { - if (!location) return; - window.open(location.target, '_blank'); + if (!url) return; + window.open(url, '_blank'); }, }; }, ({ entity }) => { - const location = findLocationForEntityMeta(entity.metadata); + const url = findEditUrl(entity); return { icon: () => , tooltip: 'Edit', onClick: () => { - if (!location) return; - window.open(createEditLink(location), '_blank'); + if (!url) return; + window.open(url, '_blank'); }, }; }, diff --git a/plugins/catalog/src/components/FavouriteEntity/FavouriteEntity.tsx b/plugins/catalog/src/components/FavouriteEntity/FavouriteEntity.tsx index 970ce32ece..1c414414aa 100644 --- a/plugins/catalog/src/components/FavouriteEntity/FavouriteEntity.tsx +++ b/plugins/catalog/src/components/FavouriteEntity/FavouriteEntity.tsx @@ -15,10 +15,10 @@ */ import React, { ComponentProps } from 'react'; +import { useStarredEntities } from '@backstage/plugin-catalog-react'; import { IconButton, Tooltip, withStyles } from '@material-ui/core'; import StarBorder from '@material-ui/icons/StarBorder'; import Star from '@material-ui/icons/Star'; -import { useStarredEntities } from '../../hooks/useStarredEntities'; import { Entity } from '@backstage/catalog-model'; type Props = ComponentProps & { entity: Entity }; diff --git a/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.tsx b/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.tsx index 6485d4f525..eb8e96d9b3 100644 --- a/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.tsx +++ b/plugins/catalog/src/components/HasComponentsCard/HasComponentsCard.tsx @@ -33,6 +33,14 @@ type Props = { variant?: 'gridItem'; }; +const columns = [ + EntityTable.columns.createEntityRefColumn({ defaultKind: 'component' }), + EntityTable.columns.createOwnerColumn(), + EntityTable.columns.createSpecTypeColumn(), + EntityTable.columns.createSpecLifecycleColumn(), + EntityTable.columns.createMetadataDescriptionColumn(), +]; + export const HasComponentsCard = ({ variant = 'gridItem' }: Props) => { const { entity } = useEntity(); const { entities, loading, error } = useRelatedEntities(entity, { @@ -72,7 +80,7 @@ export const HasComponentsCard = ({ variant = 'gridItem' }: Props) => { } - columns={EntityTable.componentEntityColumns} + columns={columns} entities={entities as ComponentEntity[]} /> ); diff --git a/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.tsx b/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.tsx index c2635b68e1..778ec1dec5 100644 --- a/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.tsx +++ b/plugins/catalog/src/components/HasSubcomponentsCard/HasSubcomponentsCard.tsx @@ -33,6 +33,14 @@ type Props = { variant?: 'gridItem'; }; +const columns = [ + EntityTable.columns.createEntityRefColumn({ defaultKind: 'component' }), + EntityTable.columns.createOwnerColumn(), + EntityTable.columns.createSpecTypeColumn(), + EntityTable.columns.createSpecLifecycleColumn(), + EntityTable.columns.createMetadataDescriptionColumn(), +]; + export const HasSubcomponentsCard = ({ variant = 'gridItem' }: Props) => { const { entity } = useEntity(); const { entities, loading, error } = useRelatedEntities(entity, { @@ -72,7 +80,7 @@ export const HasSubcomponentsCard = ({ variant = 'gridItem' }: Props) => { } - columns={EntityTable.componentEntityColumns} + columns={columns} entities={entities as ComponentEntity[]} /> ); diff --git a/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.tsx b/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.tsx index 9faa640060..5b18711d44 100644 --- a/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.tsx +++ b/plugins/catalog/src/components/HasSystemsCard/HasSystemsCard.tsx @@ -33,6 +33,12 @@ type Props = { variant?: 'gridItem'; }; +const columns = [ + EntityTable.columns.createEntityRefColumn({ defaultKind: 'system' }), + EntityTable.columns.createOwnerColumn(), + EntityTable.columns.createMetadataDescriptionColumn(), +]; + export const HasSystemsCard = ({ variant = 'gridItem' }: Props) => { const { entity } = useEntity(); const { entities, loading, error } = useRelatedEntities(entity, { @@ -71,7 +77,7 @@ export const HasSystemsCard = ({ variant = 'gridItem' }: Props) => { } - columns={EntityTable.systemEntityColumns} + columns={columns} entities={entities as SystemEntity[]} /> ); diff --git a/plugins/catalog/src/components/createEditLink.ts b/plugins/catalog/src/components/actions.ts similarity index 76% rename from plugins/catalog/src/components/createEditLink.ts rename to plugins/catalog/src/components/actions.ts index 57fc876704..72e1bf67ec 100644 --- a/plugins/catalog/src/components/createEditLink.ts +++ b/plugins/catalog/src/components/actions.ts @@ -14,7 +14,13 @@ * limitations under the License. */ -import { LocationSpec } from '@backstage/catalog-model'; +import { + LocationSpec, + Entity, + EDIT_URL_ANNOTATION, + VIEW_URL_ANNOTATION, +} from '@backstage/catalog-model'; +import { findLocationForEntityMeta } from '../data/utils'; import parseGitUrl from 'git-url-parse'; /** @@ -75,3 +81,22 @@ export const determineUrlType = (url: string): string => { } return 'url'; }; + +export const findEditUrl = ({ metadata }: Entity): string | undefined => { + const annotations = metadata.annotations || {}; + + const editUrl = annotations[EDIT_URL_ANNOTATION]; + + if (editUrl) return editUrl; + + const location = findLocationForEntityMeta(metadata); + + return location && createEditLink(location); +}; + +export const findViewUrl = ({ metadata }: Entity): string | undefined => { + const annotations = metadata.annotations || {}; + const location = findLocationForEntityMeta(metadata); + + return annotations[VIEW_URL_ANNOTATION] || location?.target; +}; diff --git a/plugins/catalog/src/data/utils.ts b/plugins/catalog/src/data/utils.ts index df14875092..ec63d94754 100644 --- a/plugins/catalog/src/data/utils.ts +++ b/plugins/catalog/src/data/utils.ts @@ -32,13 +32,17 @@ export function findLocationForEntityMeta( return undefined; } - const separatorIndex = annotation.indexOf(':'); + return parseLocation(annotation); +} + +export function parseLocation(reference: string): LocationSpec | undefined { + const separatorIndex = reference.indexOf(':'); if (separatorIndex === -1) { return undefined; } return { - type: annotation.substring(0, separatorIndex), - target: annotation.substring(separatorIndex + 1), + type: reference.substring(0, separatorIndex), + target: reference.substring(separatorIndex + 1), }; } diff --git a/plugins/catalog/src/hooks/useStarredEntities.test.tsx b/plugins/catalog/src/hooks/useStarredEntities.test.tsx deleted file mode 100644 index 78d2c4a58f..0000000000 --- a/plugins/catalog/src/hooks/useStarredEntities.test.tsx +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * 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, { PropsWithChildren } from 'react'; -import { renderHook, act } from '@testing-library/react-hooks'; -import { useStarredEntities } from './useStarredEntities'; -import { - ApiProvider, - ApiRegistry, - storageApiRef, - WebStorage, - StorageApi, -} from '@backstage/core'; -import { MockErrorApi } from '@backstage/test-utils'; -import { Entity } from '@backstage/catalog-model'; - -describe('useStarredEntities', () => { - let mockStorage: StorageApi | undefined; - - const mockEntity: Entity = { - apiVersion: '1', - kind: 'Component', - metadata: { - name: 'mock', - }, - }; - - const secondMockEntity: Entity = { - apiVersion: '1', - kind: 'Component', - metadata: { - namespace: 'test', - name: 'mock2', - }, - }; - - const wrapper = ({ children }: PropsWithChildren<{}>) => { - return ( - - {children} - - ); - }; - - beforeEach(() => { - mockStorage = new WebStorage('@backstage', new MockErrorApi()).forBucket( - Date.now().toString(), // TODO(blam): need something that changes every test run for now until the MockStorage is implemented - ); - }); - it('should return an empty set for when there is no items in storage', async () => { - const { result } = renderHook(() => useStarredEntities(), { wrapper }); - - expect(result.current.starredEntities.size).toBe(0); - }); - it('should return a set with the current items when there is items in storage', async () => { - const expectedIds = ['i', 'am', 'some', 'test', 'ids']; - const store = mockStorage?.forBucket('settings'); - await store?.set('starredEntities', expectedIds); - - const { result } = renderHook(() => useStarredEntities(), { wrapper }); - - for (const item of expectedIds) { - expect(result.current.starredEntities.has(item)).toBeTruthy(); - } - }); - it('should listen to changes when the storage is set elsewhere', async () => { - const { result, waitForNextUpdate } = renderHook( - () => useStarredEntities(), - { wrapper }, - ); - - expect(result.current.starredEntities.size).toBe(0); - expect(result.current.isStarredEntity(mockEntity)).toBeFalsy(); - - // Make this happen after awaiting for the next update so we can - // catch when the hook re-renders with the latest data - setTimeout(() => result.current.toggleStarredEntity(mockEntity), 1); - - await waitForNextUpdate(); - - expect(result.current.starredEntities.size).toBe(1); - expect(result.current.isStarredEntity(mockEntity)).toBeTruthy(); - }); - - it('should write new entries to the local store when adding a togglging entity', async () => { - const { result } = renderHook(() => useStarredEntities(), { wrapper }); - - act(() => { - result.current.toggleStarredEntity(mockEntity); - }); - - expect(result.current.isStarredEntity(mockEntity)).toBeTruthy(); - expect(result.current.isStarredEntity(secondMockEntity)).toBeFalsy(); - }); - - it('should remove an existing entity when toggling entries', async () => { - const { result } = renderHook(() => useStarredEntities(), { wrapper }); - - act(() => { - result.current.toggleStarredEntity(mockEntity); - result.current.toggleStarredEntity(secondMockEntity); - result.current.toggleStarredEntity(mockEntity); - }); - - expect(result.current.isStarredEntity(mockEntity)).toBeFalsy(); - expect(result.current.isStarredEntity(secondMockEntity)).toBeTruthy(); - }); -}); diff --git a/plugins/circleci/CHANGELOG.md b/plugins/circleci/CHANGELOG.md index 47e15ac88e..b849abe379 100644 --- a/plugins/circleci/CHANGELOG.md +++ b/plugins/circleci/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-circleci +## 0.2.10 + +### Patch Changes + +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + ## 0.2.9 ### Patch Changes diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json index 9c7794dd59..3c46020d3a 100644 --- a/plugins/circleci/package.json +++ b/plugins/circleci/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-circleci", - "version": "0.2.9", + "version": "0.2.10", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,9 +31,9 @@ "postpack": "backstage-cli postpack" }, "dependencies": { - "@backstage/catalog-model": "^0.7.1", - "@backstage/core": "^0.6.2", - "@backstage/plugin-catalog-react": "^0.0.4", + "@backstage/catalog-model": "^0.7.2", + "@backstage/core": "^0.6.3", + "@backstage/plugin-catalog-react": "^0.1.0", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -50,9 +50,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/cloudbuild/CHANGELOG.md b/plugins/cloudbuild/CHANGELOG.md index 498f32489b..f79281be18 100644 --- a/plugins/cloudbuild/CHANGELOG.md +++ b/plugins/cloudbuild/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-cloudbuild +## 0.2.11 + +### Patch Changes + +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + ## 0.2.10 ### Patch Changes diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json index 1638bd1446..07f7c03a0c 100644 --- a/plugins/cloudbuild/package.json +++ b/plugins/cloudbuild/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-cloudbuild", - "version": "0.2.10", + "version": "0.2.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,9 +30,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.7.1", - "@backstage/plugin-catalog-react": "^0.0.4", - "@backstage/core": "^0.6.2", + "@backstage/catalog-model": "^0.7.2", + "@backstage/plugin-catalog-react": "^0.1.0", + "@backstage/core": "^0.6.3", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -47,9 +47,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/cost-insights/CHANGELOG.md b/plugins/cost-insights/CHANGELOG.md index e672b33976..622454d2a9 100644 --- a/plugins/cost-insights/CHANGELOG.md +++ b/plugins/cost-insights/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-cost-insights +## 0.8.2 + +### Patch Changes + +- 38205492a: Default alert properties can be overridden using accessors +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [1407b34c6] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [3a58084b6] +- Updated dependencies [a1f5e6545] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/config@0.1.3 + ## 0.8.1 ### Patch Changes diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json index d4b8ee1ad0..e306a7fa6e 100644 --- a/plugins/cost-insights/package.json +++ b/plugins/cost-insights/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-cost-insights", - "version": "0.8.1", + "version": "0.8.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,8 +30,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/config": "^0.1.2", - "@backstage/core": "^0.6.2", + "@backstage/config": "^0.1.3", + "@backstage/core": "^0.6.3", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -55,9 +55,9 @@ "yup": "^0.29.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/cost-insights/src/alerts/ProjectGrowthAlert.test.tsx b/plugins/cost-insights/src/alerts/ProjectGrowthAlert.test.tsx new file mode 100644 index 0000000000..05a10bb2f0 --- /dev/null +++ b/plugins/cost-insights/src/alerts/ProjectGrowthAlert.test.tsx @@ -0,0 +1,101 @@ +/* + * Copyright 2020 Spotify AB + * + * 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 pluralize from 'pluralize'; +import { renderInTestApp } from '@backstage/test-utils'; +import { ProjectGrowthAlert } from './ProjectGrowthAlert'; +import { ProjectGrowthData } from '../types'; +import { + MockCurrencyProvider, + MockConfigProvider, + MockBillingDateProvider, +} from '../utils/tests'; + +const mockData: ProjectGrowthData = { + project: 'test-project', + periodStart: '2021-01-01', + periodEnd: '2021-02-01', + aggregation: [0, 0], + change: { + ratio: 0, + amount: 0, + }, + products: [ + { + id: 'product-a', + aggregation: [0, 0], + }, + ], +}; + +// suppress recharts componentDidUpdate deprecation warnings +jest.spyOn(console, 'warn').mockImplementation(() => {}); + +async function renderInContext(children: JSX.Element) { + return renderInTestApp( + + + {children} + + , + ); +} + +class CustomProjectGrowthAlert extends ProjectGrowthAlert { + get url() { + return 'path/to/resource'; + } + get title() { + return `Investigate cost growth in ${pluralize( + 'project', + this.data.products.length, + true, + )}`; + } +} + +describe('ProjectGrowthAlert', () => { + describe('constructor', () => { + it('should create a project growth alert', async () => { + const alert = new ProjectGrowthAlert(mockData); + const { getByText, queryByText } = await renderInContext(alert.element); + + expect(alert.url).toBe('/cost-insights/investigating-growth'); + expect(alert.title).toBe( + 'Investigate cost growth in project test-project', + ); + expect(alert.subtitle).toBe( + 'Cost growth outpacing business growth is unsustainable long-term.', + ); + expect(getByText('1 product')).toBeInTheDocument(); + expect(queryByText('sorted by cost')).not.toBeInTheDocument(); + }); + + it('a subclass can inherit and override defaults using accessors', async () => { + const alert = new CustomProjectGrowthAlert(mockData); + const { getByText, queryByText } = await renderInContext(alert.element); + + expect(alert.url).toBe('path/to/resource'); + expect(alert.title).toBe('Investigate cost growth in 1 project'); + expect(alert.subtitle).toBe( + 'Cost growth outpacing business growth is unsustainable long-term.', + ); + expect(getByText('1 product')).toBeInTheDocument(); + expect(queryByText('sorted by cost')).not.toBeInTheDocument(); + }); + }); +}); diff --git a/plugins/cost-insights/src/alerts/ProjectGrowthAlert.tsx b/plugins/cost-insights/src/alerts/ProjectGrowthAlert.tsx index 67eb1b5071..088e85939d 100644 --- a/plugins/cost-insights/src/alerts/ProjectGrowthAlert.tsx +++ b/plugins/cost-insights/src/alerts/ProjectGrowthAlert.tsx @@ -27,18 +27,22 @@ import { Alert, ProjectGrowthData } from '../types'; export class ProjectGrowthAlert implements Alert { data: ProjectGrowthData; - url = '/cost-insights/investigating-growth'; - subtitle = - 'Cost growth outpacing business growth is unsustainable long-term.'; - constructor(data: ProjectGrowthData) { this.data = data; } + get url() { + return '/cost-insights/investigating-growth'; + } + get title() { return `Investigate cost growth in project ${this.data.project}`; } + get subtitle() { + return 'Cost growth outpacing business growth is unsustainable long-term.'; + } + get element() { return ; } diff --git a/plugins/cost-insights/src/alerts/UnlabeledDataflowAlert.test.tsx b/plugins/cost-insights/src/alerts/UnlabeledDataflowAlert.test.tsx new file mode 100644 index 0000000000..95e213f06a --- /dev/null +++ b/plugins/cost-insights/src/alerts/UnlabeledDataflowAlert.test.tsx @@ -0,0 +1,102 @@ +/* + * Copyright 2020 Spotify AB + * + * 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 pluralize from 'pluralize'; +import { renderInTestApp } from '@backstage/test-utils'; +import { UnlabeledDataflowAlert } from './UnlabeledDataflowAlert'; +import { UnlabeledDataflowData } from '../types'; +import { + MockCurrencyProvider, + MockConfigProvider, + MockBillingDateProvider, +} from '../utils/tests'; + +const mockData: UnlabeledDataflowData = { + periodStart: '2021-02-01', + periodEnd: '2021-03-31', + unlabeledCost: 0, + labeledCost: 0, + projects: [ + { + id: 'project-a', + labeledCost: 0, + unlabeledCost: 0, + }, + ], +}; + +// suppress recharts componentDidUpdate deprecation warnings +jest.spyOn(console, 'warn').mockImplementation(() => {}); + +async function renderInContext(children: JSX.Element) { + return renderInTestApp( + + + {children} + + , + ); +} + +class CustomUnlabeledDataflowAlert extends UnlabeledDataflowAlert { + get url() { + return 'path/to/resource'; + } + get title() { + return `Add labels to ${pluralize( + 'workflow', + this.data.projects.length, + true, + )}`; + } +} + +describe('UnlabeledDataflowAlert', () => { + describe('constructor', () => { + it('should create an unlabeled dataflow alert', async () => { + const alert = new UnlabeledDataflowAlert(mockData); + const { getByText } = await renderInContext(alert.element); + + expect(alert.url).toBe('/cost-insights/labeling-jobs'); + expect(alert.title).toBe('Add labels to workflows'); + expect(alert.subtitle).toBe( + 'Labels show in billing data, enabling cost insights for each workflow.', + ); + expect( + getByText( + 'Showing costs from 1 project with unlabeled Dataflow jobs in the last 30 days.', + ), + ).toBeInTheDocument(); + }); + + it('a subclass can inherit and override defaults using accessors', async () => { + const alert = new CustomUnlabeledDataflowAlert(mockData); + const { getByText } = await renderInContext(alert.element); + + expect(alert.url).toBe('path/to/resource'); + expect(alert.title).toBe('Add labels to 1 workflow'); + expect(alert.subtitle).toBe( + 'Labels show in billing data, enabling cost insights for each workflow.', + ); + expect( + getByText( + 'Showing costs from 1 project with unlabeled Dataflow jobs in the last 30 days.', + ), + ).toBeInTheDocument(); + }); + }); +}); diff --git a/plugins/cost-insights/src/alerts/UnlabeledDataflowAlert.tsx b/plugins/cost-insights/src/alerts/UnlabeledDataflowAlert.tsx index e889e0e3d4..7d11f3cc81 100644 --- a/plugins/cost-insights/src/alerts/UnlabeledDataflowAlert.tsx +++ b/plugins/cost-insights/src/alerts/UnlabeledDataflowAlert.tsx @@ -28,15 +28,22 @@ export class UnlabeledDataflowAlert implements Alert { data: UnlabeledDataflowData; status?: AlertStatus; - url = '/cost-insights/labeling-jobs'; - title = 'Add labels to workflows'; - subtitle = - 'Labels show in billing data, enabling cost insights for each workflow.'; - constructor(data: UnlabeledDataflowData) { this.data = data; } + get url() { + return '/cost-insights/labeling-jobs'; + } + + get title() { + return 'Add labels to workflows'; + } + + get subtitle() { + return 'Labels show in billing data, enabling cost insights for each workflow.'; + } + get element() { return ; } diff --git a/plugins/explore/CHANGELOG.md b/plugins/explore/CHANGELOG.md index 698cf08c34..be284dfa64 100644 --- a/plugins/explore/CHANGELOG.md +++ b/plugins/explore/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-explore +## 0.2.7 + +### Patch Changes + +- 347137ccf: Display the owner of a domain on the domain card. +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + ## 0.2.6 ### Patch Changes diff --git a/plugins/explore/package.json b/plugins/explore/package.json index 697a8c67fe..5c370ecfac 100644 --- a/plugins/explore/package.json +++ b/plugins/explore/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-explore", - "version": "0.2.6", + "version": "0.2.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,9 +30,9 @@ "start": "backstage-cli plugin:serve" }, "dependencies": { - "@backstage/catalog-model": "^0.7.1", - "@backstage/core": "^0.6.2", - "@backstage/plugin-catalog-react": "^0.0.4", + "@backstage/catalog-model": "^0.7.2", + "@backstage/core": "^0.6.3", + "@backstage/plugin-catalog-react": "^0.1.0", "@backstage/plugin-explore-react": "^0.0.2", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", @@ -45,9 +45,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/fossa/CHANGELOG.md b/plugins/fossa/CHANGELOG.md index ebbfef0ff3..23129f83f9 100644 --- a/plugins/fossa/CHANGELOG.md +++ b/plugins/fossa/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-fossa +## 0.2.3 + +### Patch Changes + +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + ## 0.2.2 ### Patch Changes diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json index 6cc2c30b29..803b7ddf30 100644 --- a/plugins/fossa/package.json +++ b/plugins/fossa/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-fossa", - "version": "0.2.2", + "version": "0.2.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,9 +31,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.7.1", - "@backstage/core": "^0.6.2", - "@backstage/plugin-catalog-react": "^0.0.4", + "@backstage/catalog-model": "^0.7.2", + "@backstage/core": "^0.6.3", + "@backstage/plugin-catalog-react": "^0.1.0", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -44,9 +44,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/gcp-projects/package.json b/plugins/gcp-projects/package.json index d5b19fa239..b1f14753f2 100644 --- a/plugins/gcp-projects/package.json +++ b/plugins/gcp-projects/package.json @@ -30,7 +30,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.6.2", + "@backstage/core": "^0.6.3", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -41,9 +41,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/github-actions/CHANGELOG.md b/plugins/github-actions/CHANGELOG.md index 4dff868c42..ac717c1059 100644 --- a/plugins/github-actions/CHANGELOG.md +++ b/plugins/github-actions/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-github-actions +## 0.3.4 + +### Patch Changes + +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + ## 0.3.3 ### Patch Changes diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index 44599c8c36..eb203aaac8 100644 --- a/plugins/github-actions/package.json +++ b/plugins/github-actions/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-github-actions", - "version": "0.3.3", + "version": "0.3.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,9 +32,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.7.1", - "@backstage/plugin-catalog-react": "^0.0.4", - "@backstage/core": "^0.6.2", + "@backstage/catalog-model": "^0.7.2", + "@backstage/plugin-catalog-react": "^0.1.0", + "@backstage/core": "^0.6.3", "@backstage/integration": "^0.5.0", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", @@ -50,9 +50,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/gitops-profiles/package.json b/plugins/gitops-profiles/package.json index 415c43c598..1902bebc70 100644 --- a/plugins/gitops-profiles/package.json +++ b/plugins/gitops-profiles/package.json @@ -31,7 +31,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.6.2", + "@backstage/core": "^0.6.3", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -42,9 +42,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json index 48e87877d4..90936e7317 100644 --- a/plugins/graphiql/package.json +++ b/plugins/graphiql/package.json @@ -31,21 +31,21 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.6.2", + "@backstage/core": "^0.6.3", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", "graphiql": "^1.0.0-alpha.10", - "graphql": "15.4.0", + "graphql": "15.5.0", "react": "^16.13.1", "react-dom": "^16.13.1", "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/jenkins/CHANGELOG.md b/plugins/jenkins/CHANGELOG.md index 872b2c3146..8ba44c30f5 100644 --- a/plugins/jenkins/CHANGELOG.md +++ b/plugins/jenkins/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-jenkins +## 0.3.11 + +### Patch Changes + +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + ## 0.3.10 ### Patch Changes diff --git a/plugins/jenkins/README.md b/plugins/jenkins/README.md index 154fcf913d..13ff9b3547 100644 --- a/plugins/jenkins/README.md +++ b/plugins/jenkins/README.md @@ -50,7 +50,7 @@ metadata: name: 'your-component' description: 'a description' annotations: - jenkins.io/github-folder: 'folder-name/job-name' + jenkins.io/github-folder: 'folder-name/project-name' spec: type: service lifecycle: experimental @@ -84,5 +84,5 @@ YWRtaW46MTFlYzI1NmU0Mzg1MDFjM2Y1Yzc2Yjc1MWE3ZTQ3YWY4Mw== is the base64 of user a ## Limitations -- Only works with organization folder jobs backed by GitHub -- No pagination support currently, limited to 50 jobs - don't run this on a Jenkins with lots of builds +- Only works with organization folder projects backed by GitHub +- No pagination support currently, limited to 50 projects - don't run this on a Jenkins with lots of builds diff --git a/plugins/jenkins/package.json b/plugins/jenkins/package.json index bad68dadb5..817e6ae1a3 100644 --- a/plugins/jenkins/package.json +++ b/plugins/jenkins/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-jenkins", - "version": "0.3.10", + "version": "0.3.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,9 +31,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.7.1", - "@backstage/core": "^0.6.2", - "@backstage/plugin-catalog-react": "^0.0.4", + "@backstage/catalog-model": "^0.7.2", + "@backstage/core": "^0.6.3", + "@backstage/plugin-catalog-react": "^0.1.0", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -47,9 +47,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/jenkins/src/assets/JenkinsLogo.svg b/plugins/jenkins/src/assets/JenkinsLogo.svg new file mode 100644 index 0000000000..4a4538daf6 --- /dev/null +++ b/plugins/jenkins/src/assets/JenkinsLogo.svg @@ -0,0 +1,283 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/plugins/jenkins/src/components/BuildWithStepsPage/BuildWithStepsPage.tsx b/plugins/jenkins/src/components/BuildWithStepsPage/BuildWithStepsPage.tsx index d8f728bb27..5d9d81c985 100644 --- a/plugins/jenkins/src/components/BuildWithStepsPage/BuildWithStepsPage.tsx +++ b/plugins/jenkins/src/components/BuildWithStepsPage/BuildWithStepsPage.tsx @@ -15,10 +15,10 @@ */ import React from 'react'; import { useParams } from 'react-router-dom'; -import { Content, Link } from '@backstage/core'; +import { Breadcrumbs, Content, Link } from '@backstage/core'; import { + Box, Typography, - Breadcrumbs, Paper, TableContainer, Table, @@ -36,7 +36,6 @@ import ExternalLinkIcon from '@material-ui/icons/Launch'; const useStyles = makeStyles(theme => ({ root: { maxWidth: 720, - margin: theme.spacing(2), }, table: { padding: theme.spacing(1), @@ -57,9 +56,10 @@ const BuildWithStepsView = () => { return (
- Jobs + Projects Run + diff --git a/plugins/jenkins/src/components/BuildsPage/lib/CITable/CITable.tsx b/plugins/jenkins/src/components/BuildsPage/lib/CITable/CITable.tsx index 2d8f43ca80..3044094ccc 100644 --- a/plugins/jenkins/src/components/BuildsPage/lib/CITable/CITable.tsx +++ b/plugins/jenkins/src/components/BuildsPage/lib/CITable/CITable.tsx @@ -16,7 +16,7 @@ import React from 'react'; import { Box, IconButton, Link, Typography, Tooltip } from '@material-ui/core'; import RetryIcon from '@material-ui/icons/Replay'; -import GitHubIcon from '@material-ui/icons/GitHub'; +import JenkinsLogo from '../../../../assets/JenkinsLogo.svg'; import { generatePath, Link as RouterLink } from 'react-router-dom'; import { Table, TableColumn } from '@backstage/core'; import { JenkinsRunStatus } from '../Status'; @@ -231,9 +231,9 @@ export const CITableView = ({ onChangeRowsPerPage={onChangePageSize} title={ - - - {projectName} + Jenkins logo + + Project: {projectName} } columns={generatedColumns} diff --git a/plugins/kafka/CHANGELOG.md b/plugins/kafka/CHANGELOG.md index 7972091b84..a8153002c9 100644 --- a/plugins/kafka/CHANGELOG.md +++ b/plugins/kafka/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-kafka +## 0.2.4 + +### Patch Changes + +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + ## 0.2.3 ### Patch Changes diff --git a/plugins/kafka/package.json b/plugins/kafka/package.json index df8581751e..5c8dc9e934 100644 --- a/plugins/kafka/package.json +++ b/plugins/kafka/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kafka", - "version": "0.2.3", + "version": "0.2.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -20,9 +20,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.7.1", - "@backstage/core": "^0.6.2", - "@backstage/plugin-catalog-react": "^0.0.4", + "@backstage/catalog-model": "^0.7.2", + "@backstage/core": "^0.6.3", + "@backstage/plugin-catalog-react": "^0.1.0", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -33,9 +33,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/react-hooks": "^3.4.2", diff --git a/plugins/kubernetes-backend/CHANGELOG.md b/plugins/kubernetes-backend/CHANGELOG.md index 08a3a66657..e02c3e14a0 100644 --- a/plugins/kubernetes-backend/CHANGELOG.md +++ b/plugins/kubernetes-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-kubernetes-backend +## 0.2.7 + +### Patch Changes + +- a70af22a2: update kubernetes plugin backend function to use classes +- Updated dependencies [bad21a085] +- Updated dependencies [a1f5e6545] + - @backstage/catalog-model@0.7.2 + - @backstage/config@0.1.3 + ## 0.2.6 ### Patch Changes diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index 3823ee1899..9d5a0c25e0 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-backend", - "version": "0.2.6", + "version": "0.2.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,8 +33,8 @@ "dependencies": { "@aws-sdk/credential-provider-node": "^3.3.0", "@backstage/backend-common": "^0.5.2", - "@backstage/catalog-model": "^0.7.1", - "@backstage/config": "^0.1.2", + "@backstage/catalog-model": "^0.7.2", + "@backstage/config": "^0.1.3", "@kubernetes/client-node": "^0.13.2", "@types/express": "^4.17.6", "aws4": "^1.11.0", @@ -51,7 +51,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.6.0", + "@backstage/cli": "^0.6.2", "@types/aws4": "^1.5.1", "supertest": "^4.0.2" }, diff --git a/plugins/kubernetes-backend/src/service/getKubernetesObjectsByServiceIdHandler.test.ts b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts similarity index 73% rename from plugins/kubernetes-backend/src/service/getKubernetesObjectsByServiceIdHandler.test.ts rename to plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts index 5c6513e57c..95ec4f0aba 100644 --- a/plugins/kubernetes-backend/src/service/getKubernetesObjectsByServiceIdHandler.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts @@ -14,11 +14,9 @@ * limitations under the License. */ -import { handleGetKubernetesObjectsForService } from './getKubernetesObjectsForServiceHandler'; import { getVoidLogger } from '@backstage/backend-common'; import { ObjectFetchParams } from '..'; - -const TEST_SERVICE_ID = 'my-service'; +import { KubernetesFanOutHandler } from './KubernetesFanOutHandler'; const fetchObjectsForService = jest.fn(); @@ -81,34 +79,34 @@ describe('handleGetKubernetesObjectsForService', () => { mockFetch(fetchObjectsForService); - const result = await handleGetKubernetesObjectsForService( - TEST_SERVICE_ID, + const sut = new KubernetesFanOutHandler( + getVoidLogger(), { - fetchObjectsForService: fetchObjectsForService, + fetchObjectsForService, }, { getClustersByServiceId, }, - getVoidLogger(), - { - entity: { - apiVersion: 'backstage.io/v1beta1', - kind: 'Component', - metadata: { - name: 'test-component', - annotations: { - 'backstage.io/kubernetes-labels-selector': - 'backstage.io/test-label=test-component', - }, - }, - spec: { - type: 'service', - lifecycle: 'production', - owner: 'joe', + ); + + const result = await sut.getKubernetesObjectsByEntity({ + entity: { + apiVersion: 'backstage.io/v1beta1', + kind: 'Component', + metadata: { + name: 'test-component', + annotations: { + 'backstage.io/kubernetes-labels-selector': + 'backstage.io/test-label=test-component', }, }, + spec: { + type: 'service', + lifecycle: 'production', + owner: 'joe', + }, }, - ); + }); expect(getClustersByServiceId.mock.calls.length).toBe(1); expect(fetchObjectsForService.mock.calls.length).toBe(1); @@ -124,7 +122,7 @@ describe('handleGetKubernetesObjectsForService', () => { resources: [ { metadata: { - name: 'my-pods-my-service-test-cluster', + name: 'my-pods-test-component-test-cluster', }, }, ], @@ -134,7 +132,7 @@ describe('handleGetKubernetesObjectsForService', () => { resources: [ { metadata: { - name: 'my-configmaps-my-service-test-cluster', + name: 'my-configmaps-test-component-test-cluster', }, }, ], @@ -144,7 +142,7 @@ describe('handleGetKubernetesObjectsForService', () => { resources: [ { metadata: { - name: 'my-services-my-service-test-cluster', + name: 'my-services-test-component-test-cluster', }, }, ], @@ -172,37 +170,37 @@ describe('handleGetKubernetesObjectsForService', () => { mockFetch(fetchObjectsForService); - const result = await handleGetKubernetesObjectsForService( - TEST_SERVICE_ID, + const sut = new KubernetesFanOutHandler( + getVoidLogger(), { - fetchObjectsForService: fetchObjectsForService, + fetchObjectsForService, }, { getClustersByServiceId, }, - getVoidLogger(), - { - auth: { - google: 'google_token_123', + ); + + const result = await sut.getKubernetesObjectsByEntity({ + auth: { + google: 'google_token_123', + }, + entity: { + apiVersion: 'backstage.io/v1beta1', + kind: 'Component', + metadata: { + name: 'test-component', + annotations: { + 'backstage.io/kubernetes-labels-selector': + 'backstage.io/test-label=test-component', + }, }, - entity: { - apiVersion: 'backstage.io/v1beta1', - kind: 'Component', - metadata: { - name: 'test-component', - annotations: { - 'backstage.io/kubernetes-labels-selector': - 'backstage.io/test-label=test-component', - }, - }, - spec: { - type: 'service', - lifecycle: 'production', - owner: 'joe', - }, + spec: { + type: 'service', + lifecycle: 'production', + owner: 'joe', }, }, - ); + }); expect(getClustersByServiceId.mock.calls.length).toBe(1); expect(fetchObjectsForService.mock.calls.length).toBe(2); @@ -218,7 +216,7 @@ describe('handleGetKubernetesObjectsForService', () => { resources: [ { metadata: { - name: 'my-pods-my-service-test-cluster', + name: 'my-pods-test-component-test-cluster', }, }, ], @@ -228,7 +226,7 @@ describe('handleGetKubernetesObjectsForService', () => { resources: [ { metadata: { - name: 'my-configmaps-my-service-test-cluster', + name: 'my-configmaps-test-component-test-cluster', }, }, ], @@ -238,7 +236,7 @@ describe('handleGetKubernetesObjectsForService', () => { resources: [ { metadata: { - name: 'my-services-my-service-test-cluster', + name: 'my-services-test-component-test-cluster', }, }, ], @@ -256,7 +254,7 @@ describe('handleGetKubernetesObjectsForService', () => { resources: [ { metadata: { - name: 'my-pods-my-service-other-cluster', + name: 'my-pods-test-component-other-cluster', }, }, ], @@ -266,7 +264,7 @@ describe('handleGetKubernetesObjectsForService', () => { resources: [ { metadata: { - name: 'my-configmaps-my-service-other-cluster', + name: 'my-configmaps-test-component-other-cluster', }, }, ], @@ -276,7 +274,7 @@ describe('handleGetKubernetesObjectsForService', () => { resources: [ { metadata: { - name: 'my-services-my-service-other-cluster', + name: 'my-services-test-component-other-cluster', }, }, ], diff --git a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts new file mode 100644 index 0000000000..0a2fc1488a --- /dev/null +++ b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts @@ -0,0 +1,109 @@ +/* + * Copyright 2021 Spotify AB + * + * 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 { Logger } from 'winston'; +import { + ClusterDetails, + KubernetesFetcher, + KubernetesObjectTypes, + KubernetesRequestBody, + KubernetesServiceLocator, +} from '../types/types'; +import { KubernetesAuthTranslator } from '../kubernetes-auth-translator/types'; +import { KubernetesAuthTranslatorGenerator } from '../kubernetes-auth-translator/KubernetesAuthTranslatorGenerator'; + +const DEFAULT_OBJECTS = new Set([ + 'pods', + 'services', + 'configmaps', + 'deployments', + 'replicasets', + 'horizontalpodautoscalers', + 'ingresses', +]); + +export class KubernetesFanOutHandler { + private readonly logger: Logger; + private readonly fetcher: KubernetesFetcher; + private readonly serviceLocator: KubernetesServiceLocator; + + constructor( + logger: Logger, + fetcher: KubernetesFetcher, + serviceLocator: KubernetesServiceLocator, + ) { + this.logger = logger; + this.fetcher = fetcher; + this.serviceLocator = serviceLocator; + } + + async getKubernetesObjectsByEntity( + requestBody: KubernetesRequestBody, + objectTypesToFetch: Set = DEFAULT_OBJECTS, + ) { + const entityName = requestBody.entity.metadata.name; + + const clusterDetails: ClusterDetails[] = await this.serviceLocator.getClustersByServiceId( + entityName, + ); + + // Execute all of these async actions simultaneously/without blocking sequentially as no common object is modified by them + const promises: Promise[] = clusterDetails.map(cd => { + const kubernetesAuthTranslator: KubernetesAuthTranslator = KubernetesAuthTranslatorGenerator.getKubernetesAuthTranslatorInstance( + cd.authProvider, + ); + return kubernetesAuthTranslator.decorateClusterDetailsWithAuth( + cd, + requestBody, + ); + }); + const clusterDetailsDecoratedForAuth: ClusterDetails[] = await Promise.all( + promises, + ); + + this.logger.info( + `entity.metadata.name=${entityName} clusterDetails=[${clusterDetailsDecoratedForAuth + .map(c => c.name) + .join(', ')}]`, + ); + + const labelSelector: string = + requestBody.entity?.metadata?.annotations?.[ + 'backstage.io/kubernetes-label-selector' + ] || `backstage.io/kubernetes-id=${entityName}`; + + return Promise.all( + clusterDetailsDecoratedForAuth.map(clusterDetailsItem => { + return this.fetcher + .fetchObjectsForService({ + serviceId: entityName, + clusterDetails: clusterDetailsItem, + objectTypesToFetch, + labelSelector, + }) + .then(result => { + return { + cluster: { + name: clusterDetailsItem.name, + }, + resources: result.responses, + errors: result.errors, + }; + }); + }), + ).then(r => ({ items: r })); + } +} diff --git a/plugins/kubernetes-backend/src/service/getKubernetesObjectsForServiceHandler.ts b/plugins/kubernetes-backend/src/service/getKubernetesObjectsForServiceHandler.ts deleted file mode 100644 index 811a3c8acb..0000000000 --- a/plugins/kubernetes-backend/src/service/getKubernetesObjectsForServiceHandler.ts +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * 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 { Logger } from 'winston'; -import { - KubernetesRequestBody, - ClusterDetails, - KubernetesServiceLocator, - KubernetesFetcher, - KubernetesObjectTypes, - ObjectsByEntityResponse, - ObjectFetchParams, -} from '../types/types'; -import { KubernetesAuthTranslator } from '../kubernetes-auth-translator/types'; -import { KubernetesAuthTranslatorGenerator } from '../kubernetes-auth-translator/KubernetesAuthTranslatorGenerator'; - -export type GetKubernetesObjectsForServiceHandler = ( - serviceId: string, - fetcher: KubernetesFetcher, - serviceLocator: KubernetesServiceLocator, - logger: Logger, - requestBody: KubernetesRequestBody, - objectTypesToFetch?: Set, -) => Promise; - -const DEFAULT_OBJECTS = new Set([ - 'pods', - 'services', - 'configmaps', - 'deployments', - 'replicasets', - 'horizontalpodautoscalers', - 'ingresses', -]); - -// Fans out the request to all clusters that the service lives in, aggregates their responses together -export const handleGetKubernetesObjectsForService: GetKubernetesObjectsForServiceHandler = async ( - serviceId, - fetcher, - serviceLocator, - logger, - requestBody, - objectTypesToFetch = DEFAULT_OBJECTS, -) => { - const clusterDetails: ClusterDetails[] = await serviceLocator.getClustersByServiceId( - serviceId, - ); - - // Execute all of these async actions simultaneously/without blocking sequentially as no common object is modified by them - const promises: Promise[] = clusterDetails.map(cd => { - const kubernetesAuthTranslator: KubernetesAuthTranslator = KubernetesAuthTranslatorGenerator.getKubernetesAuthTranslatorInstance( - cd.authProvider, - ); - return kubernetesAuthTranslator.decorateClusterDetailsWithAuth( - cd, - requestBody, - ); - }); - const clusterDetailsDecoratedForAuth: ClusterDetails[] = await Promise.all( - promises, - ); - - logger.info( - `serviceId=${serviceId} clusterDetails=[${clusterDetailsDecoratedForAuth - .map(c => c.name) - .join(', ')}]`, - ); - - const labelSelector: string = - requestBody.entity?.metadata?.annotations?.[ - 'backstage.io/kubernetes-label-selector' - ] || `backstage.io/kubernetes-id=${requestBody.entity.metadata.name}`; - - return Promise.all( - clusterDetailsDecoratedForAuth.map(clusterDetailsItem => { - return fetcher - .fetchObjectsForService({ - serviceId, - clusterDetails: clusterDetailsItem, - objectTypesToFetch, - labelSelector, - } as ObjectFetchParams) - .then(result => { - return { - cluster: { - name: clusterDetailsItem.name, - }, - resources: result.responses, - errors: result.errors, - }; - }); - }), - ).then(r => ({ items: r })); -}; diff --git a/plugins/kubernetes-backend/src/service/router.test.ts b/plugins/kubernetes-backend/src/service/router.test.ts index a407ce9693..c91cae27df 100644 --- a/plugins/kubernetes-backend/src/service/router.test.ts +++ b/plugins/kubernetes-backend/src/service/router.test.ts @@ -18,35 +18,18 @@ import { getVoidLogger } from '@backstage/backend-common'; import express from 'express'; import request from 'supertest'; import { makeRouter } from './router'; -import { - KubernetesServiceLocator, - KubernetesFetcher, - ObjectsByEntityResponse, -} from '..'; +import { KubernetesFanOutHandler } from './KubernetesFanOutHandler'; describe('router', () => { let app: express.Express; - let kubernetesFetcher: jest.Mocked; - let kubernetesServiceLocator: jest.Mocked; - let handleGetByServiceId: jest.Mock>; + let kubernetesFanOutHandler: jest.Mocked; beforeAll(async () => { - kubernetesFetcher = { - fetchObjectsForService: jest.fn(), - }; + kubernetesFanOutHandler = { + getKubernetesObjectsByEntity: jest.fn(), + } as any; - kubernetesServiceLocator = { - getClustersByServiceId: jest.fn(), - }; - - handleGetByServiceId = jest.fn(); - - const router = makeRouter( - getVoidLogger(), - kubernetesFetcher, - kubernetesServiceLocator, - handleGetByServiceId as any, - ); + const router = makeRouter(getVoidLogger(), kubernetesFanOutHandler); app = express().use(router); }); @@ -67,7 +50,9 @@ describe('router', () => { ], }, } as any; - handleGetByServiceId.mockReturnValueOnce(Promise.resolve(result)); + kubernetesFanOutHandler.getKubernetesObjectsByEntity.mockReturnValueOnce( + Promise.resolve(result), + ); const response = await request(app).post('/services/test-service'); @@ -87,7 +72,9 @@ describe('router', () => { ], }, } as any; - handleGetByServiceId.mockReturnValueOnce(Promise.resolve(result)); + kubernetesFanOutHandler.getKubernetesObjectsByEntity.mockReturnValueOnce( + Promise.resolve(result), + ); const response = await request(app) .post('/services/test-service') @@ -103,7 +90,9 @@ describe('router', () => { }); it('internal error: lists kubernetes objects', async () => { - handleGetByServiceId.mockRejectedValue(Error('some internal error')); + kubernetesFanOutHandler.getKubernetesObjectsByEntity.mockRejectedValue( + Error('some internal error'), + ); const response = await request(app).post('/services/test-service'); diff --git a/plugins/kubernetes-backend/src/service/router.ts b/plugins/kubernetes-backend/src/service/router.ts index 38a02ad970..32b6dfb832 100644 --- a/plugins/kubernetes-backend/src/service/router.ts +++ b/plugins/kubernetes-backend/src/service/router.ts @@ -21,19 +21,15 @@ import { Config } from '@backstage/config'; import { MultiTenantServiceLocator } from '../service-locator/MultiTenantServiceLocator'; import { KubernetesClientBasedFetcher } from './KubernetesFetcher'; import { KubernetesClientProvider } from './KubernetesClientProvider'; -import { - GetKubernetesObjectsForServiceHandler, - handleGetKubernetesObjectsForService, -} from './getKubernetesObjectsForServiceHandler'; import { KubernetesRequestBody, KubernetesServiceLocator, - KubernetesFetcher, ServiceLocatorMethod, ClusterLocatorMethod, ClusterDetails, } from '..'; import { getCombinedClusterDetails } from '../cluster-locator'; +import { KubernetesFanOutHandler } from './KubernetesFanOutHandler'; export interface RouterOptions { logger: Logger; @@ -62,9 +58,7 @@ const getServiceLocator = ( export const makeRouter = ( logger: Logger, - fetcher: KubernetesFetcher, - serviceLocator: KubernetesServiceLocator, - handleGetByEntity: GetKubernetesObjectsForServiceHandler, + kubernetesFanOutHandler: KubernetesFanOutHandler, ): express.Router => { const router = Router(); router.use(express.json()); @@ -73,11 +67,7 @@ export const makeRouter = ( const serviceId = req.params.serviceId; const requestBody: KubernetesRequestBody = req.body; try { - const response = await handleGetByEntity( - serviceId, - fetcher, - serviceLocator, - logger, + const response = await kubernetesFanOutHandler.getKubernetesObjectsByEntity( requestBody, ); res.send(response); @@ -115,10 +105,11 @@ export async function createRouter( const serviceLocator = getServiceLocator(options.config, clusterDetails); - return makeRouter( + const kubernetesFanOutHandler = new KubernetesFanOutHandler( logger, fetcher, serviceLocator, - handleGetKubernetesObjectsForService, ); + + return makeRouter(logger, kubernetesFanOutHandler); } diff --git a/plugins/kubernetes/CHANGELOG.md b/plugins/kubernetes/CHANGELOG.md index 4be7017d35..75df5943dd 100644 --- a/plugins/kubernetes/CHANGELOG.md +++ b/plugins/kubernetes/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-kubernetes +## 0.3.11 + +### Patch Changes + +- Updated dependencies [a70af22a2] +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [a1f5e6545] +- Updated dependencies [2c1f2a7c2] + - @backstage/plugin-kubernetes-backend@0.2.7 + - @backstage/core@0.6.3 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + - @backstage/config@0.1.3 + ## 0.3.10 ### Patch Changes diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index e06d53989c..d38b56653f 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes", - "version": "0.3.10", + "version": "0.3.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,11 +31,11 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.7.1", - "@backstage/plugin-catalog-react": "^0.0.4", - "@backstage/config": "^0.1.2", - "@backstage/core": "^0.6.2", - "@backstage/plugin-kubernetes-backend": "^0.2.6", + "@backstage/catalog-model": "^0.7.2", + "@backstage/plugin-catalog-react": "^0.1.0", + "@backstage/config": "^0.1.3", + "@backstage/core": "^0.6.3", + "@backstage/plugin-kubernetes-backend": "^0.2.7", "@backstage/theme": "^0.2.3", "@kubernetes/client-node": "^0.13.2", "@material-ui/core": "^4.11.0", @@ -48,9 +48,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/lighthouse/CHANGELOG.md b/plugins/lighthouse/CHANGELOG.md index e4697a66d7..20b1a5c1e1 100644 --- a/plugins/lighthouse/CHANGELOG.md +++ b/plugins/lighthouse/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-lighthouse +## 0.2.12 + +### Patch Changes + +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [a1f5e6545] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + - @backstage/config@0.1.3 + ## 0.2.11 ### Patch Changes diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json index 899c173616..a8f231cc1b 100644 --- a/plugins/lighthouse/package.json +++ b/plugins/lighthouse/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-lighthouse", - "version": "0.2.11", + "version": "0.2.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,10 +31,10 @@ "start": "backstage-cli plugin:serve" }, "dependencies": { - "@backstage/catalog-model": "^0.7.1", - "@backstage/config": "^0.1.2", - "@backstage/core": "^0.6.2", - "@backstage/plugin-catalog-react": "^0.0.4", + "@backstage/catalog-model": "^0.7.2", + "@backstage/config": "^0.1.3", + "@backstage/core": "^0.6.3", + "@backstage/plugin-catalog-react": "^0.1.0", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -46,9 +46,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/newrelic/package.json b/plugins/newrelic/package.json index daf48cb1bb..d5aeaa0e5e 100644 --- a/plugins/newrelic/package.json +++ b/plugins/newrelic/package.json @@ -31,7 +31,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.6.2", + "@backstage/core": "^0.6.3", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -41,9 +41,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/org/CHANGELOG.md b/plugins/org/CHANGELOG.md index 9347ca7ca1..474d44a735 100644 --- a/plugins/org/CHANGELOG.md +++ b/plugins/org/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-org +## 0.3.8 + +### Patch Changes + +- e3bc5aad7: Use the `pageTheme` to colour the OwnershipCard boxes with their respective theme colours. +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [b6c4f485d] +- Updated dependencies [3a58084b6] +- Updated dependencies [2c1f2a7c2] + - @backstage/core-api@0.2.11 + - @backstage/core@0.6.3 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + ## 0.3.7 ### Patch Changes diff --git a/plugins/org/package.json b/plugins/org/package.json index 2d114a9184..a9b5661c2e 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-org", - "version": "0.3.7", + "version": "0.3.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -20,10 +20,10 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.7.1", - "@backstage/core": "^0.6.2", - "@backstage/core-api": "^0.2.10", - "@backstage/plugin-catalog-react": "^0.0.4", + "@backstage/catalog-model": "^0.7.2", + "@backstage/core": "^0.6.3", + "@backstage/core-api": "^0.2.11", + "@backstage/plugin-catalog-react": "^0.1.0", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -35,9 +35,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/pagerduty/CHANGELOG.md b/plugins/pagerduty/CHANGELOG.md index ec4bda11ea..85547d08c7 100644 --- a/plugins/pagerduty/CHANGELOG.md +++ b/plugins/pagerduty/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-pagerduty +## 0.3.1 + +### Patch Changes + +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + ## 0.3.0 ### Minor Changes diff --git a/plugins/pagerduty/package.json b/plugins/pagerduty/package.json index a03462df7d..3e10be41ea 100644 --- a/plugins/pagerduty/package.json +++ b/plugins/pagerduty/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-pagerduty", - "version": "0.3.0", + "version": "0.3.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,9 +30,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.7.1", - "@backstage/core": "^0.6.2", - "@backstage/plugin-catalog-react": "^0.0.4", + "@backstage/catalog-model": "^0.7.2", + "@backstage/core": "^0.6.3", + "@backstage/plugin-catalog-react": "^0.1.0", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -46,9 +46,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/register-component/CHANGELOG.md b/plugins/register-component/CHANGELOG.md index e1786c95c7..c37820a2c7 100644 --- a/plugins/register-component/CHANGELOG.md +++ b/plugins/register-component/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-register-component +## 0.2.11 + +### Patch Changes + +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + ## 0.2.10 ### Patch Changes diff --git a/plugins/register-component/package.json b/plugins/register-component/package.json index 78a8323fdc..92ea4f0f6d 100644 --- a/plugins/register-component/package.json +++ b/plugins/register-component/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-register-component", - "version": "0.2.10", + "version": "0.2.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,9 +30,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.7.1", - "@backstage/core": "^0.6.2", - "@backstage/plugin-catalog-react": "^0.0.4", + "@backstage/catalog-model": "^0.7.2", + "@backstage/core": "^0.6.3", + "@backstage/plugin-catalog-react": "^0.1.0", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -45,9 +45,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/rollbar/CHANGELOG.md b/plugins/rollbar/CHANGELOG.md index a9a28b4e95..32995efab8 100644 --- a/plugins/rollbar/CHANGELOG.md +++ b/plugins/rollbar/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-rollbar +## 0.3.2 + +### Patch Changes + +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + ## 0.3.1 ### Patch Changes diff --git a/plugins/rollbar/package.json b/plugins/rollbar/package.json index ba8947850e..1ce8007683 100644 --- a/plugins/rollbar/package.json +++ b/plugins/rollbar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-rollbar", - "version": "0.3.1", + "version": "0.3.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,9 +31,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.7.1", - "@backstage/core": "^0.6.2", - "@backstage/plugin-catalog-react": "^0.0.4", + "@backstage/catalog-model": "^0.7.2", + "@backstage/core": "^0.6.3", + "@backstage/plugin-catalog-react": "^0.1.0", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -47,9 +47,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/react-hooks": "^3.3.0", diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md index 2e56afc8c8..e7e3b0d718 100644 --- a/plugins/scaffolder-backend/CHANGELOG.md +++ b/plugins/scaffolder-backend/CHANGELOG.md @@ -1,5 +1,65 @@ # @backstage/plugin-scaffolder-backend +## 0.8.0 + +### Minor Changes + +- a5f42cf66: # Stateless scaffolding + + The scaffolder has been redesigned to be horizontally scalable and to persistently store task state and execution logs in the database. + + Each scaffolder task is given a unique task ID which is persisted in the database. + Tasks are then picked up by a `TaskWorker` which performs the scaffolding steps. + Execution logs are also persisted in the database meaning you can now refresh the scaffolder task status page without losing information. + + The task status page is now dynamically created based on the step information stored in the database. + This allows for custom steps to be displayed once the next version of the scaffolder template schema is available. + + The task page is updated to display links to both the git repository and to the newly created catalog entity. + + Component registration has moved from the frontend into a separate registration step executed by the `TaskWorker`. This requires that a `CatalogClient` is passed to the scaffolder backend instead of the old `CatalogEntityClient`. + + Make sure to update `plugins/scaffolder.ts` + + ```diff + import { + CookieCutter, + createRouter, + Preparers, + Publishers, + CreateReactAppTemplater, + Templaters, + - CatalogEntityClient, + } from '@backstage/plugin-scaffolder-backend'; + + +import { CatalogClient } from '@backstage/catalog-client'; + + const discovery = SingleHostDiscovery.fromConfig(config); + -const entityClient = new CatalogEntityClient({ discovery }); + +const catalogClient = new CatalogClient({ discoveryApi: discovery }) + + return await createRouter({ + preparers, + templaters, + publishers, + logger, + config, + dockerClient, + - entityClient, + database, + + catalogClient, + }); + ``` + + As well as adding the `@backstage/catalog-client` packages as a dependency of your backend package. + +### Patch Changes + +- Updated dependencies [bad21a085] +- Updated dependencies [a1f5e6545] + - @backstage/catalog-model@0.7.2 + - @backstage/config@0.1.3 + ## 0.7.1 ### Patch Changes diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 24636ce20e..4d9d5f5404 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend", - "version": "0.7.1", + "version": "0.8.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,8 +31,8 @@ "dependencies": { "@backstage/backend-common": "^0.5.4", "@backstage/catalog-client": "^0.3.6", - "@backstage/catalog-model": "^0.7.1", - "@backstage/config": "^0.1.2", + "@backstage/catalog-model": "^0.7.2", + "@backstage/config": "^0.1.3", "@backstage/integration": "^0.5.0", "@gitbeaker/core": "^28.0.2", "@gitbeaker/node": "^28.0.2", @@ -63,8 +63,8 @@ "yaml": "^1.10.0" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/test-utils": "^0.1.8", "@types/fs-extra": "^9.0.1", "@types/mock-fs": "^4.13.0", "@types/supertest": "^2.0.8", diff --git a/plugins/scaffolder/CHANGELOG.md b/plugins/scaffolder/CHANGELOG.md index 34b042b3a9..5d5523f821 100644 --- a/plugins/scaffolder/CHANGELOG.md +++ b/plugins/scaffolder/CHANGELOG.md @@ -1,5 +1,117 @@ # @backstage/plugin-scaffolder +## 0.6.0 + +### Minor Changes + +- a5f42cf66: The Scaffolder and Catalog plugins have been migrated to partially require use of the [new composability API](https://backstage.io/docs/plugins/composability). The Scaffolder used to register its pages using the deprecated route registration plugin API, but those registrations have been removed. This means you now need to add the Scaffolder plugin page to the app directly. + + The page is imported from the Scaffolder plugin and added to the `` component: + + ```tsx + } /> + ``` + + The Catalog plugin has also been migrated to use an [external route reference](https://backstage.io/docs/plugins/composability#binding-external-routes-in-the-app) to dynamically link to the create component page. This means you need to migrate the catalog plugin to use the new extension components, as well as bind the external route. + + To use the new extension components, replace existing usage of the `CatalogRouter` with the following: + + ```tsx + } /> + }> + + + ``` + + And to bind the external route from the catalog plugin to the scaffolder template index page, make sure you have the appropriate imports and add the following to the `createApp` call: + + ```ts + import { catalogPlugin } from '@backstage/plugin-catalog'; + import { scaffolderPlugin } from '@backstage/plugin-scaffolder'; + + const app = createApp({ + // ... + bindRoutes({ bind }) { + bind(catalogPlugin.externalRoutes, { + createComponent: scaffolderPlugin.routes.root, + }); + }, + }); + ``` + +- d0760ecdf: Moved common useStarredEntities hook to plugin-catalog-react +- e8e35fb5f: Adding Search and Filter features to Scaffolder/Templates Grid + +### Patch Changes + +- a5f42cf66: # Stateless scaffolding + + The scaffolder has been redesigned to be horizontally scalable and to persistently store task state and execution logs in the database. + + Each scaffolder task is given a unique task ID which is persisted in the database. + Tasks are then picked up by a `TaskWorker` which performs the scaffolding steps. + Execution logs are also persisted in the database meaning you can now refresh the scaffolder task status page without losing information. + + The task status page is now dynamically created based on the step information stored in the database. + This allows for custom steps to be displayed once the next version of the scaffolder template schema is available. + + The task page is updated to display links to both the git repository and to the newly created catalog entity. + + Component registration has moved from the frontend into a separate registration step executed by the `TaskWorker`. This requires that a `CatalogClient` is passed to the scaffolder backend instead of the old `CatalogEntityClient`. + + Make sure to update `plugins/scaffolder.ts` + + ```diff + import { + CookieCutter, + createRouter, + Preparers, + Publishers, + CreateReactAppTemplater, + Templaters, + - CatalogEntityClient, + } from '@backstage/plugin-scaffolder-backend'; + + +import { CatalogClient } from '@backstage/catalog-client'; + + const discovery = SingleHostDiscovery.fromConfig(config); + -const entityClient = new CatalogEntityClient({ discovery }); + +const catalogClient = new CatalogClient({ discoveryApi: discovery }) + + return await createRouter({ + preparers, + templaters, + publishers, + logger, + config, + dockerClient, + - entityClient, + database, + + catalogClient, + }); + ``` + + As well as adding the `@backstage/catalog-client` packages as a dependency of your backend package. + +- e488f0502: Update messages that process during loading, error, and no templates found. + Remove unused dependencies. +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [a1f5e6545] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + - @backstage/config@0.1.3 + ## 0.5.1 ### Patch Changes diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 2018887013..7b288a25f1 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder", - "version": "0.5.1", + "version": "0.6.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,10 +31,10 @@ }, "dependencies": { "@backstage/catalog-client": "^0.3.6", - "@backstage/catalog-model": "^0.7.1", - "@backstage/config": "^0.1.2", - "@backstage/core": "^0.6.2", - "@backstage/plugin-catalog-react": "^0.0.4", + "@backstage/catalog-model": "^0.7.2", + "@backstage/config": "^0.1.3", + "@backstage/core": "^0.6.3", + "@backstage/plugin-catalog-react": "^0.1.0", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -56,9 +56,9 @@ "zen-observable": "^0.8.15" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/scaffolder/src/components/ResultsFilter/ResultsFilter.tsx b/plugins/scaffolder/src/components/ResultsFilter/ResultsFilter.tsx index 19c88a87f7..301c6b01d8 100644 --- a/plugins/scaffolder/src/components/ResultsFilter/ResultsFilter.tsx +++ b/plugins/scaffolder/src/components/ResultsFilter/ResultsFilter.tsx @@ -25,7 +25,7 @@ import { Theme, Typography, } from '@material-ui/core'; -import React, { useCallback, useContext, useState } from 'react'; +import React, { useContext } from 'react'; import { filterGroupsContext } from '../../filter/context'; const useStyles = makeStyles(theme => ({ @@ -59,20 +59,12 @@ type Props = { export const ResultsFilter = ({ availableCategories }: Props) => { const classes = useStyles(); - const [selectedCategories, setSelectedCategories] = useState([]); const context = useContext(filterGroupsContext); if (!context) { throw new Error(`Must be used inside an EntityFilterGroupsProvider`); } - const setSelectedCatgoriesFilter = context?.setSelectedCategories; - const updateSelectedCategories = useCallback( - (categories: string[]) => { - setSelectedCategories(categories); - setSelectedCatgoriesFilter(categories); - }, - [setSelectedCategories, setSelectedCatgoriesFilter], - ); + const { selectedCategories, setSelectedCategories } = context; return ( <> @@ -80,7 +72,7 @@ export const ResultsFilter = ({ availableCategories }: Props) => { Refine Results {' '} - + @@ -95,7 +87,7 @@ export const ResultsFilter = ({ availableCategories }: Props) => { dense button onClick={() => - updateSelectedCategories( + setSelectedCategories( selectedCategories.includes(category) ? selectedCategories.filter( selectedCategory => selectedCategory !== category, diff --git a/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx b/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx index e4ebc75b2e..3f6ceb64c7 100644 --- a/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx +++ b/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx @@ -15,6 +15,7 @@ */ import React, { useEffect, useMemo, useState } from 'react'; +import { Link as RouterLink } from 'react-router-dom'; import { EntityMeta, TemplateEntityV1alpha1 } from '@backstage/catalog-model'; import { configApiRef, @@ -28,15 +29,14 @@ import { useApi, WarningPanel, } from '@backstage/core'; +import { useStarredEntities } from '@backstage/plugin-catalog-react'; import { Button, Grid, Link, makeStyles, Typography } from '@material-ui/core'; -import { Link as RouterLink } from 'react-router-dom'; +import StarIcon from '@material-ui/icons/Star'; import { EntityFilterGroupsProvider, useFilteredEntities } from '../../filter'; import { TemplateCard, TemplateCardProps } from '../TemplateCard'; import { ResultsFilter } from '../ResultsFilter/ResultsFilter'; import { ScaffolderFilter } from '../ScaffolderFilter'; import { ButtonGroup } from '../ScaffolderFilter/ScaffolderFilter'; -import StarIcon from '@material-ui/icons/Star'; -import { useStarredEntities } from '../../hooks/useStarredEntities'; import SearchToolbar from '../SearchToolbar/SearchToolbar'; const useStyles = makeStyles(theme => ({ @@ -104,7 +104,7 @@ export const ScaffolderPageContents = () => { ); const matchesQuery = (metadata: EntityMeta, query: string) => - `${metadata.title}`.toUpperCase().indexOf(query) !== -1 || + `${metadata.title}`.toUpperCase().includes(query) || metadata.tags?.join('').toUpperCase().indexOf(query) !== -1; useEffect(() => { diff --git a/plugins/scaffolder/src/filter/EntityFilterGroupsProvider.tsx b/plugins/scaffolder/src/filter/EntityFilterGroupsProvider.tsx index ba99a0294a..9e11525347 100644 --- a/plugins/scaffolder/src/filter/EntityFilterGroupsProvider.tsx +++ b/plugins/scaffolder/src/filter/EntityFilterGroupsProvider.tsx @@ -145,6 +145,7 @@ function useProvideEntityFilters(): FilterGroupsContext { setGroupSelectedFilters, setSelectedCategories, reload, + selectedCategories: selectedCategories.current, loading: !error && !entities, error, filterGroupStates, diff --git a/plugins/scaffolder/src/filter/context.ts b/plugins/scaffolder/src/filter/context.ts index f0a9d3755e..a7819be752 100644 --- a/plugins/scaffolder/src/filter/context.ts +++ b/plugins/scaffolder/src/filter/context.ts @@ -28,6 +28,7 @@ export type FilterGroupsContext = { setGroupSelectedFilters: (filterGroupId: string, filterIds: string[]) => void; setSelectedCategories: (categories: string[]) => void; reload: () => Promise; + selectedCategories: string[]; loading: boolean; error?: Error; filterGroupStates: { [filterGroupId: string]: FilterGroupStates }; diff --git a/plugins/scaffolder/src/hooks/useStarredEntities.ts b/plugins/scaffolder/src/hooks/useStarredEntities.ts deleted file mode 100644 index 7cbbbb7ce6..0000000000 --- a/plugins/scaffolder/src/hooks/useStarredEntities.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * 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 { Entity } from '@backstage/catalog-model'; -import { storageApiRef, useApi } from '@backstage/core'; -import { useCallback, useEffect, useState } from 'react'; -import { useObservable } from 'react-use'; - -const buildEntityKey = (component: Entity) => - `entity:${component.kind}:${component.metadata.namespace ?? 'default'}:${ - component.metadata.name - }`; - -export const useStarredEntities = () => { - const storageApi = useApi(storageApiRef); - const settingsStore = storageApi.forBucket('settings'); - const rawStarredEntityKeys = - settingsStore.get('starredEntities') ?? []; - - const [starredEntities, setStarredEntities] = useState( - new Set(rawStarredEntityKeys), - ); - - const observedItems = useObservable( - settingsStore.observe$('starredEntities'), - ); - - useEffect(() => { - if (observedItems?.newValue) { - const currentValue = observedItems?.newValue ?? []; - setStarredEntities(new Set(currentValue)); - } - }, [observedItems?.newValue]); - - const toggleStarredEntity = useCallback( - (entity: Entity) => { - const entityKey = buildEntityKey(entity); - if (starredEntities.has(entityKey)) { - starredEntities.delete(entityKey); - } else { - starredEntities.add(entityKey); - } - - settingsStore.set('starredEntities', Array.from(starredEntities)); - }, - [starredEntities, settingsStore], - ); - - const isStarredEntity = useCallback( - (entity: Entity) => { - const entityKey = buildEntityKey(entity); - return starredEntities.has(entityKey); - }, - [starredEntities], - ); - - return { - starredEntities, - toggleStarredEntity, - isStarredEntity, - }; -}; diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md index 887d922613..a4715a9ce1 100644 --- a/plugins/search/CHANGELOG.md +++ b/plugins/search/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-search +## 0.3.2 + +### Patch Changes + +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + ## 0.3.1 ### Patch Changes diff --git a/plugins/search/package.json b/plugins/search/package.json index e1770abfa2..0f407bc22e 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search", - "version": "0.3.1", + "version": "0.3.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,9 +29,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.6.2", - "@backstage/catalog-model": "^0.7.1", - "@backstage/plugin-catalog-react": "^0.0.4", + "@backstage/core": "^0.6.3", + "@backstage/catalog-model": "^0.7.2", + "@backstage/plugin-catalog-react": "^0.1.0", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -43,9 +43,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/sentry/CHANGELOG.md b/plugins/sentry/CHANGELOG.md index d8446686b3..2902faab77 100644 --- a/plugins/sentry/CHANGELOG.md +++ b/plugins/sentry/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-sentry +## 0.3.7 + +### Patch Changes + +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + ## 0.3.6 ### Patch Changes diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json index a3a88e1bee..f010bd3e47 100644 --- a/plugins/sentry/package.json +++ b/plugins/sentry/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-sentry", - "version": "0.3.6", + "version": "0.3.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,9 +31,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.7.1", - "@backstage/core": "^0.6.2", - "@backstage/plugin-catalog-react": "^0.0.4", + "@backstage/catalog-model": "^0.7.2", + "@backstage/core": "^0.6.3", + "@backstage/plugin-catalog-react": "^0.1.0", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -46,9 +46,9 @@ "timeago.js": "^4.0.2" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/sonarqube/CHANGELOG.md b/plugins/sonarqube/CHANGELOG.md index 85d861e5d3..677cdcbb32 100644 --- a/plugins/sonarqube/CHANGELOG.md +++ b/plugins/sonarqube/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-sonarqube +## 0.1.13 + +### Patch Changes + +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + ## 0.1.12 ### Patch Changes diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index 0219a9d8fa..ba6c173a59 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-sonarqube", - "version": "0.1.12", + "version": "0.1.13", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,9 +32,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.7.1", - "@backstage/plugin-catalog-react": "^0.0.4", - "@backstage/core": "^0.6.2", + "@backstage/catalog-model": "^0.7.2", + "@backstage/plugin-catalog-react": "^0.1.0", + "@backstage/core": "^0.6.3", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -47,9 +47,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/splunk-on-call/CHANGELOG.md b/plugins/splunk-on-call/CHANGELOG.md index ad98bf1feb..bff3bcf8bf 100644 --- a/plugins/splunk-on-call/CHANGELOG.md +++ b/plugins/splunk-on-call/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-splunk-on-call +## 0.1.3 + +### Patch Changes + +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + ## 0.1.2 ### Patch Changes diff --git a/plugins/splunk-on-call/package.json b/plugins/splunk-on-call/package.json index 3573c1bc5e..8600afb105 100644 --- a/plugins/splunk-on-call/package.json +++ b/plugins/splunk-on-call/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-splunk-on-call", - "version": "0.1.2", + "version": "0.1.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,9 +30,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.7.1", - "@backstage/core": "^0.6.2", - "@backstage/plugin-catalog-react": "^0.0.4", + "@backstage/catalog-model": "^0.7.2", + "@backstage/core": "^0.6.3", + "@backstage/plugin-catalog-react": "^0.1.0", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -45,9 +45,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/tech-radar/CHANGELOG.md b/plugins/tech-radar/CHANGELOG.md index 3c4e3a0706..697469bf7a 100644 --- a/plugins/tech-radar/CHANGELOG.md +++ b/plugins/tech-radar/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-tech-radar +## 0.3.6 + +### Patch Changes + +- 9f2b3a26e: Added a dialog box that will show up when a you click on link on the radar and display the description if provided. +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [1407b34c6] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [3a58084b6] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + ## 0.3.5 ### Patch Changes diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index 5b21613053..223d5c1762 100644 --- a/plugins/tech-radar/package.json +++ b/plugins/tech-radar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-radar", - "version": "0.3.5", + "version": "0.3.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,7 +30,7 @@ "start": "backstage-cli plugin:serve" }, "dependencies": { - "@backstage/core": "^0.6.2", + "@backstage/core": "^0.6.3", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -43,9 +43,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/techdocs-backend/CHANGELOG.md b/plugins/techdocs-backend/CHANGELOG.md index cae37c076e..49e3fdbc44 100644 --- a/plugins/techdocs-backend/CHANGELOG.md +++ b/plugins/techdocs-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-techdocs-backend +## 0.6.2 + +### Patch Changes + +- f37992797: Got rid of some `attr` and cleaned up a bit in the TechDocs config schema. +- Updated dependencies [bad21a085] +- Updated dependencies [2499f6cde] +- Updated dependencies [a1f5e6545] +- Updated dependencies [1e4ddd71d] + - @backstage/catalog-model@0.7.2 + - @backstage/techdocs-common@0.4.2 + - @backstage/config@0.1.3 + ## 0.6.1 ### Patch Changes diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index 994e05fefa..03bea5233d 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-backend", - "version": "0.6.1", + "version": "0.6.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,9 +31,9 @@ }, "dependencies": { "@backstage/backend-common": "^0.5.4", - "@backstage/catalog-model": "^0.7.1", - "@backstage/config": "^0.1.2", - "@backstage/techdocs-common": "^0.4.1", + "@backstage/catalog-model": "^0.7.2", + "@backstage/config": "^0.1.3", + "@backstage/techdocs-common": "^0.4.2", "@types/dockerode": "^3.2.1", "@types/express": "^4.17.6", "cross-fetch": "^3.0.6", @@ -45,7 +45,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.6.1", + "@backstage/cli": "^0.6.2", "supertest": "^4.0.2" }, "files": [ diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index 1772ea62fe..a1e7e456d4 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-techdocs +## 0.5.8 + +### Patch Changes + +- f37992797: Got rid of some `attr` and cleaned up a bit in the TechDocs config schema. +- 2499f6cde: Add support for assuming role in AWS integrations +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [dc12852c9] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [2499f6cde] +- Updated dependencies [a1f5e6545] +- Updated dependencies [1e4ddd71d] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/test-utils@0.1.8 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + - @backstage/techdocs-common@0.4.2 + - @backstage/config@0.1.3 + ## 0.5.7 ### Patch Changes diff --git a/plugins/techdocs/config.d.ts b/plugins/techdocs/config.d.ts index d85269d2ec..1c49833d68 100644 --- a/plugins/techdocs/config.d.ts +++ b/plugins/techdocs/config.d.ts @@ -65,6 +65,11 @@ export interface Config { * @visibility secret */ secretAccessKey: string; + /** + * ARN of role to be assumed + * @visibility backend + */ + roleArn?: string; }; /** * (Required) Cloud Storage Bucket Name diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index fdedc7d4dc..360441945d 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs", - "version": "0.5.7", + "version": "0.5.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,13 +31,13 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/config": "^0.1.2", - "@backstage/catalog-model": "^0.7.1", - "@backstage/core": "^0.6.2", - "@backstage/plugin-catalog-react": "^0.0.4", - "@backstage/test-utils": "^0.1.7", + "@backstage/config": "^0.1.3", + "@backstage/catalog-model": "^0.7.2", + "@backstage/core": "^0.6.3", + "@backstage/plugin-catalog-react": "^0.1.0", + "@backstage/test-utils": "^0.1.8", "@backstage/theme": "^0.2.3", - "@backstage/techdocs-common": "^0.4.1", + "@backstage/techdocs-common": "^0.4.2", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", @@ -50,9 +50,9 @@ "sanitize-html": "^2.3.2" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index f6cd6231c1..0e5d9a2859 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -30,7 +30,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core": "^0.6.2", + "@backstage/core": "^0.6.3", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -41,9 +41,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/plugins/welcome/package.json b/plugins/welcome/package.json index 81ba864a24..cb8452e8f8 100644 --- a/plugins/welcome/package.json +++ b/plugins/welcome/package.json @@ -30,7 +30,7 @@ "start": "backstage-cli plugin:serve" }, "dependencies": { - "@backstage/core": "^0.6.2", + "@backstage/core": "^0.6.3", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", @@ -41,9 +41,9 @@ "react-use": "^15.3.3" }, "devDependencies": { - "@backstage/cli": "^0.6.1", - "@backstage/dev-utils": "^0.1.11", - "@backstage/test-utils": "^0.1.7", + "@backstage/cli": "^0.6.2", + "@backstage/dev-utils": "^0.1.12", + "@backstage/test-utils": "^0.1.8", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.4.1", "@testing-library/user-event": "^12.0.7", diff --git a/yarn.lock b/yarn.lock index 90e7e8bb14..c13dad3caa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -44,6 +44,19 @@ dependencies: xss "^1.0.6" +"@apollographql/graphql-upload-8-fork@^8.1.3": + version "8.1.3" + resolved "https://registry.npmjs.org/@apollographql/graphql-upload-8-fork/-/graphql-upload-8-fork-8.1.3.tgz#a0d4e0d5cec8e126d78bd915c264d6b90f5784bc" + integrity sha512-ssOPUT7euLqDXcdVv3Qs4LoL4BPtfermW1IOouaqEmj36TpHYDmYDIbKoSQxikd9vtMumFnP87OybH7sC9fJ6g== + dependencies: + "@types/express" "*" + "@types/fs-capacitor" "*" + "@types/koa" "*" + busboy "^0.3.1" + fs-capacitor "^2.0.4" + http-errors "^1.7.3" + object-path "^0.11.4" + "@ardatan/aggregate-error@0.0.1": version "0.0.1" resolved "https://registry.npmjs.org/@ardatan/aggregate-error/-/aggregate-error-0.0.1.tgz#1403ac5de10d8ca689fc1f65844c27179ae1d44f" @@ -1803,9 +1816,9 @@ to-fast-properties "^2.0.0" "@backstage/catalog-model@^0.2.0": - version "0.7.1" + version "0.7.2" dependencies: - "@backstage/config" "^0.1.2" + "@backstage/config" "^0.1.3" "@types/json-schema" "^7.0.5" "@types/yup" "^0.29.8" ajv "^7.0.3" @@ -1815,9 +1828,9 @@ yup "^0.29.3" "@backstage/catalog-model@^0.3.0": - version "0.7.1" + version "0.7.2" dependencies: - "@backstage/config" "^0.1.2" + "@backstage/config" "^0.1.3" "@types/json-schema" "^7.0.5" "@types/yup" "^0.29.8" ajv "^7.0.3" @@ -1827,10 +1840,10 @@ yup "^0.29.3" "@backstage/core@^0.3.0": - version "0.6.2" + version "0.6.3" dependencies: - "@backstage/config" "^0.1.2" - "@backstage/core-api" "^0.2.10" + "@backstage/config" "^0.1.3" + "@backstage/core-api" "^0.2.11" "@backstage/theme" "^0.2.3" "@material-ui/core" "^4.11.0" "@material-ui/icons" "^4.9.1" @@ -1868,12 +1881,34 @@ zen-observable "^0.8.15" "@backstage/plugin-catalog@^0.2.1": - version "0.3.2" + version "0.4.0" dependencies: "@backstage/catalog-client" "^0.3.6" - "@backstage/catalog-model" "^0.7.1" - "@backstage/core" "^0.6.2" - "@backstage/plugin-catalog-react" "^0.0.4" + "@backstage/catalog-model" "^0.7.2" + "@backstage/core" "^0.6.3" + "@backstage/plugin-catalog-react" "^0.1.0" + "@backstage/theme" "^0.2.3" + "@material-ui/core" "^4.11.0" + "@material-ui/icons" "^4.9.1" + "@material-ui/lab" "4.0.0-alpha.45" + "@types/react" "^16.9" + classnames "^2.2.6" + git-url-parse "^11.4.4" + react "^16.13.1" + react-dom "^16.13.1" + react-helmet "6.1.0" + react-router "6.0.0-beta.0" + react-router-dom "6.0.0-beta.0" + react-use "^15.3.3" + swr "^0.3.0" + +"@backstage/plugin-catalog@^0.3.1": + version "0.4.0" + dependencies: + "@backstage/catalog-client" "^0.3.6" + "@backstage/catalog-model" "^0.7.2" + "@backstage/core" "^0.6.3" + "@backstage/plugin-catalog-react" "^0.1.0" "@backstage/theme" "^0.2.3" "@material-ui/core" "^4.11.0" "@material-ui/icons" "^4.9.1" @@ -3845,9 +3880,9 @@ react-transition-group "^4.4.0" "@material-ui/icons@^4.9.1": - version "4.9.1" - resolved "https://registry.npmjs.org/@material-ui/icons/-/icons-4.9.1.tgz#fdeadf8cb3d89208945b33dbc50c7c616d0bd665" - integrity sha512-GBitL3oBWO0hzBhvA9KxqcowRUsA0qzwKkURyC8nppnC3fw54KPKZ+d4V1Eeg/UnDRSzDaI9nGCdel/eh9AQMg== + version "4.11.2" + resolved "https://registry.npmjs.org/@material-ui/icons/-/icons-4.11.2.tgz#b3a7353266519cd743b6461ae9fdfcb1b25eb4c5" + integrity sha512-fQNsKX2TxBmqIGJCSi3tGTO/gZ+eJgWmMJkgDiOfyNaunNaxcklJQFaFogYcFl0qFuaEz1qaXYXboa/bUXVSOQ== dependencies: "@babel/runtime" "^7.4.4" @@ -5783,7 +5818,14 @@ resolved "https://registry.npmjs.org/@types/core-js/-/core-js-2.5.4.tgz#fc42ebde7d9cfa7c5f2668f117449b02348e41fd" integrity sha512-Xwy8o12ak+iYgFr/KCVaVK5Sy+jFMiiPAID3+ObvMlBzy26XQJw5xu+a6rlHsrJENXj/AwJOGsJpVohUjAzSKQ== -"@types/cors@^2.8.4", "@types/cors@^2.8.6": +"@types/cors@2.8.8": + version "2.8.8" + resolved "https://registry.npmjs.org/@types/cors/-/cors-2.8.8.tgz#317a8d8561995c60e35b9e0fcaa8d36660c98092" + integrity sha512-fO3gf3DxU2Trcbr75O7obVndW/X5k8rJNZkLXlQWStTHhP71PkRqjwPIEI0yMnJdg9R9OasjU+Bsr+Hr1xy/0w== + dependencies: + "@types/express" "*" + +"@types/cors@^2.8.6": version "2.8.9" resolved "https://registry.npmjs.org/@types/cors/-/cors-2.8.9.tgz#4bd1fcac72eca8d5bec93e76c7fdcbdc1bc2cd4a" integrity sha512-zurD1ibz21BRlAOIKP8yhrxlqKx6L9VCwkB5kMiP6nZAhoF5MvC7qS1qPA7nRcr1GJolfkQC7/EAL4hdYejLtg== @@ -5884,7 +5926,7 @@ resolved "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== -"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.5": +"@types/express-serve-static-core@*", "@types/express-serve-static-core@4.17.18", "@types/express-serve-static-core@^4.17.5": version "4.17.18" resolved "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.18.tgz#8371e260f40e0e1ca0c116a9afcd9426fa094c40" integrity sha512-m4JTwx5RUBNZvky/JJ8swEJPKFd8si08pPF2PfizYjGZOKr/svUWPcoUmLow6MmPzhasphB7gSTINY67xn3JNA== @@ -5973,16 +6015,6 @@ dependencies: "@types/node" "*" -"@types/graphql-upload@^8.0.0": - version "8.0.3" - resolved "https://registry.npmjs.org/@types/graphql-upload/-/graphql-upload-8.0.3.tgz#b371edb5f305a2a1f7b7843a890a2a7adc55c3ec" - integrity sha512-hmLg9pCU/GmxBscg8GCr1vmSoEmbItNNxdD5YH2TJkXm//8atjwuprB+xJBK714JG1dkxbbhp5RHX+Pz1KsCMA== - dependencies: - "@types/express" "*" - "@types/fs-capacitor" "*" - "@types/koa" "*" - graphql "^14.5.3" - "@types/hast@^2.0.0": version "2.3.1" resolved "https://registry.npmjs.org/@types/hast/-/hast-2.3.1.tgz#b16872f2a6144c7025f296fb9636a667ebb79cd9" @@ -6893,9 +6925,9 @@ "@types/node" "*" "@types/xml2js@^0.4.7": - version "0.4.7" - resolved "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.7.tgz#cd5b6c67bbec741ac625718a76e6cb99bc34365e" - integrity sha512-f5VOKSMEE0O+/L54FHwA/a7vcx9mHeSDM71844yHCOhh8Cin2xQa0UFw0b7Vc5hoZ3Ih6ZHaDobjfLih4tWPNw== + version "0.4.8" + resolved "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.8.tgz#84c120c864a5976d0b5cf2f930a75d850fc2b03a" + integrity sha512-EyvT83ezOdec7BhDaEcsklWy7RSIdi6CNe95tmOAK0yx/Lm30C9K75snT3fYayK59ApC2oyW+rcHErdG05FHJA== dependencies: "@types/node" "*" @@ -7471,43 +7503,21 @@ anymatch@^3.0.3, anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" -apollo-cache-control@^0.11.1: - version "0.11.1" - resolved "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.11.1.tgz#3bce0924ae7322a8b9f7ca1e2fb036d1fc9f1df5" - integrity sha512-6iHa8TkcKt4rx5SKRzDNjUIpCQX+7/FlZwD7vRh9JDnM4VH8SWhpj8fUR3CiEY8Kuc4ChXnOY8bCcMju5KPnIQ== +apollo-cache-control@^0.11.6: + version "0.11.6" + resolved "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.11.6.tgz#f7bdf924272af47ac474cf3f3f35cfc038cc9485" + integrity sha512-YZ+uuIG+fPy+mkpBS2qKF0v1qlzZ3PW6xZVaDukeK3ed3iAs4L/2YnkTqau3OmoF/VPzX2FmSkocX/OVd59YSw== dependencies: - apollo-server-env "^2.4.5" - apollo-server-plugin-base "^0.9.1" + apollo-server-env "^3.0.0" + apollo-server-plugin-base "^0.10.4" -apollo-datasource@^0.7.2: - version "0.7.2" - resolved "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-0.7.2.tgz#1662ee93453a9b89af6f73ce561bde46b41ebf31" - integrity sha512-ibnW+s4BMp4K2AgzLEtvzkjg7dJgCaw9M5b5N0YKNmeRZRnl/I/qBTQae648FsRKgMwTbRQIvBhQ0URUFAqFOw== +apollo-datasource@^0.7.3: + version "0.7.3" + resolved "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-0.7.3.tgz#c824eb1457bdee5a3173ced0e35e594547e687a0" + integrity sha512-PE0ucdZYjHjUyXrFWRwT02yLcx2DACsZ0jm1Mp/0m/I9nZu/fEkvJxfsryXB6JndpmQO77gQHixf/xGCN976kA== dependencies: - apollo-server-caching "^0.5.2" - apollo-server-env "^2.4.5" - -apollo-engine-reporting-protobuf@^0.5.2: - version "0.5.2" - resolved "https://registry.npmjs.org/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.5.2.tgz#b01812508a1c583328a8dc603769bc63b8895e7e" - integrity sha512-4wm9FR3B7UvJxcK/69rOiS5CAJPEYKufeRWb257ZLfX7NGFTMqvbc1hu4q8Ch7swB26rTpkzfsftLED9DqH9qg== - dependencies: - "@apollo/protobufjs" "^1.0.3" - -apollo-engine-reporting@^2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/apollo-engine-reporting/-/apollo-engine-reporting-2.3.0.tgz#3bb59f81aaf6b967ed098896a4a60a053b4eed5a" - integrity sha512-SbcPLFuUZcRqDEZ6mSs8uHM9Ftr8yyt2IEu0JA8c3LNBmYXSLM7MHqFe80SVcosYSTBgtMz8mLJO8orhYoSYZw== - dependencies: - apollo-engine-reporting-protobuf "^0.5.2" - apollo-graphql "^0.5.0" - apollo-server-caching "^0.5.2" - apollo-server-env "^2.4.5" - apollo-server-errors "^2.4.2" - apollo-server-plugin-base "^0.9.1" - apollo-server-types "^0.5.1" - async-retry "^1.2.1" - uuid "^8.0.0" + apollo-server-caching "^0.5.3" + apollo-server-env "^3.0.0" apollo-env@^0.6.5: version "0.6.5" @@ -7519,12 +7529,22 @@ apollo-env@^0.6.5: node-fetch "^2.2.0" sha.js "^2.4.11" -apollo-graphql@^0.5.0: - version "0.5.0" - resolved "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.5.0.tgz#7e9152093211b58352aa6504d8d39ec7241d6872" - integrity sha512-YSdF/BKPbsnQpxWpmCE53pBJX44aaoif31Y22I/qKpB6ZSGzYijV5YBoCL5Q15H2oA/v/02Oazh9lbp4ek3eig== +apollo-env@^0.6.6: + version "0.6.6" + resolved "https://registry.npmjs.org/apollo-env/-/apollo-env-0.6.6.tgz#d7880805c4e96ee3d4142900a405176a04779438" + integrity sha512-hXI9PjJtzmD34XviBU+4sPMOxnifYrHVmxpjykqI/dUD2G3yTiuRaiQqwRwB2RCdwC1Ug/jBfoQ/NHDTnnjndQ== dependencies: - apollo-env "^0.6.5" + "@types/node-fetch" "2.5.7" + core-js "^3.0.1" + node-fetch "^2.2.0" + sha.js "^2.4.11" + +apollo-graphql@^0.6.0: + version "0.6.1" + resolved "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.6.1.tgz#d0bf0aff76f445de3da10e08f6974f1bf65f5753" + integrity sha512-ZRXAV+k+hboCVS+FW86FW/QgnDR7gm/xMUwJPGXEbV53OLGuQQdIT0NCYK7AzzVkCfsbb7NJ3mmEclkZY9uuxQ== + dependencies: + apollo-env "^0.6.6" lodash.sortby "^4.7.0" apollo-link-http-common@^0.2.14: @@ -7546,6 +7566,13 @@ apollo-link@^1.2.12, apollo-link@^1.2.14: tslib "^1.9.3" zen-observable-ts "^0.8.21" +apollo-reporting-protobuf@^0.6.2: + version "0.6.2" + resolved "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-0.6.2.tgz#5572866be9b77f133916532b10e15fbaa4158304" + integrity sha512-WJTJxLM+MRHNUxt1RTl4zD0HrLdH44F2mDzMweBj1yHL0kSt8I1WwoiF/wiGVSpnG48LZrBegCaOJeuVbJTbtw== + dependencies: + "@apollo/protobufjs" "^1.0.3" + apollo-server-caching@0.5.1: version "0.5.1" resolved "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.5.1.tgz#5cd0536ad5473abb667cc82b59bc56b96fb35db6" @@ -7553,45 +7580,48 @@ apollo-server-caching@0.5.1: dependencies: lru-cache "^5.0.0" -apollo-server-caching@^0.5.2: - version "0.5.2" - resolved "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.5.2.tgz#bef5d5e0d48473a454927a66b7bb947a0b6eb13e" - integrity sha512-HUcP3TlgRsuGgeTOn8QMbkdx0hLPXyEJehZIPrcof0ATz7j7aTPA4at7gaiFHCo8gk07DaWYGB3PFgjboXRcWQ== +apollo-server-caching@^0.5.3: + version "0.5.3" + resolved "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.5.3.tgz#cf42a77ad09a46290a246810075eaa029b5305e1" + integrity sha512-iMi3087iphDAI0U2iSBE9qtx9kQoMMEWr6w+LwXruBD95ek9DWyj7OeC2U/ngLjRsXM43DoBDXlu7R+uMjahrQ== dependencies: - lru-cache "^5.0.0" + lru-cache "^6.0.0" -apollo-server-core@^2.16.1: - version "2.16.1" - resolved "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.16.1.tgz#5b5b8245ab9c0cb6c2367ec19ab855dea6ccea3a" - integrity sha512-nuwn5ZBbmzPwDetb3FgiFFJlNK7ZBFg8kis/raymrjd3eBGdNcOyMTJDl6J9673X9Xqp+dXQmFYDW/G3G8S1YA== +apollo-server-core@^2.16.1, apollo-server-core@^2.21.0: + version "2.21.0" + resolved "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.21.0.tgz#12ee11aee61fa124f11b1d73cae2e068112a3a53" + integrity sha512-GtIiq2F0dVDLzzIuO5+dK/pGq/sGxYlKCqAuQQqzYg0fvZ7fukyluXtcTe0tMI+FJZjU0j0WnKgiLsboCoAlPQ== dependencies: "@apollographql/apollo-tools" "^0.4.3" "@apollographql/graphql-playground-html" "1.6.26" - "@types/graphql-upload" "^8.0.0" + "@apollographql/graphql-upload-8-fork" "^8.1.3" "@types/ws" "^7.0.0" - apollo-cache-control "^0.11.1" - apollo-datasource "^0.7.2" - apollo-engine-reporting "^2.3.0" - apollo-server-caching "^0.5.2" - apollo-server-env "^2.4.5" + apollo-cache-control "^0.11.6" + apollo-datasource "^0.7.3" + apollo-graphql "^0.6.0" + apollo-reporting-protobuf "^0.6.2" + apollo-server-caching "^0.5.3" + apollo-server-env "^3.0.0" apollo-server-errors "^2.4.2" - apollo-server-plugin-base "^0.9.1" - apollo-server-types "^0.5.1" - apollo-tracing "^0.11.1" + apollo-server-plugin-base "^0.10.4" + apollo-server-types "^0.6.3" + apollo-tracing "^0.12.2" + async-retry "^1.2.1" fast-json-stable-stringify "^2.0.0" - graphql-extensions "^0.12.4" - graphql-tag "^2.9.2" - graphql-tools "^4.0.0" - graphql-upload "^8.0.2" + graphql-extensions "^0.12.8" + graphql-tag "^2.11.0" + graphql-tools "^4.0.8" loglevel "^1.6.7" + lru-cache "^6.0.0" sha.js "^2.4.11" subscriptions-transport-ws "^0.9.11" + uuid "^8.0.0" ws "^6.0.0" -apollo-server-env@^2.4.5: - version "2.4.5" - resolved "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-2.4.5.tgz#73730b4f0439094a2272a9d0caa4079d4b661d5f" - integrity sha512-nfNhmGPzbq3xCEWT8eRpoHXIPNcNy3QcEoBlzVMjeglrBGryLG2LXwBSPnVmTRRrzUYugX0ULBtgE3rBFNoUgA== +apollo-server-env@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-3.0.0.tgz#0157c51f52b63aee39af190760acf789ffc744d9" + integrity sha512-tPSN+VttnPsoQAl/SBVUpGbLA97MXG990XIwq6YUnJyAixrrsjW1xYG7RlaOqetxm80y5mBZKLrRDiiSsW/vog== dependencies: node-fetch "^2.1.2" util.promisify "^1.0.0" @@ -7602,42 +7632,43 @@ apollo-server-errors@^2.4.2: integrity sha512-FeGxW3Batn6sUtX3OVVUm7o56EgjxDlmgpTLNyWcLb0j6P8mw9oLNyAm3B+deHA4KNdNHO5BmHS2g1SJYjqPCQ== apollo-server-express@^2.16.1: - version "2.16.1" - resolved "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.16.1.tgz#7438bca590ef8577d24d20ba0b6d582c120c0146" - integrity sha512-Oq5YNcaMYnRk6jDmA9LWf8oSd2KHDVe7jQ4wtooAvG9FVUD+FaFBgSkytXHMvtifQh2wdF07Ri8uDLMz6IQjTw== + version "2.21.0" + resolved "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.21.0.tgz#29bd4ec728e1992da240c5956c3ce6d95c1d252e" + integrity sha512-zbOSNGuxUjlOFZnRrbMpga3pKDEroitF4NAqoVxgBivx7v2hGsE7rljct3PucTx2cMN90AyYe3cU4oA8jBxZIQ== dependencies: "@apollographql/graphql-playground-html" "1.6.26" "@types/accepts" "^1.3.5" "@types/body-parser" "1.19.0" - "@types/cors" "^2.8.4" + "@types/cors" "2.8.8" "@types/express" "4.17.7" + "@types/express-serve-static-core" "4.17.18" accepts "^1.3.5" - apollo-server-core "^2.16.1" - apollo-server-types "^0.5.1" + apollo-server-core "^2.21.0" + apollo-server-types "^0.6.3" body-parser "^1.18.3" cors "^2.8.4" express "^4.17.1" graphql-subscriptions "^1.0.0" - graphql-tools "^4.0.0" + graphql-tools "^4.0.8" parseurl "^1.3.2" subscriptions-transport-ws "^0.9.16" type-is "^1.6.16" -apollo-server-plugin-base@^0.9.1: - version "0.9.1" - resolved "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.9.1.tgz#a62ae9ab4e89790fd4cc5d123bb616da34e8e5fb" - integrity sha512-kvrX4Z3FdpjrZdHkyl5iY2A1Wvp4b6KQp00DeZqss7GyyKNUBKr80/7RQgBLEw7EWM7WB19j459xM/TjvW0FKQ== +apollo-server-plugin-base@^0.10.4: + version "0.10.4" + resolved "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.10.4.tgz#fbf73f64f95537ca9f9639dd7c535eb5eeb95dcd" + integrity sha512-HRhbyHgHFTLP0ImubQObYhSgpmVH4Rk1BinnceZmwudIVLKrqayIVOELdyext/QnSmmzg5W7vF3NLGBcVGMqDg== dependencies: - apollo-server-types "^0.5.1" + apollo-server-types "^0.6.3" -apollo-server-types@^0.5.1: - version "0.5.1" - resolved "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.5.1.tgz#091c09652894d6532db9ba873574443adabf85b9" - integrity sha512-my2cPw+DAb2qVnIuBcsRKGyS28uIc2vjFxa1NpRoJZe9gK0BWUBk7wzXnIzWy3HZ5Er11e/40MPTUesNfMYNVA== +apollo-server-types@^0.6.3: + version "0.6.3" + resolved "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.6.3.tgz#f7aa25ff7157863264d01a77d7934aa6e13399e8" + integrity sha512-aVR7SlSGGY41E1f11YYz5bvwA89uGmkVUtzMiklDhZ7IgRJhysT5Dflt5IuwDxp+NdQkIhVCErUXakopocFLAg== dependencies: - apollo-engine-reporting-protobuf "^0.5.2" - apollo-server-caching "^0.5.2" - apollo-server-env "^2.4.5" + apollo-reporting-protobuf "^0.6.2" + apollo-server-caching "^0.5.3" + apollo-server-env "^3.0.0" apollo-server@^2.16.1: version "2.16.1" @@ -7650,13 +7681,13 @@ apollo-server@^2.16.1: graphql-subscriptions "^1.0.0" graphql-tools "^4.0.0" -apollo-tracing@^0.11.1: - version "0.11.2" - resolved "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.11.2.tgz#14308b176e021f5e6ec3ee670f8f96e9fbfdb50c" - integrity sha512-QjmRd2ozGD+PfmF6U9w/w6jrclYSBNczN6Bzppr8qA5somEGl5pqdprIZYL28H0IapZiutA3x6p6ZVF/cVX8wA== +apollo-tracing@^0.12.2: + version "0.12.2" + resolved "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.12.2.tgz#a261c3970bb421b6dadf50cd85d75b2567a7e52c" + integrity sha512-SYN4o0C0wR1fyS3+P0FthyvsQVHFopdmN3IU64IaspR/RZScPxZ3Ae8uu++fTvkQflAkglnFM0aX6DkZERBp6w== dependencies: - apollo-server-env "^2.4.5" - apollo-server-plugin-base "^0.9.1" + apollo-server-env "^3.0.0" + apollo-server-plugin-base "^0.10.4" apollo-upload-client@^13.0.0: version "13.0.0" @@ -12924,6 +12955,14 @@ file-loader@^6.0.0: loader-utils "^2.0.0" schema-utils "^2.7.1" +file-loader@^6.2.0: + version "6.2.0" + resolved "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" + integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + file-system-cache@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/file-system-cache/-/file-system-cache-1.0.5.tgz#84259b36a2bbb8d3d6eb1021d3132ffe64cfff4f" @@ -13992,14 +14031,14 @@ graphql-config@^3.0.2: string-env-interpolation "1.0.1" tslib "^2.0.0" -graphql-extensions@^0.12.4: - version "0.12.4" - resolved "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.12.4.tgz#c0aa49a20f983a2da641526d1e505996bd2b4188" - integrity sha512-GnR4LiWk3s2bGOqIh6V1JgnSXw2RCH4NOgbCFEWvB6JqWHXTlXnLZ8bRSkCiD4pltv7RHUPWqN/sGh8R6Ae/ag== +graphql-extensions@^0.12.8: + version "0.12.8" + resolved "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.12.8.tgz#9cdc2c43d8fe5e0f6c3177a004ac011da2a8aa0f" + integrity sha512-xjsSaB6yKt9jarFNNdivl2VOx52WySYhxPgf8Y16g6GKZyAzBoIFiwyGw5PJDlOSUa6cpmzn6o7z8fVMbSAbkg== dependencies: "@apollographql/apollo-tools" "^0.4.3" - apollo-server-env "^2.4.5" - apollo-server-types "^0.5.1" + apollo-server-env "^3.0.0" + apollo-server-types "^0.6.3" graphql-language-service-interface@^2.4.0: version "2.4.0" @@ -14057,11 +14096,6 @@ graphql-tag@^2.11.0: resolved "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.11.0.tgz#1deb53a01c46a7eb401d6cb59dec86fa1cccbffd" integrity sha512-VmsD5pJqWJnQZMUeRwrDhfgoyqcfwEkvtpANqcoUG8/tOLkwNgU9mzub/Mc78OJMhHjx7gfAMTxzdG43VGg3bA== -graphql-tag@^2.9.2: - version "2.10.4" - resolved "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.10.4.tgz#2f301a98219be8b178a6453bb7e33b79b66d8f83" - integrity sha512-O7vG5BT3w6Sotc26ybcvLKNTdfr4GfsIVMD+LdYqXCeJIYPRyp8BIsDOUtxw7S1PYvRw5vH3278J2EDezR6mfA== - graphql-tools@5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/graphql-tools/-/graphql-tools-5.0.0.tgz#67281c834a0e29f458adba8018f424816fa627e9" @@ -14076,7 +14110,7 @@ graphql-tools@5.0.0: tslib "^1.11.1" uuid "^7.0.3" -graphql-tools@^4.0.0: +graphql-tools@^4.0.0, graphql-tools@^4.0.8: version "4.0.8" resolved "https://registry.npmjs.org/graphql-tools/-/graphql-tools-4.0.8.tgz#e7fb9f0d43408fb0878ba66b522ce871bafe9d30" integrity sha512-MW+ioleBrwhRjalKjYaLQbr+920pHBgy9vM/n47sswtns8+96sRn5M/G+J1eu7IMeKWiN/9p6tmwCHU7552VJg== @@ -14092,27 +14126,10 @@ graphql-type-json@^0.3.2: resolved "https://registry.npmjs.org/graphql-type-json/-/graphql-type-json-0.3.2.tgz#f53a851dbfe07bd1c8157d24150064baab41e115" integrity sha512-J+vjof74oMlCWXSvt0DOf2APEdZOCdubEvGDUAlqH//VBYcOYsGgRW7Xzorr44LvkjiuvecWc8fChxuZZbChtg== -graphql-upload@^8.0.2: - version "8.1.0" - resolved "https://registry.npmjs.org/graphql-upload/-/graphql-upload-8.1.0.tgz#6d0ab662db5677a68bfb1f2c870ab2544c14939a" - integrity sha512-U2OiDI5VxYmzRKw0Z2dmfk0zkqMRaecH9Smh1U277gVgVe9Qn+18xqf4skwr4YJszGIh7iQDZ57+5ygOK9sM/Q== - dependencies: - busboy "^0.3.1" - fs-capacitor "^2.0.4" - http-errors "^1.7.3" - object-path "^0.11.4" - -graphql@15.4.0, graphql@^15.3.0: - version "15.4.0" - resolved "https://registry.npmjs.org/graphql/-/graphql-15.4.0.tgz#e459dea1150da5a106486ba7276518b5295a4347" - integrity sha512-EB3zgGchcabbsU9cFe1j+yxdzKQKAbGUWRb13DsrsMN1yyfmmIq+2+L5MqVWcDCE4V89R5AyUOi7sMOGxdsYtA== - -graphql@^14.5.3: - version "14.7.0" - resolved "https://registry.npmjs.org/graphql/-/graphql-14.7.0.tgz#7fa79a80a69be4a31c27dda824dc04dac2035a72" - integrity sha512-l0xWZpoPKpppFzMfvVyFmp9vLN7w/ZZJPefUicMCepfJeQ8sMcztloGYY9DfjVPo6tIUDzU5Hw3MUbIjj9AVVA== - dependencies: - iterall "^1.2.2" +graphql@15.5.0, graphql@^15.3.0: + version "15.5.0" + resolved "https://registry.npmjs.org/graphql/-/graphql-15.5.0.tgz#39d19494dbe69d1ea719915b578bf920344a69d5" + integrity sha512-OmaM7y0kaK31NKG31q4YbD2beNYa6jBBKtMFT6gLYJljHLJr42IqJ8KX08u3Li/0ifzTU5HjmoOOrwa5BRLeDA== growly@^1.3.0: version "1.3.0" @@ -15682,7 +15699,7 @@ istanbul-reports@^3.0.2: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -iterall@^1.1.3, iterall@^1.2.1, iterall@^1.2.2, iterall@^1.3.0: +iterall@^1.1.3, iterall@^1.2.1, iterall@^1.3.0: version "1.3.0" resolved "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz#afcb08492e2915cbd8a0884eb93a8c94d0d72fea" integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg== @@ -22752,6 +22769,15 @@ schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7.0, schema-utils@^2.7 ajv "^6.12.4" ajv-keywords "^3.5.2" +schema-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef" + integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA== + dependencies: + "@types/json-schema" "^7.0.6" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + screenfull@^5.0.0: version "5.0.2" resolved "https://registry.npmjs.org/screenfull/-/screenfull-5.0.2.tgz#b9acdcf1ec676a948674df5cd0ff66b902b0bed7" @@ -23943,7 +23969,7 @@ stylis@3.5.0: resolved "https://registry.npmjs.org/stylis/-/stylis-3.5.0.tgz#016fa239663d77f868fef5b67cf201c4b7c701e1" integrity sha512-pP7yXN6dwMzAR29Q0mBrabPCe0/mNO1MSr93bhay+hcZondvMMTpeGyd8nbhYJdyperNT2DRxONQuUGcJr5iPw== -subscriptions-transport-ws@0.9.18: +subscriptions-transport-ws@0.9.18, subscriptions-transport-ws@^0.9.11, subscriptions-transport-ws@^0.9.16: version "0.9.18" resolved "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.18.tgz#bcf02320c911fbadb054f7f928e51c6041a37b97" integrity sha512-tztzcBTNoEbuErsVQpTN2xUNN/efAZXyCyL5m3x4t6SKrEiTL2N8SaKWBFWM4u56pL79ULif3zjyeq+oV+nOaA== @@ -23954,17 +23980,6 @@ subscriptions-transport-ws@0.9.18: symbol-observable "^1.0.4" ws "^5.2.0" -subscriptions-transport-ws@^0.9.11, subscriptions-transport-ws@^0.9.16: - version "0.9.17" - resolved "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.17.tgz#e30e40f0caae0d2781903c01a8cb51b6e2682098" - integrity sha512-hNHi2N80PBz4T0V0QhnnsMGvG3XDFDS9mS6BhZ3R12T6EBywC8d/uJscsga0cVO4DKtXCkCRrWm2sOYrbOdhEA== - dependencies: - backo2 "^1.0.2" - eventemitter3 "^3.1.0" - iterall "^1.2.1" - symbol-observable "^1.0.4" - ws "^5.2.0" - sucrase@^3.16.0: version "3.17.0" resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.17.0.tgz#d9fe5d7e359d884cdb31130358fbdfc18bfb4c24"