diff --git a/.changeset/angry-eels-watch.md b/.changeset/angry-eels-watch.md
deleted file mode 100644
index cd252d5558..0000000000
--- a/.changeset/angry-eels-watch.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-rollbar-backend': patch
----
-
-Moved `@backstage/test-utils` to `devDependencies`.
diff --git a/.changeset/beige-wolves-kneel.md b/.changeset/beige-wolves-kneel.md
deleted file mode 100644
index 2c768a3f03..0000000000
--- a/.changeset/beige-wolves-kneel.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/backend-test-utils': patch
----
-
-Lazy-load `testcontainers` module in order to avoid side-effects.
diff --git a/.changeset/chatty-gifts-fry.md b/.changeset/chatty-gifts-fry.md
deleted file mode 100644
index 25f0a70bd9..0000000000
--- a/.changeset/chatty-gifts-fry.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-auth-backend': patch
----
-
-Replaces the usage of `got` with `node-fetch` in the `getUserPhoto` method of the Microsoft provider
diff --git a/.changeset/chatty-wombats-buy.md b/.changeset/chatty-wombats-buy.md
deleted file mode 100644
index aa743a6a71..0000000000
--- a/.changeset/chatty-wombats-buy.md
+++ /dev/null
@@ -1,24 +0,0 @@
----
-'@backstage/create-app': patch
----
-
-removed inline and internal CSS from index.html
-
-To make this change to an existing app, apply the following changes to the `packages/app/public/index.html` file:
-
-Remove internal style
-
-```diff
--
-```
-
-Remove inline style from the body tag
-
-```diff
--
-+
-```
diff --git a/.changeset/curly-bugs-stare.md b/.changeset/curly-bugs-stare.md
deleted file mode 100644
index 88e1d86e84..0000000000
--- a/.changeset/curly-bugs-stare.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-cost-insights': patch
----
-
-Fixed an accidental re-export of `@backstage/test-utils` that broke this plugin in the most recent release.
diff --git a/.changeset/curly-pillows-provide.md b/.changeset/curly-pillows-provide.md
deleted file mode 100644
index e6a218233b..0000000000
--- a/.changeset/curly-pillows-provide.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/test-utils': patch
----
-
-JSON serialize and freeze values stored by the `MockStorageApi`.
diff --git a/.changeset/cyan-goats-confess.md b/.changeset/cyan-goats-confess.md
deleted file mode 100644
index 0ba500dc7f..0000000000
--- a/.changeset/cyan-goats-confess.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/techdocs-common': patch
----
-
-Bump `@azure/identity` from `^1.5.0` to `^2.0.1`.
diff --git a/.changeset/dar-jag-gar.md b/.changeset/dar-jag-gar.md
deleted file mode 100644
index 5989614101..0000000000
--- a/.changeset/dar-jag-gar.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/backend-common': patch
----
-
-In-memory cache clients instantiated from the same cache manager now share the same memory space.
diff --git a/.changeset/eight-worms-report.md b/.changeset/eight-worms-report.md
deleted file mode 100644
index 1dc12db0e4..0000000000
--- a/.changeset/eight-worms-report.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/backend-common': patch
----
-
-Use the default CSP policy provided by `helmet` directly rather than a copy.
diff --git a/.changeset/eighty-dancers-heal.md b/.changeset/eighty-dancers-heal.md
deleted file mode 100644
index 9286e75d2c..0000000000
--- a/.changeset/eighty-dancers-heal.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-auth-backend': patch
----
-
-Update `auth0` and `onelogin` providers to allow for `authHandler` and `signIn.resolver` configuration.
diff --git a/.changeset/eleven-pianos-fail.md b/.changeset/eleven-pianos-fail.md
deleted file mode 100644
index 5b0aa76ae9..0000000000
--- a/.changeset/eleven-pianos-fail.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-auth-backend': patch
----
-
-Fixed bug on refresh token on Okta provider, now it gets the refresh token and it sends it into providerInfo
diff --git a/.changeset/fluffy-toys-tease.md b/.changeset/fluffy-toys-tease.md
deleted file mode 100644
index f20eaebb2c..0000000000
--- a/.changeset/fluffy-toys-tease.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-tech-insights': minor
----
-
-fixes api auth in tech-insights plugin
diff --git a/.changeset/four-phones-shave.md b/.changeset/four-phones-shave.md
deleted file mode 100644
index 1ef58bdadb..0000000000
--- a/.changeset/four-phones-shave.md
+++ /dev/null
@@ -1,29 +0,0 @@
----
-'@backstage/plugin-auth-backend': minor
----
-
-Avoid ever returning OAuth refresh tokens back to the client, and always exchange refresh tokens for a new one when available for all providers.
-
-This comes with a breaking change to the TypeScript API for custom auth providers. The `refresh` method of `OAuthHandlers` implementation must now return a `{ response, refreshToken }` object rather than a direct response. Existing `refresh` implementations are typically migrated by changing an existing return expression that looks like this:
-
-```ts
-return await this.handleResult({
- fullProfile,
- params,
- accessToken,
- refreshToken,
-});
-```
-
-Into the following:
-
-```ts
-return {
- response: await this.handleResult({
- fullProfile,
- params,
- accessToken,
- }),
- refreshToken,
-};
-```
diff --git a/.changeset/four-waves-tan.md b/.changeset/four-waves-tan.md
deleted file mode 100644
index 444891d31b..0000000000
--- a/.changeset/four-waves-tan.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-search': patch
----
-
-Internal cleanup of the exports structure
diff --git a/.changeset/great-mayflies-travel.md b/.changeset/great-mayflies-travel.md
new file mode 100644
index 0000000000..6927cc2a5e
--- /dev/null
+++ b/.changeset/great-mayflies-travel.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-search': patch
+---
+
+Fix missing search context issue with `HomePageSearchBar`
diff --git a/.changeset/happy-moose-worry.md b/.changeset/happy-moose-worry.md
deleted file mode 100644
index 66f0728f7d..0000000000
--- a/.changeset/happy-moose-worry.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/create-app': patch
----
-
-Removed unused templating asset.
diff --git a/.changeset/honest-chefs-mate.md b/.changeset/honest-chefs-mate.md
deleted file mode 100644
index dfc1ff16fb..0000000000
--- a/.changeset/honest-chefs-mate.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-app-backend': patch
----
-
-Set `X-Frame-Options: deny` rather than the default `sameorigin` for all content served by the `app-backend`.`
diff --git a/.changeset/light-singers-double.md b/.changeset/light-singers-double.md
deleted file mode 100644
index e21017373d..0000000000
--- a/.changeset/light-singers-double.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/cli': patch
----
-
-Fix issue with plugin:serve for Plugins not using Lerna monorepo.
diff --git a/.changeset/long-waves-hear.md b/.changeset/long-waves-hear.md
deleted file mode 100644
index 8decec294b..0000000000
--- a/.changeset/long-waves-hear.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/cli': patch
----
-
-remove inline CSS from serve_index.html
diff --git a/.changeset/lucky-bats-reflect.md b/.changeset/lucky-bats-reflect.md
deleted file mode 100644
index ad3171382e..0000000000
--- a/.changeset/lucky-bats-reflect.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-'@backstage/backend-common': patch
-'@backstage/plugin-catalog': patch
-'@backstage/plugin-catalog-backend': patch
-'@backstage/plugin-scaffolder': patch
-'@backstage/plugin-scaffolder-backend': patch
----
-
-Uptake changes to the GitHub Credentials Provider interface.
diff --git a/.changeset/modern-buses-protect.md b/.changeset/modern-buses-protect.md
deleted file mode 100644
index 2aed52eca0..0000000000
--- a/.changeset/modern-buses-protect.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-'@backstage/plugin-catalog-react': patch
----
-
-When a user has zero owned entities when viewing an entity kind in the catalog
-page, it will be automatically redirected to see all the entities. Furthermore,
-for the kind User and Group there are no longer the owned selector.
diff --git a/.changeset/modern-waves-lay.md b/.changeset/modern-waves-lay.md
deleted file mode 100644
index c0d9804379..0000000000
--- a/.changeset/modern-waves-lay.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/create-app': patch
----
-
-Add a comment to the default backend about the fallback 404 handler.
diff --git a/.changeset/neat-insects-ring.md b/.changeset/neat-insects-ring.md
deleted file mode 100644
index a46b6d44e3..0000000000
--- a/.changeset/neat-insects-ring.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-'@backstage/plugin-techdocs': patch
----
-
-Add the techdocs.sanitizer.allowedIframeHosts config.
-This config allows all iframes which have the host of the attribute src in the 'allowedIframehosts' list to be displayed in the documentation.
diff --git a/.changeset/new-tips-shop.md b/.changeset/new-tips-shop.md
deleted file mode 100644
index 3ab4e817d0..0000000000
--- a/.changeset/new-tips-shop.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@techdocs/cli': patch
----
-
-remove internal and inline CSS from index.html
diff --git a/.changeset/plenty-flies-repair.md b/.changeset/plenty-flies-repair.md
deleted file mode 100644
index 7e9690a7f3..0000000000
--- a/.changeset/plenty-flies-repair.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-rollbar-backend': patch
----
-
-Replace the usage of `axios` with `node-fetch` in the Rollbar API
diff --git a/.changeset/poor-zoos-invent.md b/.changeset/poor-zoos-invent.md
deleted file mode 100644
index a1c87bd3ad..0000000000
--- a/.changeset/poor-zoos-invent.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-'@backstage/plugin-scaffolder': patch
-'@backstage/plugin-scaffolder-backend': patch
-'@backstage/plugin-scaffolder-common': patch
----
-
-Support navigating back to pre-filled templates to update inputs of scaffolder tasks for resubmission
diff --git a/.changeset/purple-trains-matter.md b/.changeset/purple-trains-matter.md
new file mode 100644
index 0000000000..39531e4680
--- /dev/null
+++ b/.changeset/purple-trains-matter.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog-react': patch
+---
+
+Add Override Components for Components in @backstage/plugin-catalog-react
diff --git a/.changeset/search-en-jul-hemma.md b/.changeset/search-en-jul-hemma.md
deleted file mode 100644
index 9fae9fcaa5..0000000000
--- a/.changeset/search-en-jul-hemma.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-'@backstage/plugin-search': patch
----
-
-Introduces a `` variant, which operates on the same part of a search query as the existing ``, but in a more opinionated way (as a single-select control surface suitable for faceted search UIs).
-
-Check the [search plugin storybook](https://backstage.io/storybook/?path=/story/plugins-search-searchtype--accordion) to see how it can be used.
diff --git a/.changeset/search-odd-starfishes-raise.md b/.changeset/search-odd-starfishes-raise.md
deleted file mode 100644
index 73627cf457..0000000000
--- a/.changeset/search-odd-starfishes-raise.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-search': patch
----
-
-Captures the search term entered in the SearchBarBase as a `search` event.
diff --git a/.changeset/search-over-tysta-skogor.md b/.changeset/search-over-tysta-skogor.md
deleted file mode 100644
index 5398ae7f5f..0000000000
--- a/.changeset/search-over-tysta-skogor.md
+++ /dev/null
@@ -1,58 +0,0 @@
----
-'@backstage/create-app': patch
----
-
-The `` filter in the composed `SearchPage.tsx` was replaced with the `` variant.
-
-This is an entirely optional change; if you wish to display a control surface for search `types` as a single-select accordion (as opposed to the current multi-select of checkboxes), you can make the following (or similar) changes to your search page layout:
-
-```diff
---- a/packages/app/src/components/search/SearchPage.tsx
-+++ b/packages/app/src/components/search/SearchPage.tsx
-@@ -11,7 +11,7 @@ import {
- SearchType,
- DefaultResultListItem,
- } from '@backstage/plugin-search';
--import { Content, Header, Page } from '@backstage/core-components';
-+import { CatalogIcon, Content, DocsIcon, Header, Page } from '@backstage/core-components';
-
- const useStyles = makeStyles((theme: Theme) => ({
- bar: {
-@@ -19,6 +19,7 @@ const useStyles = makeStyles((theme: Theme) => ({
- },
- filters: {
- padding: theme.spacing(2),
-+ marginTop: theme.spacing(2),
- },
- filter: {
- '& + &': {
-@@ -41,12 +42,23 @@ const SearchPage = () => {
-
-
-
-+ ,
-+ },
-+ {
-+ value: 'techdocs',
-+ name: 'Documentation',
-+ icon: ,
-+ },
-+ ]}
-+ />
-
--
- {
- // ...
-+ const scheduler = taskScheduler.forPlugin(plugin);
- return {
-+ scheduler,
- // ...
-```
diff --git a/.changeset/slimy-socks-pump.md b/.changeset/slimy-socks-pump.md
deleted file mode 100644
index f7252340f1..0000000000
--- a/.changeset/slimy-socks-pump.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-tech-insights': patch
----
-
-Export `techInsightsApiRef` and associated types.
diff --git a/.changeset/small-monkeys-live.md b/.changeset/small-monkeys-live.md
new file mode 100644
index 0000000000..2e5a8ff719
--- /dev/null
+++ b/.changeset/small-monkeys-live.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-tech-insights': patch
+---
+
+remove unnecessary http request when running all checks
diff --git a/.changeset/small-points-allow.md b/.changeset/small-points-allow.md
deleted file mode 100644
index 2228fc8883..0000000000
--- a/.changeset/small-points-allow.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/config-loader': patch
----
-
-Bump `typescript-json-schema` from `^0.51.0` to `^0.52.0`.
diff --git a/.changeset/spicy-moons-poke.md b/.changeset/spicy-moons-poke.md
deleted file mode 100644
index cc39d629bf..0000000000
--- a/.changeset/spicy-moons-poke.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-tech-insights-backend-module-jsonfc': patch
----
-
-ability to add custom operators
diff --git a/.changeset/tame-ways-prove.md b/.changeset/tame-ways-prove.md
deleted file mode 100644
index 4f625d0a05..0000000000
--- a/.changeset/tame-ways-prove.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/cli': patch
----
-
-Add option to build command for minifying the generated code
diff --git a/.changeset/tender-ducks-tie.md b/.changeset/tender-ducks-tie.md
new file mode 100644
index 0000000000..ada9f2bf37
--- /dev/null
+++ b/.changeset/tender-ducks-tie.md
@@ -0,0 +1,6 @@
+---
+'@backstage/plugin-api-docs': patch
+'@backstage/plugin-catalog': patch
+---
+
+Support customizing index page layouts via outlets
diff --git a/.changeset/twenty-hornets-train.md b/.changeset/twenty-hornets-train.md
deleted file mode 100644
index 957bfd00da..0000000000
--- a/.changeset/twenty-hornets-train.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-auth-backend': patch
----
-
-Enforce cookie SSL protection when in production for auth-backend sessions
diff --git a/.changeset/two-rice-pull.md b/.changeset/two-rice-pull.md
new file mode 100644
index 0000000000..3c6138094d
--- /dev/null
+++ b/.changeset/two-rice-pull.md
@@ -0,0 +1,9 @@
+---
+'@backstage/backend-tasks': patch
+---
+
+Updated README to clarify the following:
+
+- Dashes cannot be used in the `id`, changed to an underscore in the example
+- The `timeout` is required, this was also added to the example
+- Added a note about tasks not running as expected for local development using persistent database
diff --git a/.changeset/wet-chefs-exercise.md b/.changeset/wet-chefs-exercise.md
deleted file mode 100644
index cf8a2e538e..0000000000
--- a/.changeset/wet-chefs-exercise.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@backstage/plugin-api-docs': patch
----
-
-Display entity title on `ApiDefinitionCard` if defined
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 7222edef08..109f90eff6 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -124,6 +124,9 @@ jobs:
- name: check api reports and generate API reference
run: yarn build:api-reports:only --ci --docs
+ - name: verify changesets
+ run: node scripts/verify-changesets.js
+
- name: verify doc links
run: node scripts/verify-links.js
diff --git a/ADOPTERS.md b/ADOPTERS.md
index 32dff321ca..95f7812636 100644
--- a/ADOPTERS.md
+++ b/ADOPTERS.md
@@ -78,3 +78,4 @@
| [Keyloop](https://www.keyloop.com/) | [Andre Wanlin](https://github.com/awanlin) | Future-motive Developer Portal to help our teams create technology to make everything about buying and owning a car better. 🚗 |
| [Simply Business](https://sbtech.simplybusiness.co.uk/) | [@addersuk](https://github.com/addersuk), [@LightningStairs](https://github.com/LightningStairs), [@punitcse](https://github.com/punitcse), [@moltenice](https://github.com/moltenice) | Central developer portal to access everything a developer needs such as docs, internal service catalog, and the ability to quickly create a new service from a template. Internally developed Backstage plugins allow us to customise the experience to how we work. |
| [Overwolf](https://www.overwolf.com) | [@tomwolfgang](https://github.com/tomwolfgang) | Dev portal - software catalog, tech-docs, scaffolding |
+| [Hotmart](https://www.hotmart.com) | [@fabioviana-hotmart](https://github.com/fabioviana-hotmart) | The main Developers Portal to centralize docs, applications and technical metrics. |
diff --git a/docs/features/kubernetes/configuration.md b/docs/features/kubernetes/configuration.md
index 32ab830322..492cd86022 100644
--- a/docs/features/kubernetes/configuration.md
+++ b/docs/features/kubernetes/configuration.md
@@ -39,6 +39,7 @@ kubernetes:
region: 'europe-west1'
skipTLSVerify: true
skipMetricsLookup: true
+ exposeDashboard: true
```
### `serviceLocatorMethod`
@@ -113,9 +114,13 @@ kubectl -n get secret $(kubectl -n get sa Note: The catalog index page is designed to have a minimal code footprint to
> support easy customization, but creating a copy does introduce a possibility
@@ -21,12 +20,11 @@ the catalog - you can replace the routing in `App.tsx` to point to your own
For example, suppose that I want to allow filtering by a custom annotation added
to entities, `company.com/security-tier`. To start, I'll copy the code for the
-default catalog page and create a component in a
-[new plugin](../../plugins/create-a-plugin.md):
+default catalog page and create a component.
```tsx
// imports, etc omitted for brevity. for full source see:
-// https://github.com/backstage/backstage/blob/master/plugins/catalog/src/components/CatalogPage/CatalogPage.tsx
+// https://github.com/backstage/backstage/blob/master/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx
export const CustomCatalogPage = ({
columns,
actions,
@@ -167,21 +165,7 @@ export const CustomCatalogPage = ({
};
```
-This page itself can be exported as a routable extension in the plugin:
-
-```ts
-export const CustomCatalogIndexPage = myPlugin.provide(
- createRoutableExtension({
- name: 'CustomCatalogIndexPage',
- component: () =>
- import('./components/CustomCatalogPage').then(m => m.CustomCatalogPage),
- mountPoint: catalogRouteRef,
- }),
-);
-```
-
-Finally, we can replace the catalog route in the Backstage application with our
-new `CustomCatalogIndexPage`.
+Finally, we can apply our new `CustomCatalogPage`.
```diff
# packages/app/src/App.tsx
@@ -189,7 +173,9 @@ const routes = (
- } />
-+ } />
++ }>
++
++
```
The same method can be used to customize the _default_ filters with a different
diff --git a/docs/getting-started/app-custom-theme.md b/docs/getting-started/app-custom-theme.md
index a4ca0771df..b9b74f92dd 100644
--- a/docs/getting-started/app-custom-theme.md
+++ b/docs/getting-started/app-custom-theme.md
@@ -53,8 +53,10 @@ To add a custom theme to your Backstage app, you pass it as configuration to
For example, adding the theme that we created in the previous section can be
done like this:
-```ts
+```tsx
import { createApp } from '@backstage/app-defaults';
+import { ThemeProvider } from '@material-ui/core/styles';
+import CssBaseline from '@material-ui/core/CssBaseline';
const app = createApp({
apis: ...,
@@ -63,7 +65,11 @@ const app = createApp({
id: 'my-theme',
title: 'My Custom Theme',
variant: 'light',
- theme: myTheme,
+ Provider: ({ children }) => (
+
+ {children}
+
+ ),
}]
})
```
@@ -76,60 +82,67 @@ want to use the default themes, they are exported as `lightTheme` and
## Example of a custom theme
```ts
-const themeOptions = createThemeOptions({
+import {
+ createTheme,
+ genPageTheme,
+ lightTheme,
+ shapes,
+} from '@backstage/theme';
+
+const myTheme = createTheme({
palette: {
...lightTheme.palette,
primary: {
- main: '#123456',
+ main: '#343b58',
},
secondary: {
- main: '#123456',
+ main: '#565a6e',
},
error: {
- main: '#123456',
+ main: '#8c4351',
},
warning: {
- main: '#123456',
+ main: '#8f5e15',
},
info: {
- main: '#123456',
+ main: '#34548a',
},
success: {
- main: '#123456',
+ main: '#485e30',
},
background: {
- default: '#123456',
- paper: '#123456',
+ default: '#d5d6db',
+ paper: '#d5d6db',
},
banner: {
- info: '#123456',
- error: '#123456',
- text: '#123456',
- link: '#123456',
+ info: '#34548a',
+ error: '#8c4351',
+ text: '#343b58',
+ link: '#565a6e',
},
- errorBackground: '#123456',
- warningBackground: '#123456',
- infoBackground: '#123456',
+ errorBackground: '#8c4351',
+ warningBackground: '#8f5e15',
+ infoBackground: '#343b58',
navigation: {
- background: '#123456',
- indicator: '#123456',
- color: '#123456',
- selectedColor: '#123456',
+ background: '#343b58',
+ indicator: '#8f5e15',
+ color: '#d5d6db',
+ selectedColor: '#ffffff',
},
},
defaultPageTheme: 'home',
- fontFamily: 'Comic Sans',
+ fontFamily: 'Comic Sans MS',
/* below drives the header colors */
pageTheme: {
- home: genPageTheme(['#123456', '#123456'], shapes.wave),
- documentation: genPageTheme(['#123456', '#123456'], shapes.wave2),
- tool: genPageTheme(['#123456', '#123456'], shapes.round),
- service: genPageTheme(['#123456', '#123456'], shapes.wave),
- website: genPageTheme(['#123456', '#123456'], shapes.wave),
- library: genPageTheme(['#123456', '#123456'], shapes.wave),
- other: genPageTheme(['#123456', '#123456'], shapes.wave),
- app: genPageTheme(['#123456', '#123456'], shapes.wave),
- apis: genPageTheme(['#123456', '#123456'], shapes.wave),
+ home: genPageTheme(['#8c4351', '#343b58'], shapes.wave),
+ documentation: genPageTheme(['#8c4351', '#343b58'], shapes.wave2),
+ tool: genPageTheme(['#8c4351', '#343b58'], shapes.round),
+ service: genPageTheme(['#8c4351', '#343b58'], shapes.wave),
+ website: genPageTheme(['#8c4351', '#343b58'], shapes.wave),
+ library: genPageTheme(['#8c4351', '#343b58'], shapes.wave),
+ other: genPageTheme(['#8c4351', '#343b58'], shapes.wave),
+ app: genPageTheme(['#8c4351', '#343b58'], shapes.wave),
+ apis: genPageTheme(['#8c4351', '#343b58'], shapes.wave),
},
});
```
@@ -162,7 +175,7 @@ wouldn't be enough to alter the `box-shadow` property or to add css rules that
aren't already defined like a margin. For these cases you should also create an
override.
-```ts
+```tsx
import { createApp } from '@backstage/core-app-api';
import { BackstageTheme, lightTheme } from '@backstage/theme';
/**
@@ -187,6 +200,16 @@ export const createCustomThemeOverrides = (
};
};
+const customTheme: BackstageTheme = {
+ ...lightTheme,
+ overrides: {
+ // These are the overrides that Backstage applies to `material-ui` components
+ ...lightTheme.overrides,
+ // These are your custom overrides, either to `material-ui` or Backstage components.
+ ...createCustomThemeOverrides(lightTheme),
+ },
+};
+
const app = createApp({
apis: ...,
plugins: ...,
@@ -194,15 +217,11 @@ const app = createApp({
id: 'my-theme',
title: 'My Custom Theme',
variant: 'light',
- theme: {
- ...lightTheme,
- overrides: {
- // These are the overrides that Backstage applies to `material-ui` components
- ...lightTheme.overrides,
- // These are your custom overrides, either to `material-ui` or Backstage components.
- ...createCustomThemeOverrides(lightTheme),
- },
- },
+ Provider: ({ children }) => (
+
+ {children}
+
+ ),
}]
});
```
diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md
index 0f7b64ad5e..11c1cf7777 100644
--- a/packages/backend-common/CHANGELOG.md
+++ b/packages/backend-common/CHANGELOG.md
@@ -1,5 +1,17 @@
# @backstage/backend-common
+## 0.10.1
+
+### Patch Changes
+
+- 94cdf5d1bd: In-memory cache clients instantiated from the same cache manager now share the same memory space.
+- 916b2f1f3e: Use the default CSP policy provided by `helmet` directly rather than a copy.
+- 7d4b4e937c: Uptake changes to the GitHub Credentials Provider interface.
+- 995e4c7d9d: Added support for non-"amazonaws.com" hosts (for example when testing with LocalStack) in AwsS3UrlReader.
+- Updated dependencies
+ - @backstage/integration@0.7.0
+ - @backstage/config-loader@0.9.1
+
## 0.10.0
### Minor Changes
diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json
index cde1a7f67f..3aa368f963 100644
--- a/packages/backend-common/package.json
+++ b/packages/backend-common/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-common",
"description": "Common functionality library for Backstage backends",
- "version": "0.10.0",
+ "version": "0.10.1",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -31,9 +31,9 @@
"dependencies": {
"@backstage/cli-common": "^0.1.6",
"@backstage/config": "^0.1.11",
- "@backstage/config-loader": "^0.9.0",
+ "@backstage/config-loader": "^0.9.1",
"@backstage/errors": "^0.1.5",
- "@backstage/integration": "^0.6.10",
+ "@backstage/integration": "^0.7.0",
"@backstage/types": "^0.1.1",
"@google-cloud/storage": "^5.8.0",
"@lerna/project": "^4.0.0",
@@ -81,8 +81,8 @@
}
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/cli": "^0.10.4",
+ "@backstage/test-utils": "^0.2.1",
"@types/archiver": "^5.1.0",
"@types/compression": "^1.7.0",
"@types/concat-stream": "^1.6.0",
diff --git a/packages/backend-common/src/reading/AwsS3UrlReader.test.ts b/packages/backend-common/src/reading/AwsS3UrlReader.test.ts
index a3ae8b647f..2911699a5d 100644
--- a/packages/backend-common/src/reading/AwsS3UrlReader.test.ts
+++ b/packages/backend-common/src/reading/AwsS3UrlReader.test.ts
@@ -178,7 +178,7 @@ describe('AwsS3UrlReader', () => {
),
).rejects.toThrow(
Error(
- `Could not retrieve file from S3; caused by Error: not a valid AWS S3 URL: https://test-bucket.s3.us-east-2.NOTamazonaws.com/file.yaml`,
+ `Could not retrieve file from S3; caused by Error: invalid AWS S3 URL, cannot parse region from host in https://test-bucket.s3.us-east-2.NOTamazonaws.com/file.yaml`,
),
);
});
@@ -234,7 +234,7 @@ describe('AwsS3UrlReader', () => {
),
).rejects.toThrow(
Error(
- `Could not retrieve file from S3; caused by Error: not a valid AWS S3 URL: https://test-bucket.s3.us-east-2.NOTamazonaws.com/file.yaml`,
+ `Could not retrieve file from S3; caused by Error: invalid AWS S3 URL, cannot parse region from host in https://test-bucket.s3.us-east-2.NOTamazonaws.com/file.yaml`,
),
);
});
@@ -332,4 +332,47 @@ describe('AwsS3UrlReader', () => {
expect(body.toString().trim()).toBe('site_name: Test');
});
});
+
+ describe('readNonAwsHost', () => {
+ let awsS3UrlReader: AwsS3UrlReader;
+
+ beforeAll(() => {
+ AWSMock.setSDKInstance(aws);
+ AWSMock.mock(
+ 'S3',
+ 'getObject',
+ Buffer.from(
+ require('fs').readFileSync(
+ path.resolve(
+ __dirname,
+ '__fixtures__/awsS3/awsS3-mock-object.yaml',
+ ),
+ ),
+ ),
+ );
+
+ const s3 = new aws.S3();
+ awsS3UrlReader = new AwsS3UrlReader(
+ new AwsS3Integration(
+ readAwsS3IntegrationConfig(
+ new ConfigReader({
+ host: 'localhost:4566',
+ accessKeyId: 'fake-access-key',
+ secretAccessKey: 'fake-secret-key',
+ endpoint: 'http://localhost:4566',
+ s3ForcePathStyle: true,
+ }),
+ ),
+ ),
+ { s3, treeResponseFactory },
+ );
+ });
+
+ it('returns contents of an object in a bucket', async () => {
+ const response = await awsS3UrlReader.read(
+ 'http://localhost:4566/test-bucket/awsS3-mock-object.yaml',
+ );
+ expect(response.toString().trim()).toBe('site_name: Test');
+ });
+ });
});
diff --git a/packages/backend-common/src/reading/AwsS3UrlReader.ts b/packages/backend-common/src/reading/AwsS3UrlReader.ts
index 0d806fcfaa..1fca72e91c 100644
--- a/packages/backend-common/src/reading/AwsS3UrlReader.ts
+++ b/packages/backend-common/src/reading/AwsS3UrlReader.ts
@@ -27,12 +27,17 @@ import {
UrlReader,
} from './types';
import getRawBody from 'raw-body';
-import { AwsS3Integration, ScmIntegrations } from '@backstage/integration';
+import {
+ AwsS3Integration,
+ ScmIntegrations,
+ AwsS3IntegrationConfig,
+} from '@backstage/integration';
import { ForwardedError, NotModifiedError } from '@backstage/errors';
import { ListObjectsV2Output, ObjectList } from 'aws-sdk/clients/s3';
const parseURL = (
url: string,
+ config: AwsS3IntegrationConfig,
): { path: string; bucket: string; region: string } => {
let { host, pathname } = new URL(url);
@@ -42,20 +47,45 @@ const parseURL = (
*/
pathname = pathname.substr(1);
+ let bucket;
+ let region;
+
/**
- * Checks that the given URL is a valid S3 object url.
- * Format of a Valid S3 URL: https://bucket-name.s3.Region.amazonaws.com/keyname
+ * Path style URLs: https://s3.Region.amazonaws.com/bucket-name/key-name
+ * Virtual hosted style URLs: https://bucket-name.s3.Region.amazonaws.com/key-name
+ * See https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html#path-style-access
*/
- const validHost = new RegExp(
- /^[a-z\d][a-z\d\.-]{1,61}[a-z\d]\.s3\.[a-z\d-]+\.amazonaws.com$/,
- );
- if (!validHost.test(host)) {
- throw new Error(`not a valid AWS S3 URL: ${url}`);
+ if (config.s3ForcePathStyle) {
+ if (pathname.indexOf('/') < 0) {
+ throw new Error(
+ `invalid path-style AWS S3 URL, ${url} does not contain bucket in the path`,
+ );
+ }
+ [bucket] = pathname.split('/');
+ pathname = pathname.substr(bucket.length + 1);
+ } else {
+ if (host.indexOf('.') < 0) {
+ throw new Error(
+ `invalid virtual hosted-style AWS S3 URL, ${url} does not contain bucket prefix in the host`,
+ );
+ }
+ [bucket] = host.split('.');
+ host = host.substr(bucket.length + 1);
}
- const [bucket] = host.split(/\.s3\.[a-z\d-]+\.amazonaws.com/);
- host = host.substring(bucket.length);
- const [, , region, ,] = host.split('.');
+ // Only extract region from *.amazonaws.com hosts
+ if (config.host === 'amazonaws.com') {
+ // At this point bucket prefix is removed from host for virtual hosted URLs
+ const match = host.match(/^s3\.([a-z\d-]+)\.amazonaws\.com$/);
+ if (!match) {
+ throw new Error(
+ `invalid AWS S3 URL, cannot parse region from host in ${url}`,
+ );
+ }
+ region = match[1];
+ } else {
+ region = '';
+ }
return {
path: pathname,
@@ -70,9 +100,12 @@ export class AwsS3UrlReader implements UrlReader {
return integrations.awsS3.list().map(integration => {
const creds = AwsS3UrlReader.buildCredentials(integration);
+
const s3 = new S3({
apiVersion: '2006-03-01',
credentials: creds,
+ endpoint: integration.config.endpoint,
+ s3ForcePathStyle: integration.config.s3ForcePathStyle,
});
const reader = new AwsS3UrlReader(integration, {
s3,
@@ -138,7 +171,7 @@ export class AwsS3UrlReader implements UrlReader {
options?: ReadUrlOptions,
): Promise {
try {
- const { path, bucket, region } = parseURL(url);
+ const { path, bucket, region } = parseURL(url, this.integration.config);
aws.config.update({ region: region });
let params;
@@ -178,7 +211,7 @@ export class AwsS3UrlReader implements UrlReader {
options?: ReadTreeOptions,
): Promise {
try {
- const { path, bucket, region } = parseURL(url);
+ const { path, bucket, region } = parseURL(url, this.integration.config);
const allObjects: ObjectList = [];
const responses = [];
let continuationToken: string | undefined;
diff --git a/packages/backend-tasks/README.md b/packages/backend-tasks/README.md
index d3c361c02c..fe55f37afd 100644
--- a/packages/backend-tasks/README.md
+++ b/packages/backend-tasks/README.md
@@ -21,14 +21,19 @@ import { Duration } from 'luxon';
const scheduler = TaskScheduler.fromConfig(rootConfig).forPlugin('my-plugin');
await scheduler.scheduleTask({
- id: 'refresh-things',
+ id: 'refresh_things',
frequency: Duration.fromObject({ minutes: 10 }),
+ timeout: Duration.fromObject({ minutes: 15 }),
fn: async () => {
await entityProvider.run();
},
});
```
+## Local Development
+
+When working with the `@backstage/backend-tasks` library you may run into your task not running immediately at startup as expected if you are using a persistent database. This is by design - the library respects the previous state and does not run the task sooner than the specified frequency. If you want to get around this, there is a table called `backstage_backend_tasks__tasks` in the applicable plugin's database which will contain a record with the next run date and time. You can delete this record to get things back to what you expect.
+
## Documentation
- [Backstage Readme](https://github.com/backstage/backstage/blob/master/README.md)
diff --git a/packages/backend-test-utils/CHANGELOG.md b/packages/backend-test-utils/CHANGELOG.md
index b10dadb21c..f484a0fb8f 100644
--- a/packages/backend-test-utils/CHANGELOG.md
+++ b/packages/backend-test-utils/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/backend-test-utils
+## 0.1.12
+
+### Patch Changes
+
+- 130b7aadf2: Lazy-load `testcontainers` module in order to avoid side-effects.
+- Updated dependencies
+ - @backstage/backend-common@0.10.1
+ - @backstage/cli@0.10.4
+
## 0.1.11
### Patch Changes
diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json
index 218965c79f..e52398f0ef 100644
--- a/packages/backend-test-utils/package.json
+++ b/packages/backend-test-utils/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-test-utils",
"description": "Test helpers library for Backstage backends",
- "version": "0.1.11",
+ "version": "0.1.12",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -30,8 +30,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.10.0",
- "@backstage/cli": "^0.10.3",
+ "@backstage/backend-common": "^0.10.1",
+ "@backstage/cli": "^0.10.4",
"@backstage/config": "^0.1.9",
"knex": "^0.95.1",
"mysql2": "^2.2.5",
@@ -41,7 +41,7 @@
"uuid": "^8.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"jest": "^26.0.1"
},
"files": [
diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md
index 89283122f2..f3c2d4f861 100644
--- a/packages/backend/CHANGELOG.md
+++ b/packages/backend/CHANGELOG.md
@@ -1,5 +1,25 @@
# example-backend
+## 0.2.59
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-rollbar-backend@0.1.18
+ - @backstage/plugin-auth-backend@0.6.0
+ - @backstage/backend-common@0.10.1
+ - @backstage/plugin-app-backend@0.3.21
+ - @backstage/plugin-catalog-backend@0.19.4
+ - @backstage/plugin-scaffolder-backend@0.15.19
+ - @backstage/integration@0.7.0
+ - @backstage/plugin-techdocs-backend@0.12.2
+ - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.4
+ - @backstage/plugin-permission-backend@0.2.3
+ - @backstage/plugin-permission-node@0.2.3
+ - @backstage/plugin-code-coverage-backend@0.1.18
+ - @backstage/plugin-scaffolder-backend-module-rails@0.2.2
+ - @backstage/plugin-todo-backend@0.1.17
+
## 0.2.58
### Patch Changes
diff --git a/packages/backend/package.json b/packages/backend/package.json
index 4bdcad58f7..f204659789 100644
--- a/packages/backend/package.json
+++ b/packages/backend/package.json
@@ -1,6 +1,6 @@
{
"name": "example-backend",
- "version": "0.2.58",
+ "version": "0.2.59",
"main": "dist/index.cjs.js",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -24,38 +24,38 @@
"migrate:create": "knex migrate:make -x ts"
},
"dependencies": {
- "@backstage/backend-common": "^0.10.0",
+ "@backstage/backend-common": "^0.10.1",
"@backstage/backend-tasks": "^0.1.0",
"@backstage/catalog-client": "^0.5.3",
"@backstage/catalog-model": "^0.9.8",
"@backstage/config": "^0.1.10",
- "@backstage/integration": "^0.6.10",
- "@backstage/plugin-app-backend": "^0.3.20",
- "@backstage/plugin-auth-backend": "^0.5.2",
+ "@backstage/integration": "^0.7.0",
+ "@backstage/plugin-app-backend": "^0.3.21",
+ "@backstage/plugin-auth-backend": "^0.6.0",
"@backstage/plugin-azure-devops-backend": "^0.2.6",
"@backstage/plugin-badges-backend": "^0.1.14",
- "@backstage/plugin-catalog-backend": "^0.19.3",
- "@backstage/plugin-code-coverage-backend": "^0.1.17",
+ "@backstage/plugin-catalog-backend": "^0.19.4",
+ "@backstage/plugin-code-coverage-backend": "^0.1.18",
"@backstage/plugin-graphql-backend": "^0.1.10",
"@backstage/plugin-jenkins-backend": "^0.1.10",
"@backstage/plugin-kubernetes-backend": "^0.4.1",
"@backstage/plugin-kafka-backend": "^0.2.13",
- "@backstage/plugin-permission-backend": "^0.2.2",
+ "@backstage/plugin-permission-backend": "^0.2.3",
"@backstage/plugin-permission-common": "^0.3.0",
- "@backstage/plugin-permission-node": "^0.2.2",
+ "@backstage/plugin-permission-node": "^0.2.3",
"@backstage/plugin-proxy-backend": "^0.2.15",
- "@backstage/plugin-rollbar-backend": "^0.1.17",
- "@backstage/plugin-scaffolder-backend": "^0.15.18",
- "@backstage/plugin-scaffolder-backend-module-rails": "^0.2.1",
+ "@backstage/plugin-rollbar-backend": "^0.1.18",
+ "@backstage/plugin-scaffolder-backend": "^0.15.19",
+ "@backstage/plugin-scaffolder-backend-module-rails": "^0.2.2",
"@backstage/plugin-search-backend": "^0.3.0",
"@backstage/plugin-search-backend-node": "^0.4.2",
"@backstage/plugin-search-backend-module-elasticsearch": "^0.0.7",
"@backstage/plugin-search-backend-module-pg": "^0.2.3",
- "@backstage/plugin-techdocs-backend": "^0.12.1",
+ "@backstage/plugin-techdocs-backend": "^0.12.2",
"@backstage/plugin-tech-insights-backend": "^0.1.4",
"@backstage/plugin-tech-insights-node": "^0.1.2",
- "@backstage/plugin-tech-insights-backend-module-jsonfc": "^0.1.3",
- "@backstage/plugin-todo-backend": "^0.1.16",
+ "@backstage/plugin-tech-insights-backend-module-jsonfc": "^0.1.4",
+ "@backstage/plugin-todo-backend": "^0.1.17",
"@gitbeaker/node": "^34.6.0",
"@octokit/rest": "^18.5.3",
"azure-devops-node-api": "^11.0.1",
@@ -72,7 +72,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@types/dockerode": "^3.3.0",
"@types/express": "^4.17.6",
"@types/express-serve-static-core": "^4.17.5"
diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md
index 73e49693c2..8847545348 100644
--- a/packages/cli/CHANGELOG.md
+++ b/packages/cli/CHANGELOG.md
@@ -1,5 +1,16 @@
# @backstage/cli
+## 0.10.4
+
+### Patch Changes
+
+- 1d26017090: Fix issue with plugin:serve for Plugins not using Lerna monorepo.
+- 9c3aaf3512: Bump `@typescript-eslint/eslint-plugin` to `4.33.0`
+- 808828e4fa: remove inline CSS from serve_index.html
+- 6e4080d31b: Add option to build command for minifying the generated code
+- Updated dependencies
+ - @backstage/config-loader@0.9.1
+
## 0.10.3
### Patch Changes
diff --git a/packages/cli/package.json b/packages/cli/package.json
index 42a33da0db..21ba9b00b1 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.10.3",
+ "version": "0.10.4",
"private": false,
"publishConfig": {
"access": "public"
@@ -30,7 +30,7 @@
"dependencies": {
"@backstage/cli-common": "^0.1.6",
"@backstage/config": "^0.1.11",
- "@backstage/config-loader": "^0.9.0",
+ "@backstage/config-loader": "^0.9.1",
"@backstage/errors": "^0.1.5",
"@backstage/types": "^0.1.1",
"@hot-loader/react-dom": "^16.13.0",
@@ -51,7 +51,7 @@
"@svgr/rollup": "5.5.x",
"@svgr/webpack": "5.5.x",
"@types/webpack-env": "^1.15.2",
- "@typescript-eslint/eslint-plugin": "^v4.30.0",
+ "@typescript-eslint/eslint-plugin": "^v4.33.0",
"@typescript-eslint/parser": "^v4.28.3",
"@yarnpkg/lockfile": "^1.1.0",
"bfj": "^7.0.2",
@@ -114,13 +114,13 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/backend-common": "^0.10.0",
+ "@backstage/backend-common": "^0.10.1",
"@backstage/config": "^0.1.11",
"@backstage/core-components": "^0.8.2",
"@backstage/core-plugin-api": "^0.4.0",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@backstage/theme": "^0.2.14",
"@types/diff": "^5.0.0",
"@types/express": "^4.17.6",
diff --git a/packages/config-loader/CHANGELOG.md b/packages/config-loader/CHANGELOG.md
index cadd31555b..36aae32e8b 100644
--- a/packages/config-loader/CHANGELOG.md
+++ b/packages/config-loader/CHANGELOG.md
@@ -1,5 +1,11 @@
# @backstage/config-loader
+## 0.9.1
+
+### Patch Changes
+
+- 84663d59a3: Bump `typescript-json-schema` from `^0.51.0` to `^0.52.0`.
+
## 0.9.0
### Minor Changes
diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json
index 07fab1fd82..d909cde58c 100644
--- a/packages/config-loader/package.json
+++ b/packages/config-loader/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/config-loader",
"description": "Config loading functionality used by Backstage backend, and CLI",
- "version": "0.9.0",
+ "version": "0.9.1",
"private": false,
"publishConfig": {
"access": "public",
diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md
index 9d71eadeb0..969b9da42b 100644
--- a/packages/create-app/CHANGELOG.md
+++ b/packages/create-app/CHANGELOG.md
@@ -1,5 +1,125 @@
# @backstage/create-app
+## 0.4.10
+
+### Patch Changes
+
+- 79b342bd36: removed inline and internal CSS from index.html
+
+ To make this change to an existing app, apply the following changes to the `packages/app/public/index.html` file:
+
+ Remove internal style
+
+ ```diff
+ -
+ ```
+
+ Remove inline style from the body tag
+
+ ```diff
+ -
+ +
+ ```
+
+- d33b65dc52: Removed unused templating asset.
+- 613ad12960: Add a comment to the default backend about the fallback 404 handler.
+- 20af5a701f: The `` filter in the composed `SearchPage.tsx` was replaced with the `` variant.
+
+ This is an entirely optional change; if you wish to display a control surface for search `types` as a single-select accordion (as opposed to the current multi-select of checkboxes), you can make the following (or similar) changes to your search page layout:
+
+ ```diff
+ --- a/packages/app/src/components/search/SearchPage.tsx
+ +++ b/packages/app/src/components/search/SearchPage.tsx
+ @@ -11,7 +11,7 @@ import {
+ SearchType,
+ DefaultResultListItem,
+ } from '@backstage/plugin-search';
+ -import { Content, Header, Page } from '@backstage/core-components';
+ +import { CatalogIcon, Content, DocsIcon, Header, Page } from '@backstage/core-components';
+
+ const useStyles = makeStyles((theme: Theme) => ({
+ bar: {
+ @@ -19,6 +19,7 @@ const useStyles = makeStyles((theme: Theme) => ({
+ },
+ filters: {
+ padding: theme.spacing(2),
+ + marginTop: theme.spacing(2),
+ },
+ filter: {
+ '& + &': {
+ @@ -41,12 +42,23 @@ const SearchPage = () => {
+
+
+
+ + ,
+ + },
+ + {
+ + value: 'techdocs',
+ + name: 'Documentation',
+ + icon: ,
+ + },
+ + ]}
+ + />
+
+ -
+ {
+ // ...
+ + const scheduler = taskScheduler.forPlugin(plugin);
+ return {
+ + scheduler,
+ // ...
+ ```
+
## 0.4.9
### Patch Changes
diff --git a/packages/create-app/package.json b/packages/create-app/package.json
index 810df43f47..af1d20b215 100644
--- a/packages/create-app/package.json
+++ b/packages/create-app/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/create-app",
"description": "A CLI that helps you create your own Backstage app",
- "version": "0.4.9",
+ "version": "0.4.10",
"private": false,
"publishConfig": {
"access": "public"
diff --git a/packages/integration-react/CHANGELOG.md b/packages/integration-react/CHANGELOG.md
index 680ffc4847..121b778143 100644
--- a/packages/integration-react/CHANGELOG.md
+++ b/packages/integration-react/CHANGELOG.md
@@ -1,5 +1,12 @@
# @backstage/integration-react
+## 0.1.17
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/integration@0.7.0
+
## 0.1.16
### Patch Changes
diff --git a/packages/integration-react/package.json b/packages/integration-react/package.json
index 97d8ebea1a..62f9e8d593 100644
--- a/packages/integration-react/package.json
+++ b/packages/integration-react/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/integration-react",
"description": "Frontend package for managing integrations towards external systems",
- "version": "0.1.16",
+ "version": "0.1.17",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -24,7 +24,7 @@
"@backstage/config": "^0.1.11",
"@backstage/core-components": "^0.8.2",
"@backstage/core-plugin-api": "^0.4.0",
- "@backstage/integration": "^0.6.10",
+ "@backstage/integration": "^0.7.0",
"@backstage/theme": "^0.2.14",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -35,9 +35,9 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/packages/integration/CHANGELOG.md b/packages/integration/CHANGELOG.md
index e3380082f7..359d2dd11e 100644
--- a/packages/integration/CHANGELOG.md
+++ b/packages/integration/CHANGELOG.md
@@ -1,5 +1,23 @@
# @backstage/integration
+## 0.7.0
+
+### Minor Changes
+
+- 7d4b4e937c: Create an interface for the GitHub credentials provider in order to support providing implementations.
+
+ We have changed the name of the `GithubCredentialsProvider` to `SingleInstanceGithubCredentialsProvider`.
+
+ `GithubCredentialsProvider` is now an interface that maybe implemented to provide a custom mechanism to retrieve GitHub credentials.
+
+ In a later release we will support configuring URL readers, scaffolder tasks, and processors with customer GitHub credentials providers.
+
+ If you want to uptake this release, you will need to replace all references to `GithubCredentialsProvider.create` with `SingleInstanceGithubCredentialsProvider.create`.
+
+### Patch Changes
+
+- cf2e20a792: Added `endpoint` and `s3ForcePathStyle` as optional configuration for AWS S3 integrations.
+
## 0.6.10
### Patch Changes
diff --git a/packages/integration/api-report.md b/packages/integration/api-report.md
index 00623dc917..8e74470973 100644
--- a/packages/integration/api-report.md
+++ b/packages/integration/api-report.md
@@ -30,6 +30,8 @@ export class AwsS3Integration implements ScmIntegration {
// @public
export type AwsS3IntegrationConfig = {
host: string;
+ endpoint?: string;
+ s3ForcePathStyle?: boolean;
accessKeyId?: string;
secretAccessKey?: string;
roleArn?: string;
diff --git a/packages/integration/config.d.ts b/packages/integration/config.d.ts
index 90cc10f77b..8873f0f220 100644
--- a/packages/integration/config.d.ts
+++ b/packages/integration/config.d.ts
@@ -167,10 +167,23 @@ export interface Config {
/** Integration configuration for AWS S3 Service */
awsS3?: Array<{
/**
- * The host of the target that this matches on, e.g. "amazonaws.com".
+ * AWS Endpoint.
+ * The endpoint URI to send requests to. The default endpoint is built from the configured region.
+ * @see https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#constructor-property
+ *
+ * Supports non-AWS providers, e.g. for LocalStack, endpoint may look like http://localhost:4566
* @visibility frontend
*/
- host: string;
+ endpoint?: string;
+
+ /**
+ * Whether to use path style URLs when communicating with S3.
+ * Defaults to false.
+ * This allows providers like LocalStack, Minio and Wasabi (and possibly others) to be used.
+ * @visibility frontend
+ */
+ s3ForcePathStyle?: boolean;
+
/**
* Account access key used to authenticate requests.
* @visibility backend
diff --git a/packages/integration/package.json b/packages/integration/package.json
index ccf005ccec..ae674d2cf1 100644
--- a/packages/integration/package.json
+++ b/packages/integration/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/integration",
"description": "Helpers for managing integrations towards external systems",
- "version": "0.6.10",
+ "version": "0.7.0",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -39,9 +39,9 @@
"lodash": "^4.17.21"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
- "@backstage/config-loader": "^0.9.0",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/cli": "^0.10.4",
+ "@backstage/config-loader": "^0.9.1",
+ "@backstage/test-utils": "^0.2.1",
"@types/jest": "^26.0.7",
"@types/luxon": "^2.0.4",
"msw": "^0.35.0"
diff --git a/packages/integration/src/awsS3/AwsS3Integration.test.ts b/packages/integration/src/awsS3/AwsS3Integration.test.ts
index 481f3c1951..2987f46a8a 100644
--- a/packages/integration/src/awsS3/AwsS3Integration.test.ts
+++ b/packages/integration/src/awsS3/AwsS3Integration.test.ts
@@ -24,7 +24,7 @@ describe('AwsS3Integration', () => {
integrations: {
awsS3: [
{
- host: 'a.com',
+ endpoint: 'https://a.com',
accessKeyId: 'access key',
secretAccessKey: 'secret key',
},
diff --git a/packages/integration/src/awsS3/config.test.ts b/packages/integration/src/awsS3/config.test.ts
index 1c7d7d1647..4885a41a2a 100644
--- a/packages/integration/src/awsS3/config.test.ts
+++ b/packages/integration/src/awsS3/config.test.ts
@@ -26,16 +26,33 @@ describe('readAwsS3IntegrationConfig', () => {
return new ConfigReader(data);
}
- it('reads all values', () => {
+ it('reads all values (default)', () => {
const output = readAwsS3IntegrationConfig(
buildConfig({
- host: 'amazonaws.com',
accessKeyId: 'fake-key',
secretAccessKey: 'fake-secret-key',
}),
);
expect(output).toEqual({
host: 'amazonaws.com',
+ s3ForcePathStyle: false,
+ accessKeyId: 'fake-key',
+ secretAccessKey: 'fake-secret-key',
+ });
+ });
+ it('reads all values (endpoint)', () => {
+ const output = readAwsS3IntegrationConfig(
+ buildConfig({
+ endpoint: 'http://localhost:4566',
+ s3ForcePathStyle: true,
+ accessKeyId: 'fake-key',
+ secretAccessKey: 'fake-secret-key',
+ }),
+ );
+ expect(output).toEqual({
+ host: 'localhost:4566',
+ endpoint: 'http://localhost:4566',
+ s3ForcePathStyle: true,
accessKeyId: 'fake-key',
secretAccessKey: 'fake-secret-key',
});
@@ -59,6 +76,7 @@ describe('readAwsS3IntegrationConfigs', () => {
);
expect(output).toContainEqual({
host: 'amazonaws.com',
+ s3ForcePathStyle: false,
accessKeyId: 'key',
secretAccessKey: 'secret',
});
diff --git a/packages/integration/src/awsS3/config.ts b/packages/integration/src/awsS3/config.ts
index 6b5a23c85c..45cbdbe210 100644
--- a/packages/integration/src/awsS3/config.ts
+++ b/packages/integration/src/awsS3/config.ts
@@ -15,7 +15,6 @@
*/
import { Config } from '@backstage/config';
-import { isValidHost } from '../helpers';
const AMAZON_AWS_HOST = 'amazonaws.com';
@@ -26,24 +25,38 @@ const AMAZON_AWS_HOST = 'amazonaws.com';
*/
export type AwsS3IntegrationConfig = {
/**
- * The host of the target that this matches on, e.g. "amazonaws.com"
- *
- * Currently only "amazonaws.com" is supported.
+ * Host, derived from endpoint, and defaults to amazonaws.com
*/
host: string;
/**
- * accessKeyId
+ * (Optional) AWS Endpoint.
+ * The endpoint URI to send requests to. The default endpoint is built from the configured region.
+ * @see https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#constructor-property
+ *
+ * Supports non-AWS providers, e.g. for LocalStack, endpoint may look like http://localhost:4566
+ */
+ endpoint?: string;
+
+ /**
+ * (Optional) Whether to use path style URLs when communicating with S3.
+ * Defaults to false.
+ * This allows providers like LocalStack, Minio and Wasabi (and possibly others) to be used.
+ */
+ s3ForcePathStyle?: boolean;
+
+ /**
+ * (Optional) User access key id
*/
accessKeyId?: string;
/**
- * secretAccessKey
+ * (Optional) User secret access key
*/
secretAccessKey?: string;
/**
- * roleArn
+ * (Optional) ARN of role to be assumed
*/
roleArn?: string;
};
@@ -58,18 +71,42 @@ export type AwsS3IntegrationConfig = {
export function readAwsS3IntegrationConfig(
config: Config,
): AwsS3IntegrationConfig {
- const host = config.getOptionalString('host') ?? AMAZON_AWS_HOST;
+ const endpoint = config.getOptionalString('endpoint');
+ const s3ForcePathStyle =
+ config.getOptionalBoolean('s3ForcePathStyle') ?? false;
+ let host;
+ let pathname;
+ if (endpoint) {
+ try {
+ const url = new URL(endpoint);
+ host = url.host;
+ pathname = url.pathname;
+ } catch {
+ throw new Error(
+ `invalid awsS3 integration config, endpoint '${endpoint}' is not a valid URL`,
+ );
+ }
+ if (pathname !== '/') {
+ throw new Error(
+ `invalid awsS3 integration config, endpoints cannot contain path, got '${endpoint}'`,
+ );
+ }
+ } else {
+ host = AMAZON_AWS_HOST;
+ }
+
const accessKeyId = config.getOptionalString('accessKeyId');
const secretAccessKey = config.getOptionalString('secretAccessKey');
const roleArn = config.getOptionalString('roleArn');
- if (!isValidHost(host)) {
- throw new Error(
- `Invalid awsS3 integration config, '${host}' is not a valid host`,
- );
- }
-
- return { host, accessKeyId, secretAccessKey, roleArn };
+ return {
+ host,
+ endpoint,
+ s3ForcePathStyle,
+ accessKeyId,
+ secretAccessKey,
+ roleArn,
+ };
}
/**
diff --git a/packages/techdocs-cli/CHANGELOG.md b/packages/techdocs-cli/CHANGELOG.md
index d283c34b43..1690b9131c 100644
--- a/packages/techdocs-cli/CHANGELOG.md
+++ b/packages/techdocs-cli/CHANGELOG.md
@@ -1,5 +1,14 @@
# @techdocs/cli
+## 0.8.10
+
+### Patch Changes
+
+- 8fbc988bfc: remove internal and inline CSS from index.html
+- Updated dependencies
+ - @backstage/techdocs-common@0.11.2
+ - @backstage/backend-common@0.10.1
+
## 0.8.9
### Patch Changes
diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json
index be7c9f6b6a..b4c4ade6a3 100644
--- a/packages/techdocs-cli/package.json
+++ b/packages/techdocs-cli/package.json
@@ -1,7 +1,7 @@
{
"name": "@techdocs/cli",
"description": "Utility CLI for managing TechDocs sites in Backstage.",
- "version": "0.8.9",
+ "version": "0.8.10",
"private": false,
"publishConfig": {
"access": "public"
@@ -32,7 +32,7 @@
"techdocs-cli": "bin/techdocs-cli"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@types/commander": "^2.12.2",
"@types/fs-extra": "^9.0.6",
"@types/http-proxy": "^1.17.4",
@@ -56,10 +56,10 @@
"ext": "ts"
},
"dependencies": {
- "@backstage/backend-common": "^0.10.0",
+ "@backstage/backend-common": "^0.10.1",
"@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.10",
- "@backstage/techdocs-common": "^0.11.1",
+ "@backstage/techdocs-common": "^0.11.2",
"@types/dockerode": "^3.3.0",
"commander": "^6.1.0",
"dockerode": "^3.3.1",
diff --git a/packages/techdocs-common/CHANGELOG.md b/packages/techdocs-common/CHANGELOG.md
index ed5539752f..96281958b6 100644
--- a/packages/techdocs-common/CHANGELOG.md
+++ b/packages/techdocs-common/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/techdocs-common
+## 0.11.2
+
+### Patch Changes
+
+- c2c8768771: Bump `@azure/identity` from `^1.5.0` to `^2.0.1`.
+- Updated dependencies
+ - @backstage/backend-common@0.10.1
+ - @backstage/integration@0.7.0
+
## 0.11.1
### Patch Changes
diff --git a/packages/techdocs-common/package.json b/packages/techdocs-common/package.json
index 7d50a2bcba..f3e0f2d0d4 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.11.1",
+ "version": "0.11.2",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -38,12 +38,12 @@
"dependencies": {
"@azure/identity": "^2.0.1",
"@azure/storage-blob": "^12.5.0",
- "@backstage/backend-common": "^0.10.0",
+ "@backstage/backend-common": "^0.10.1",
"@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.11",
"@backstage/errors": "^0.1.5",
"@backstage/search-common": "^0.2.1",
- "@backstage/integration": "^0.6.10",
+ "@backstage/integration": "^0.7.0",
"@google-cloud/storage": "^5.6.0",
"@trendyol-js/openstack-swift-sdk": "^0.0.5",
"@types/express": "^4.17.6",
@@ -60,7 +60,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@types/fs-extra": "^9.0.5",
"@types/js-yaml": "^4.0.0",
"@types/mime-types": "^2.1.0",
diff --git a/packages/test-utils/CHANGELOG.md b/packages/test-utils/CHANGELOG.md
index 144c0ad257..fa747f84d1 100644
--- a/packages/test-utils/CHANGELOG.md
+++ b/packages/test-utils/CHANGELOG.md
@@ -1,5 +1,11 @@
# @backstage/test-utils
+## 0.2.1
+
+### Patch Changes
+
+- c36b7794f7: JSON serialize and freeze values stored by the `MockStorageApi`.
+
## 0.2.0
### Minor Changes
diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json
index c125885d88..acfe03bf99 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.2.0",
+ "version": "0.2.1",
"private": false,
"publishConfig": {
"access": "public",
@@ -47,7 +47,7 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32"
},
diff --git a/plugins/allure/package.json b/plugins/allure/package.json
index bfffe95d6d..6c6908dbc1 100644
--- a/plugins/allure/package.json
+++ b/plugins/allure/package.json
@@ -37,10 +37,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/analytics-module-ga/package.json b/plugins/analytics-module-ga/package.json
index 00fe5b6651..52a72e7cce 100644
--- a/plugins/analytics-module-ga/package.json
+++ b/plugins/analytics-module-ga/package.json
@@ -35,10 +35,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/apache-airflow/package.json b/plugins/apache-airflow/package.json
index 0c25b8a174..2ddcbd26a8 100644
--- a/plugins/apache-airflow/package.json
+++ b/plugins/apache-airflow/package.json
@@ -33,10 +33,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/api-docs/CHANGELOG.md b/plugins/api-docs/CHANGELOG.md
index 5baf5ac05a..989f4d33ba 100644
--- a/plugins/api-docs/CHANGELOG.md
+++ b/plugins/api-docs/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-api-docs
+## 0.6.20
+
+### Patch Changes
+
+- de81b7455e: Display entity title on `ApiDefinitionCard` if defined
+- Updated dependencies
+ - @backstage/plugin-catalog@0.7.6
+ - @backstage/plugin-catalog-react@0.6.9
+
## 0.6.19
### Patch Changes
diff --git a/plugins/api-docs/api-report.md b/plugins/api-docs/api-report.md
index 111660ae07..f0e8c06aab 100644
--- a/plugins/api-docs/api-report.md
+++ b/plugins/api-docs/api-report.md
@@ -5,7 +5,6 @@
```ts
///
-import { Action } from '@material-table/core';
import { ApiEntity } from '@backstage/catalog-model';
import { ApiRef } from '@backstage/core-plugin-api';
import { BackstagePlugin } from '@backstage/core-plugin-api';
@@ -15,6 +14,7 @@ import { ExternalRouteRef } from '@backstage/core-plugin-api';
import { default as React_2 } from 'react';
import { RouteRef } from '@backstage/core-plugin-api';
import { TableColumn } from '@backstage/core-components';
+import { TableProps } from '@backstage/core-components';
import { UserListFilterKind } from '@backstage/plugin-catalog-react';
// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts
@@ -53,27 +53,17 @@ const apiDocsPlugin: BackstagePlugin<
export { apiDocsPlugin };
export { apiDocsPlugin as plugin };
+// @public
+export const ApiExplorerIndexPage: (
+ props: DefaultApiExplorerPageProps,
+) => JSX.Element;
+
// Warning: (ae-missing-release-tag) "ApiExplorerPage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
-export const ApiExplorerPage: ({
- initiallySelectedFilter,
- columns,
- actions,
-}: {
- initiallySelectedFilter?: UserListFilterKind | undefined;
- columns?: TableColumn[] | undefined;
- actions?:
- | (
- | Action
- | {
- action: (rowData: CatalogTableRow) => Action;
- position: string;
- }
- | ((rowData: CatalogTableRow) => Action)
- )[]
- | undefined;
-}) => JSX.Element;
+export const ApiExplorerPage: (
+ props: DefaultApiExplorerPageProps,
+) => JSX.Element;
// Warning: (ae-missing-release-tag) "ApiTypeTitle" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
@@ -110,6 +100,20 @@ export const ConsumedApisCard: ({ variant }: Props_2) => JSX.Element;
// @public (undocumented)
export const ConsumingComponentsCard: ({ variant }: Props_5) => JSX.Element;
+// @public
+export const DefaultApiExplorerPage: ({
+ initiallySelectedFilter,
+ columns,
+ actions,
+}: DefaultApiExplorerPageProps) => JSX.Element;
+
+// @public
+export type DefaultApiExplorerPageProps = {
+ initiallySelectedFilter?: UserListFilterKind;
+ columns?: TableColumn[];
+ actions?: TableProps['actions'];
+};
+
// Warning: (ae-missing-release-tag) "defaultDefinitionWidgets" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json
index b361d991cb..d1ba6080e5 100644
--- a/plugins/api-docs/package.json
+++ b/plugins/api-docs/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-api-docs",
"description": "A Backstage plugin that helps represent API entities in the frontend",
- "version": "0.6.19",
+ "version": "0.6.20",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -34,8 +34,8 @@
"@backstage/catalog-model": "^0.9.7",
"@backstage/core-components": "^0.8.2",
"@backstage/core-plugin-api": "^0.4.0",
- "@backstage/plugin-catalog": "^0.7.5",
- "@backstage/plugin-catalog-react": "^0.6.8",
+ "@backstage/plugin-catalog": "^0.7.6",
+ "@backstage/plugin-catalog-react": "^0.6.9",
"@backstage/theme": "^0.2.14",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -54,10 +54,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.test.tsx b/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.test.tsx
index 3629110d47..760d1ab59d 100644
--- a/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.test.tsx
+++ b/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.test.tsx
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Backstage Authors
+ * Copyright 2021 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,185 +14,31 @@
* limitations under the License.
*/
-import { Entity, RELATION_MEMBER_OF } from '@backstage/catalog-model';
-import { ConfigReader } from '@backstage/core-app-api';
-import { TableColumn, TableProps } from '@backstage/core-components';
-import {
- ConfigApi,
- configApiRef,
- storageApiRef,
-} from '@backstage/core-plugin-api';
-import { CatalogTableRow } from '@backstage/plugin-catalog';
-import {
- CatalogApi,
- catalogApiRef,
- DefaultStarredEntitiesApi,
- entityRouteRef,
- starredEntitiesApiRef,
-} from '@backstage/plugin-catalog-react';
-import {
- MockStorageApi,
- TestApiProvider,
- wrapInTestApp,
-} from '@backstage/test-utils';
-import DashboardIcon from '@material-ui/icons/Dashboard';
-import { render } from '@testing-library/react';
import React from 'react';
-import { apiDocsConfigRef } from '../../config';
+import { renderInTestApp } from '@backstage/test-utils';
+import { useOutlet } from 'react-router';
import { ApiExplorerPage } from './ApiExplorerPage';
-describe('ApiCatalogPage', () => {
- const catalogApi: Partial = {
- getEntities: () =>
- Promise.resolve({
- items: [
- {
- apiVersion: 'backstage.io/v1alpha1',
- kind: 'API',
- metadata: {
- name: 'Entity1',
- },
- spec: { type: 'openapi' },
- },
- ] as Entity[],
- }),
- getLocationByEntity: () =>
- Promise.resolve({ id: 'id', type: 'github', target: 'url' }),
- getEntityByName: async entityName => {
- return {
- apiVersion: 'backstage.io/v1alpha1',
- kind: 'User',
- metadata: { name: entityName.name },
- relations: [
- {
- type: RELATION_MEMBER_OF,
- target: { namespace: 'default', kind: 'Group', name: 'tools' },
- },
- ],
- };
- },
- };
+jest.mock('react-router', () => ({
+ ...jest.requireActual('react-router'),
+ useOutlet: jest.fn().mockReturnValue('Route Children'),
+}));
- const configApi: ConfigApi = new ConfigReader({
- organization: {
- name: 'My Company',
- },
+jest.mock('./DefaultApiExplorerPage', () => ({
+ DefaultApiExplorerPage: jest.fn().mockReturnValue('DefaultApiExplorerPage'),
+}));
+
+describe('ApiExplorerPage', () => {
+ it('renders provided router element', async () => {
+ const { getByText } = await renderInTestApp();
+
+ expect(getByText('Route Children')).toBeInTheDocument();
});
- const apiDocsConfig = {
- getApiDefinitionWidget: () => undefined,
- };
+ it('renders DefaultApiExplorerPage home when no router children are provided', async () => {
+ (useOutlet as jest.Mock).mockReturnValueOnce(null);
+ const { getByText } = await renderInTestApp();
- const storageApi = MockStorageApi.create();
-
- const renderWrapped = (children: React.ReactNode) =>
- render(
- wrapInTestApp(
-
- {children}
- ,
- {
- mountedRoutes: {
- '/catalog/:namespace/:kind/:name': entityRouteRef,
- },
- },
- ),
- );
-
- // this test right now causes some red lines in the log output when running tests
- // related to some theme issues in mui-table
- // https://github.com/mbrn/material-table/issues/1293
- it('should render', async () => {
- const { findByText } = renderWrapped();
- expect(await findByText(/My Company API Explorer/)).toBeInTheDocument();
- });
-
- it('should render the default column of the grid', async () => {
- const { getAllByRole } = renderWrapped();
-
- const columnHeader = getAllByRole('button').filter(
- c => c.tagName === 'SPAN',
- );
- const columnHeaderLabels = columnHeader.map(c => c.textContent);
-
- expect(columnHeaderLabels).toEqual([
- 'Name',
- 'System',
- 'Owner',
- 'Type',
- 'Lifecycle',
- 'Description',
- 'Tags',
- 'Actions',
- ]);
- });
-
- it('should render the custom column passed as prop', async () => {
- const columns: TableColumn[] = [
- { title: 'Foo', field: 'entity.foo' },
- { title: 'Bar', field: 'entity.bar' },
- { title: 'Baz', field: 'entity.spec.lifecycle' },
- ];
- const { getAllByRole } = renderWrapped(
- ,
- );
-
- const columnHeader = getAllByRole('button').filter(
- c => c.tagName === 'SPAN',
- );
- const columnHeaderLabels = columnHeader.map(c => c.textContent);
-
- expect(columnHeaderLabels).toEqual(['Foo', 'Bar', 'Baz', 'Actions']);
- });
-
- it('should render the default actions of an item in the grid', async () => {
- const { findByTitle, findByText } = await renderWrapped(
- ,
- );
- expect(await findByText(/All \(1\)/)).toBeInTheDocument();
- expect(await findByTitle(/View/)).toBeInTheDocument();
- expect(await findByTitle(/View/)).toBeInTheDocument();
- expect(await findByTitle(/Edit/)).toBeInTheDocument();
- expect(await findByTitle(/Add to favorites/)).toBeInTheDocument();
- });
-
- it('should render the custom actions of an item passed as prop', async () => {
- const actions: TableProps['actions'] = [
- () => {
- return {
- icon: () => ,
- tooltip: 'Foo Action',
- disabled: false,
- onClick: () => jest.fn(),
- };
- },
- () => {
- return {
- icon: () => ,
- tooltip: 'Bar Action',
- disabled: true,
- onClick: () => jest.fn(),
- };
- },
- ];
-
- const { findByTitle, findByText } = await renderWrapped(
- ,
- );
- expect(await findByText(/All \(1\)/)).toBeInTheDocument();
- expect(await findByTitle(/Foo Action/)).toBeInTheDocument();
- expect(await findByTitle(/Bar Action/)).toBeInTheDocument();
- expect((await findByTitle(/Bar Action/)).firstChild).toBeDisabled();
+ expect(getByText('DefaultApiExplorerPage')).toBeInTheDocument();
});
});
diff --git a/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.tsx b/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.tsx
index f28574145e..68ab0a1647 100644
--- a/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.tsx
+++ b/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerPage.tsx
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Backstage Authors
+ * Copyright 2021 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,97 +14,19 @@
* limitations under the License.
*/
-import {
- Content,
- ContentHeader,
- CreateButton,
- PageWithHeader,
- SupportButton,
- TableColumn,
- TableProps,
-} from '@backstage/core-components';
-import { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api';
-import {
- CatalogTable,
- CatalogTableRow,
- FilteredEntityLayout,
- EntityListContainer,
- FilterContainer,
-} from '@backstage/plugin-catalog';
-import {
- EntityKindPicker,
- EntityLifecyclePicker,
- EntityListProvider,
- EntityOwnerPicker,
- EntityTagPicker,
- EntityTypePicker,
- UserListFilterKind,
- UserListPicker,
-} from '@backstage/plugin-catalog-react';
import React from 'react';
-import { createComponentRouteRef } from '../../routes';
+import { useOutlet } from 'react-router';
+import {
+ DefaultApiExplorerPage,
+ DefaultApiExplorerPageProps,
+} from './DefaultApiExplorerPage';
-const defaultColumns: TableColumn[] = [
- CatalogTable.columns.createNameColumn({ defaultKind: 'API' }),
- CatalogTable.columns.createSystemColumn(),
- CatalogTable.columns.createOwnerColumn(),
- CatalogTable.columns.createSpecTypeColumn(),
- CatalogTable.columns.createSpecLifecycleColumn(),
- CatalogTable.columns.createMetadataDescriptionColumn(),
- CatalogTable.columns.createTagsColumn(),
-];
+/**
+ * ApiExplorerPage
+ * @public
+ */
+export const ApiExplorerPage = (props: DefaultApiExplorerPageProps) => {
+ const outlet = useOutlet();
-type ApiExplorerPageProps = {
- initiallySelectedFilter?: UserListFilterKind;
- columns?: TableColumn[];
- actions?: TableProps['actions'];
-};
-
-export const ApiExplorerPage = ({
- initiallySelectedFilter = 'all',
- columns,
- actions,
-}: ApiExplorerPageProps) => {
- const configApi = useApi(configApiRef);
- const generatedSubtitle = `${
- configApi.getOptionalString('organization.name') ?? 'Backstage'
- } API Explorer`;
- const createComponentLink = useRouteRef(createComponentRouteRef);
-
- return (
-
-
-
-
- All your APIs
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
+ return outlet || ;
};
diff --git a/plugins/api-docs/src/components/ApiExplorerPage/DefaultApiExplorerPage.test.tsx b/plugins/api-docs/src/components/ApiExplorerPage/DefaultApiExplorerPage.test.tsx
new file mode 100644
index 0000000000..9e4c861e24
--- /dev/null
+++ b/plugins/api-docs/src/components/ApiExplorerPage/DefaultApiExplorerPage.test.tsx
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Entity, RELATION_MEMBER_OF } from '@backstage/catalog-model';
+import { ConfigReader } from '@backstage/core-app-api';
+import { TableColumn, TableProps } from '@backstage/core-components';
+import {
+ ConfigApi,
+ configApiRef,
+ storageApiRef,
+} from '@backstage/core-plugin-api';
+import { CatalogTableRow } from '@backstage/plugin-catalog';
+import {
+ CatalogApi,
+ catalogApiRef,
+ DefaultStarredEntitiesApi,
+ entityRouteRef,
+ starredEntitiesApiRef,
+} from '@backstage/plugin-catalog-react';
+import {
+ MockStorageApi,
+ TestApiProvider,
+ wrapInTestApp,
+} from '@backstage/test-utils';
+import DashboardIcon from '@material-ui/icons/Dashboard';
+import { render } from '@testing-library/react';
+import React from 'react';
+import { apiDocsConfigRef } from '../../config';
+import { DefaultApiExplorerPage } from './DefaultApiExplorerPage';
+
+describe('DefaultApiExplorerPage', () => {
+ const catalogApi: Partial = {
+ getEntities: () =>
+ Promise.resolve({
+ items: [
+ {
+ apiVersion: 'backstage.io/v1alpha1',
+ kind: 'API',
+ metadata: {
+ name: 'Entity1',
+ },
+ spec: { type: 'openapi' },
+ },
+ ] as Entity[],
+ }),
+ getLocationByEntity: () =>
+ Promise.resolve({ id: 'id', type: 'github', target: 'url' }),
+ getEntityByName: async entityName => {
+ return {
+ apiVersion: 'backstage.io/v1alpha1',
+ kind: 'User',
+ metadata: { name: entityName.name },
+ relations: [
+ {
+ type: RELATION_MEMBER_OF,
+ target: { namespace: 'default', kind: 'Group', name: 'tools' },
+ },
+ ],
+ };
+ },
+ };
+
+ const configApi: ConfigApi = new ConfigReader({
+ organization: {
+ name: 'My Company',
+ },
+ });
+
+ const apiDocsConfig = {
+ getApiDefinitionWidget: () => undefined,
+ };
+
+ const storageApi = MockStorageApi.create();
+
+ const renderWrapped = (children: React.ReactNode) =>
+ render(
+ wrapInTestApp(
+
+ {children}
+ ,
+ {
+ mountedRoutes: {
+ '/catalog/:namespace/:kind/:name': entityRouteRef,
+ },
+ },
+ ),
+ );
+
+ // this test right now causes some red lines in the log output when running tests
+ // related to some theme issues in mui-table
+ // https://github.com/mbrn/material-table/issues/1293
+ it('should render', async () => {
+ const { findByText } = renderWrapped();
+ expect(await findByText(/My Company API Explorer/)).toBeInTheDocument();
+ });
+
+ it('should render the default column of the grid', async () => {
+ const { getAllByRole } = renderWrapped();
+
+ const columnHeader = getAllByRole('button').filter(
+ c => c.tagName === 'SPAN',
+ );
+ const columnHeaderLabels = columnHeader.map(c => c.textContent);
+
+ expect(columnHeaderLabels).toEqual([
+ 'Name',
+ 'System',
+ 'Owner',
+ 'Type',
+ 'Lifecycle',
+ 'Description',
+ 'Tags',
+ 'Actions',
+ ]);
+ });
+
+ it('should render the custom column passed as prop', async () => {
+ const columns: TableColumn[] = [
+ { title: 'Foo', field: 'entity.foo' },
+ { title: 'Bar', field: 'entity.bar' },
+ { title: 'Baz', field: 'entity.spec.lifecycle' },
+ ];
+ const { getAllByRole } = renderWrapped(
+ ,
+ );
+
+ const columnHeader = getAllByRole('button').filter(
+ c => c.tagName === 'SPAN',
+ );
+ const columnHeaderLabels = columnHeader.map(c => c.textContent);
+
+ expect(columnHeaderLabels).toEqual(['Foo', 'Bar', 'Baz', 'Actions']);
+ });
+
+ it('should render the default actions of an item in the grid', async () => {
+ const { findByTitle, findByText } = await renderWrapped(
+ ,
+ );
+ expect(await findByText(/All \(1\)/)).toBeInTheDocument();
+ expect(await findByTitle(/View/)).toBeInTheDocument();
+ expect(await findByTitle(/View/)).toBeInTheDocument();
+ expect(await findByTitle(/Edit/)).toBeInTheDocument();
+ expect(await findByTitle(/Add to favorites/)).toBeInTheDocument();
+ });
+
+ it('should render the custom actions of an item passed as prop', async () => {
+ const actions: TableProps['actions'] = [
+ () => {
+ return {
+ icon: () => ,
+ tooltip: 'Foo Action',
+ disabled: false,
+ onClick: () => jest.fn(),
+ };
+ },
+ () => {
+ return {
+ icon: () => ,
+ tooltip: 'Bar Action',
+ disabled: true,
+ onClick: () => jest.fn(),
+ };
+ },
+ ];
+
+ const { findByTitle, findByText } = await renderWrapped(
+ ,
+ );
+ expect(await findByText(/All \(1\)/)).toBeInTheDocument();
+ expect(await findByTitle(/Foo Action/)).toBeInTheDocument();
+ expect(await findByTitle(/Bar Action/)).toBeInTheDocument();
+ expect((await findByTitle(/Bar Action/)).firstChild).toBeDisabled();
+ });
+});
diff --git a/plugins/api-docs/src/components/ApiExplorerPage/DefaultApiExplorerPage.tsx b/plugins/api-docs/src/components/ApiExplorerPage/DefaultApiExplorerPage.tsx
new file mode 100644
index 0000000000..5ddda96daa
--- /dev/null
+++ b/plugins/api-docs/src/components/ApiExplorerPage/DefaultApiExplorerPage.tsx
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ Content,
+ ContentHeader,
+ CreateButton,
+ PageWithHeader,
+ SupportButton,
+ TableColumn,
+ TableProps,
+} from '@backstage/core-components';
+import { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api';
+import {
+ CatalogTable,
+ CatalogTableRow,
+ FilteredEntityLayout,
+ EntityListContainer,
+ FilterContainer,
+} from '@backstage/plugin-catalog';
+import {
+ EntityKindPicker,
+ EntityLifecyclePicker,
+ EntityListProvider,
+ EntityOwnerPicker,
+ EntityTagPicker,
+ EntityTypePicker,
+ UserListFilterKind,
+ UserListPicker,
+} from '@backstage/plugin-catalog-react';
+import React from 'react';
+import { createComponentRouteRef } from '../../routes';
+
+const defaultColumns: TableColumn[] = [
+ CatalogTable.columns.createNameColumn({ defaultKind: 'API' }),
+ CatalogTable.columns.createSystemColumn(),
+ CatalogTable.columns.createOwnerColumn(),
+ CatalogTable.columns.createSpecTypeColumn(),
+ CatalogTable.columns.createSpecLifecycleColumn(),
+ CatalogTable.columns.createMetadataDescriptionColumn(),
+ CatalogTable.columns.createTagsColumn(),
+];
+
+/**
+ * DefaultApiExplorerPageProps
+ * @public
+ */
+export type DefaultApiExplorerPageProps = {
+ initiallySelectedFilter?: UserListFilterKind;
+ columns?: TableColumn[];
+ actions?: TableProps['actions'];
+};
+
+/**
+ * DefaultApiExplorerPage
+ * @public
+ */
+export const DefaultApiExplorerPage = ({
+ initiallySelectedFilter = 'all',
+ columns,
+ actions,
+}: DefaultApiExplorerPageProps) => {
+ const configApi = useApi(configApiRef);
+ const generatedSubtitle = `${
+ configApi.getOptionalString('organization.name') ?? 'Backstage'
+ } API Explorer`;
+ const createComponentLink = useRouteRef(createComponentRouteRef);
+
+ return (
+
+
+
+
+ All your APIs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/plugins/api-docs/src/components/ApiExplorerPage/index.ts b/plugins/api-docs/src/components/ApiExplorerPage/index.ts
index 3d170260ad..813ca90229 100644
--- a/plugins/api-docs/src/components/ApiExplorerPage/index.ts
+++ b/plugins/api-docs/src/components/ApiExplorerPage/index.ts
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Backstage Authors
+ * Copyright 2021 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,4 +14,6 @@
* limitations under the License.
*/
-export { ApiExplorerPage } from './ApiExplorerPage';
+export { ApiExplorerPage as ApiExplorerIndexPage } from './ApiExplorerPage';
+export { DefaultApiExplorerPage } from './DefaultApiExplorerPage';
+export type { DefaultApiExplorerPageProps } from './DefaultApiExplorerPage';
diff --git a/plugins/api-docs/src/components/index.ts b/plugins/api-docs/src/components/index.ts
index c0af59dc52..f4d8034b56 100644
--- a/plugins/api-docs/src/components/index.ts
+++ b/plugins/api-docs/src/components/index.ts
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+export * from './ApiExplorerPage';
export * from './ApiDefinitionCard';
export * from './ApisCards';
export * from './AsyncApiDefinitionWidget';
diff --git a/plugins/api-docs/src/plugin.ts b/plugins/api-docs/src/plugin.ts
index f400be9c7c..61695b4a7a 100644
--- a/plugins/api-docs/src/plugin.ts
+++ b/plugins/api-docs/src/plugin.ts
@@ -53,7 +53,7 @@ export const ApiExplorerPage = apiDocsPlugin.provide(
createRoutableExtension({
name: 'ApiExplorerPage',
component: () =>
- import('./components/ApiExplorerPage').then(m => m.ApiExplorerPage),
+ import('./components/ApiExplorerPage').then(m => m.ApiExplorerIndexPage),
mountPoint: rootRoute,
}),
);
diff --git a/plugins/app-backend/CHANGELOG.md b/plugins/app-backend/CHANGELOG.md
index 892deeed88..1ae02be713 100644
--- a/plugins/app-backend/CHANGELOG.md
+++ b/plugins/app-backend/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-app-backend
+## 0.3.21
+
+### Patch Changes
+
+- 9d9cfc1b8a: Set `X-Frame-Options: deny` rather than the default `sameorigin` for all content served by the `app-backend`.`
+- Updated dependencies
+ - @backstage/backend-common@0.10.1
+ - @backstage/config-loader@0.9.1
+
## 0.3.20
### Patch Changes
diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json
index 58469b27fe..b1a01a8345 100644
--- a/plugins/app-backend/package.json
+++ b/plugins/app-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-app-backend",
"description": "A Backstage backend plugin that serves the Backstage frontend app",
- "version": "0.3.20",
+ "version": "0.3.21",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -30,8 +30,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.10.0",
- "@backstage/config-loader": "^0.9.0",
+ "@backstage/backend-common": "^0.10.1",
+ "@backstage/config-loader": "^0.9.1",
"@backstage/config": "^0.1.11",
"@backstage/types": "^0.1.1",
"@types/express": "^4.17.6",
@@ -43,7 +43,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/types": "^0.1.1",
"@types/supertest": "^2.0.8",
"msw": "^0.35.0",
diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md
index 86d3c2a30d..c130b58dc8 100644
--- a/plugins/auth-backend/CHANGELOG.md
+++ b/plugins/auth-backend/CHANGELOG.md
@@ -1,5 +1,45 @@
# @backstage/plugin-auth-backend
+## 0.6.0
+
+### Minor Changes
+
+- c88cdacc1a: Avoid ever returning OAuth refresh tokens back to the client, and always exchange refresh tokens for a new one when available for all providers.
+
+ This comes with a breaking change to the TypeScript API for custom auth providers. The `refresh` method of `OAuthHandlers` implementation must now return a `{ response, refreshToken }` object rather than a direct response. Existing `refresh` implementations are typically migrated by changing an existing return expression that looks like this:
+
+ ```ts
+ return await this.handleResult({
+ fullProfile,
+ params,
+ accessToken,
+ refreshToken,
+ });
+ ```
+
+ Into the following:
+
+ ```ts
+ return {
+ response: await this.handleResult({
+ fullProfile,
+ params,
+ accessToken,
+ }),
+ refreshToken,
+ };
+ ```
+
+### Patch Changes
+
+- f0f81f6cc7: Replaces the usage of `got` with `node-fetch` in the `getUserPhoto` method of the Microsoft provider
+- 2f26120a36: Update `auth0` and `onelogin` providers to allow for `authHandler` and `signIn.resolver` configuration.
+- a9abafa9df: Fixed bug on refresh token on Okta provider, now it gets the refresh token and it sends it into providerInfo
+- eb48e78886: Enforce cookie SSL protection when in production for auth-backend sessions
+- Updated dependencies
+ - @backstage/test-utils@0.2.1
+ - @backstage/backend-common@0.10.1
+
## 0.5.2
### Patch Changes
diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json
index 1f3d47a346..620c8b397a 100644
--- a/plugins/auth-backend/package.json
+++ b/plugins/auth-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-auth-backend",
"description": "A Backstage backend plugin that handles authentication",
- "version": "0.5.2",
+ "version": "0.6.0",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -30,12 +30,12 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.10.0",
+ "@backstage/backend-common": "^0.10.1",
"@backstage/catalog-client": "^0.5.3",
"@backstage/catalog-model": "^0.9.8",
"@backstage/config": "^0.1.11",
"@backstage/errors": "^0.1.5",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@google-cloud/firestore": "^4.15.1",
"@types/express": "^4.17.6",
"@types/passport": "^1.0.3",
@@ -72,7 +72,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@types/body-parser": "^1.19.0",
"@types/cookie-parser": "^1.4.2",
"@types/express-session": "^1.17.2",
diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json
index 86b26af501..3c1f5dd351 100644
--- a/plugins/azure-devops/package.json
+++ b/plugins/azure-devops/package.json
@@ -46,10 +46,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/badges/package.json b/plugins/badges/package.json
index 2f9f109752..663d6f0824 100644
--- a/plugins/badges/package.json
+++ b/plugins/badges/package.json
@@ -43,10 +43,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/bazaar/package.json b/plugins/bazaar/package.json
index c36a529d1c..9bf4f22afe 100644
--- a/plugins/bazaar/package.json
+++ b/plugins/bazaar/package.json
@@ -43,7 +43,7 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/dev-utils": "^0.2.15",
"@testing-library/jest-dom": "^5.10.1",
"cross-fetch": "^3.0.6"
diff --git a/plugins/bitrise/package.json b/plugins/bitrise/package.json
index 36d2f3006d..3ef3fc1722 100644
--- a/plugins/bitrise/package.json
+++ b/plugins/bitrise/package.json
@@ -40,10 +40,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md
index 43138d734f..e53bb50e1a 100644
--- a/plugins/catalog-backend/CHANGELOG.md
+++ b/plugins/catalog-backend/CHANGELOG.md
@@ -1,5 +1,15 @@
# @backstage/plugin-catalog-backend
+## 0.19.4
+
+### Patch Changes
+
+- 7d4b4e937c: Uptake changes to the GitHub Credentials Provider interface.
+- 3a63491c5f: Filter out projects with missing `default_branch` from GitLab Discovery.
+- Updated dependencies
+ - @backstage/backend-common@0.10.1
+ - @backstage/integration@0.7.0
+
## 0.19.3
### Patch Changes
diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json
index 3f8f20dc1f..01e79314c5 100644
--- a/plugins/catalog-backend/package.json
+++ b/plugins/catalog-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-backend",
"description": "The Backstage backend plugin that provides the Backstage catalog",
- "version": "0.19.3",
+ "version": "0.19.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -30,12 +30,12 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.10.0",
+ "@backstage/backend-common": "^0.10.1",
"@backstage/catalog-client": "^0.5.3",
"@backstage/catalog-model": "^0.9.8",
"@backstage/config": "^0.1.11",
"@backstage/errors": "^0.1.5",
- "@backstage/integration": "^0.6.10",
+ "@backstage/integration": "^0.7.0",
"@backstage/search-common": "^0.2.1",
"@backstage/types": "^0.1.1",
"@octokit/graphql": "^4.5.8",
@@ -62,9 +62,9 @@
"yup": "^0.32.9"
},
"devDependencies": {
- "@backstage/backend-test-utils": "^0.1.11",
- "@backstage/cli": "^0.10.3",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/backend-test-utils": "^0.1.12",
+ "@backstage/cli": "^0.10.4",
+ "@backstage/test-utils": "^0.2.1",
"@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/GitLabDiscoveryProcessor.test.ts b/plugins/catalog-backend/src/ingestion/processors/GitLabDiscoveryProcessor.test.ts
index 311de05673..8d85d7375f 100644
--- a/plugins/catalog-backend/src/ingestion/processors/GitLabDiscoveryProcessor.test.ts
+++ b/plugins/catalog-backend/src/ingestion/processors/GitLabDiscoveryProcessor.test.ts
@@ -184,6 +184,13 @@ describe('GitlabDiscoveryProcessor', () => {
last_activity_at: '2021-08-05T11:03:05.774Z',
web_url: 'https://gitlab.fake/3',
},
+ {
+ id: 4,
+ archived: false,
+ default_branch: undefined, // MISSING DEFAULT BRANCH
+ last_activity_at: '2021-08-05T11:03:05.774Z',
+ web_url: 'https://gitlab.fake/4',
+ },
],
};
default:
diff --git a/plugins/catalog-backend/src/ingestion/processors/GitLabDiscoveryProcessor.ts b/plugins/catalog-backend/src/ingestion/processors/GitLabDiscoveryProcessor.ts
index 70ccd44793..fabf3a1136 100644
--- a/plugins/catalog-backend/src/ingestion/processors/GitLabDiscoveryProcessor.ts
+++ b/plugins/catalog-backend/src/ingestion/processors/GitLabDiscoveryProcessor.ts
@@ -94,9 +94,16 @@ export class GitLabDiscoveryProcessor implements CatalogProcessor {
};
for await (const project of projects) {
result.scanned++;
- if (!project.archived) {
- result.matches.push(project);
+
+ if (project.archived) {
+ continue;
}
+
+ if (branch === '*' && project.default_branch === undefined) {
+ continue;
+ }
+
+ result.matches.push(project);
}
for (const project of result.matches) {
diff --git a/plugins/catalog-backend/src/ingestion/processors/gitlab/types.ts b/plugins/catalog-backend/src/ingestion/processors/gitlab/types.ts
index a66411ddc8..d41ed73aac 100644
--- a/plugins/catalog-backend/src/ingestion/processors/gitlab/types.ts
+++ b/plugins/catalog-backend/src/ingestion/processors/gitlab/types.ts
@@ -16,7 +16,7 @@
export type GitLabProject = {
id: number;
- default_branch: string;
+ default_branch?: string;
archived: boolean;
last_activity_at: string;
web_url: string;
diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json
index 09278edba2..c294ba8e24 100644
--- a/plugins/catalog-graph/package.json
+++ b/plugins/catalog-graph/package.json
@@ -42,10 +42,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md
index 9257c7b0f5..d575f64ab7 100644
--- a/plugins/catalog-import/CHANGELOG.md
+++ b/plugins/catalog-import/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-catalog-import
+## 0.7.7
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.6.9
+ - @backstage/integration@0.7.0
+ - @backstage/integration-react@0.1.17
+
## 0.7.6
### Patch Changes
diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json
index 94fe6a573f..3f6570dca2 100644
--- a/plugins/catalog-import/package.json
+++ b/plugins/catalog-import/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-import",
"description": "A Backstage plugin the helps you import entities into your catalog",
- "version": "0.7.6",
+ "version": "0.7.7",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -36,9 +36,9 @@
"@backstage/core-components": "^0.8.2",
"@backstage/core-plugin-api": "^0.4.0",
"@backstage/errors": "^0.1.3",
- "@backstage/integration": "^0.6.10",
- "@backstage/integration-react": "^0.1.16",
- "@backstage/plugin-catalog-react": "^0.6.8",
+ "@backstage/integration": "^0.7.0",
+ "@backstage/integration-react": "^0.1.17",
+ "@backstage/plugin-catalog-react": "^0.6.9",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.57",
@@ -56,10 +56,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md
index b8a4128919..8db0fd7573 100644
--- a/plugins/catalog-react/CHANGELOG.md
+++ b/plugins/catalog-react/CHANGELOG.md
@@ -1,5 +1,15 @@
# @backstage/plugin-catalog-react
+## 0.6.9
+
+### Patch Changes
+
+- c6fdddec77: When a user has zero owned entities when viewing an entity kind in the catalog
+ page, it will be automatically redirected to see all the entities. Furthermore,
+ for the kind User and Group there are no longer the owned selector.
+- Updated dependencies
+ - @backstage/integration@0.7.0
+
## 0.6.8
### Patch Changes
diff --git a/plugins/catalog-react/api-report.md b/plugins/catalog-react/api-report.md
index d5cf06107c..673d9256f1 100644
--- a/plugins/catalog-react/api-report.md
+++ b/plugins/catalog-react/api-report.md
@@ -19,12 +19,14 @@ import { IconButton } from '@material-ui/core';
import { IdentityApi } from '@backstage/core-plugin-api';
import { LinkProps } from '@backstage/core-components';
import { Observable } from '@backstage/types';
+import { Overrides } from '@material-ui/core/styles/overrides';
import { PropsWithChildren } from 'react';
import { default as React_2 } from 'react';
import { ReactNode } from 'react';
import { RouteRef } from '@backstage/core-plugin-api';
import { ScmIntegrationRegistry } from '@backstage/integration';
import { StorageApi } from '@backstage/core-plugin-api';
+import { StyleRules } from '@material-ui/core/styles/withStyles';
import { SystemEntity } from '@backstage/catalog-model';
import { TableColumn } from '@backstage/core-components';
import { UserEntity } from '@backstage/catalog-model';
@@ -52,6 +54,13 @@ export interface AsyncEntityProviderProps {
refresh?: VoidFunction;
}
+// @public (undocumented)
+export type BackstageOverrides = Overrides & {
+ [Name in keyof CatalogReactComponentsNameToClassKey]?: Partial<
+ StyleRules
+ >;
+};
+
export { CATALOG_FILTER_EXISTS };
export { CatalogApi };
@@ -61,6 +70,35 @@ export { CatalogApi };
// @public (undocumented)
export const catalogApiRef: ApiRef;
+// @public (undocumented)
+export type CatalogReactComponentsNameToClassKey = {
+ CatalogReactUserListPicker: CatalogReactUserListPickerClassKey;
+ CatalogReactEntityLifecyclePicker: CatalogReactEntityLifecyclePickerClassKey;
+ CatalogReactEntitySearchBar: CatalogReactEntitySearchBarClassKey;
+ CatalogReactEntityTagPicker: CatalogReactEntityTagPickerClassKey;
+ CatalogReactEntityOwnerPicker: CatalogReactEntityOwnerPickerClassKey;
+};
+
+// @public (undocumented)
+export type CatalogReactEntityLifecyclePickerClassKey = 'input';
+
+// @public (undocumented)
+export type CatalogReactEntityOwnerPickerClassKey = 'input';
+
+// @public (undocumented)
+export type CatalogReactEntitySearchBarClassKey = 'searchToolbar' | 'input';
+
+// @public (undocumented)
+export type CatalogReactEntityTagPickerClassKey = 'input';
+
+// @public (undocumented)
+export type CatalogReactUserListPickerClassKey =
+ | 'root'
+ | 'title'
+ | 'listIcon'
+ | 'menuItem'
+ | 'groupWrapper';
+
// Warning: (ae-missing-release-tag) "catalogRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json
index 1283d45612..912ef5f653 100644
--- a/plugins/catalog-react/package.json
+++ b/plugins/catalog-react/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog-react",
"description": "A frontend library that helps other Backstage plugins interact with the catalog",
- "version": "0.6.8",
+ "version": "0.6.9",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -34,7 +34,7 @@
"@backstage/core-components": "^0.8.2",
"@backstage/core-plugin-api": "^0.4.0",
"@backstage/errors": "^0.1.4",
- "@backstage/integration": "^0.6.10",
+ "@backstage/integration": "^0.7.0",
"@backstage/types": "^0.1.1",
"@backstage/version-bridge": "^0.1.1",
"@material-ui/core": "^4.12.2",
@@ -52,9 +52,9 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/plugins/catalog-react/src/components/EntityLifecyclePicker/EntityLifecyclePicker.tsx b/plugins/catalog-react/src/components/EntityLifecyclePicker/EntityLifecyclePicker.tsx
index 750692ed2e..630b1700a0 100644
--- a/plugins/catalog-react/src/components/EntityLifecyclePicker/EntityLifecyclePicker.tsx
+++ b/plugins/catalog-react/src/components/EntityLifecyclePicker/EntityLifecyclePicker.tsx
@@ -31,6 +31,9 @@ import React, { useEffect, useMemo, useState } from 'react';
import { useEntityListProvider } from '../../hooks/useEntityListProvider';
import { EntityLifecycleFilter } from '../../filters';
+/** @public */
+export type CatalogReactEntityLifecyclePickerClassKey = 'input';
+
const useStyles = makeStyles(
{
input: {},
diff --git a/plugins/catalog-react/src/components/EntityLifecyclePicker/index.ts b/plugins/catalog-react/src/components/EntityLifecyclePicker/index.ts
index 4b8cfb282d..def25eabf4 100644
--- a/plugins/catalog-react/src/components/EntityLifecyclePicker/index.ts
+++ b/plugins/catalog-react/src/components/EntityLifecyclePicker/index.ts
@@ -15,3 +15,4 @@
*/
export { EntityLifecyclePicker } from './EntityLifecyclePicker';
+export type { CatalogReactEntityLifecyclePickerClassKey } from './EntityLifecyclePicker';
diff --git a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx
index dbf6a33164..ae88858666 100644
--- a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx
+++ b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx
@@ -33,6 +33,9 @@ import { EntityOwnerFilter } from '../../filters';
import { getEntityRelations } from '../../utils';
import { formatEntityRefTitle } from '../EntityRefLink';
+/** @public */
+export type CatalogReactEntityOwnerPickerClassKey = 'input';
+
const useStyles = makeStyles(
{
input: {},
diff --git a/plugins/catalog-react/src/components/EntityOwnerPicker/index.ts b/plugins/catalog-react/src/components/EntityOwnerPicker/index.ts
index f30928718b..c20db945f7 100644
--- a/plugins/catalog-react/src/components/EntityOwnerPicker/index.ts
+++ b/plugins/catalog-react/src/components/EntityOwnerPicker/index.ts
@@ -15,3 +15,4 @@
*/
export { EntityOwnerPicker } from './EntityOwnerPicker';
+export type { CatalogReactEntityOwnerPickerClassKey } from './EntityOwnerPicker';
diff --git a/plugins/catalog-react/src/components/EntitySearchBar/EntitySearchBar.tsx b/plugins/catalog-react/src/components/EntitySearchBar/EntitySearchBar.tsx
index 3a848591a3..57c7f58413 100644
--- a/plugins/catalog-react/src/components/EntitySearchBar/EntitySearchBar.tsx
+++ b/plugins/catalog-react/src/components/EntitySearchBar/EntitySearchBar.tsx
@@ -29,6 +29,9 @@ import { useDebounce } from 'react-use';
import { useEntityListProvider } from '../../hooks/useEntityListProvider';
import { EntityTextFilter } from '../../filters';
+/** @public */
+export type CatalogReactEntitySearchBarClassKey = 'searchToolbar' | 'input';
+
const useStyles = makeStyles(
_theme => ({
searchToolbar: {
diff --git a/plugins/catalog-react/src/components/EntitySearchBar/index.ts b/plugins/catalog-react/src/components/EntitySearchBar/index.ts
index 044b8ee416..e82c06d94e 100644
--- a/plugins/catalog-react/src/components/EntitySearchBar/index.ts
+++ b/plugins/catalog-react/src/components/EntitySearchBar/index.ts
@@ -15,3 +15,4 @@
*/
export { EntitySearchBar } from './EntitySearchBar';
+export type { CatalogReactEntitySearchBarClassKey } from './EntitySearchBar';
diff --git a/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.tsx b/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.tsx
index 9e00f7e7b0..a25c50c0a9 100644
--- a/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.tsx
+++ b/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.tsx
@@ -31,6 +31,9 @@ import React, { useEffect, useMemo, useState } from 'react';
import { useEntityListProvider } from '../../hooks/useEntityListProvider';
import { EntityTagFilter } from '../../filters';
+/** @public */
+export type CatalogReactEntityTagPickerClassKey = 'input';
+
const useStyles = makeStyles(
{
input: {},
diff --git a/plugins/catalog-react/src/components/EntityTagPicker/index.ts b/plugins/catalog-react/src/components/EntityTagPicker/index.ts
index cb8d418a41..c982d33df0 100644
--- a/plugins/catalog-react/src/components/EntityTagPicker/index.ts
+++ b/plugins/catalog-react/src/components/EntityTagPicker/index.ts
@@ -15,3 +15,4 @@
*/
export { EntityTagPicker } from './EntityTagPicker';
+export type { CatalogReactEntityTagPickerClassKey } from './EntityTagPicker';
diff --git a/plugins/catalog-react/src/components/UserListPicker/UserListPicker.tsx b/plugins/catalog-react/src/components/UserListPicker/UserListPicker.tsx
index 9aafdf1437..8746752b08 100644
--- a/plugins/catalog-react/src/components/UserListPicker/UserListPicker.tsx
+++ b/plugins/catalog-react/src/components/UserListPicker/UserListPicker.tsx
@@ -43,6 +43,14 @@ import {
import { UserListFilterKind } from '../../types';
import { reduceEntityFilters } from '../../utils';
+/** @public */
+export type CatalogReactUserListPickerClassKey =
+ | 'root'
+ | 'title'
+ | 'listIcon'
+ | 'menuItem'
+ | 'groupWrapper';
+
const useStyles = makeStyles(
theme => ({
root: {
diff --git a/plugins/catalog-react/src/components/UserListPicker/index.ts b/plugins/catalog-react/src/components/UserListPicker/index.ts
index 0bacaee8ca..45cb471197 100644
--- a/plugins/catalog-react/src/components/UserListPicker/index.ts
+++ b/plugins/catalog-react/src/components/UserListPicker/index.ts
@@ -15,3 +15,4 @@
*/
export { UserListPicker } from './UserListPicker';
+export type { CatalogReactUserListPickerClassKey } from './UserListPicker';
diff --git a/plugins/catalog-react/src/index.ts b/plugins/catalog-react/src/index.ts
index cf7a679f7a..7bf1bd1221 100644
--- a/plugins/catalog-react/src/index.ts
+++ b/plugins/catalog-react/src/index.ts
@@ -37,3 +37,4 @@ export {
export * from './testUtils';
export * from './types';
export * from './utils';
+export * from './overridableComponents';
diff --git a/plugins/catalog-react/src/overridableComponents.ts b/plugins/catalog-react/src/overridableComponents.ts
new file mode 100644
index 0000000000..1e654988e4
--- /dev/null
+++ b/plugins/catalog-react/src/overridableComponents.ts
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { Overrides } from '@material-ui/core/styles/overrides';
+import { StyleRules } from '@material-ui/core/styles/withStyles';
+
+import {
+ CatalogReactUserListPickerClassKey,
+ CatalogReactEntityLifecyclePickerClassKey,
+ CatalogReactEntitySearchBarClassKey,
+ CatalogReactEntityTagPickerClassKey,
+ CatalogReactEntityOwnerPickerClassKey,
+} from './components';
+
+/** @public */
+export type CatalogReactComponentsNameToClassKey = {
+ CatalogReactUserListPicker: CatalogReactUserListPickerClassKey;
+ CatalogReactEntityLifecyclePicker: CatalogReactEntityLifecyclePickerClassKey;
+ CatalogReactEntitySearchBar: CatalogReactEntitySearchBarClassKey;
+ CatalogReactEntityTagPicker: CatalogReactEntityTagPickerClassKey;
+ CatalogReactEntityOwnerPicker: CatalogReactEntityOwnerPickerClassKey;
+};
+
+/** @public */
+export type BackstageOverrides = Overrides & {
+ [Name in keyof CatalogReactComponentsNameToClassKey]?: Partial<
+ StyleRules
+ >;
+};
diff --git a/plugins/catalog/CHANGELOG.md b/plugins/catalog/CHANGELOG.md
index cb2dcfc079..2e626caf20 100644
--- a/plugins/catalog/CHANGELOG.md
+++ b/plugins/catalog/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-catalog
+## 0.7.6
+
+### Patch Changes
+
+- 7d4b4e937c: Uptake changes to the GitHub Credentials Provider interface.
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.6.9
+ - @backstage/integration-react@0.1.17
+
## 0.7.5
### Patch Changes
diff --git a/plugins/catalog/api-report.md b/plugins/catalog/api-report.md
index 80271c89af..c046e031de 100644
--- a/plugins/catalog/api-report.md
+++ b/plugins/catalog/api-report.md
@@ -126,15 +126,10 @@ export class CatalogClientWrapper implements CatalogApi {
// @public (undocumented)
export const CatalogEntityPage: () => JSX.Element;
-// Warning: (ae-forgotten-export) The symbol "CatalogPageProps" needs to be exported by the entry point index.d.ts
// Warning: (ae-missing-release-tag) "CatalogIndexPage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
-export const CatalogIndexPage: ({
- columns,
- actions,
- initiallySelectedFilter,
-}: CatalogPageProps) => JSX.Element;
+export const CatalogIndexPage: (props: DefaultCatalogPageProps) => JSX.Element;
// Warning: (ae-forgotten-export) The symbol "CatalogKindHeaderProps" needs to be exported by the entry point index.d.ts
// Warning: (ae-missing-release-tag) "CatalogKindHeader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
@@ -236,6 +231,13 @@ export function createSystemColumn(): TableColumn;
// @public (undocumented)
export function createTagsColumn(): TableColumn;
+// @public
+export type DefaultCatalogPageProps = {
+ initiallySelectedFilter?: UserListFilterKind;
+ columns?: TableColumn[];
+ actions?: TableProps['actions'];
+};
+
// Warning: (ae-missing-release-tag) "EntityAboutCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json
index 92003dca88..83720b9a90 100644
--- a/plugins/catalog/package.json
+++ b/plugins/catalog/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-catalog",
"description": "The Backstage plugin for browsing the Backstage catalog",
- "version": "0.7.5",
+ "version": "0.7.6",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -36,8 +36,8 @@
"@backstage/core-components": "^0.8.2",
"@backstage/core-plugin-api": "^0.4.0",
"@backstage/errors": "^0.1.3",
- "@backstage/integration-react": "^0.1.16",
- "@backstage/plugin-catalog-react": "^0.6.8",
+ "@backstage/integration-react": "^0.1.17",
+ "@backstage/plugin-catalog-react": "^0.6.9",
"@backstage/theme": "^0.2.14",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -53,10 +53,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/catalog/src/components/CatalogPage/CatalogPage.test.tsx b/plugins/catalog/src/components/CatalogPage/CatalogPage.test.tsx
index effd9f5bc6..6fbdcf40a2 100644
--- a/plugins/catalog/src/components/CatalogPage/CatalogPage.test.tsx
+++ b/plugins/catalog/src/components/CatalogPage/CatalogPage.test.tsx
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Backstage Authors
+ * Copyright 2021 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,272 +14,31 @@
* limitations under the License.
*/
-import { CatalogApi } from '@backstage/catalog-client';
-import {
- Entity,
- RELATION_MEMBER_OF,
- RELATION_OWNED_BY,
-} from '@backstage/catalog-model';
-import { TableColumn, TableProps } from '@backstage/core-components';
-import {
- IdentityApi,
- identityApiRef,
- ProfileInfo,
- storageApiRef,
-} from '@backstage/core-plugin-api';
-import {
- catalogApiRef,
- DefaultStarredEntitiesApi,
- entityRouteRef,
- starredEntitiesApiRef,
-} from '@backstage/plugin-catalog-react';
-import {
- mockBreakpoint,
- MockStorageApi,
- renderWithEffects,
- TestApiProvider,
- wrapInTestApp,
-} from '@backstage/test-utils';
-import DashboardIcon from '@material-ui/icons/Dashboard';
-import { fireEvent, screen } from '@testing-library/react';
import React from 'react';
-import { createComponentRouteRef } from '../../routes';
-import { EntityRow } from '../CatalogTable';
+import { renderInTestApp } from '@backstage/test-utils';
+import { useOutlet } from 'react-router';
import { CatalogPage } from './CatalogPage';
+jest.mock('react-router', () => ({
+ ...jest.requireActual('react-router'),
+ useOutlet: jest.fn().mockReturnValue('Route Children'),
+}));
+
+jest.mock('./DefaultCatalogPage', () => ({
+ DefaultCatalogPage: jest.fn().mockReturnValue('DefaultCatalogPage'),
+}));
+
describe('CatalogPage', () => {
- const origReplaceState = window.history.replaceState;
- beforeEach(() => {
- window.history.replaceState = jest.fn();
- });
- afterEach(() => {
- window.history.replaceState = origReplaceState;
+ it('renders provided router element', async () => {
+ const { getByText } = await renderInTestApp();
+
+ expect(getByText('Route Children')).toBeInTheDocument();
});
- const catalogApi: Partial = {
- getEntities: () =>
- Promise.resolve({
- items: [
- {
- apiVersion: 'backstage.io/v1alpha1',
- kind: 'Component',
- metadata: {
- name: 'Entity1',
- },
- spec: {
- owner: 'tools',
- type: 'service',
- },
- relations: [
- {
- type: RELATION_OWNED_BY,
- target: { kind: 'Group', name: 'tools', namespace: 'default' },
- },
- ],
- },
- {
- apiVersion: 'backstage.io/v1alpha1',
- kind: 'Component',
- metadata: {
- name: 'Entity2',
- },
- spec: {
- owner: 'not-tools',
- type: 'service',
- },
- relations: [
- {
- type: RELATION_OWNED_BY,
- target: {
- kind: 'Group',
- name: 'not-tools',
- namespace: 'default',
- },
- },
- ],
- },
- ] as Entity[],
- }),
- getLocationByEntity: () =>
- Promise.resolve({ id: 'id', type: 'github', target: 'url' }),
- getEntityByName: async entityName => {
- return {
- apiVersion: 'backstage.io/v1alpha1',
- kind: 'User',
- metadata: { name: entityName.name },
- relations: [
- {
- type: RELATION_MEMBER_OF,
- target: { namespace: 'default', kind: 'Group', name: 'tools' },
- },
- ],
- };
- },
- };
- const testProfile: Partial = {
- displayName: 'Display Name',
- };
- const identityApi: Partial = {
- getUserId: () => 'tools',
- getIdToken: async () => undefined,
- getProfile: () => testProfile,
- };
- const storageApi = MockStorageApi.create();
+ it('renders DefaultCatalogPage home when no router children are provided', async () => {
+ (useOutlet as jest.Mock).mockReturnValueOnce(null);
+ const { getByText } = await renderInTestApp();
- const renderWrapped = (children: React.ReactNode) =>
- renderWithEffects(
- wrapInTestApp(
-
- {children}
- ,
- {
- mountedRoutes: {
- '/create': createComponentRouteRef,
- '/catalog/:namespace/:kind/:name': entityRouteRef,
- },
- },
- ),
- );
-
- // TODO(freben): The test timeouts are bumped in this file, because it seems
- // page and table rerenders accumulate to occasionally go over the default
- // limit. We should investigate why these timeouts happen.
-
- it('should render the default column of the grid', async () => {
- const { getAllByRole } = await renderWrapped();
-
- const columnHeader = getAllByRole('button').filter(
- c => c.tagName === 'SPAN',
- );
- const columnHeaderLabels = columnHeader.map(c => c.textContent);
-
- expect(columnHeaderLabels).toEqual([
- 'Name',
- 'System',
- 'Owner',
- 'Type',
- 'Lifecycle',
- 'Description',
- 'Tags',
- 'Actions',
- ]);
- }, 20_000);
-
- it('should render the custom column passed as prop', async () => {
- const columns: TableColumn[] = [
- { title: 'Foo', field: 'entity.foo' },
- { title: 'Bar', field: 'entity.bar' },
- { title: 'Baz', field: 'entity.spec.lifecycle' },
- ];
- const { getAllByRole } = await renderWrapped(
- ,
- );
-
- const columnHeader = getAllByRole('button').filter(
- c => c.tagName === 'SPAN',
- );
- const columnHeaderLabels = columnHeader.map(c => c.textContent);
- expect(columnHeaderLabels).toEqual(['Foo', 'Bar', 'Baz', 'Actions']);
- }, 20_000);
-
- it('should render the default actions of an item in the grid', async () => {
- const { getByTestId, findByTitle, findByText } = await renderWrapped(
- ,
- );
- fireEvent.click(getByTestId('user-picker-owned'));
- expect(await findByText(/Owned \(1\)/)).toBeInTheDocument();
- expect(await findByTitle(/View/)).toBeInTheDocument();
- expect(await findByTitle(/Edit/)).toBeInTheDocument();
- expect(await findByTitle(/Add to favorites/)).toBeInTheDocument();
- }, 20_000);
-
- it('should render the custom actions of an item passed as prop', async () => {
- const actions: TableProps['actions'] = [
- () => {
- return {
- icon: () => ,
- tooltip: 'Foo Action',
- disabled: false,
- onClick: () => jest.fn(),
- };
- },
- () => {
- return {
- icon: () => ,
- tooltip: 'Bar Action',
- disabled: true,
- onClick: () => jest.fn(),
- };
- },
- ];
-
- const { getByTestId, findByTitle, findByText } = await renderWrapped(
- ,
- );
- fireEvent.click(getByTestId('user-picker-owned'));
- expect(await findByText(/Owned \(1\)/)).toBeInTheDocument();
- expect(await findByTitle(/Foo Action/)).toBeInTheDocument();
- expect(await findByTitle(/Bar Action/)).toBeInTheDocument();
- expect((await findByTitle(/Bar Action/)).firstChild).toBeDisabled();
- }, 20_000);
-
- // this test right now causes some red lines in the log output when running tests
- // related to some theme issues in mui-table
- // https://github.com/mbrn/material-table/issues/1293
- it('should render', async () => {
- const { findByText, getByTestId } = await renderWrapped();
- fireEvent.click(getByTestId('user-picker-owned'));
- await expect(findByText(/Owned \(1\)/)).resolves.toBeInTheDocument();
- fireEvent.click(getByTestId('user-picker-all'));
- await expect(findByText(/All \(2\)/)).resolves.toBeInTheDocument();
- }, 20_000);
-
- it('should set initial filter correctly', async () => {
- const { findByText } = await renderWrapped(
- ,
- );
- await expect(findByText(/All \(2\)/)).resolves.toBeInTheDocument();
- }, 20_000);
-
- // this test is for fixing the bug after favoriting an entity, the matching
- // entities defaulting to "owned" filter and not based on the selected filter
- it('should render the correct entities filtered on the selected filter', async () => {
- const { getByTestId } = await renderWrapped();
- fireEvent.click(getByTestId('user-picker-owned'));
- await expect(screen.findByText(/Owned \(1\)/)).resolves.toBeInTheDocument();
- fireEvent.click(screen.getByTestId('user-picker-starred'));
- await expect(
- screen.findByText(/Starred \(0\)/),
- ).resolves.toBeInTheDocument();
- fireEvent.click(screen.getByTestId('user-picker-all'));
- await expect(screen.findByText(/All \(2\)/)).resolves.toBeInTheDocument();
-
- const starredIcons = await screen.findAllByTitle('Add to favorites');
- fireEvent.click(starredIcons[0]);
- await expect(screen.findByText(/All \(2\)/)).resolves.toBeInTheDocument();
-
- fireEvent.click(screen.getByTestId('user-picker-starred'));
- await expect(
- screen.findByText(/Starred \(1\)/),
- ).resolves.toBeInTheDocument();
- }, 20_000);
-
- it('should wrap filter in drawer on smaller screens', async () => {
- mockBreakpoint({ matches: true });
- const { getByRole } = await renderWrapped();
- const button = getByRole('button', { name: 'Filters' });
- expect(getByRole('presentation', { hidden: true })).toBeInTheDocument();
- fireEvent.click(button);
- expect(getByRole('presentation')).toBeVisible();
- }, 20_000);
+ expect(getByText('DefaultCatalogPage')).toBeInTheDocument();
+ });
});
diff --git a/plugins/catalog/src/components/CatalogPage/CatalogPage.tsx b/plugins/catalog/src/components/CatalogPage/CatalogPage.tsx
index ec29d3839b..cf49cff244 100644
--- a/plugins/catalog/src/components/CatalogPage/CatalogPage.tsx
+++ b/plugins/catalog/src/components/CatalogPage/CatalogPage.tsx
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Backstage Authors
+ * Copyright 2021 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,76 +14,15 @@
* limitations under the License.
*/
-import {
- Content,
- ContentHeader,
- CreateButton,
- PageWithHeader,
- SupportButton,
- TableColumn,
- TableProps,
-} from '@backstage/core-components';
-import { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api';
-import {
- EntityLifecyclePicker,
- EntityListProvider,
- EntityOwnerPicker,
- EntityTagPicker,
- EntityTypePicker,
- UserListFilterKind,
- UserListPicker,
-} from '@backstage/plugin-catalog-react';
import React from 'react';
-import { createComponentRouteRef } from '../../routes';
-import { CatalogTable } from '../CatalogTable';
-import { EntityRow } from '../CatalogTable/types';
+import { useOutlet } from 'react-router';
import {
- FilteredEntityLayout,
- EntityListContainer,
- FilterContainer,
-} from '../FilteredEntityLayout';
-import { CatalogKindHeader } from '../CatalogKindHeader';
+ DefaultCatalogPage,
+ DefaultCatalogPageProps,
+} from './DefaultCatalogPage';
-export type CatalogPageProps = {
- initiallySelectedFilter?: UserListFilterKind;
- columns?: TableColumn[];
- actions?: TableProps['actions'];
-};
-
-export const CatalogPage = ({
- columns,
- actions,
- initiallySelectedFilter = 'owned',
-}: CatalogPageProps) => {
- const orgName =
- useApi(configApiRef).getOptionalString('organization.name') ?? 'Backstage';
- const createComponentLink = useRouteRef(createComponentRouteRef);
-
- return (
-
-
-
- }>
-
- All your software catalog entities
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
+export const CatalogPage = (props: DefaultCatalogPageProps) => {
+ const outlet = useOutlet();
+
+ return outlet || ;
};
diff --git a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx
new file mode 100644
index 0000000000..5f21ba364b
--- /dev/null
+++ b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx
@@ -0,0 +1,287 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { CatalogApi } from '@backstage/catalog-client';
+import {
+ Entity,
+ RELATION_MEMBER_OF,
+ RELATION_OWNED_BY,
+} from '@backstage/catalog-model';
+import { TableColumn, TableProps } from '@backstage/core-components';
+import {
+ IdentityApi,
+ identityApiRef,
+ ProfileInfo,
+ storageApiRef,
+} from '@backstage/core-plugin-api';
+import {
+ catalogApiRef,
+ DefaultStarredEntitiesApi,
+ entityRouteRef,
+ starredEntitiesApiRef,
+} from '@backstage/plugin-catalog-react';
+import {
+ mockBreakpoint,
+ MockStorageApi,
+ renderWithEffects,
+ TestApiProvider,
+ wrapInTestApp,
+} from '@backstage/test-utils';
+import DashboardIcon from '@material-ui/icons/Dashboard';
+import { fireEvent, screen } from '@testing-library/react';
+import React from 'react';
+import { createComponentRouteRef } from '../../routes';
+import { EntityRow } from '../CatalogTable';
+import { DefaultCatalogPage } from './DefaultCatalogPage';
+
+describe('DefaultCatalogPage', () => {
+ const origReplaceState = window.history.replaceState;
+ beforeEach(() => {
+ window.history.replaceState = jest.fn();
+ });
+ afterEach(() => {
+ window.history.replaceState = origReplaceState;
+ });
+
+ const catalogApi: Partial = {
+ getEntities: () =>
+ Promise.resolve({
+ items: [
+ {
+ apiVersion: 'backstage.io/v1alpha1',
+ kind: 'Component',
+ metadata: {
+ name: 'Entity1',
+ },
+ spec: {
+ owner: 'tools',
+ type: 'service',
+ },
+ relations: [
+ {
+ type: RELATION_OWNED_BY,
+ target: { kind: 'Group', name: 'tools', namespace: 'default' },
+ },
+ ],
+ },
+ {
+ apiVersion: 'backstage.io/v1alpha1',
+ kind: 'Component',
+ metadata: {
+ name: 'Entity2',
+ },
+ spec: {
+ owner: 'not-tools',
+ type: 'service',
+ },
+ relations: [
+ {
+ type: RELATION_OWNED_BY,
+ target: {
+ kind: 'Group',
+ name: 'not-tools',
+ namespace: 'default',
+ },
+ },
+ ],
+ },
+ ] as Entity[],
+ }),
+ getLocationByEntity: () =>
+ Promise.resolve({ id: 'id', type: 'github', target: 'url' }),
+ getEntityByName: async entityName => {
+ return {
+ apiVersion: 'backstage.io/v1alpha1',
+ kind: 'User',
+ metadata: { name: entityName.name },
+ relations: [
+ {
+ type: RELATION_MEMBER_OF,
+ target: { namespace: 'default', kind: 'Group', name: 'tools' },
+ },
+ ],
+ };
+ },
+ };
+ const testProfile: Partial = {
+ displayName: 'Display Name',
+ };
+ const identityApi: Partial = {
+ getUserId: () => 'tools',
+ getIdToken: async () => undefined,
+ getProfile: () => testProfile,
+ };
+ const storageApi = MockStorageApi.create();
+
+ const renderWrapped = (children: React.ReactNode) =>
+ renderWithEffects(
+ wrapInTestApp(
+
+ {children}
+ ,
+ {
+ mountedRoutes: {
+ '/create': createComponentRouteRef,
+ '/catalog/:namespace/:kind/:name': entityRouteRef,
+ },
+ },
+ ),
+ );
+
+ // TODO(freben): The test timeouts are bumped in this file, because it seems
+ // page and table rerenders accumulate to occasionally go over the default
+ // limit. We should investigate why these timeouts happen.
+
+ it('should render the default column of the grid', async () => {
+ const { getAllByRole } = await renderWrapped();
+
+ const columnHeader = getAllByRole('button').filter(
+ c => c.tagName === 'SPAN',
+ );
+ const columnHeaderLabels = columnHeader.map(c => c.textContent);
+
+ expect(columnHeaderLabels).toEqual([
+ 'Name',
+ 'System',
+ 'Owner',
+ 'Type',
+ 'Lifecycle',
+ 'Description',
+ 'Tags',
+ 'Actions',
+ ]);
+ }, 20_000);
+
+ it('should render the custom column passed as prop', async () => {
+ const columns: TableColumn[] = [
+ { title: 'Foo', field: 'entity.foo' },
+ { title: 'Bar', field: 'entity.bar' },
+ { title: 'Baz', field: 'entity.spec.lifecycle' },
+ ];
+ const { getAllByRole } = await renderWrapped(
+ ,
+ );
+
+ const columnHeader = getAllByRole('button').filter(
+ c => c.tagName === 'SPAN',
+ );
+ const columnHeaderLabels = columnHeader.map(c => c.textContent);
+ expect(columnHeaderLabels).toEqual(['Foo', 'Bar', 'Baz', 'Actions']);
+ }, 20_000);
+
+ it('should render the default actions of an item in the grid', async () => {
+ const { getByTestId, findByTitle, findByText } = await renderWrapped(
+ ,
+ );
+ fireEvent.click(getByTestId('user-picker-owned'));
+ expect(await findByText(/Owned \(1\)/)).toBeInTheDocument();
+ expect(await findByTitle(/View/)).toBeInTheDocument();
+ expect(await findByTitle(/Edit/)).toBeInTheDocument();
+ expect(await findByTitle(/Add to favorites/)).toBeInTheDocument();
+ }, 20_000);
+
+ it('should render the custom actions of an item passed as prop', async () => {
+ const actions: TableProps['actions'] = [
+ () => {
+ return {
+ icon: () => ,
+ tooltip: 'Foo Action',
+ disabled: false,
+ onClick: () => jest.fn(),
+ };
+ },
+ () => {
+ return {
+ icon: () => ,
+ tooltip: 'Bar Action',
+ disabled: true,
+ onClick: () => jest.fn(),
+ };
+ },
+ ];
+
+ const { getByTestId, findByTitle, findByText } = await renderWrapped(
+ ,
+ );
+ fireEvent.click(getByTestId('user-picker-owned'));
+ expect(await findByText(/Owned \(1\)/)).toBeInTheDocument();
+ expect(await findByTitle(/Foo Action/)).toBeInTheDocument();
+ expect(await findByTitle(/Bar Action/)).toBeInTheDocument();
+ expect((await findByTitle(/Bar Action/)).firstChild).toBeDisabled();
+ }, 20_000);
+
+ // this test right now causes some red lines in the log output when running tests
+ // related to some theme issues in mui-table
+ // https://github.com/mbrn/material-table/issues/1293
+ it('should render', async () => {
+ const { findByText, getByTestId } = await renderWrapped(
+ ,
+ );
+ fireEvent.click(getByTestId('user-picker-owned'));
+ await expect(findByText(/Owned \(1\)/)).resolves.toBeInTheDocument();
+ fireEvent.click(getByTestId('user-picker-all'));
+ await expect(findByText(/All \(2\)/)).resolves.toBeInTheDocument();
+ }, 20_000);
+
+ it('should set initial filter correctly', async () => {
+ const { findByText } = await renderWrapped(
+ ,
+ );
+ await expect(findByText(/All \(2\)/)).resolves.toBeInTheDocument();
+ }, 20_000);
+
+ // this test is for fixing the bug after favoriting an entity, the matching
+ // entities defaulting to "owned" filter and not based on the selected filter
+ it('should render the correct entities filtered on the selected filter', async () => {
+ const { getByTestId } = await renderWrapped();
+ fireEvent.click(getByTestId('user-picker-owned'));
+ await expect(screen.findByText(/Owned \(1\)/)).resolves.toBeInTheDocument();
+ fireEvent.click(screen.getByTestId('user-picker-starred'));
+ await expect(
+ screen.findByText(/Starred \(0\)/),
+ ).resolves.toBeInTheDocument();
+ fireEvent.click(screen.getByTestId('user-picker-all'));
+ await expect(screen.findByText(/All \(2\)/)).resolves.toBeInTheDocument();
+
+ const starredIcons = await screen.findAllByTitle('Add to favorites');
+ fireEvent.click(starredIcons[0]);
+ await expect(screen.findByText(/All \(2\)/)).resolves.toBeInTheDocument();
+
+ fireEvent.click(screen.getByTestId('user-picker-starred'));
+ await expect(
+ screen.findByText(/Starred \(1\)/),
+ ).resolves.toBeInTheDocument();
+ }, 20_000);
+
+ it('should wrap filter in drawer on smaller screens', async () => {
+ mockBreakpoint({ matches: true });
+ const { getByRole } = await renderWrapped();
+ const button = getByRole('button', { name: 'Filters' });
+ expect(getByRole('presentation', { hidden: true })).toBeInTheDocument();
+ fireEvent.click(button);
+ expect(getByRole('presentation')).toBeVisible();
+ }, 20_000);
+});
diff --git a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx
new file mode 100644
index 0000000000..1453a39bbc
--- /dev/null
+++ b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ Content,
+ ContentHeader,
+ CreateButton,
+ PageWithHeader,
+ SupportButton,
+ TableColumn,
+ TableProps,
+} from '@backstage/core-components';
+import { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api';
+import {
+ EntityLifecyclePicker,
+ EntityListProvider,
+ EntityOwnerPicker,
+ EntityTagPicker,
+ EntityTypePicker,
+ UserListFilterKind,
+ UserListPicker,
+} from '@backstage/plugin-catalog-react';
+import React from 'react';
+import { createComponentRouteRef } from '../../routes';
+import { CatalogTable } from '../CatalogTable';
+import { EntityRow } from '../CatalogTable/types';
+import {
+ FilteredEntityLayout,
+ EntityListContainer,
+ FilterContainer,
+} from '../FilteredEntityLayout';
+import { CatalogKindHeader } from '../CatalogKindHeader';
+
+/**
+ * DefaultCatalogPageProps
+ * @public
+ */
+export type DefaultCatalogPageProps = {
+ initiallySelectedFilter?: UserListFilterKind;
+ columns?: TableColumn[];
+ actions?: TableProps['actions'];
+};
+
+export const DefaultCatalogPage = ({
+ columns,
+ actions,
+ initiallySelectedFilter = 'owned',
+}: DefaultCatalogPageProps) => {
+ const orgName =
+ useApi(configApiRef).getOptionalString('organization.name') ?? 'Backstage';
+ const createComponentLink = useRouteRef(createComponentRouteRef);
+
+ return (
+
+
+
+ }>
+
+ All your software catalog entities
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/plugins/catalog/src/components/CatalogPage/index.ts b/plugins/catalog/src/components/CatalogPage/index.ts
index dc7ed68229..ca6a13c034 100644
--- a/plugins/catalog/src/components/CatalogPage/index.ts
+++ b/plugins/catalog/src/components/CatalogPage/index.ts
@@ -14,3 +14,5 @@
* limitations under the License.
*/
export { CatalogPage } from './CatalogPage';
+export { DefaultCatalogPage } from './DefaultCatalogPage';
+export type { DefaultCatalogPageProps } from './DefaultCatalogPage';
diff --git a/plugins/catalog/src/index.ts b/plugins/catalog/src/index.ts
index d804bbaf83..56cae80b6a 100644
--- a/plugins/catalog/src/index.ts
+++ b/plugins/catalog/src/index.ts
@@ -54,3 +54,4 @@ export {
export type { EntityLinksEmptyStateClassKey } from './components/EntityLinksCard';
export type { SystemDiagramCardClassKey } from './components/SystemDiagramCard';
+export type { DefaultCatalogPageProps } from './components/CatalogPage';
diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json
index 5e88164b3c..7a6fda44e5 100644
--- a/plugins/circleci/package.json
+++ b/plugins/circleci/package.json
@@ -52,10 +52,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json
index e3834572fc..9c6c5586f7 100644
--- a/plugins/cloudbuild/package.json
+++ b/plugins/cloudbuild/package.json
@@ -49,10 +49,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/code-coverage-backend/CHANGELOG.md b/plugins/code-coverage-backend/CHANGELOG.md
index 4d7b7cc379..1fd78b862b 100644
--- a/plugins/code-coverage-backend/CHANGELOG.md
+++ b/plugins/code-coverage-backend/CHANGELOG.md
@@ -1,5 +1,13 @@
# @backstage/plugin-code-coverage-backend
+## 0.1.18
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.10.1
+ - @backstage/integration@0.7.0
+
## 0.1.17
### Patch Changes
diff --git a/plugins/code-coverage-backend/package.json b/plugins/code-coverage-backend/package.json
index 009eb38906..4a24cada7c 100644
--- a/plugins/code-coverage-backend/package.json
+++ b/plugins/code-coverage-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-code-coverage-backend",
"description": "A Backstage backend plugin that helps you keep track of your code coverage",
- "version": "0.1.17",
+ "version": "0.1.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,12 +20,12 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.10.0",
+ "@backstage/backend-common": "^0.10.1",
"@backstage/catalog-client": "^0.5.3",
"@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.10",
"@backstage/errors": "^0.1.5",
- "@backstage/integration": "^0.6.10",
+ "@backstage/integration": "^0.7.0",
"@types/express": "^4.17.6",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
@@ -36,7 +36,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@types/express-xml-bodyparser": "^0.3.2",
"@types/supertest": "^2.0.8",
"msw": "^0.35.0",
diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json
index f7127cd824..1fb00c7ba4 100644
--- a/plugins/code-coverage/package.json
+++ b/plugins/code-coverage/package.json
@@ -43,10 +43,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json
index 0725070a9b..03891b498c 100644
--- a/plugins/config-schema/package.json
+++ b/plugins/config-schema/package.json
@@ -38,10 +38,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/cost-insights/CHANGELOG.md b/plugins/cost-insights/CHANGELOG.md
index c2f0c3bbb9..2e47db3bb8 100644
--- a/plugins/cost-insights/CHANGELOG.md
+++ b/plugins/cost-insights/CHANGELOG.md
@@ -1,5 +1,11 @@
# @backstage/plugin-cost-insights
+## 0.11.15
+
+### Patch Changes
+
+- 7858c2abdc: Fixed an accidental re-export of `@backstage/test-utils` that broke this plugin in the most recent release.
+
## 0.11.14
### Patch Changes
diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json
index 8323d12dcf..e1995f2e49 100644
--- a/plugins/cost-insights/package.json
+++ b/plugins/cost-insights/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-cost-insights",
"description": "A Backstage plugin that helps you keep track of your cloud spend",
- "version": "0.11.14",
+ "version": "0.11.15",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -56,10 +56,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/explore/package.json b/plugins/explore/package.json
index 4bf38ddb99..943fe915f7 100644
--- a/plugins/explore/package.json
+++ b/plugins/explore/package.json
@@ -50,10 +50,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/firehydrant/package.json b/plugins/firehydrant/package.json
index 4e36033f00..5db5ce7018 100644
--- a/plugins/firehydrant/package.json
+++ b/plugins/firehydrant/package.json
@@ -36,10 +36,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json
index 464388be50..80cc98a32a 100644
--- a/plugins/fossa/package.json
+++ b/plugins/fossa/package.json
@@ -50,10 +50,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/gcp-projects/package.json b/plugins/gcp-projects/package.json
index f608614e18..05b2976efb 100644
--- a/plugins/gcp-projects/package.json
+++ b/plugins/gcp-projects/package.json
@@ -44,10 +44,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/git-release-manager/CHANGELOG.md b/plugins/git-release-manager/CHANGELOG.md
index 468120a36b..1f7dc43cbd 100644
--- a/plugins/git-release-manager/CHANGELOG.md
+++ b/plugins/git-release-manager/CHANGELOG.md
@@ -1,5 +1,12 @@
# @backstage/plugin-git-release-manager
+## 0.3.6
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/integration@0.7.0
+
## 0.3.5
### Patch Changes
diff --git a/plugins/git-release-manager/package.json b/plugins/git-release-manager/package.json
index 89ed787c5a..32fb6bba1e 100644
--- a/plugins/git-release-manager/package.json
+++ b/plugins/git-release-manager/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-git-release-manager",
"description": "A Backstage plugin that helps you manage releases in git",
- "version": "0.3.5",
+ "version": "0.3.6",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -23,7 +23,7 @@
"dependencies": {
"@backstage/core-components": "^0.8.2",
"@backstage/core-plugin-api": "^0.4.0",
- "@backstage/integration": "^0.6.10",
+ "@backstage/integration": "^0.7.0",
"@backstage/theme": "^0.2.14",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -40,10 +40,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/plugins/github-actions/CHANGELOG.md b/plugins/github-actions/CHANGELOG.md
index 5f932693d5..4c65a93a43 100644
--- a/plugins/github-actions/CHANGELOG.md
+++ b/plugins/github-actions/CHANGELOG.md
@@ -1,5 +1,13 @@
# @backstage/plugin-github-actions
+## 0.4.29
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.6.9
+ - @backstage/integration@0.7.0
+
## 0.4.28
### Patch Changes
diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json
index 85e1ed04c3..7c3c475a0a 100644
--- a/plugins/github-actions/package.json
+++ b/plugins/github-actions/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-github-actions",
"description": "A Backstage plugin that integrates towards GitHub Actions",
- "version": "0.4.28",
+ "version": "0.4.29",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -36,8 +36,8 @@
"@backstage/catalog-model": "^0.9.8",
"@backstage/core-components": "^0.8.2",
"@backstage/core-plugin-api": "^0.4.0",
- "@backstage/integration": "^0.6.10",
- "@backstage/plugin-catalog-react": "^0.6.8",
+ "@backstage/integration": "^0.7.0",
+ "@backstage/plugin-catalog-react": "^0.6.9",
"@backstage/theme": "^0.2.14",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -52,10 +52,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/github-deployments/CHANGELOG.md b/plugins/github-deployments/CHANGELOG.md
index 6cda495e58..3d456e56d5 100644
--- a/plugins/github-deployments/CHANGELOG.md
+++ b/plugins/github-deployments/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-github-deployments
+## 0.1.24
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.6.9
+ - @backstage/integration@0.7.0
+ - @backstage/integration-react@0.1.17
+
## 0.1.23
### Patch Changes
diff --git a/plugins/github-deployments/package.json b/plugins/github-deployments/package.json
index 5147e2dc9c..8e023e6cd2 100644
--- a/plugins/github-deployments/package.json
+++ b/plugins/github-deployments/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-github-deployments",
"description": "A Backstage plugin that integrates towards GitHub Deployments",
- "version": "0.1.23",
+ "version": "0.1.24",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -25,9 +25,9 @@
"@backstage/core-components": "^0.8.2",
"@backstage/core-plugin-api": "^0.4.0",
"@backstage/errors": "^0.1.3",
- "@backstage/integration": "^0.6.10",
- "@backstage/integration-react": "^0.1.16",
- "@backstage/plugin-catalog-react": "^0.6.8",
+ "@backstage/integration": "^0.7.0",
+ "@backstage/integration-react": "^0.1.17",
+ "@backstage/plugin-catalog-react": "^0.6.9",
"@backstage/theme": "^0.2.14",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -40,10 +40,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/gitops-profiles/package.json b/plugins/gitops-profiles/package.json
index 064a170522..1defa61667 100644
--- a/plugins/gitops-profiles/package.json
+++ b/plugins/gitops-profiles/package.json
@@ -45,10 +45,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json
index 25dfa0b2da..510e06a3a4 100644
--- a/plugins/graphiql/package.json
+++ b/plugins/graphiql/package.json
@@ -45,10 +45,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/home/package.json b/plugins/home/package.json
index adb26e76d0..ea924d2aa1 100644
--- a/plugins/home/package.json
+++ b/plugins/home/package.json
@@ -36,10 +36,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/ilert/package.json b/plugins/ilert/package.json
index 145a91ba75..de904d9a3e 100644
--- a/plugins/ilert/package.json
+++ b/plugins/ilert/package.json
@@ -40,10 +40,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/jenkins/package.json b/plugins/jenkins/package.json
index ea3df7b719..eba8b8405b 100644
--- a/plugins/jenkins/package.json
+++ b/plugins/jenkins/package.json
@@ -50,10 +50,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/kafka/package.json b/plugins/kafka/package.json
index 149979752e..6ba86a62a1 100644
--- a/plugins/kafka/package.json
+++ b/plugins/kafka/package.json
@@ -36,10 +36,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/plugins/kubernetes-backend/api-report.md b/plugins/kubernetes-backend/api-report.md
index 7d3adac1c4..9b181c8514 100644
--- a/plugins/kubernetes-backend/api-report.md
+++ b/plugins/kubernetes-backend/api-report.md
@@ -6,6 +6,7 @@
import { Config } from '@backstage/config';
import express from 'express';
import type { FetchResponse } from '@backstage/plugin-kubernetes-common';
+import type { JsonObject } from '@backstage/types';
import type { KubernetesFetchError } from '@backstage/plugin-kubernetes-common';
import type { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common';
import { Logger as Logger_2 } from 'winston';
@@ -31,6 +32,7 @@ export interface ClusterDetails {
// (undocumented)
caData?: string | undefined;
dashboardApp?: string;
+ dashboardParameters?: JsonObject;
dashboardUrl?: string;
name: string;
// (undocumented)
diff --git a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts
index f5d6b56893..6ece380f28 100644
--- a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts
+++ b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts
@@ -176,4 +176,76 @@ describe('ConfigClusterLocator', () => {
},
]);
});
+
+ it('one cluster with dashboardParameters', async () => {
+ const config: Config = new ConfigReader({
+ clusters: [
+ {
+ name: 'cluster1',
+ url: 'http://localhost:8080',
+ authProvider: 'serviceAccount',
+ dashboardApp: 'gke',
+ dashboardParameters: {
+ projectId: 'some-project',
+ region: 'some-region',
+ clusterName: 'cluster1',
+ },
+ },
+ ],
+ });
+
+ const sut = ConfigClusterLocator.fromConfig(config);
+
+ const result = await sut.getClusters();
+
+ expect(result).toStrictEqual([
+ {
+ name: 'cluster1',
+ serviceAccountToken: undefined,
+ url: 'http://localhost:8080',
+ authProvider: 'serviceAccount',
+ skipMetricsLookup: false,
+ skipTLSVerify: false,
+ caData: undefined,
+ dashboardApp: 'gke',
+ dashboardParameters: {
+ projectId: 'some-project',
+ region: 'some-region',
+ clusterName: 'cluster1',
+ },
+ },
+ ]);
+ });
+
+ it('one cluster with dashboardUrl', async () => {
+ const config: Config = new ConfigReader({
+ clusters: [
+ {
+ name: 'cluster1',
+ url: 'http://localhost:8080',
+ authProvider: 'serviceAccount',
+ dashboardApp: 'standard',
+ dashboardUrl: 'http://someurl',
+ },
+ ],
+ });
+
+ const sut = ConfigClusterLocator.fromConfig(config);
+
+ const result = await sut.getClusters();
+
+ expect(result).toStrictEqual([
+ {
+ name: 'cluster1',
+ serviceAccountToken: undefined,
+ url: 'http://localhost:8080',
+ authProvider: 'serviceAccount',
+ skipMetricsLookup: false,
+ skipTLSVerify: false,
+ caData: undefined,
+ dashboardApp: 'standard',
+ dashboardUrl: 'http://someurl',
+ },
+ ]);
+ });
});
diff --git a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts
index 36b5f58f2c..d8436b6c24 100644
--- a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts
+++ b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts
@@ -47,6 +47,9 @@ export class ConfigClusterLocator implements KubernetesClustersSupplier {
if (dashboardApp) {
clusterDetails.dashboardApp = dashboardApp;
}
+ if (c.has('dashboardParameters')) {
+ clusterDetails.dashboardParameters = c.get('dashboardParameters');
+ }
switch (authProvider) {
case 'google': {
diff --git a/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.test.ts b/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.test.ts
index bd342f566b..6bef8e0009 100644
--- a/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.test.ts
+++ b/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.test.ts
@@ -226,5 +226,51 @@ describe('GkeClusterLocator', () => {
parent: 'projects/some-project/locations/some-region',
});
});
+ it('expose GKE dashboard', async () => {
+ mockedListClusters.mockReturnValueOnce([
+ {
+ clusters: [
+ {
+ name: 'some-cluster',
+ endpoint: '1.2.3.4',
+ },
+ ],
+ },
+ ]);
+
+ const config: Config = new ConfigReader({
+ type: 'gke',
+ projectId: 'some-project',
+ region: 'some-region',
+ skipMetricsLookup: true,
+ exposeDashboard: true,
+ });
+
+ const sut = GkeClusterLocator.fromConfigWithClient(config, {
+ listClusters: mockedListClusters,
+ } as any);
+
+ const result = await sut.getClusters();
+
+ expect(result).toStrictEqual([
+ {
+ authProvider: 'google',
+ name: 'some-cluster',
+ url: 'https://1.2.3.4',
+ skipTLSVerify: false,
+ skipMetricsLookup: true,
+ dashboardApp: 'gke',
+ dashboardParameters: {
+ clusterName: 'some-cluster',
+ projectId: 'some-project',
+ region: 'some-region',
+ },
+ },
+ ]);
+ expect(mockedListClusters).toBeCalledTimes(1);
+ expect(mockedListClusters).toHaveBeenCalledWith({
+ parent: 'projects/some-project/locations/some-region',
+ });
+ });
});
});
diff --git a/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts b/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts
index d7f5050399..8b70db40eb 100644
--- a/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts
+++ b/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts
@@ -24,6 +24,7 @@ type GkeClusterLocatorOptions = {
region?: string;
skipTLSVerify?: boolean;
skipMetricsLookup?: boolean;
+ exposeDashboard?: boolean;
};
export class GkeClusterLocator implements KubernetesClustersSupplier {
@@ -42,6 +43,7 @@ export class GkeClusterLocator implements KubernetesClustersSupplier {
skipTLSVerify: config.getOptionalBoolean('skipTLSVerify') ?? false,
skipMetricsLookup:
config.getOptionalBoolean('skipMetricsLookup') ?? false,
+ exposeDashboard: config.getOptionalBoolean('exposeDashboard') ?? false,
};
return new GkeClusterLocator(options, client);
}
@@ -55,8 +57,13 @@ export class GkeClusterLocator implements KubernetesClustersSupplier {
// TODO pass caData into the object
async getClusters(): Promise {
- const { projectId, region, skipTLSVerify, skipMetricsLookup } =
- this.options;
+ const {
+ projectId,
+ region,
+ skipTLSVerify,
+ skipMetricsLookup,
+ exposeDashboard,
+ } = this.options;
const request = {
parent: `projects/${projectId}/locations/${region}`,
};
@@ -70,6 +77,16 @@ export class GkeClusterLocator implements KubernetesClustersSupplier {
authProvider: 'google',
skipTLSVerify,
skipMetricsLookup,
+ ...(exposeDashboard
+ ? {
+ dashboardApp: 'gke',
+ dashboardParameters: {
+ projectId,
+ region,
+ clusterName: r.name,
+ },
+ }
+ : {}),
}));
} catch (e) {
throw new ForwardedError(
diff --git a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts
index a25c220b80..b15ec1386e 100644
--- a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts
+++ b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts
@@ -255,6 +255,10 @@ export class KubernetesFanOutHandler {
if (clusterDetailsItem.dashboardApp) {
objects.cluster.dashboardApp = clusterDetailsItem.dashboardApp;
}
+ if (clusterDetailsItem.dashboardParameters) {
+ objects.cluster.dashboardParameters =
+ clusterDetailsItem.dashboardParameters;
+ }
return objects;
});
}),
diff --git a/plugins/kubernetes-backend/src/types/types.ts b/plugins/kubernetes-backend/src/types/types.ts
index a0ec0832c1..4f25805063 100644
--- a/plugins/kubernetes-backend/src/types/types.ts
+++ b/plugins/kubernetes-backend/src/types/types.ts
@@ -15,6 +15,7 @@
*/
import { Logger } from 'winston';
+import type { JsonObject } from '@backstage/types';
import type {
FetchResponse,
KubernetesFetchError,
@@ -111,6 +112,7 @@ export interface ClusterDetails {
* using the dashboardApp property, in order to properly format
* links to kubernetes resources, otherwise it will assume that you're running the standard one.
* @see dashboardApp
+ * @see dashboardParameters
*/
dashboardUrl?: string;
/**
@@ -129,6 +131,12 @@ export interface ClusterDetails {
* ```
*/
dashboardApp?: string;
+ /**
+ * Specifies specific parameters used by some dashboard URL formatters.
+ * This is used by the GKE formatter which requires the project, region and cluster name.
+ * @see dashboardApp
+ */
+ dashboardParameters?: JsonObject;
}
export interface GKEClusterDetails extends ClusterDetails {}
diff --git a/plugins/kubernetes-common/api-report.md b/plugins/kubernetes-common/api-report.md
index f3500aa271..15019d71c3 100644
--- a/plugins/kubernetes-common/api-report.md
+++ b/plugins/kubernetes-common/api-report.md
@@ -4,6 +4,7 @@
```ts
import { Entity } from '@backstage/catalog-model';
+import type { JsonObject } from '@backstage/types';
import { V1ConfigMap } from '@kubernetes/client-node';
import { V1CronJob } from '@kubernetes/client-node';
import { V1Deployment } from '@kubernetes/client-node';
@@ -62,6 +63,7 @@ export interface ClientPodStatus {
// @public (undocumented)
export interface ClusterAttributes {
dashboardApp?: string;
+ dashboardParameters?: JsonObject;
dashboardUrl?: string;
name: string;
}
diff --git a/plugins/kubernetes-common/src/types.ts b/plugins/kubernetes-common/src/types.ts
index 0c5af00a97..afda9b5299 100644
--- a/plugins/kubernetes-common/src/types.ts
+++ b/plugins/kubernetes-common/src/types.ts
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import type { JsonObject } from '@backstage/types';
import {
V1ConfigMap,
V1CronJob,
@@ -45,6 +46,7 @@ export interface ClusterAttributes {
* Note that you should specify the app used for the dashboard
* using the dashboardApp property, in order to properly format
* links to kubernetes resources, otherwise it will assume that you're running the standard one.
+ * Also, for cloud clusters such as GKE, you should provide addititonal parameters using dashboardParameters.
* @see dashboardApp
*/
dashboardUrl?: string;
@@ -64,6 +66,11 @@ export interface ClusterAttributes {
* ```
*/
dashboardApp?: string;
+ /**
+ * Specifies specific parameters used by some dashboard URL formatters.
+ * This is used by the GKE formatter which requires the project, region and cluster name.
+ */
+ dashboardParameters?: JsonObject;
}
export interface ClusterObjects {
diff --git a/plugins/kubernetes/api-report.md b/plugins/kubernetes/api-report.md
index 33ac98fb76..8dc0114738 100644
--- a/plugins/kubernetes/api-report.md
+++ b/plugins/kubernetes/api-report.md
@@ -10,6 +10,7 @@ import { BackstagePlugin } from '@backstage/core-plugin-api';
import { DiscoveryApi } from '@backstage/core-plugin-api';
import { Entity } from '@backstage/catalog-model';
import { IdentityApi } from '@backstage/core-plugin-api';
+import type { JsonObject } from '@backstage/types';
import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common';
import { OAuthApi } from '@backstage/core-plugin-api';
import { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common';
diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json
index 1a39042316..111a444f0d 100644
--- a/plugins/kubernetes/package.json
+++ b/plugins/kubernetes/package.json
@@ -53,10 +53,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/plugins/kubernetes/src/components/KubernetesDrawer/KubernetesDrawer.tsx b/plugins/kubernetes/src/components/KubernetesDrawer/KubernetesDrawer.tsx
index b4ea31dc8d..8a177cf6dd 100644
--- a/plugins/kubernetes/src/components/KubernetesDrawer/KubernetesDrawer.tsx
+++ b/plugins/kubernetes/src/components/KubernetesDrawer/KubernetesDrawer.tsx
@@ -155,6 +155,7 @@ const KubernetesDrawerContent = ({
const { clusterLink, errorMessage } = tryFormatClusterLink({
dashboardUrl: cluster.dashboardUrl,
dashboardApp: cluster.dashboardApp,
+ dashboardParameters: cluster.dashboardParameters,
object,
kind,
});
diff --git a/plugins/kubernetes/src/types/types.ts b/plugins/kubernetes/src/types/types.ts
index d6ef8fa784..1bdfa181d9 100644
--- a/plugins/kubernetes/src/types/types.ts
+++ b/plugins/kubernetes/src/types/types.ts
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import type { JsonObject } from '@backstage/types';
import {
V1Deployment,
V1Pod,
@@ -43,7 +44,8 @@ export interface GroupedResponses extends DeploymentResources {
}
export interface ClusterLinksFormatterOptions {
- dashboardUrl: URL;
+ dashboardUrl?: URL;
+ dashboardParameters?: JsonObject;
object: any;
kind: string;
}
diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatClusterLink.test.ts b/plugins/kubernetes/src/utils/clusterLinks/formatClusterLink.test.ts
index 31e07a0f14..b767d496a2 100644
--- a/plugins/kubernetes/src/utils/clusterLinks/formatClusterLink.test.ts
+++ b/plugins/kubernetes/src/utils/clusterLinks/formatClusterLink.test.ts
@@ -114,5 +114,47 @@ describe('clusterLinks', () => {
);
});
});
+ describe('GKE app', () => {
+ it('should return an url on the deployment', () => {
+ const url = formatClusterLink({
+ dashboardApp: 'gke',
+ dashboardParameters: {
+ projectId: 'foobar-333614',
+ region: 'us-east1-c',
+ clusterName: 'cluster-1',
+ },
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'Deployment',
+ });
+ expect(url).toBe(
+ 'https://console.cloud.google.com/kubernetes/deployment/us-east1-c/cluster-1/bar/foobar/overview?project=foobar-333614',
+ );
+ });
+ it('should return an url on the service', () => {
+ const url = formatClusterLink({
+ dashboardApp: 'gke',
+ dashboardParameters: {
+ projectId: 'foobar-333614',
+ region: 'us-east1-c',
+ clusterName: 'cluster-1',
+ },
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'Service',
+ });
+ expect(url).toBe(
+ 'https://console.cloud.google.com/kubernetes/service/us-east1-c/cluster-1/bar/foobar/overview?project=foobar-333614',
+ );
+ });
+ });
});
});
diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatClusterLink.ts b/plugins/kubernetes/src/utils/clusterLinks/formatClusterLink.ts
index a8f83a9c76..6a998bbce2 100644
--- a/plugins/kubernetes/src/utils/clusterLinks/formatClusterLink.ts
+++ b/plugins/kubernetes/src/utils/clusterLinks/formatClusterLink.ts
@@ -14,20 +14,22 @@
* limitations under the License.
*/
+import type { JsonObject } from '@backstage/types';
import { defaultFormatterName, clusterLinksFormatters } from './formatters';
export type FormatClusterLinkOptions = {
dashboardUrl?: string;
dashboardApp?: string;
+ dashboardParameters?: JsonObject;
object: any;
kind: string;
};
export function formatClusterLink(options: FormatClusterLinkOptions) {
- if (!options.dashboardUrl) {
+ if (!options.dashboardUrl && !options.dashboardParameters) {
return undefined;
}
- if (!options.object) {
+ if (options.dashboardUrl && !options.object) {
return options.dashboardUrl;
}
const app = options.dashboardApp || defaultFormatterName;
@@ -36,7 +38,10 @@ export function formatClusterLink(options: FormatClusterLinkOptions) {
throw new Error(`Could not find Kubernetes dashboard app named '${app}'`);
}
const url = formatter({
- dashboardUrl: new URL(options.dashboardUrl),
+ dashboardUrl: options.dashboardUrl
+ ? new URL(options.dashboardUrl)
+ : undefined,
+ dashboardParameters: options.dashboardParameters,
object: options.object,
kind: options.kind,
});
diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/gke.test.ts b/plugins/kubernetes/src/utils/clusterLinks/formatters/gke.test.ts
index e566404daf..20541f216d 100644
--- a/plugins/kubernetes/src/utils/clusterLinks/formatters/gke.test.ts
+++ b/plugins/kubernetes/src/utils/clusterLinks/formatters/gke.test.ts
@@ -16,10 +16,9 @@
import { gkeFormatter } from './gke';
describe('clusterLinks - GKE formatter', () => {
- it('should return an url on the workloads when there is a namespace only', () => {
+ it('should provide a dashboardParameters in the options', () => {
expect(() =>
gkeFormatter({
- dashboardUrl: new URL('https://k8s.foo.com'),
object: {
metadata: {
name: 'foobar',
@@ -28,6 +27,196 @@ describe('clusterLinks - GKE formatter', () => {
},
kind: 'Deployment',
}),
- ).toThrowError('GKE formatter is not yet implemented. Please, contribute!');
+ ).toThrowError('GKE dashboard requires a dashboardParameters option');
+ });
+ it('should provide a projectId in the dashboardParameters options', () => {
+ expect(() =>
+ gkeFormatter({
+ dashboardParameters: {
+ region: 'us-east1-c',
+ clusterName: 'cluster-1',
+ },
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'Deployment',
+ }),
+ ).toThrowError(
+ 'GKE dashboard requires a "projectId" of type string in the dashboardParameters option',
+ );
+ });
+ it('should provide a region in the dashboardParameters options', () => {
+ expect(() =>
+ gkeFormatter({
+ dashboardParameters: {
+ projectId: 'foobar-333614',
+ clusterName: 'cluster-1',
+ },
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'Deployment',
+ }),
+ ).toThrowError(
+ 'GKE dashboard requires a "region" of type string in the dashboardParameters option',
+ );
+ });
+ it('should provide a clusterName in the dashboardParameters options', () => {
+ expect(() =>
+ gkeFormatter({
+ dashboardParameters: {
+ projectId: 'foobar-333614',
+ region: 'us-east1-c',
+ },
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'Deployment',
+ }),
+ ).toThrowError(
+ 'GKE dashboard requires a "clusterName" of type string in the dashboardParameters option',
+ );
+ });
+ it('should return an url on the cluster when there is a namespace only', () => {
+ const url = gkeFormatter({
+ dashboardParameters: {
+ projectId: 'foobar-333614',
+ region: 'us-east1-c',
+ clusterName: 'cluster-1',
+ },
+ object: {
+ metadata: {
+ namespace: 'bar',
+ },
+ },
+ kind: 'foo',
+ });
+ expect(url.href).toBe(
+ 'https://console.cloud.google.com/kubernetes/clusters/details/us-east1-c/cluster-1/details?project=foobar-333614',
+ );
+ });
+ it('should return an url on the cluster when the kind is not recognizeed', () => {
+ const url = gkeFormatter({
+ dashboardParameters: {
+ projectId: 'foobar-333614',
+ region: 'us-east1-c',
+ clusterName: 'cluster-1',
+ },
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'UnknownKind',
+ });
+ expect(url.href).toBe(
+ 'https://console.cloud.google.com/kubernetes/clusters/details/us-east1-c/cluster-1/details?project=foobar-333614',
+ );
+ });
+ it('should return an url on the deployment', () => {
+ const url = gkeFormatter({
+ dashboardParameters: {
+ projectId: 'foobar-333614',
+ region: 'us-east1-c',
+ clusterName: 'cluster-1',
+ },
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'Deployment',
+ });
+ expect(url.href).toBe(
+ 'https://console.cloud.google.com/kubernetes/deployment/us-east1-c/cluster-1/bar/foobar/overview?project=foobar-333614',
+ );
+ });
+
+ it('should return an url on the service', () => {
+ const url = gkeFormatter({
+ dashboardParameters: {
+ projectId: 'foobar-333614',
+ region: 'us-east1-c',
+ clusterName: 'cluster-1',
+ },
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'Service',
+ });
+ expect(url.href).toBe(
+ 'https://console.cloud.google.com/kubernetes/service/us-east1-c/cluster-1/bar/foobar/overview?project=foobar-333614',
+ );
+ });
+ it('should return an url on the pod', () => {
+ const url = gkeFormatter({
+ dashboardParameters: {
+ projectId: 'foobar-333614',
+ region: 'us-east1-c',
+ clusterName: 'cluster-1',
+ },
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'Pod',
+ });
+ expect(url.href).toBe(
+ 'https://console.cloud.google.com/kubernetes/pod/us-east1-c/cluster-1/bar/foobar/details?project=foobar-333614',
+ );
+ });
+ it('should return an url on the ingress', () => {
+ const url = gkeFormatter({
+ dashboardParameters: {
+ projectId: 'foobar-333614',
+ region: 'us-east1-c',
+ clusterName: 'cluster-1',
+ },
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'Ingress',
+ });
+ expect(url.href).toBe(
+ 'https://console.cloud.google.com/kubernetes/ingress/us-east1-c/cluster-1/bar/foobar/details?project=foobar-333614',
+ );
+ });
+ it('should return an url on the deployment for a hpa', () => {
+ const url = gkeFormatter({
+ dashboardParameters: {
+ projectId: 'foobar-333614',
+ region: 'us-east1-c',
+ clusterName: 'cluster-1',
+ },
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'HorizontalPodAutoscaler',
+ });
+ expect(url.href).toBe(
+ 'https://console.cloud.google.com/kubernetes/deployment/us-east1-c/cluster-1/bar/foobar/overview?project=foobar-333614',
+ );
});
});
diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/gke.ts b/plugins/kubernetes/src/utils/clusterLinks/formatters/gke.ts
index 30e7fa3123..957032e6e2 100644
--- a/plugins/kubernetes/src/utils/clusterLinks/formatters/gke.ts
+++ b/plugins/kubernetes/src/utils/clusterLinks/formatters/gke.ts
@@ -15,6 +15,53 @@
*/
import { ClusterLinksFormatterOptions } from '../../../types/types';
-export function gkeFormatter(_options: ClusterLinksFormatterOptions): URL {
- throw new Error('GKE formatter is not yet implemented. Please, contribute!');
+const kindMappings: Record = {
+ deployment: 'deployment',
+ pod: 'pod',
+ ingress: 'ingress',
+ service: 'service',
+ horizontalpodautoscaler: 'deployment',
+};
+
+export function gkeFormatter(options: ClusterLinksFormatterOptions): URL {
+ if (!options.dashboardParameters) {
+ throw new Error('GKE dashboard requires a dashboardParameters option');
+ }
+ const args = options.dashboardParameters;
+ if (typeof args.projectId !== 'string') {
+ throw new Error(
+ 'GKE dashboard requires a "projectId" of type string in the dashboardParameters option',
+ );
+ }
+ if (typeof args.region !== 'string') {
+ throw new Error(
+ 'GKE dashboard requires a "region" of type string in the dashboardParameters option',
+ );
+ }
+ if (typeof args.clusterName !== 'string') {
+ throw new Error(
+ 'GKE dashboard requires a "clusterName" of type string in the dashboardParameters option',
+ );
+ }
+ const basePath = new URL('https://console.cloud.google.com/');
+ const region = encodeURIComponent(args.region);
+ const clusterName = encodeURIComponent(args.clusterName);
+ const name = encodeURIComponent(options.object.metadata?.name ?? '');
+ const namespace = encodeURIComponent(
+ options.object.metadata?.namespace ?? '',
+ );
+ const validKind = kindMappings[options.kind.toLocaleLowerCase('en-US')];
+ let path = '';
+ if (namespace && name && validKind) {
+ const kindsWithDetails = ['ingress', 'pod'];
+ const landingPage = kindsWithDetails.includes(validKind)
+ ? 'details'
+ : 'overview';
+ path = `kubernetes/${validKind}/${region}/${clusterName}/${namespace}/${name}/${landingPage}`;
+ } else {
+ path = `kubernetes/clusters/details/${region}/${clusterName}/details`;
+ }
+ const result = new URL(path, basePath);
+ result.searchParams.set('project', args.projectId);
+ return result;
}
diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/openshift.test.ts b/plugins/kubernetes/src/utils/clusterLinks/formatters/openshift.test.ts
index f0b85cad49..2380d3e2d5 100644
--- a/plugins/kubernetes/src/utils/clusterLinks/formatters/openshift.test.ts
+++ b/plugins/kubernetes/src/utils/clusterLinks/formatters/openshift.test.ts
@@ -16,6 +16,19 @@
import { openshiftFormatter } from './openshift';
describe('clusterLinks - OpenShift formatter', () => {
+ it('should provide a dashboardUrl in the options', () => {
+ expect(() =>
+ openshiftFormatter({
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'Deployment',
+ }),
+ ).toThrowError('OpenShift dashboard requires a dashboardUrl option');
+ });
it('should return an url on the workloads when there is a namespace only', () => {
const url = openshiftFormatter({
dashboardUrl: new URL('https://k8s.foo.com'),
diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/openshift.ts b/plugins/kubernetes/src/utils/clusterLinks/formatters/openshift.ts
index 6c20cd4720..c5b7313061 100644
--- a/plugins/kubernetes/src/utils/clusterLinks/formatters/openshift.ts
+++ b/plugins/kubernetes/src/utils/clusterLinks/formatters/openshift.ts
@@ -24,6 +24,9 @@ const kindMappings: Record = {
};
export function openshiftFormatter(options: ClusterLinksFormatterOptions): URL {
+ if (!options.dashboardUrl) {
+ throw new Error('OpenShift dashboard requires a dashboardUrl option');
+ }
const basePath = new URL(options.dashboardUrl.href);
const name = encodeURIComponent(options.object.metadata?.name ?? '');
const namespace = encodeURIComponent(
diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.test.ts b/plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.test.ts
index cb200387a3..45983deab0 100644
--- a/plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.test.ts
+++ b/plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.test.ts
@@ -16,6 +16,19 @@
import { rancherFormatter } from './rancher';
describe('clusterLinks - rancher formatter', () => {
+ it('should provide a dashboardUrl in the options', () => {
+ expect(() =>
+ rancherFormatter({
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'Deployment',
+ }),
+ ).toThrowError('Rancher dashboard requires a dashboardUrl option');
+ });
it('should return a url on the workloads when there is a namespace only', () => {
const url = rancherFormatter({
dashboardUrl: new URL('https://k8s.foo.com'),
diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.ts b/plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.ts
index 1ace39ec59..6c72730181 100644
--- a/plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.ts
+++ b/plugins/kubernetes/src/utils/clusterLinks/formatters/rancher.ts
@@ -23,6 +23,9 @@ const kindMappings: Record = {
};
export function rancherFormatter(options: ClusterLinksFormatterOptions): URL {
+ if (!options.dashboardUrl) {
+ throw new Error('Rancher dashboard requires a dashboardUrl option');
+ }
const basePath = new URL(options.dashboardUrl.href);
const name = encodeURIComponent(options.object.metadata?.name ?? '');
const namespace = encodeURIComponent(
diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/standard.test.ts b/plugins/kubernetes/src/utils/clusterLinks/formatters/standard.test.ts
index 0b3c21a627..c0ee3f534d 100644
--- a/plugins/kubernetes/src/utils/clusterLinks/formatters/standard.test.ts
+++ b/plugins/kubernetes/src/utils/clusterLinks/formatters/standard.test.ts
@@ -23,6 +23,19 @@ function formatUrl(url: URL) {
}
describe('clusterLinks - standard formatter', () => {
+ it('should provide a dashboardUrl in the options', () => {
+ expect(() =>
+ standardFormatter({
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'Deployment',
+ }),
+ ).toThrowError('standard dashboard requires a dashboardUrl option');
+ });
it('should return an url on the workloads when there is a namespace only', () => {
const url = standardFormatter({
dashboardUrl: new URL('https://k8s.foo.com'),
@@ -67,6 +80,21 @@ describe('clusterLinks - standard formatter', () => {
'https://k8s.foo.com/#/deployment/bar/foobar?namespace=bar',
);
});
+ it('should return an url on the pod', () => {
+ const url = standardFormatter({
+ dashboardUrl: new URL('https://k8s.foo.com/'),
+ object: {
+ metadata: {
+ name: 'foobar',
+ namespace: 'bar',
+ },
+ },
+ kind: 'Pod',
+ });
+ expect(formatUrl(url)).toBe(
+ 'https://k8s.foo.com/#/pod/bar/foobar?namespace=bar',
+ );
+ });
it('should return an url on the deployment with a prefix 1', () => {
const url = standardFormatter({
dashboardUrl: new URL('https://k8s.foo.com/some/prefix'),
diff --git a/plugins/kubernetes/src/utils/clusterLinks/formatters/standard.ts b/plugins/kubernetes/src/utils/clusterLinks/formatters/standard.ts
index e28c9fae2b..a7428a8722 100644
--- a/plugins/kubernetes/src/utils/clusterLinks/formatters/standard.ts
+++ b/plugins/kubernetes/src/utils/clusterLinks/formatters/standard.ts
@@ -17,12 +17,16 @@ import { ClusterLinksFormatterOptions } from '../../../types/types';
const kindMappings: Record = {
deployment: 'deployment',
+ pod: 'pod',
ingress: 'ingress',
service: 'service',
horizontalpodautoscaler: 'deployment',
};
export function standardFormatter(options: ClusterLinksFormatterOptions) {
+ if (!options.dashboardUrl) {
+ throw new Error('standard dashboard requires a dashboardUrl option');
+ }
const result = new URL(options.dashboardUrl.href);
const name = encodeURIComponent(options.object.metadata?.name ?? '');
const namespace = encodeURIComponent(
diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json
index a9b1e679d0..51970e16c5 100644
--- a/plugins/lighthouse/package.json
+++ b/plugins/lighthouse/package.json
@@ -48,10 +48,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/plugins/newrelic-dashboard/package.json b/plugins/newrelic-dashboard/package.json
index 0502d130cf..2a81be3b99 100644
--- a/plugins/newrelic-dashboard/package.json
+++ b/plugins/newrelic-dashboard/package.json
@@ -31,7 +31,7 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/dev-utils": "^0.2.15",
"@testing-library/jest-dom": "^5.10.1",
"@types/react": "^16.13.1 || ^17.0.0",
diff --git a/plugins/newrelic/package.json b/plugins/newrelic/package.json
index 42b1a832fa..135e03e495 100644
--- a/plugins/newrelic/package.json
+++ b/plugins/newrelic/package.json
@@ -44,10 +44,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/org/package.json b/plugins/org/package.json
index 2b17df45b2..1a952dfe2f 100644
--- a/plugins/org/package.json
+++ b/plugins/org/package.json
@@ -39,11 +39,11 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
- "@backstage/core-app-api": "^0.3.0",
"@backstage/catalog-client": "^0.5.3",
+ "@backstage/cli": "^0.10.4",
+ "@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/pagerduty/package.json b/plugins/pagerduty/package.json
index 3656ae682d..458180841e 100644
--- a/plugins/pagerduty/package.json
+++ b/plugins/pagerduty/package.json
@@ -49,10 +49,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/permission-backend/CHANGELOG.md b/plugins/permission-backend/CHANGELOG.md
index 15474c8348..76ee47ab32 100644
--- a/plugins/permission-backend/CHANGELOG.md
+++ b/plugins/permission-backend/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-permission-backend
+## 0.2.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-auth-backend@0.6.0
+ - @backstage/backend-common@0.10.1
+ - @backstage/plugin-permission-node@0.2.3
+
## 0.2.2
### Patch Changes
diff --git a/plugins/permission-backend/package.json b/plugins/permission-backend/package.json
index a06e22a9b7..890495f646 100644
--- a/plugins/permission-backend/package.json
+++ b/plugins/permission-backend/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-permission-backend",
- "version": "0.2.2",
+ "version": "0.2.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -19,11 +19,11 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.10.0",
+ "@backstage/backend-common": "^0.10.1",
"@backstage/config": "^0.1.11",
- "@backstage/plugin-auth-backend": "^0.5.2",
+ "@backstage/plugin-auth-backend": "^0.6.0",
"@backstage/plugin-permission-common": "^0.3.0",
- "@backstage/plugin-permission-node": "^0.2.2",
+ "@backstage/plugin-permission-node": "^0.2.3",
"@types/express": "*",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
@@ -33,7 +33,7 @@
"zod": "^3.11.6"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@types/supertest": "^2.0.8",
"supertest": "^6.1.6",
"msw": "^0.35.0"
diff --git a/plugins/permission-node/CHANGELOG.md b/plugins/permission-node/CHANGELOG.md
index e49dfdc228..377b48f45e 100644
--- a/plugins/permission-node/CHANGELOG.md
+++ b/plugins/permission-node/CHANGELOG.md
@@ -1,5 +1,13 @@
# @backstage/plugin-permission-node
+## 0.2.3
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-auth-backend@0.6.0
+ - @backstage/backend-common@0.10.1
+
## 0.2.2
### Patch Changes
diff --git a/plugins/permission-node/package.json b/plugins/permission-node/package.json
index 9100500f1f..55f955110e 100644
--- a/plugins/permission-node/package.json
+++ b/plugins/permission-node/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-permission-node",
"description": "Common permission and authorization utilities for backend plugins",
- "version": "0.2.2",
+ "version": "0.2.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -29,16 +29,16 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.10.0",
+ "@backstage/backend-common": "^0.10.1",
"@backstage/config": "^0.1.11",
- "@backstage/plugin-auth-backend": "^0.5.2",
+ "@backstage/plugin-auth-backend": "^0.6.0",
"@backstage/plugin-permission-common": "^0.3.0",
"@types/express": "^4.17.6",
"express": "^4.17.1",
"zod": "^3.11.6"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@types/supertest": "^2.0.8",
"msw": "^0.35.0",
"supertest": "^6.1.3"
diff --git a/plugins/rollbar-backend/CHANGELOG.md b/plugins/rollbar-backend/CHANGELOG.md
index 49de959e2b..2d568b8be1 100644
--- a/plugins/rollbar-backend/CHANGELOG.md
+++ b/plugins/rollbar-backend/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-rollbar-backend
+## 0.1.18
+
+### Patch Changes
+
+- 152bd9ba2b: Moved `@backstage/test-utils` to `devDependencies`.
+- c5e175cde9: Replace the usage of `axios` with `node-fetch` in the Rollbar API
+- Updated dependencies
+ - @backstage/backend-common@0.10.1
+
## 0.1.17
### Patch Changes
diff --git a/plugins/rollbar-backend/package.json b/plugins/rollbar-backend/package.json
index def1514909..5257402661 100644
--- a/plugins/rollbar-backend/package.json
+++ b/plugins/rollbar-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-rollbar-backend",
"description": "A Backstage backend plugin that integrates towards Rollbar",
- "version": "0.1.17",
+ "version": "0.1.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,7 +31,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.10.0",
+ "@backstage/backend-common": "^0.10.1",
"@backstage/config": "^0.1.10",
"@types/express": "^4.17.6",
"camelcase-keys": "^6.2.2",
@@ -48,8 +48,8 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/cli": "^0.10.4",
+ "@backstage/test-utils": "^0.2.1",
"@types/supertest": "^2.0.8",
"msw": "^0.36.3",
"supertest": "^6.1.3"
diff --git a/plugins/rollbar/package.json b/plugins/rollbar/package.json
index 67dbebb80d..df5305b851 100644
--- a/plugins/rollbar/package.json
+++ b/plugins/rollbar/package.json
@@ -50,10 +50,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md
index 38f336e5cc..52a82025c9 100644
--- a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md
+++ b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-scaffolder-backend-module-cookiecutter
+## 0.1.7
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.10.1
+ - @backstage/plugin-scaffolder-backend@0.15.19
+ - @backstage/integration@0.7.0
+
## 0.1.6
### Patch Changes
diff --git a/plugins/scaffolder-backend-module-cookiecutter/package.json b/plugins/scaffolder-backend-module-cookiecutter/package.json
index 68f5bc9a54..349cda084e 100644
--- a/plugins/scaffolder-backend-module-cookiecutter/package.json
+++ b/plugins/scaffolder-backend-module-cookiecutter/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-scaffolder-backend-module-cookiecutter",
"description": "A module for the scaffolder backend that lets you template projects using cookiecutter",
- "version": "0.1.6",
+ "version": "0.1.7",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,10 +20,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.10.0",
+ "@backstage/backend-common": "^0.10.1",
"@backstage/errors": "^0.1.4",
- "@backstage/integration": "^0.6.10",
- "@backstage/plugin-scaffolder-backend": "^0.15.18",
+ "@backstage/integration": "^0.7.0",
+ "@backstage/plugin-scaffolder-backend": "^0.15.19",
"@backstage/config": "^0.1.11",
"@backstage/types": "^0.1.1",
"command-exists": "^1.2.9",
@@ -32,7 +32,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@types/fs-extra": "^9.0.1",
"@types/mock-fs": "^4.13.0",
"@types/jest": "^26.0.7",
diff --git a/plugins/scaffolder-backend-module-rails/CHANGELOG.md b/plugins/scaffolder-backend-module-rails/CHANGELOG.md
index 1abf510af4..70c35ba33e 100644
--- a/plugins/scaffolder-backend-module-rails/CHANGELOG.md
+++ b/plugins/scaffolder-backend-module-rails/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-scaffolder-backend-module-rails
+## 0.2.2
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.10.1
+ - @backstage/plugin-scaffolder-backend@0.15.19
+ - @backstage/integration@0.7.0
+
## 0.2.1
### Patch Changes
diff --git a/plugins/scaffolder-backend-module-rails/package.json b/plugins/scaffolder-backend-module-rails/package.json
index 7021ce9c0b..42a910e624 100644
--- a/plugins/scaffolder-backend-module-rails/package.json
+++ b/plugins/scaffolder-backend-module-rails/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-scaffolder-backend-module-rails",
"description": "A module for the scaffolder backend that lets you template projects using Rails",
- "version": "0.2.1",
+ "version": "0.2.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,17 +21,17 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.10.0",
- "@backstage/plugin-scaffolder-backend": "^0.15.18",
+ "@backstage/backend-common": "^0.10.1",
+ "@backstage/plugin-scaffolder-backend": "^0.15.19",
"@backstage/config": "^0.1.11",
"@backstage/errors": "^0.1.4",
- "@backstage/integration": "^0.6.10",
+ "@backstage/integration": "^0.7.0",
"@backstage/types": "^0.1.1",
"command-exists": "^1.2.9",
"fs-extra": "^9.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"@types/command-exists": "^1.2.0",
diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md
index 8af6b497cc..1a138a16e0 100644
--- a/plugins/scaffolder-backend/CHANGELOG.md
+++ b/plugins/scaffolder-backend/CHANGELOG.md
@@ -1,5 +1,19 @@
# @backstage/plugin-scaffolder-backend
+## 0.15.19
+
+### Patch Changes
+
+- 7d4b4e937c: Uptake changes to the GitHub Credentials Provider interface.
+- d078377f67: Support navigating back to pre-filled templates to update inputs of scaffolder tasks for resubmission
+- 5f8ceba1b1: Support custom file name for `catalog:write` action
+- Updated dependencies
+ - @backstage/backend-common@0.10.1
+ - @backstage/plugin-catalog-backend@0.19.4
+ - @backstage/plugin-scaffolder-common@0.1.2
+ - @backstage/integration@0.7.0
+ - @backstage/plugin-scaffolder-backend-module-cookiecutter@0.1.7
+
## 0.15.18
### Patch Changes
diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json
index ba5dceb699..8fb5bdcdab 100644
--- a/plugins/scaffolder-backend/package.json
+++ b/plugins/scaffolder-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-scaffolder-backend",
"description": "The Backstage backend plugin that helps you create new things",
- "version": "0.15.18",
+ "version": "0.15.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,15 +31,15 @@
"build:assets": "node scripts/build-nunjucks.js"
},
"dependencies": {
- "@backstage/backend-common": "^0.10.0",
+ "@backstage/backend-common": "^0.10.1",
"@backstage/catalog-client": "^0.5.3",
"@backstage/catalog-model": "^0.9.8",
"@backstage/config": "^0.1.11",
"@backstage/errors": "^0.1.5",
- "@backstage/integration": "^0.6.10",
- "@backstage/plugin-catalog-backend": "^0.19.3",
- "@backstage/plugin-scaffolder-common": "^0.1.1",
- "@backstage/plugin-scaffolder-backend-module-cookiecutter": "^0.1.6",
+ "@backstage/integration": "^0.7.0",
+ "@backstage/plugin-catalog-backend": "^0.19.4",
+ "@backstage/plugin-scaffolder-common": "^0.1.2",
+ "@backstage/plugin-scaffolder-backend-module-cookiecutter": "^0.1.7",
"@backstage/types": "^0.1.1",
"@gitbeaker/core": "^34.6.0",
"@gitbeaker/node": "^34.6.0",
@@ -73,8 +73,8 @@
"vm2": "^3.9.5"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/cli": "^0.10.4",
+ "@backstage/test-utils": "^0.2.1",
"@types/command-exists": "^1.2.0",
"@types/fs-extra": "^9.0.1",
"@types/git-url-parse": "^9.0.0",
diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.test.ts
index 48c44f090a..8b1be0c187 100644
--- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.test.ts
+++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.test.ts
@@ -69,4 +69,33 @@ describe('catalog:write', () => {
yaml.stringify(entity),
);
});
+
+ it('should support a custom filename', async () => {
+ const entity = {
+ apiVersion: 'backstage.io/v1alpha1',
+ kind: 'Component',
+ metadata: {
+ name: 'n',
+ namespace: 'ns',
+ annotations: {
+ [ORIGIN_LOCATION_ANNOTATION]: 'url:https://example.com',
+ },
+ },
+ spec: {},
+ };
+
+ await action.handler({
+ ...mockContext,
+ input: {
+ filePath: 'some-dir/entity-info.yaml',
+ entity,
+ },
+ });
+
+ expect(fsMock.writeFile).toHaveBeenCalledTimes(1);
+ expect(fsMock.writeFile).toHaveBeenCalledWith(
+ resolvePath(mockContext.workspacePath, 'some-dir/entity-info.yaml'),
+ yaml.stringify(entity),
+ );
+ });
});
diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts
index b813244020..46220358c7 100644
--- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts
+++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts
@@ -21,13 +21,18 @@ import { Entity } from '@backstage/catalog-model';
import { resolveSafeChildPath } from '@backstage/backend-common';
export function createCatalogWriteAction() {
- return createTemplateAction<{ name?: string; entity: Entity }>({
+ return createTemplateAction<{ filePath?: string; entity: Entity }>({
id: 'catalog:write',
description: 'Writes the catalog-info.yaml for your template',
schema: {
input: {
type: 'object',
properties: {
+ filePath: {
+ title: 'Catalog file path',
+ description: 'Defaults to catalog-info.yaml',
+ type: 'string',
+ },
entity: {
title: 'Entity info to write catalog-info.yaml',
description:
@@ -39,10 +44,11 @@ export function createCatalogWriteAction() {
},
async handler(ctx) {
ctx.logStream.write(`Writing catalog-info.yaml`);
- const { entity } = ctx.input;
+ const { filePath, entity } = ctx.input;
+ const path = filePath ?? 'catalog-info.yaml';
await fs.writeFile(
- resolveSafeChildPath(ctx.workspacePath, 'catalog-info.yaml'),
+ resolveSafeChildPath(ctx.workspacePath, path),
yaml.stringify(entity),
);
},
diff --git a/plugins/scaffolder-common/CHANGELOG.md b/plugins/scaffolder-common/CHANGELOG.md
index db139b2782..f2d9ea26b3 100644
--- a/plugins/scaffolder-common/CHANGELOG.md
+++ b/plugins/scaffolder-common/CHANGELOG.md
@@ -1,5 +1,11 @@
# @backstage/plugin-scaffolder-common
+## 0.1.2
+
+### Patch Changes
+
+- d078377f67: Support navigating back to pre-filled templates to update inputs of scaffolder tasks for resubmission
+
## 0.1.1
### Patch Changes
diff --git a/plugins/scaffolder-common/package.json b/plugins/scaffolder-common/package.json
index 9099eda99d..80644a6739 100644
--- a/plugins/scaffolder-common/package.json
+++ b/plugins/scaffolder-common/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-scaffolder-common",
"description": "Common functionalities for the scaffolder, to be shared between scaffolder and scaffolder-backend plugin",
- "version": "0.1.1",
+ "version": "0.1.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -40,6 +40,6 @@
"@backstage/types": "^0.1.1"
},
"devDependencies": {
- "@backstage/cli": "^0.10.0"
+ "@backstage/cli": "^0.10.4"
}
}
diff --git a/plugins/scaffolder/CHANGELOG.md b/plugins/scaffolder/CHANGELOG.md
index 29a8437066..78870ae5ab 100644
--- a/plugins/scaffolder/CHANGELOG.md
+++ b/plugins/scaffolder/CHANGELOG.md
@@ -1,5 +1,18 @@
# @backstage/plugin-scaffolder
+## 0.11.16
+
+### Patch Changes
+
+- 9c25894892: Implement a `EntityTagsPicker` field extension
+- 7d4b4e937c: Uptake changes to the GitHub Credentials Provider interface.
+- d078377f67: Support navigating back to pre-filled templates to update inputs of scaffolder tasks for resubmission
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.6.9
+ - @backstage/plugin-scaffolder-common@0.1.2
+ - @backstage/integration@0.7.0
+ - @backstage/integration-react@0.1.17
+
## 0.11.15
### Patch Changes
diff --git a/plugins/scaffolder/api-report.md b/plugins/scaffolder/api-report.md
index 4f6928e72d..5252e08299 100644
--- a/plugins/scaffolder/api-report.md
+++ b/plugins/scaffolder/api-report.md
@@ -80,6 +80,16 @@ export const EntityPicker: ({
// @public (undocumented)
export const EntityPickerFieldExtension: () => null;
+// @public
+export const EntityTagsPicker: ({
+ formData,
+ onChange,
+ uiSchema,
+}: FieldProps) => JSX.Element;
+
+// @public
+export const EntityTagsPickerFieldExtension: () => null;
+
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts
// Warning: (ae-missing-release-tag) "FavouriteTemplate" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json
index 2c9112a77a..ec33430b02 100644
--- a/plugins/scaffolder/package.json
+++ b/plugins/scaffolder/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-scaffolder",
"description": "The Backstage plugin that helps you create new things",
- "version": "0.11.15",
+ "version": "0.11.16",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -37,10 +37,10 @@
"@backstage/core-components": "^0.8.2",
"@backstage/core-plugin-api": "^0.4.0",
"@backstage/errors": "^0.1.5",
- "@backstage/integration": "^0.6.10",
- "@backstage/integration-react": "^0.1.16",
- "@backstage/plugin-catalog-react": "^0.6.8",
- "@backstage/plugin-scaffolder-common": "^0.1.1",
+ "@backstage/integration": "^0.7.0",
+ "@backstage/integration-react": "^0.1.17",
+ "@backstage/plugin-catalog-react": "^0.6.9",
+ "@backstage/plugin-scaffolder-common": "^0.1.2",
"@backstage/theme": "^0.2.14",
"@backstage/types": "^0.1.1",
"@material-ui/core": "^4.12.2",
@@ -67,11 +67,11 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/plugin-catalog": "^0.7.5",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/plugin-catalog": "^0.7.6",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/plugins/scaffolder/src/components/fields/EntityTagsPicker/EntityTagsPicker.tsx b/plugins/scaffolder/src/components/fields/EntityTagsPicker/EntityTagsPicker.tsx
new file mode 100644
index 0000000000..b21398a3f4
--- /dev/null
+++ b/plugins/scaffolder/src/components/fields/EntityTagsPicker/EntityTagsPicker.tsx
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React, { useState } from 'react';
+import { useAsync, useEffectOnce } from 'react-use';
+import { CatalogEntitiesRequest } from '@backstage/catalog-client';
+import { Entity, makeValidator } from '@backstage/catalog-model';
+import { useApi } from '@backstage/core-plugin-api';
+import { catalogApiRef } from '@backstage/plugin-catalog-react';
+import { FormControl, TextField } from '@material-ui/core';
+import { Autocomplete } from '@material-ui/lab';
+import { FieldProps } from '@rjsf/core';
+
+/**
+ * EntityTagsPicker
+ * @public
+ */
+export const EntityTagsPicker = ({
+ formData,
+ onChange,
+ uiSchema,
+}: FieldProps) => {
+ const catalogApi = useApi(catalogApiRef);
+ const [inputValue, setInputValue] = useState('');
+ const [inputError, setInputError] = useState(false);
+ const tagValidator = makeValidator().isValidTag;
+ const kinds = uiSchema['ui:options']?.kinds as string[];
+
+ const { loading, value: existingTags } = useAsync(async () => {
+ const tagsRequest: CatalogEntitiesRequest = { fields: ['metadata.tags'] };
+ if (kinds) {
+ tagsRequest.filter = { kind: kinds };
+ }
+
+ const entities = await catalogApi.getEntities(tagsRequest);
+
+ return [
+ ...new Set(
+ entities.items
+ .flatMap((e: Entity) => e.metadata?.tags)
+ .filter(Boolean) as string[],
+ ),
+ ].sort();
+ });
+
+ const setTags = (_: React.ChangeEvent<{}>, values: string[] | null) => {
+ // Reset error state in case all tags were removed
+ let hasError = false;
+ let addDuplicate = false;
+ const currentTags = formData || [];
+
+ // If adding a new tag
+ if (values?.length && currentTags.length < values.length) {
+ const newTag = (values[values.length - 1] = values[values.length - 1]
+ .toLocaleLowerCase('en-US')
+ .trim());
+ hasError = !tagValidator(newTag);
+ addDuplicate = currentTags.indexOf(newTag) !== -1;
+ }
+
+ setInputError(hasError);
+ setInputValue(!hasError ? '' : inputValue);
+ if (!hasError && !addDuplicate) {
+ onChange(values || []);
+ }
+ };
+
+ // Initialize field to always return an array
+ useEffectOnce(() => onChange(formData || []));
+
+ return (
+
+ (
+ setInputValue(e.target.value)}
+ error={inputError}
+ helperText="Add any relevant tags, hit 'Enter' to add new tags. Valid format: [a-z0-9+#] separated by [-], at most 63 characters"
+ />
+ )}
+ />
+
+ );
+};
diff --git a/plugins/scaffolder/src/components/fields/EntityTagsPicker/index.ts b/plugins/scaffolder/src/components/fields/EntityTagsPicker/index.ts
new file mode 100644
index 0000000000..09f4d5c519
--- /dev/null
+++ b/plugins/scaffolder/src/components/fields/EntityTagsPicker/index.ts
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export { EntityTagsPicker } from './EntityTagsPicker';
diff --git a/plugins/scaffolder/src/components/fields/index.ts b/plugins/scaffolder/src/components/fields/index.ts
index 299470e220..ecde218029 100644
--- a/plugins/scaffolder/src/components/fields/index.ts
+++ b/plugins/scaffolder/src/components/fields/index.ts
@@ -19,3 +19,4 @@ export * from './OwnerPicker';
export * from './RepoUrlPicker';
export * from './TextValuePicker';
export * from './OwnedEntityPicker';
+export * from './EntityTagsPicker';
diff --git a/plugins/scaffolder/src/extensions/default.ts b/plugins/scaffolder/src/extensions/default.ts
index 12a29809e0..820cc0e6d3 100644
--- a/plugins/scaffolder/src/extensions/default.ts
+++ b/plugins/scaffolder/src/extensions/default.ts
@@ -18,6 +18,7 @@ import {
EntityNamePicker,
entityNamePickerValidation,
} from '../components/fields/EntityNamePicker';
+import { EntityTagsPicker } from '../components/fields/EntityTagsPicker';
import { OwnerPicker } from '../components/fields/OwnerPicker';
import {
repoPickerValidation,
@@ -36,6 +37,10 @@ export const DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS: FieldExtensionOptions[] = [
name: 'EntityNamePicker',
validation: entityNamePickerValidation,
},
+ {
+ component: EntityTagsPicker,
+ name: 'EntityTagsPicker',
+ },
{
component: RepoUrlPicker,
name: 'RepoUrlPicker',
diff --git a/plugins/scaffolder/src/index.ts b/plugins/scaffolder/src/index.ts
index dfbd2af296..3851b2151b 100644
--- a/plugins/scaffolder/src/index.ts
+++ b/plugins/scaffolder/src/index.ts
@@ -30,6 +30,7 @@ export type { CustomFieldValidator, FieldExtensionOptions } from './extensions';
export {
EntityPickerFieldExtension,
EntityNamePickerFieldExtension,
+ EntityTagsPickerFieldExtension,
OwnerPickerFieldExtension,
OwnedEntityPickerFieldExtension,
RepoUrlPickerFieldExtension,
@@ -40,6 +41,7 @@ export {
export {
EntityNamePicker,
EntityPicker,
+ EntityTagsPicker,
OwnerPicker,
RepoUrlPicker,
TextValuePicker,
diff --git a/plugins/scaffolder/src/plugin.ts b/plugins/scaffolder/src/plugin.ts
index 95cad50eba..02b36c4bb6 100644
--- a/plugins/scaffolder/src/plugin.ts
+++ b/plugins/scaffolder/src/plugin.ts
@@ -36,6 +36,7 @@ import {
identityApiRef,
} from '@backstage/core-plugin-api';
import { OwnedEntityPicker } from './components/fields/OwnedEntityPicker';
+import { EntityTagsPicker } from './components/fields/EntityTagsPicker';
export const scaffolderPlugin = createPlugin({
id: 'scaffolder',
@@ -103,3 +104,14 @@ export const OwnedEntityPickerFieldExtension = scaffolderPlugin.provide(
name: 'OwnedEntityPicker',
}),
);
+
+/**
+ * EntityTagsPickerFieldExtension
+ * @public
+ */
+export const EntityTagsPickerFieldExtension = scaffolderPlugin.provide(
+ createScaffolderFieldExtension({
+ component: EntityTagsPicker,
+ name: 'EntityTagsPicker',
+ }),
+);
diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md
index 4ff92cfb76..376a02b5fb 100644
--- a/plugins/search/CHANGELOG.md
+++ b/plugins/search/CHANGELOG.md
@@ -1,5 +1,18 @@
# @backstage/plugin-search
+## 0.5.3
+
+### Patch Changes
+
+- 6d8e3a9651: Internal cleanup of the exports structure
+- 8b532a6c02: Introduces a `` variant, which operates on the same part of a search query as the existing ``, but in a more opinionated way (as a single-select control surface suitable for faceted search UIs).
+
+ Check the [search plugin storybook](https://backstage.io/storybook/?path=/story/plugins-search-searchtype--accordion) to see how it can be used.
+
+- af4980fb5d: Captures the search term entered in the SearchBarBase as a `search` event.
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.6.9
+
## 0.5.2
### Patch Changes
diff --git a/plugins/search/package.json b/plugins/search/package.json
index a308fc0a22..c9e7d0aba1 100644
--- a/plugins/search/package.json
+++ b/plugins/search/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-search",
"description": "The Backstage plugin that provides your backstage app with search",
- "version": "0.5.2",
+ "version": "0.5.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -35,7 +35,7 @@
"@backstage/core-components": "^0.8.2",
"@backstage/core-plugin-api": "^0.4.0",
"@backstage/errors": "^0.1.4",
- "@backstage/plugin-catalog-react": "^0.6.8",
+ "@backstage/plugin-catalog-react": "^0.6.9",
"@backstage/search-common": "^0.2.1",
"@backstage/theme": "^0.2.14",
"@backstage/types": "^0.1.1",
@@ -52,10 +52,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/plugins/search/src/components/SearchBar/SearchBar.tsx b/plugins/search/src/components/SearchBar/SearchBar.tsx
index aa4b1e728a..188341cd6c 100644
--- a/plugins/search/src/components/SearchBar/SearchBar.tsx
+++ b/plugins/search/src/components/SearchBar/SearchBar.tsx
@@ -20,6 +20,7 @@ import React, {
useState,
useEffect,
useCallback,
+ useContext,
} from 'react';
import { useDebounce } from 'react-use';
import { configApiRef, useApi } from '@backstage/core-plugin-api';
@@ -32,7 +33,11 @@ import {
import SearchIcon from '@material-ui/icons/Search';
import ClearButton from '@material-ui/icons/Clear';
-import { useSearch } from '../SearchContext';
+import {
+ SearchContext,
+ SearchContextProvider,
+ useSearch,
+} from '../SearchContext';
import { TrackSearch } from '../SearchTracker';
/**
@@ -48,6 +53,11 @@ export type SearchBarBaseProps = Omit & {
onChange: (value: string) => void;
};
+const useSearchContextCheck = () => {
+ const context = useContext(SearchContext);
+ return context !== undefined;
+};
+
/**
* All search boxes exported by the search plugin are based on the ,
* and this one is based on the component from Material UI.
@@ -69,6 +79,7 @@ export const SearchBarBase = ({
}: SearchBarBaseProps) => {
const configApi = useApi(configApiRef);
const [value, setValue] = useState(defaultValue as string);
+ const hasSearchContext = useSearchContextCheck();
useEffect(() => {
setValue(prevValue =>
@@ -119,7 +130,7 @@ export const SearchBarBase = ({
);
- return (
+ const searchBar = (
);
+
+ return hasSearchContext ? (
+ searchBar
+ ) : (
+ {searchBar}
+ );
};
/**
diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json
index c1eadc5646..3b810b7bfc 100644
--- a/plugins/sentry/package.json
+++ b/plugins/sentry/package.json
@@ -49,10 +49,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/shortcuts/package.json b/plugins/shortcuts/package.json
index 17c9328a92..1770fea044 100644
--- a/plugins/shortcuts/package.json
+++ b/plugins/shortcuts/package.json
@@ -39,10 +39,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json
index 71ec7e7f29..9eba8bcfb1 100644
--- a/plugins/sonarqube/package.json
+++ b/plugins/sonarqube/package.json
@@ -50,10 +50,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/splunk-on-call/package.json b/plugins/splunk-on-call/package.json
index e6ffc43402..7277db6355 100644
--- a/plugins/splunk-on-call/package.json
+++ b/plugins/splunk-on-call/package.json
@@ -48,10 +48,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md b/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md
index a6bd7824c9..544bfc3c2b 100644
--- a/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md
+++ b/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md
@@ -1,5 +1,13 @@
# @backstage/plugin-tech-insights-backend-module-jsonfc
+## 0.1.4
+
+### Patch Changes
+
+- 8d00dc427c: ability to add custom operators
+- Updated dependencies
+ - @backstage/backend-common@0.10.1
+
## 0.1.3
### Patch Changes
diff --git a/plugins/tech-insights-backend-module-jsonfc/package.json b/plugins/tech-insights-backend-module-jsonfc/package.json
index d7ee1bfb58..30f00f4210 100644
--- a/plugins/tech-insights-backend-module-jsonfc/package.json
+++ b/plugins/tech-insights-backend-module-jsonfc/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-tech-insights-backend-module-jsonfc",
- "version": "0.1.3",
+ "version": "0.1.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,7 +31,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.10.0",
+ "@backstage/backend-common": "^0.10.1",
"@backstage/config": "^0.1.8",
"@backstage/errors": "^0.1.5",
"@backstage/plugin-tech-insights-common": "^0.2.0",
@@ -43,7 +43,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@types/node-cron": "^2.0.4"
},
"files": [
diff --git a/plugins/tech-insights/CHANGELOG.md b/plugins/tech-insights/CHANGELOG.md
index d353cecba0..e761faab97 100644
--- a/plugins/tech-insights/CHANGELOG.md
+++ b/plugins/tech-insights/CHANGELOG.md
@@ -1,5 +1,14 @@
# @backstage/plugin-tech-insights
+## 0.1.3
+
+### Patch Changes
+
+- a86f5c1701: Fixed API auth in tech-insights plugin
+- d83079fc11: Export `techInsightsApiRef` and associated types.
+- Updated dependencies
+ - @backstage/plugin-catalog-react@0.6.9
+
## 0.1.2
### Patch Changes
diff --git a/plugins/tech-insights/package.json b/plugins/tech-insights/package.json
index f8382984de..d661f5846c 100644
--- a/plugins/tech-insights/package.json
+++ b/plugins/tech-insights/package.json
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-tech-insights",
- "version": "0.1.2",
+ "version": "0.1.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -24,7 +24,7 @@
"@backstage/core-components": "^0.8.2",
"@backstage/core-plugin-api": "^0.4.0",
"@backstage/errors": "^0.1.4",
- "@backstage/plugin-catalog-react": "^0.6.8",
+ "@backstage/plugin-catalog-react": "^0.6.9",
"@backstage/plugin-tech-insights-common": "^0.2.0",
"@backstage/theme": "^0.2.14",
"@backstage/types": "^0.1.1",
@@ -39,10 +39,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/tech-insights/src/api/TechInsightsClient.ts b/plugins/tech-insights/src/api/TechInsightsClient.ts
index 43979e60b0..2298f463f5 100644
--- a/plugins/tech-insights/src/api/TechInsightsClient.ts
+++ b/plugins/tech-insights/src/api/TechInsightsClient.ts
@@ -66,20 +66,20 @@ export class TechInsightsClient implements TechInsightsApi {
async runChecks(
entityParams: EntityName,
- checks: Check[],
+ checks?: Check[],
): Promise {
const url = await this.discoveryApi.getBaseUrl('tech-insights');
const token = await this.identityApi.getIdToken();
const { namespace, kind, name } = entityParams;
- const allChecks = checks ? checks : await this.getAllChecks();
- const checkIds = allChecks.map((check: Check) => check.id);
+ const checkIds = checks ? checks.map(check => check.id) : [];
+ const requestBody = { checks: checkIds.length > 0 ? checkIds : undefined };
const response = await fetch(
`${url}/checks/run/${encodeURIComponent(namespace)}/${encodeURIComponent(
kind,
)}/${encodeURIComponent(name)}`,
{
method: 'POST',
- body: JSON.stringify({ checks: checkIds }),
+ body: JSON.stringify(requestBody),
headers: {
'Content-Type': 'application/json',
...(token && { Authorization: `Bearer ${token}` }),
diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json
index b9154db76e..50968a6a2f 100644
--- a/plugins/tech-radar/package.json
+++ b/plugins/tech-radar/package.json
@@ -46,10 +46,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/techdocs-backend/CHANGELOG.md b/plugins/techdocs-backend/CHANGELOG.md
index dee69523ef..256a402a24 100644
--- a/plugins/techdocs-backend/CHANGELOG.md
+++ b/plugins/techdocs-backend/CHANGELOG.md
@@ -1,5 +1,15 @@
# @backstage/plugin-techdocs-backend
+## 0.12.2
+
+### Patch Changes
+
+- da676a49ab: Add support for API auth in DefaultTechDocsCollator
+- Updated dependencies
+ - @backstage/techdocs-common@0.11.2
+ - @backstage/backend-common@0.10.1
+ - @backstage/integration@0.7.0
+
## 0.12.1
### Patch Changes
diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json
index 89dcda5968..0d5a86ffc7 100644
--- a/plugins/techdocs-backend/package.json
+++ b/plugins/techdocs-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-techdocs-backend",
"description": "The Backstage backend plugin that renders technical documentation for your components",
- "version": "0.12.1",
+ "version": "0.12.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,14 +31,14 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.10.0",
+ "@backstage/backend-common": "^0.10.1",
"@backstage/catalog-client": "^0.5.3",
"@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.11",
"@backstage/errors": "^0.1.5",
- "@backstage/integration": "^0.6.10",
+ "@backstage/integration": "^0.7.0",
"@backstage/search-common": "^0.2.1",
- "@backstage/techdocs-common": "^0.11.1",
+ "@backstage/techdocs-common": "^0.11.2",
"@types/express": "^4.17.6",
"cross-fetch": "^3.0.6",
"dockerode": "^3.3.1",
@@ -52,8 +52,8 @@
"winston": "^3.2.1"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/cli": "^0.10.4",
+ "@backstage/test-utils": "^0.2.1",
"@types/dockerode": "^3.3.0",
"msw": "^0.35.0",
"supertest": "^6.1.3"
diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md
index 2883181f13..2cfa8064e9 100644
--- a/plugins/techdocs/CHANGELOG.md
+++ b/plugins/techdocs/CHANGELOG.md
@@ -1,5 +1,18 @@
# @backstage/plugin-techdocs
+## 0.12.12
+
+### Patch Changes
+
+- aa8f764a3e: Add the techdocs.sanitizer.allowedIframeHosts config.
+ This config allows all iframes which have the host of the attribute src in the 'allowedIframehosts' list to be displayed in the documentation.
+- Updated dependencies
+ - @backstage/plugin-search@0.5.3
+ - @backstage/plugin-catalog@0.7.6
+ - @backstage/plugin-catalog-react@0.6.9
+ - @backstage/integration@0.7.0
+ - @backstage/integration-react@0.1.17
+
## 0.12.11
### Patch Changes
diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json
index b702b45073..f45be5b4b7 100644
--- a/plugins/techdocs/package.json
+++ b/plugins/techdocs/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-techdocs",
"description": "The Backstage plugin that renders technical documentation for your components",
- "version": "0.12.11",
+ "version": "0.12.12",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -37,11 +37,11 @@
"@backstage/core-components": "^0.8.2",
"@backstage/core-plugin-api": "^0.4.0",
"@backstage/errors": "^0.1.5",
- "@backstage/integration": "^0.6.10",
- "@backstage/integration-react": "^0.1.16",
- "@backstage/plugin-catalog": "^0.7.5",
- "@backstage/plugin-catalog-react": "^0.6.8",
- "@backstage/plugin-search": "^0.5.2",
+ "@backstage/integration": "^0.7.0",
+ "@backstage/integration-react": "^0.1.17",
+ "@backstage/plugin-catalog": "^0.7.6",
+ "@backstage/plugin-catalog-react": "^0.6.9",
+ "@backstage/plugin-search": "^0.5.3",
"@backstage/theme": "^0.2.14",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -62,10 +62,10 @@
"react-dom": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/plugins/todo-backend/CHANGELOG.md b/plugins/todo-backend/CHANGELOG.md
index 2c854a2beb..41ffd3e79d 100644
--- a/plugins/todo-backend/CHANGELOG.md
+++ b/plugins/todo-backend/CHANGELOG.md
@@ -1,5 +1,13 @@
# @backstage/plugin-todo-backend
+## 0.1.17
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/backend-common@0.10.1
+ - @backstage/integration@0.7.0
+
## 0.1.16
### Patch Changes
diff --git a/plugins/todo-backend/package.json b/plugins/todo-backend/package.json
index f8578cd544..7368f69fd8 100644
--- a/plugins/todo-backend/package.json
+++ b/plugins/todo-backend/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-todo-backend",
"description": "A Backstage backend plugin that lets you browse TODO comments in your source code",
- "version": "0.1.16",
+ "version": "0.1.17",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -25,12 +25,12 @@
"clean": "backstage-cli clean"
},
"dependencies": {
- "@backstage/backend-common": "^0.10.0",
+ "@backstage/backend-common": "^0.10.1",
"@backstage/catalog-client": "^0.5.3",
"@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.10",
"@backstage/errors": "^0.1.3",
- "@backstage/integration": "^0.6.10",
+ "@backstage/integration": "^0.7.0",
"@types/express": "^4.17.6",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
@@ -39,7 +39,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@types/supertest": "^2.0.8",
"msw": "^0.35.0",
"supertest": "^6.1.3"
diff --git a/plugins/todo/package.json b/plugins/todo/package.json
index 6f86c47db9..a2a94d11b1 100644
--- a/plugins/todo/package.json
+++ b/plugins/todo/package.json
@@ -42,10 +42,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json
index cd7225ac72..f43fc36e17 100644
--- a/plugins/user-settings/package.json
+++ b/plugins/user-settings/package.json
@@ -44,10 +44,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/plugins/xcmetrics/package.json b/plugins/xcmetrics/package.json
index 64a19fc0f2..88001a68db 100644
--- a/plugins/xcmetrics/package.json
+++ b/plugins/xcmetrics/package.json
@@ -37,10 +37,10 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.10.3",
+ "@backstage/cli": "^0.10.4",
"@backstage/core-app-api": "^0.3.0",
"@backstage/dev-utils": "^0.2.15",
- "@backstage/test-utils": "^0.2.0",
+ "@backstage/test-utils": "^0.2.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/scripts/verify-changesets.js b/scripts/verify-changesets.js
new file mode 100755
index 0000000000..8d828ee058
--- /dev/null
+++ b/scripts/verify-changesets.js
@@ -0,0 +1,88 @@
+#!/usr/bin/env node
+/*
+ * Copyright 2020 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* eslint-disable import/no-extraneous-dependencies */
+
+const { resolve: resolvePath } = require('path');
+const fs = require('fs-extra');
+const { default: parseChangeset } = require('@changesets/parse');
+
+const privatePackages = new Set([
+ 'example-app',
+ 'example-backend',
+ 'e2e-test',
+ 'storybook',
+ 'embedded-techdocs-app',
+]);
+
+async function main() {
+ process.chdir(resolvePath(__dirname, '../.changeset'));
+
+ const fileNames = await fs.readdir('.');
+ const changesetNames = fileNames.filter(
+ name => name.endsWith('.md') && name !== 'README.md',
+ );
+
+ const changesets = await Promise.all(
+ changesetNames.map(async name => {
+ const content = await fs.readFile(name, 'utf8');
+ return { name, ...parseChangeset(content) };
+ }),
+ );
+
+ const errors = [];
+ for (const changeset of changesets) {
+ const privateReleases = changeset.releases.filter(release =>
+ privatePackages.has(release.name),
+ );
+ if (privateReleases.length > 0) {
+ const names = privateReleases
+ .map(release => `'${release.name}'`)
+ .join(', ');
+ errors.push({
+ name: changeset.name,
+ messages: [
+ `Should not contain releases of the following packages since they are not published: ${names}`,
+ ],
+ });
+ }
+ }
+
+ if (errors.length) {
+ console.log();
+ console.log('***********************************************************');
+ console.log('* Changeset verification failed! *');
+ console.log('***********************************************************');
+ console.log();
+ for (const error of errors) {
+ console.error(`Changeset '${error.name}' is invalid:`);
+ console.log();
+ for (const message of error.messages) {
+ console.error(` ${message}`);
+ }
+ }
+ console.log();
+ console.log('***********************************************************');
+ console.log();
+ process.exit(1);
+ }
+}
+
+main().catch(error => {
+ console.error(error.stack);
+ process.exit(1);
+});
diff --git a/yarn.lock b/yarn.lock
index 4ddb332fb3..1730c6f376 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2498,6 +2498,19 @@
react-use "^17.2.4"
zen-observable "^0.8.15"
+"@backstage/integration@^0.6.4", "@backstage/integration@^0.6.7":
+ version "0.6.10"
+ resolved "https://registry.npmjs.org/@backstage/integration/-/integration-0.6.10.tgz#e55a26f5124445de74e46944f63c263c9b985995"
+ integrity sha512-qGAZ7rflWdZdjUgxzLWmkrR1zPC5ep62d0fqtwg77MZsGwBNrbNOI2qJbk+IRPmOgym2Adg2C95O2UV7Hyde7g==
+ dependencies:
+ "@backstage/config" "^0.1.11"
+ "@octokit/auth-app" "^3.4.0"
+ "@octokit/rest" "^18.5.3"
+ cross-fetch "^3.0.6"
+ git-url-parse "^11.6.0"
+ lodash "^4.17.21"
+ luxon "^2.0.2"
+
"@backstage/plugin-catalog-react@^0.4.0":
version "0.4.6"
resolved "https://registry.npmjs.org/@backstage/plugin-catalog-react/-/plugin-catalog-react-0.4.6.tgz#f33f3cd734f110d3c547f7eae4e25d14806ec796"
@@ -7821,9 +7834,9 @@
integrity sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==
"@types/jscodeshift@^0.11.0":
- version "0.11.0"
- resolved "https://registry.npmjs.org/@types/jscodeshift/-/jscodeshift-0.11.0.tgz#7224cf1a4d0383b4fb2694ffed52f57b45c3325b"
- integrity sha512-OcJgr5GznWCEx2Oeg4eMUZYwssTHFj/tU8grrNCKdFQtAEAa0ezDiPHbCdSkyWrRSurXrYbNbHdhxbbB76pXNg==
+ version "0.11.3"
+ resolved "https://registry.npmjs.org/@types/jscodeshift/-/jscodeshift-0.11.3.tgz#8dcab24ced39dcab1c8ff3461b3d171aafee3d48"
+ integrity sha512-pM0JD9kWVDH9DQp5Y6td16924V3MwZHei8P3cTeuFhXpzpk0K+iWraBZz8wF61QkFs9fZeAQNX0q8SG0+TFm2w==
dependencies:
ast-types "^0.14.1"
recast "^0.20.3"
@@ -8764,28 +8777,29 @@
resolved "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.2.tgz#808c9fa7e4517274ed555fa158f2de4b4f468e71"
integrity sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg==
-"@typescript-eslint/eslint-plugin@^v4.30.0":
- version "4.30.0"
- resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.30.0.tgz#4a0c1ae96b953f4e67435e20248d812bfa55e4fb"
- integrity sha512-NgAnqk55RQ/SD+tZFD9aPwNSeHmDHHe5rtUyhIq0ZeCWZEvo4DK9rYz7v9HDuQZFvn320Ot+AikaCKMFKLlD0g==
+"@typescript-eslint/eslint-plugin@^v4.33.0":
+ version "4.33.0"
+ resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz#c24dc7c8069c7706bc40d99f6fa87edcb2005276"
+ integrity sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==
dependencies:
- "@typescript-eslint/experimental-utils" "4.30.0"
- "@typescript-eslint/scope-manager" "4.30.0"
+ "@typescript-eslint/experimental-utils" "4.33.0"
+ "@typescript-eslint/scope-manager" "4.33.0"
debug "^4.3.1"
functional-red-black-tree "^1.0.1"
+ ignore "^5.1.8"
regexpp "^3.1.0"
semver "^7.3.5"
tsutils "^3.21.0"
-"@typescript-eslint/experimental-utils@4.30.0", "@typescript-eslint/experimental-utils@^4.0.1":
- version "4.30.0"
- resolved "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.30.0.tgz#9e49704fef568432ae16fc0d6685c13d67db0fd5"
- integrity sha512-K8RNIX9GnBsv5v4TjtwkKtqMSzYpjqAQg/oSphtxf3xxdt6T0owqnpojztjjTcatSteH3hLj3t/kklKx87NPqw==
+"@typescript-eslint/experimental-utils@4.33.0", "@typescript-eslint/experimental-utils@^4.0.1":
+ version "4.33.0"
+ resolved "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz#6f2a786a4209fa2222989e9380b5331b2810f7fd"
+ integrity sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==
dependencies:
"@types/json-schema" "^7.0.7"
- "@typescript-eslint/scope-manager" "4.30.0"
- "@typescript-eslint/types" "4.30.0"
- "@typescript-eslint/typescript-estree" "4.30.0"
+ "@typescript-eslint/scope-manager" "4.33.0"
+ "@typescript-eslint/types" "4.33.0"
+ "@typescript-eslint/typescript-estree" "4.33.0"
eslint-scope "^5.1.1"
eslint-utils "^3.0.0"
@@ -8807,23 +8821,23 @@
"@typescript-eslint/types" "4.28.3"
"@typescript-eslint/visitor-keys" "4.28.3"
-"@typescript-eslint/scope-manager@4.30.0":
- version "4.30.0"
- resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.30.0.tgz#1a3ffbb385b1a06be85cd5165a22324f069a85ee"
- integrity sha512-VJ/jAXovxNh7rIXCQbYhkyV2Y3Ac/0cVHP/FruTJSAUUm4Oacmn/nkN5zfWmWFEanN4ggP0vJSHOeajtHq3f8A==
+"@typescript-eslint/scope-manager@4.33.0":
+ version "4.33.0"
+ resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz#d38e49280d983e8772e29121cf8c6e9221f280a3"
+ integrity sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==
dependencies:
- "@typescript-eslint/types" "4.30.0"
- "@typescript-eslint/visitor-keys" "4.30.0"
+ "@typescript-eslint/types" "4.33.0"
+ "@typescript-eslint/visitor-keys" "4.33.0"
"@typescript-eslint/types@4.28.3":
version "4.28.3"
resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.3.tgz#8fffd436a3bada422c2c1da56060a0566a9506c7"
integrity sha512-kQFaEsQBQVtA9VGVyciyTbIg7S3WoKHNuOp/UF5RG40900KtGqfoiETWD/v0lzRXc+euVE9NXmfer9dLkUJrkA==
-"@typescript-eslint/types@4.30.0":
- version "4.30.0"
- resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.30.0.tgz#fb9d9b0358426f18687fba82eb0b0f869780204f"
- integrity sha512-YKldqbNU9K4WpTNwBqtAerQKLLW/X2A/j4yw92e3ZJYLx+BpKLeheyzoPfzIXHfM8BXfoleTdiYwpsvVPvHrDw==
+"@typescript-eslint/types@4.33.0":
+ version "4.33.0"
+ resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz#a1e59036a3b53ae8430ceebf2a919dc7f9af6d72"
+ integrity sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==
"@typescript-eslint/typescript-estree@4.28.3":
version "4.28.3"
@@ -8838,13 +8852,13 @@
semver "^7.3.5"
tsutils "^3.21.0"
-"@typescript-eslint/typescript-estree@4.30.0":
- version "4.30.0"
- resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.30.0.tgz#ae57833da72a753f4846cd3053758c771670c2ac"
- integrity sha512-6WN7UFYvykr/U0Qgy4kz48iGPWILvYL34xXJxvDQeiRE018B7POspNRVtAZscWntEPZpFCx4hcz/XBT+erenfg==
+"@typescript-eslint/typescript-estree@4.33.0":
+ version "4.33.0"
+ resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz#0dfb51c2908f68c5c08d82aefeaf166a17c24609"
+ integrity sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==
dependencies:
- "@typescript-eslint/types" "4.30.0"
- "@typescript-eslint/visitor-keys" "4.30.0"
+ "@typescript-eslint/types" "4.33.0"
+ "@typescript-eslint/visitor-keys" "4.33.0"
debug "^4.3.1"
globby "^11.0.3"
is-glob "^4.0.1"
@@ -8859,12 +8873,12 @@
"@typescript-eslint/types" "4.28.3"
eslint-visitor-keys "^2.0.0"
-"@typescript-eslint/visitor-keys@4.30.0":
- version "4.30.0"
- resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.30.0.tgz#a47c6272fc71b0c627d1691f68eaecf4ad71445e"
- integrity sha512-pNaaxDt/Ol/+JZwzP7MqWc8PJQTUhZwoee/PVlQ+iYoYhagccvoHnC9e4l+C/krQYYkENxznhVSDwClIbZVxRw==
+"@typescript-eslint/visitor-keys@4.33.0":
+ version "4.33.0"
+ resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz#2a22f77a41604289b7a186586e9ec48ca92ef1dd"
+ integrity sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==
dependencies:
- "@typescript-eslint/types" "4.30.0"
+ "@typescript-eslint/types" "4.33.0"
eslint-visitor-keys "^2.0.0"
"@webassemblyjs/ast@1.11.1":
@@ -14841,9 +14855,9 @@ express-prom-bundle@^6.3.6:
url-value-parser "^2.0.0"
express-promise-router@^4.1.0:
- version "4.1.0"
- resolved "https://registry.npmjs.org/express-promise-router/-/express-promise-router-4.1.0.tgz#79160e145c27610ba411bceb0552a36f11dbab4f"
- integrity sha512-nvg0X1Rj8oajPPC+fG3t4e740aNmQZRZY6dRLbiiM56Dvd8213RJ4kaxhZVTdQLut+l4DZdfeJkyx2VENPMBdw==
+ version "4.1.1"
+ resolved "https://registry.npmjs.org/express-promise-router/-/express-promise-router-4.1.1.tgz#8fac102060b9bcc868f84d34fbb12fd8fa494291"
+ integrity sha512-Lkvcy/ZGrBhzkl3y7uYBHLMtLI4D6XQ2kiFg9dq7fbktBch5gjqJ0+KovX0cvCAvTJw92raWunRLM/OM+5l4fA==
dependencies:
is-promise "^4.0.0"
lodash.flattendeep "^4.0.0"
@@ -17194,10 +17208,10 @@ ignore@^4.0.3, ignore@^4.0.6:
resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
-ignore@^5.1.4:
- version "5.1.4"
- resolved "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf"
- integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==
+ignore@^5.1.4, ignore@^5.1.8:
+ version "5.2.0"
+ resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a"
+ integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==
immer@8.0.1:
version "8.0.1"