Merge branch 'master' of https://github.com/spotify/backstage into k8s-load-with-only-queryselector

This commit is contained in:
Fidel Coria
2021-02-23 10:17:16 -06:00
191 changed files with 3127 additions and 1442 deletions
-53
View File
@@ -1,53 +0,0 @@
---
'@backstage/plugin-scaffolder': patch
'@backstage/plugin-scaffolder-backend': minor
---
# Stateless scaffolding
The scaffolder has been redesigned to be horizontally scalable and to persistently store task state and execution logs in the database.
Each scaffolder task is given a unique task ID which is persisted in the database.
Tasks are then picked up by a `TaskWorker` which performs the scaffolding steps.
Execution logs are also persisted in the database meaning you can now refresh the scaffolder task status page without losing information.
The task status page is now dynamically created based on the step information stored in the database.
This allows for custom steps to be displayed once the next version of the scaffolder template schema is available.
The task page is updated to display links to both the git repository and to the newly created catalog entity.
Component registration has moved from the frontend into a separate registration step executed by the `TaskWorker`. This requires that a `CatalogClient` is passed to the scaffolder backend instead of the old `CatalogEntityClient`.
Make sure to update `plugins/scaffolder.ts`
```diff
import {
CookieCutter,
createRouter,
Preparers,
Publishers,
CreateReactAppTemplater,
Templaters,
- CatalogEntityClient,
} from '@backstage/plugin-scaffolder-backend';
+import { CatalogClient } from '@backstage/catalog-client';
const discovery = SingleHostDiscovery.fromConfig(config);
-const entityClient = new CatalogEntityClient({ discovery });
+const catalogClient = new CatalogClient({ discoveryApi: discovery })
return await createRouter({
preparers,
templaters,
publishers,
logger,
config,
dockerClient,
- entityClient,
database,
+ catalogClient,
});
```
As well as adding the `@backstage/catalog-client` packages as a dependency of your backend package.
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/plugin-scaffolder': patch
---
Update messages that process during loading, error, and no templates found.
Remove unused dependencies.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/test-utils': patch
---
Allow `ExternalRouteRef` instances to be passed as a route ref to `mountedRoutes`.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-org': patch
---
Use the `pageTheme` to colour the OwnershipCard boxes with their respective theme colours.
-39
View File
@@ -1,39 +0,0 @@
---
'@backstage/plugin-catalog': minor
'@backstage/plugin-scaffolder': minor
---
The Scaffolder and Catalog plugins have been migrated to partially require use of the [new composability API](https://backstage.io/docs/plugins/composability). The Scaffolder used to register its pages using the deprecated route registration plugin API, but those registrations have been removed. This means you now need to add the Scaffolder plugin page to the app directly.
The page is imported from the Scaffolder plugin and added to the `<FlatRoutes>` component:
```tsx
<Route path="/create" element={<ScaffolderPage />} />
```
The Catalog plugin has also been migrated to use an [external route reference](https://backstage.io/docs/plugins/composability#binding-external-routes-in-the-app) to dynamically link to the create component page. This means you need to migrate the catalog plugin to use the new extension components, as well as bind the external route.
To use the new extension components, replace existing usage of the `CatalogRouter` with the following:
```tsx
<Route path="/catalog" element={<CatalogIndexPage />} />
<Route path="/catalog/:namespace/:kind/:name" element={<CatalogEntityPage />}>
<EntityPage />
</Route>
```
And to bind the external route from the catalog plugin to the scaffolder template index page, make sure you have the appropriate imports and add the following to the `createApp` call:
```ts
import { catalogPlugin } from '@backstage/plugin-catalog';
import { scaffolderPlugin } from '@backstage/plugin-scaffolder';
const app = createApp({
// ...
bindRoutes({ bind }) {
bind(catalogPlugin.externalRoutes, {
createComponent: scaffolderPlugin.routes.root,
});
},
});
```
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/plugin-techdocs': patch
'@backstage/plugin-techdocs-backend': patch
---
Got rid of some `attr` and cleaned up a bit in the TechDocs config schema.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-explore': patch
---
Display the owner of a domain on the domain card.
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/core-api': patch
'@backstage/core': patch
---
More informative error message for missing ApiContext.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-scaffolder': minor
---
Adding Search and Filter features to Scaffolder/Templates Grid
-7
View File
@@ -1,7 +0,0 @@
---
'@backstage/core': patch
'@backstage/plugin-catalog-react': patch
---
Forward link styling of `EntityRefLink` and `EnriryRefLinks` into the underling
`Link`.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-tech-radar': patch
---
Added a dialog box that will show up when a you click on link on the radar and display the description if provided.
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/core': patch
---
Deprecate `type` of `ItemCard` and introduce new `subtitle` which allows passing
react nodes.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-app-backend': patch
---
Clarify troubleshooting steps for schema serialization issues.
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/plugin-api-docs': patch
'@backstage/plugin-catalog': patch
---
Changes made in CatalogTable and ApiExplorerTable for using the OverflowTooltip component for truncating large description and showing tooltip on hover-over.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/techdocs-common': patch
---
Fix AWS, GCS and Azure publisher to work on Windows.
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/plugin-jenkins': patch
---
- Add Jenkins logo to project page.
- Move to new Backstage breadcrumb component.
- Change references of deprecated "Job" terminology to "Project" per [Jenkins Glossary](https://www.jenkins.io/doc/book/glossary/).
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/core': patch
---
Introduced generic OverflowTooltip component for cases where longer text needs to be truncated with ellipsis and show hover tooltip with full text. This is particularly useful in the cases where longer description text is rendered in table. e.g. CatalogTable and ApiExplorerTable.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-react': patch
---
Fixed EntityProvider setting 'loading' bool erroneously to true
-86
View File
@@ -1,86 +0,0 @@
---
'@backstage/create-app': patch
---
**BREAKING CHANGE**
The Scaffolder and Catalog plugins have been migrated to partially require use of the [new composability API](https://backstage.io/docs/plugins/composability). The Scaffolder used to register its pages using the deprecated route registration plugin API, but those registrations have been removed. This means you now need to add the Scaffolder plugin page to the app directly.
The Catalog plugin has also been migrated to use an [external route reference](https://backstage.io/docs/plugins/composability#binding-external-routes-in-the-app) to dynamically link to the create component page. This means you need to migrate the catalog plugin to use the new extension components, as well as bind the external route.
Apply the following changes to `packages/app/src/App.tsx`:
```diff
-import { Router as CatalogRouter } from '@backstage/plugin-catalog';
+import {
+ catalogPlugin,
+ CatalogIndexPage,
+ CatalogEntityPage,
+} from '@backstage/plugin-catalog';
+import { scaffolderPlugin, ScaffolderPage } from '@backstage/plugin-scaffolder';
# The following addition to the app config allows the catalog plugin to link to the
# component creation page, i.e. the scaffolder. You can chose a different target if you want to.
const app = createApp({
apis,
plugins: Object.values(plugins),
+ bindRoutes({ bind }) {
+ bind(catalogPlugin.externalRoutes, {
+ createComponent: scaffolderPlugin.routes.root,
+ });
+ }
});
# Apply these changes within FlatRoutes. It is important to have migrated to using FlatRoutes
# for this to work, if you haven't done that yet, see the previous entries in this changelog.
- <Route
- path="/catalog"
- element={<CatalogRouter EntityPage={EntityPage} />}
- />
+ <Route path="/catalog" element={<CatalogIndexPage />} />
+ <Route
+ path="/catalog/:namespace/:kind/:name"
+ element={<CatalogEntityPage />}
+ >
+ <EntityPage />
+ </Route>
<Route path="/docs" element={<DocsRouter />} />
+ <Route path="/create" element={<ScaffolderPage />} />
```
The scaffolder has been redesigned to be horizontally scalable and to persistently store task state and execution logs in the database. Component registration has moved from the frontend into a separate registration step executed by the `TaskWorker`. This requires that a `CatalogClient` is passed to the scaffolder backend instead of the old `CatalogEntityClient`.
The default catalog client comes from the `@backstage/catalog-client`, which you need to add as a dependency in `packages/backend/package.json`.
Once the dependency has been added, apply the following changes to`packages/backend/src/plugins/scaffolder.ts`:
```diff
import {
CookieCutter,
createRouter,
Preparers,
Publishers,
CreateReactAppTemplater,
Templaters,
- CatalogEntityClient,
} from '@backstage/plugin-scaffolder-backend';
+import { CatalogClient } from '@backstage/catalog-client';
const discovery = SingleHostDiscovery.fromConfig(config);
-const entityClient = new CatalogEntityClient({ discovery });
+const catalogClient = new CatalogClient({ discoveryApi: discovery })
return await createRouter({
preparers,
templaters,
publishers,
logger,
config,
dockerClient,
- entityClient,
database,
+ catalogClient,
});
```
See the `@backstage/scaffolder-backend` changelog for more information about this change.
+3
View File
@@ -94,6 +94,7 @@ Zalando
Zhou
Zolotusky
abc
accessors
adamdmharvey
andrewthauer
api
@@ -166,6 +167,7 @@ interop
jq
js
json
jsonnet
jsx
kubectl
kubernetes
@@ -203,6 +205,7 @@ octokit
oidc
onboarding
pagerduty
pageview
parallelization
plantuml
postgres
-20
View File
@@ -24,7 +24,6 @@ Below is a cleaned up output of `yarn backstage-cli --help`.
```text
app:build Build an app for a production release
app:diff Diff an existing app with the creation template
app:serve Serve an app for local development
backend:build Build a backend plugin
@@ -112,25 +111,6 @@ Options:
-h, --help display help for command
```
## app:diff
Scope: `app`
Diff an existing app with the template used in `@backstage/create-app`. This
will verify that your app package has not diverged from the template, and can be
useful to run after updating the version of `@backstage/cli` in your app.
This command is experimental and may be removed in the future.
```text
Usage: backstage-cli app:diff
Options:
--check Fail if changes are required
--yes Apply all changes
-h, --help display help for command
```
## app:serve
Scope: `app`
@@ -70,6 +70,35 @@ The value of this annotation is a location reference string (see above). If this
annotation is specified, it is expected to point to a repository that the
TechDocs system can read and generate docs from.
### backstage.io/view-url, backstage.io/edit-url
```yaml
# Example:
metadata:
annotations:
backstage.io/view-url: https://some.website/catalog-info.yaml
backstage.io/edit-url: https://github.com/my-org/catalog/edit/master/my-service.jsonnet
```
These annotations allow customising links from the catalog pages. The view URL
should point to the canonical metadata YAML that governs this entity. The edit
URL should point to the source file for the metadata. In the example above,
`my-org` generates its catalog data from Jsonnet files in a monorepo, so the
view and edit links need changing.
### backstage.io/source-location
```yaml
# Example:
metadata:
annotations:
backstage.io/source-location: github:https://github.com/my-org/my-service
```
A `Location` reference that points to the source code of the entity (typically a
`Component`). Useful when catalog files do not get ingested from the source code
repository itself.
### jenkins.io/github-folder
```yaml
@@ -191,6 +191,27 @@ techdocs:
Refer to the
[official AWS documentation for obtaining the credentials](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/getting-your-credentials.html).
**3c. Authentication using an assumed role** Users with multiple AWS accounts
may want to use a role for S3 storage that is in a different AWS account. Using
the `roleArn` parameter as seen below, you can instruct the TechDocs publisher
to assume a role before accessing S3.
```yaml
techdocs:
publisher:
type: 'awsS3'
awsS3:
bucketName: 'name-of-techdocs-storage-bucket'
region:
$env: AWS_REGION
credentials:
roleArn: arn:aws:iam::123456789012:role/my-backstage-role
```
Note: Assuming a role requires that primary credentials are already configured
at `AWS.config.credentials`. Read more about
[assuming roles in AWS](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html).
**4. That's it!**
Your Backstage app is now ready to use AWS S3 for TechDocs, to store and read
@@ -0,0 +1,24 @@
---
id: installation
title: Google Analytics Installation
sidebar_label: Installation
# prettier-ignore
description: Adding Google Analytics to Your App
---
There is a basic Google Analytics integration built into Backstage. You can
enable it by adding the following to your app configuration:
```yaml
app:
googleAnalyticsTrackingId: UA-000000-0
```
Replace the tracking ID with your own.
For more information, learn about Google Analytics
[here](https://marketingplatform.google.com/about/analytics/).
The default behavior is only to send a pageview hit to Google Analytics. To
record more, look at the developer documentation
[here](https://developers.google.com/analytics/devguides/collection/gtagjs).
+2 -12
View File
@@ -10,18 +10,8 @@ Backstage integrator.
## Google Analytics
There is a basic Google Analytics integration built into Backstage. You can
enable it by adding the following to your app configuration:
```yaml
app:
googleAnalyticsTrackingId: UA-000000-0
```
Replace the tracking ID with your own.
For more information, learn about Google Analytics
[here](https://marketingplatform.google.com/about/analytics/).
See how to install Google Analytics in your app
[here](../integrations/google-analytics/installation.md)
## Logging
+2
View File
@@ -21,6 +21,8 @@ const Background = props => {
<Block.Paragraph>
To explore the UI and basic features of Backstage firsthand, go
to: <a href="https://demo.backstage.io">demo.backstage.io</a>.
(Tip: click All to view all the example components in the
service catalog.)
</Block.Paragraph>
<Block.Paragraph>
Watch the videos below to get an introduction to Backstage and to
+5
View File
@@ -112,6 +112,11 @@
"type": "subcategory",
"label": "LDAP",
"ids": ["integrations/ldap/org"]
},
{
"type": "subcategory",
"label": "Google Analytics",
"ids": ["integrations/google-analytics/installation"]
}
],
"Plugins": [
+2
View File
@@ -70,6 +70,8 @@ nav:
- Org Data: 'integrations/github/org.md'
- LDAP:
- Org Data: 'integrations/ldap/org.md'
- Google Analytics:
- Installation: 'integrations/google-analytics/installation.md'
- Plugins:
- Overview: 'plugins/index.md'
- Existing plugins: 'plugins/existing-plugins.md'
+1 -1
View File
@@ -23,7 +23,7 @@
"docker-build": "yarn tsc && yarn workspace example-backend build --build-dependencies && yarn workspace example-backend build-image",
"create-plugin": "backstage-cli create-plugin --scope backstage --no-private",
"remove-plugin": "backstage-cli remove-plugin",
"release": "changeset version && yarn diff --yes && yarn prettier --write '{packages,plugins}/*/{package.json,CHANGELOG.md}' && yarn install --frozen-lockfile",
"release": "changeset version && yarn diff --yes && yarn prettier --write '{packages,plugins}/*/{package.json,CHANGELOG.md}' && yarn install",
"prettier:check": "prettier --check .",
"lerna": "lerna",
"storybook": "yarn workspace storybook start",
+59
View File
@@ -1,5 +1,64 @@
# example-app
## 0.2.17
### Patch Changes
- Updated dependencies [3a58084b6]
- Updated dependencies [a5f42cf66]
- Updated dependencies [38205492a]
- Updated dependencies [e488f0502]
- Updated dependencies [e799e74d4]
- Updated dependencies [e3bc5aad7]
- Updated dependencies [a5f42cf66]
- Updated dependencies [a8953a9c9]
- Updated dependencies [f37992797]
- Updated dependencies [347137ccf]
- Updated dependencies [d0760ecdf]
- Updated dependencies [1407b34c6]
- Updated dependencies [88f1f1b60]
- Updated dependencies [d6593abe6]
- Updated dependencies [bad21a085]
- Updated dependencies [e8e35fb5f]
- Updated dependencies [9615e68fb]
- Updated dependencies [e780e119c]
- Updated dependencies [437bac549]
- Updated dependencies [9f2b3a26e]
- Updated dependencies [49f9b7346]
- Updated dependencies [5c2e2863f]
- Updated dependencies [968b588f7]
- Updated dependencies [3a58084b6]
- Updated dependencies [2499f6cde]
- Updated dependencies [5469a9761]
- Updated dependencies [60d1bc3e7]
- Updated dependencies [2c1f2a7c2]
- Updated dependencies [6266ddd11]
- @backstage/core@0.6.3
- @backstage/plugin-scaffolder@0.6.0
- @backstage/plugin-cost-insights@0.8.2
- @backstage/plugin-org@0.3.8
- @backstage/plugin-catalog@0.4.0
- @backstage/plugin-catalog-import@0.4.2
- @backstage/plugin-techdocs@0.5.8
- @backstage/plugin-explore@0.2.7
- @backstage/plugin-catalog-react@0.1.0
- @backstage/plugin-api-docs@0.4.7
- @backstage/catalog-model@0.7.2
- @backstage/cli@0.6.2
- @backstage/plugin-tech-radar@0.3.6
- @backstage/plugin-circleci@0.2.10
- @backstage/plugin-cloudbuild@0.2.11
- @backstage/plugin-github-actions@0.3.4
- @backstage/plugin-jenkins@0.3.11
- @backstage/plugin-kafka@0.2.4
- @backstage/plugin-kubernetes@0.3.11
- @backstage/plugin-lighthouse@0.2.12
- @backstage/plugin-pagerduty@0.3.1
- @backstage/plugin-register-component@0.2.11
- @backstage/plugin-rollbar@0.3.2
- @backstage/plugin-search@0.3.2
- @backstage/plugin-sentry@0.3.7
## 0.2.16
### Patch Changes
+27 -27
View File
@@ -1,38 +1,38 @@
{
"name": "example-app",
"version": "0.2.16",
"version": "0.2.17",
"private": true,
"bundled": true,
"dependencies": {
"@backstage/catalog-model": "^0.7.1",
"@backstage/cli": "^0.6.1",
"@backstage/core": "^0.6.2",
"@backstage/plugin-api-docs": "^0.4.6",
"@backstage/plugin-catalog": "^0.3.2",
"@backstage/plugin-catalog-react": "^0.0.4",
"@backstage/plugin-catalog-import": "^0.4.1",
"@backstage/plugin-circleci": "^0.2.9",
"@backstage/plugin-cloudbuild": "^0.2.10",
"@backstage/plugin-cost-insights": "^0.8.1",
"@backstage/plugin-explore": "^0.2.6",
"@backstage/catalog-model": "^0.7.2",
"@backstage/cli": "^0.6.2",
"@backstage/core": "^0.6.3",
"@backstage/plugin-api-docs": "^0.4.7",
"@backstage/plugin-catalog": "^0.4.0",
"@backstage/plugin-catalog-react": "^0.1.0",
"@backstage/plugin-catalog-import": "^0.4.2",
"@backstage/plugin-circleci": "^0.2.10",
"@backstage/plugin-cloudbuild": "^0.2.11",
"@backstage/plugin-cost-insights": "^0.8.2",
"@backstage/plugin-explore": "^0.2.7",
"@backstage/plugin-gcp-projects": "^0.2.4",
"@backstage/plugin-github-actions": "^0.3.3",
"@backstage/plugin-github-actions": "^0.3.4",
"@backstage/plugin-gitops-profiles": "^0.2.5",
"@backstage/plugin-graphiql": "^0.2.7",
"@backstage/plugin-org": "^0.3.7",
"@backstage/plugin-jenkins": "^0.3.10",
"@backstage/plugin-kafka": "^0.2.3",
"@backstage/plugin-kubernetes": "^0.3.10",
"@backstage/plugin-lighthouse": "^0.2.11",
"@backstage/plugin-org": "^0.3.8",
"@backstage/plugin-jenkins": "^0.3.11",
"@backstage/plugin-kafka": "^0.2.4",
"@backstage/plugin-kubernetes": "^0.3.11",
"@backstage/plugin-lighthouse": "^0.2.12",
"@backstage/plugin-newrelic": "^0.2.5",
"@backstage/plugin-pagerduty": "0.3.0",
"@backstage/plugin-register-component": "^0.2.10",
"@backstage/plugin-rollbar": "^0.3.1",
"@backstage/plugin-scaffolder": "^0.5.1",
"@backstage/plugin-sentry": "^0.3.6",
"@backstage/plugin-search": "^0.3.1",
"@backstage/plugin-tech-radar": "^0.3.5",
"@backstage/plugin-techdocs": "^0.5.7",
"@backstage/plugin-pagerduty": "0.3.1",
"@backstage/plugin-register-component": "^0.2.11",
"@backstage/plugin-rollbar": "^0.3.2",
"@backstage/plugin-scaffolder": "^0.6.0",
"@backstage/plugin-sentry": "^0.3.7",
"@backstage/plugin-search": "^0.3.2",
"@backstage/plugin-tech-radar": "^0.3.6",
"@backstage/plugin-techdocs": "^0.5.8",
"@backstage/plugin-user-settings": "^0.2.6",
"@backstage/theme": "^0.2.3",
"@material-ui/core": "^4.11.0",
@@ -53,7 +53,7 @@
"zen-observable": "^0.8.15"
},
"devDependencies": {
"@backstage/test-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.8",
"@testing-library/cypress": "^7.0.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+22
View File
@@ -1,5 +1,27 @@
# example-backend
## 0.2.17
### Patch Changes
- Updated dependencies [a70af22a2]
- Updated dependencies [ec504e7b4]
- Updated dependencies [a5f42cf66]
- Updated dependencies [f37992797]
- Updated dependencies [bad21a085]
- Updated dependencies [1c06cb312]
- Updated dependencies [2499f6cde]
- Updated dependencies [a1f5e6545]
- @backstage/plugin-kubernetes-backend@0.2.7
- @backstage/plugin-auth-backend@0.3.2
- @backstage/plugin-scaffolder-backend@0.8.0
- @backstage/plugin-techdocs-backend@0.6.2
- @backstage/catalog-model@0.7.2
- @backstage/plugin-app-backend@0.3.8
- @backstage/plugin-catalog-backend@0.6.3
- @backstage/config@0.1.3
- example-app@0.2.17
## 0.2.15
### Patch Changes
+11 -11
View File
@@ -1,6 +1,6 @@
{
"name": "example-backend",
"version": "0.2.15",
"version": "0.2.17",
"main": "dist/index.cjs.js",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -29,23 +29,23 @@
"dependencies": {
"@backstage/backend-common": "^0.5.3",
"@backstage/catalog-client": "^0.3.6",
"@backstage/catalog-model": "^0.7.1",
"@backstage/config": "^0.1.2",
"@backstage/plugin-app-backend": "^0.3.7",
"@backstage/plugin-auth-backend": "^0.3.0",
"@backstage/plugin-catalog-backend": "^0.6.1",
"@backstage/catalog-model": "^0.7.2",
"@backstage/config": "^0.1.3",
"@backstage/plugin-app-backend": "^0.3.8",
"@backstage/plugin-auth-backend": "^0.3.2",
"@backstage/plugin-catalog-backend": "^0.6.3",
"@backstage/plugin-graphql-backend": "^0.1.5",
"@backstage/plugin-kubernetes-backend": "^0.2.6",
"@backstage/plugin-kubernetes-backend": "^0.2.7",
"@backstage/plugin-kafka-backend": "^0.2.0",
"@backstage/plugin-proxy-backend": "^0.2.4",
"@backstage/plugin-rollbar-backend": "^0.1.7",
"@backstage/plugin-scaffolder-backend": "^0.7.0",
"@backstage/plugin-techdocs-backend": "^0.6.0",
"@backstage/plugin-scaffolder-backend": "^0.8.0",
"@backstage/plugin-techdocs-backend": "^0.6.2",
"@gitbeaker/node": "^28.0.2",
"@octokit/rest": "^18.0.12",
"azure-devops-node-api": "^10.1.1",
"dockerode": "^3.2.1",
"example-app": "^0.2.15",
"example-app": "^0.2.17",
"express": "^4.17.1",
"express-promise-router": "^3.0.3",
"knex": "^0.21.6",
@@ -55,7 +55,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/cli": "^0.6.0",
"@backstage/cli": "^0.6.2",
"@types/dockerode": "^3.2.1",
"@types/express": "^4.17.6",
"@types/express-serve-static-core": "^4.17.5"
+8
View File
@@ -1,5 +1,13 @@
# @backstage/catalog-model
## 0.7.2
### Patch Changes
- bad21a085: Implement annotations for customising Entity URLs in the Catalog pages.
- Updated dependencies [a1f5e6545]
- @backstage/config@0.1.3
## 0.7.1
### Patch Changes
@@ -2,7 +2,8 @@ apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: petstore
description: Petstore
# This is an extra long description
description: The Petstore is an example API used to show features of the OpenAPI spec.
links:
- url: https://github.com/swagger-api/swagger-petstore
title: GitHub Repo
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/catalog-model",
"version": "0.7.1",
"version": "0.7.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -29,7 +29,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/config": "^0.1.2",
"@backstage/config": "^0.1.3",
"@types/json-schema": "^7.0.5",
"@types/yup": "^0.29.8",
"ajv": "^7.0.3",
@@ -39,7 +39,7 @@
"yup": "^0.29.3"
},
"devDependencies": {
"@backstage/cli": "^0.6.0",
"@backstage/cli": "^0.6.2",
"@types/express": "^4.17.6",
"@types/jest": "^26.0.7",
"@types/lodash": "^4.14.151",
@@ -27,3 +27,9 @@ export const ENTITY_META_GENERATED_FIELDS = [
'etag',
'generation',
] as const;
/**
* Annotations for linking to entity from catalog pages.
*/
export const VIEW_URL_ANNOTATION = 'backstage.io/view-url';
export const EDIT_URL_ANNOTATION = 'backstage.io/edit-url';
@@ -17,6 +17,8 @@
export {
ENTITY_DEFAULT_NAMESPACE,
ENTITY_META_GENERATED_FIELDS,
VIEW_URL_ANNOTATION,
EDIT_URL_ANNOTATION,
} from './constants';
export type {
Entity,
@@ -17,3 +17,5 @@
export const LOCATION_ANNOTATION = 'backstage.io/managed-by-location';
export const ORIGIN_LOCATION_ANNOTATION =
'backstage.io/managed-by-origin-location';
export const SOURCE_LOCATION_ANNOTATION = 'backstage.io/source-location';
+5 -1
View File
@@ -20,4 +20,8 @@ export {
locationSpecSchema,
analyzeLocationSchema,
} from './validation';
export { LOCATION_ANNOTATION, ORIGIN_LOCATION_ANNOTATION } from './annotation';
export {
LOCATION_ANNOTATION,
ORIGIN_LOCATION_ANNOTATION,
SOURCE_LOCATION_ANNOTATION,
} from './annotation';
+9
View File
@@ -1,5 +1,14 @@
# @backstage/cli
## 0.6.2
### Patch Changes
- e780e119c: Add missing `file-loader` dependency which could cause issues with loading images and other assets.
- 6266ddd11: The `yarn backstage-cli app:diff` has been broken since a couple of months. The command to perform updates `yarn backstage-cli versions:bump` prints change logs which seems to be a good replacement for this command.
- Updated dependencies [a1f5e6545]
- @backstage/config@0.1.3
## 0.6.1
### Patch Changes
+7 -6
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/cli",
"description": "CLI for developing Backstage plugins and apps",
"version": "0.6.1",
"version": "0.6.2",
"private": false,
"publishConfig": {
"access": "public"
@@ -31,7 +31,7 @@
"@babel/core": "^7.4.4",
"@babel/plugin-transform-modules-commonjs": "^7.4.4",
"@backstage/cli-common": "^0.1.1",
"@backstage/config": "^0.1.2",
"@backstage/config": "^0.1.3",
"@backstage/config-loader": "^0.5.1",
"@hot-loader/react-dom": "^16.13.0",
"@lerna/package-graph": "^4.0.0",
@@ -74,6 +74,7 @@
"eslint-plugin-react": "^7.12.4",
"eslint-plugin-react-hooks": "^4.0.0",
"express": "^4.17.1",
"file-loader": "^6.2.0",
"fork-ts-checker-webpack-plugin": "^4.0.5",
"fs-extra": "^9.0.0",
"handlebars": "^4.7.3",
@@ -116,10 +117,10 @@
},
"devDependencies": {
"@backstage/backend-common": "^0.5.4",
"@backstage/config": "^0.1.2",
"@backstage/core": "^0.6.2",
"@backstage/dev-utils": "^0.1.11",
"@backstage/test-utils": "^0.1.6",
"@backstage/config": "^0.1.3",
"@backstage/core": "^0.6.3",
"@backstage/dev-utils": "^0.1.12",
"@backstage/test-utils": "^0.1.8",
"@backstage/theme": "^0.2.3",
"@types/diff": "^4.0.2",
"@types/express": "^4.17.6",
-74
View File
@@ -1,74 +0,0 @@
/*
* Copyright 2020 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Command } from 'commander';
import {
diffTemplateFiles,
handlers,
handleAllFiles,
inquirerPromptFunc,
makeCheckPromptFunc,
yesPromptFunc,
} from '../../lib/diff';
import { version } from '../../lib/version';
const fileHandlers = [
{
patterns: ['packages/app/package.json'],
handler: handlers.appPackageJson,
},
{
patterns: [/tsconfig\.json$/],
handler: handlers.exactMatch,
},
{
patterns: [
/README\.md$/,
/\.eslintrc\.js$/,
// make sure files in 1st level of src/ and dev/ exist
/^packages\/app\/(src|dev)\/[^/]+$/,
],
handler: handlers.exists,
},
{
patterns: [
'lerna.json',
/^src\//,
/^patches\//,
/^packages\/app\/public\//,
/^packages\/app\/cypress/,
// Let plugin:diff take care of the plugins
/^plugins/,
/package\.json$/,
],
handler: handlers.skip,
},
];
export default async (cmd: Command) => {
let promptFunc = inquirerPromptFunc;
let finalize = () => {};
if (cmd.check) {
[promptFunc, finalize] = makeCheckPromptFunc();
} else if (cmd.yes) {
promptFunc = yesPromptFunc;
}
const templateFiles = await diffTemplateFiles('default-app', { version });
await handleAllFiles(fileHandlers, templateFiles, promptFunc);
await finalize();
};
-7
View File
@@ -76,13 +76,6 @@ export function registerCommands(program: CommanderStatic) {
.option(...configOption)
.action(lazy(() => import('./backend/dev').then(m => m.default)));
program
.command('app:diff')
.option('--check', 'Fail if changes are required')
.option('--yes', 'Apply all changes')
.description('Diff an existing app with the creation template')
.action(lazy(() => import('./app/diff').then(m => m.default)));
program
.command('create-plugin')
.option(
+14
View File
@@ -1,5 +1,19 @@
# @backstage/config
## 0.1.3
### Patch Changes
- a1f5e6545: Adds an optional type to `config.get` & `config.getOptional`. This avoids the need for casting. For example:
```ts
const config = useApi(configApiRef);
const myConfig = config.get<SomeTypeDefinition>('myPlugin.complexConfig');
// vs
const myConfig config.get('myPlugin.complexConfig') as SomeTypeDefinition;
```
## 0.1.2
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/config",
"description": "Config API used by Backstage core, backend, and CLI",
"version": "0.1.2",
"version": "0.1.3",
"private": false,
"publishConfig": {
"access": "public",
+6 -6
View File
@@ -88,22 +88,22 @@ export class ConfigReader implements Config {
return [...new Set([...localKeys, ...fallbackKeys])];
}
get(key?: string): JsonValue {
get<T = JsonValue>(key?: string): T {
const value = this.getOptional(key);
if (value === undefined) {
throw new Error(errors.missing(this.fullKey(key ?? '')));
}
return value;
return value as T;
}
getOptional(key?: string): JsonValue | undefined {
getOptional<T = JsonValue>(key?: string): T | undefined {
const value = this.readValue(key);
const fallbackValue = this.fallback?.getOptional(key);
const fallbackValue = this.fallback?.getOptional<T>(key);
if (value === undefined) {
return fallbackValue;
} else if (fallbackValue === undefined) {
return value;
return value as T;
}
// Avoid merging arrays and primitive values, since that's how merging works for other
@@ -113,7 +113,7 @@ export class ConfigReader implements Config {
{ value: cloneDeep(fallbackValue) },
{ value },
(into, from) => (!isObject(from) || !isObject(into) ? from : undefined),
).value;
).value as T;
}
getConfig(key: string): ConfigReader {
+2 -2
View File
@@ -34,8 +34,8 @@ export type Config = {
keys(): string[];
get(key?: string): JsonValue;
getOptional(key?: string): JsonValue | undefined;
get<T = JsonValue>(key?: string): T;
getOptional<T = JsonValue>(key?: string): T | undefined;
getConfig(key: string): Config;
getOptionalConfig(key: string): Config | undefined;
+11
View File
@@ -1,5 +1,16 @@
# @backstage/core-api
## 0.2.11
### Patch Changes
- 3a58084b6: The `FlatRoutes` components now renders the not found page of the app if no routes are matched.
- 1407b34c6: More informative error message for missing ApiContext.
- b6c4f485d: Fix error when querying Backstage Identity with SAML authentication
- 3a58084b6: Created separate `AppContext` type to be returned from `useApp` rather than the `BackstageApp` itself. The `AppContext` type includes but deprecates `getPlugins`, `getProvider`, `getRouter`, and `getRoutes`. In addition, the `AppContext` adds a new `getComponents` method which providers access to the app components.
- Updated dependencies [a1f5e6545]
- @backstage/config@0.1.3
## 0.2.10
### Patch Changes
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/core-api",
"description": "Internal Core API used by Backstage plugins and apps",
"version": "0.2.10",
"version": "0.2.11",
"private": false,
"publishConfig": {
"access": "public",
@@ -29,7 +29,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/config": "^0.1.2",
"@backstage/config": "^0.1.3",
"@backstage/theme": "^0.2.3",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -42,8 +42,8 @@
"zen-observable": "^0.8.15"
},
"devDependencies": {
"@backstage/cli": "^0.6.1",
"@backstage/test-utils": "^0.1.6",
"@backstage/cli": "^0.6.2",
"@backstage/test-utils": "^0.1.8",
"@backstage/test-utils-core": "^0.1.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
@@ -83,7 +83,7 @@ class SamlAuth implements ProfileInfoApi, BackstageIdentityApi, SessionApi {
}
async getBackstageIdentity(
options: AuthRequestOptions,
options: AuthRequestOptions = {},
): Promise<BackstageIdentity | undefined> {
const session = await this.sessionManager.getSession(options);
return session?.backstageIdentity;
+64 -11
View File
@@ -64,6 +64,7 @@ import { AppThemeProvider } from './AppThemeProvider';
import {
AppComponents,
AppConfigLoader,
AppContext,
AppOptions,
AppRouteBinder,
BackstageApp,
@@ -139,6 +140,42 @@ function useConfigLoader(
return { api: configReader };
}
class AppContextImpl implements AppContext {
constructor(private readonly app: PrivateAppImpl) {}
getPlugins(): BackstagePlugin<any, any>[] {
// eslint-disable-next-line no-console
console.warn('appContext.getPlugins() is deprecated and will be removed');
return this.app.getPlugins();
}
getSystemIcon(key: string): IconComponent {
return this.app.getSystemIcon(key);
}
getComponents(): AppComponents {
return this.app.getComponents();
}
getProvider(): React.ComponentType<{}> {
// eslint-disable-next-line no-console
console.warn('appContext.getProvider() is deprecated and will be removed');
return this.app.getProvider();
}
getRouter(): React.ComponentType<{}> {
// eslint-disable-next-line no-console
console.warn('appContext.getRouter() is deprecated and will be removed');
return this.app.getRouter();
}
getRoutes(): JSX.Element[] {
// eslint-disable-next-line no-console
console.warn('appContext.getRoutes() is deprecated and will be removed');
return this.app.getRoutes();
}
}
export class PrivateAppImpl implements BackstageApp {
private apiHolder?: ApiHolder;
private configApi?: ConfigApi;
@@ -173,11 +210,13 @@ export class PrivateAppImpl implements BackstageApp {
return this.icons[key];
}
getComponents(): AppComponents {
return this.components;
}
getRoutes(): JSX.Element[] {
const routes = new Array<JSX.Element>();
const featureFlagsApi = this.getApiHolder().get(featureFlagsApiRef)!;
const { NotFoundErrorPage } = this.components;
for (const plugin of this.plugins.values()) {
@@ -211,13 +250,6 @@ export class PrivateAppImpl implements BackstageApp {
routes.push(<Navigate key={from.path} to={to.path} />);
break;
}
case 'feature-flag': {
featureFlagsApi.registerFlag({
name: output.name,
pluginId: plugin.getId(),
});
break;
}
default:
break;
}
@@ -236,6 +268,27 @@ export class PrivateAppImpl implements BackstageApp {
}
getProvider(): ComponentType<{}> {
const appContext = new AppContextImpl(this);
const apiHolder = this.getApiHolder();
const featureFlagsApi = this.getApiHolder().get(featureFlagsApiRef)!;
for (const plugin of this.plugins.values()) {
for (const output of plugin.output()) {
switch (output.type) {
case 'feature-flag': {
featureFlagsApi.registerFlag({
name: output.name,
pluginId: plugin.getId(),
});
break;
}
default:
break;
}
}
}
const Provider = ({ children }: PropsWithChildren<{}>) => {
const appThemeApi = useMemo(
() => AppThemeSelector.createWithStorage(this.themes),
@@ -272,8 +325,8 @@ export class PrivateAppImpl implements BackstageApp {
this.configApi = loadedConfig.api;
return (
<ApiProvider apis={this.getApiHolder()}>
<AppContextProvider app={this}>
<ApiProvider apis={apiHolder}>
<AppContextProvider appContext={appContext}>
<AppThemeProvider>
<RoutingProvider
routePaths={routePaths}
+9 -9
View File
@@ -15,25 +15,25 @@
*/
import React, { createContext, PropsWithChildren, useContext } from 'react';
import { BackstageApp } from './types';
import { AppContext } from './types';
const Context = createContext<BackstageApp | undefined>(undefined);
const Context = createContext<AppContext | undefined>(undefined);
type Props = {
app: BackstageApp;
appContext: AppContext;
};
export const AppContextProvider = ({
app,
appContext,
children,
}: PropsWithChildren<Props>) => (
<Context.Provider value={app} children={children} />
<Context.Provider value={appContext} children={children} />
);
export const useApp = (): BackstageApp => {
const app = useContext(Context);
if (!app) {
export const useApp = (): AppContext => {
const appContext = useContext(Context);
if (!appContext) {
throw new Error('No app context available');
}
return app;
return appContext;
};
+34
View File
@@ -187,6 +187,40 @@ export type BackstageApp = {
/**
* Routes component that contains all routes for plugin pages in the app.
*
* @deprecated Registering routes in plugins is deprecated and this method will be removed.
*/
getRoutes(): JSX.Element[];
};
export type AppContext = {
/**
* @deprecated Will be removed
*/
getPlugins(): BackstagePlugin<any, any>[];
/**
* Get a common or custom icon for this app.
*/
getSystemIcon(key: IconKey): IconComponent;
/**
* Get the components registered for various purposes in the app.
*/
getComponents(): AppComponents;
/**
* @deprecated Will be removed
*/
getProvider(): ComponentType<{}>;
/**
* @deprecated Will be removed
*/
getRouter(): ComponentType<{}>;
/**
* @deprecated Will be removed
*/
getRoutes(): JSX.Element[];
};
+11 -1
View File
@@ -14,8 +14,9 @@
* limitations under the License.
*/
import { ReactNode, Children, isValidElement, Fragment } from 'react';
import React, { ReactNode, Children, isValidElement, Fragment } from 'react';
import { useRoutes } from 'react-router-dom';
import { useApp } from '../app';
type RouteObject = {
path: string;
@@ -71,6 +72,15 @@ type FlatRoutesProps = {
};
export const FlatRoutes = (props: FlatRoutesProps): JSX.Element | null => {
const app = useApp();
const { NotFoundErrorPage } = app.getComponents();
const routes = createRoutesFromChildren(props.children);
// TODO(Rugvip): Possibly add a way to skip this, like a noNotFoundPage prop
routes.push({
element: <NotFoundErrorPage />,
path: '/*',
});
return useRoutes(routes);
};
+21
View File
@@ -1,5 +1,26 @@
# @backstage/core
## 0.6.3
### Patch Changes
- 3a58084b6: The `FlatRoutes` components now renders the not found page of the app if no routes are matched.
- e799e74d4: Fix `OverflowTooltip` cutting off the bottom of letters like "g" and "y".
- 1407b34c6: More informative error message for missing ApiContext.
- 9615e68fb: Forward link styling of `EntityRefLink` and `EnriryRefLinks` into the underling
`Link`.
- 49f9b7346: Deprecate `type` of `ItemCard` and introduce new `subtitle` which allows passing
react nodes.
- 3a58084b6: Created separate `AppContext` type to be returned from `useApp` rather than the `BackstageApp` itself. The `AppContext` type includes but deprecates `getPlugins`, `getProvider`, `getRouter`, and `getRoutes`. In addition, the `AppContext` adds a new `getComponents` method which providers access to the app components.
- 2c1f2a7c2: Introduced generic OverflowTooltip component for cases where longer text needs to be truncated with ellipsis and show hover tooltip with full text. This is particularly useful in the cases where longer description text is rendered in table. e.g. CatalogTable and ApiExplorerTable.
- Updated dependencies [3a58084b6]
- Updated dependencies [1407b34c6]
- Updated dependencies [b6c4f485d]
- Updated dependencies [3a58084b6]
- Updated dependencies [a1f5e6545]
- @backstage/core-api@0.2.11
- @backstage/config@0.1.3
## 0.6.2
### Patch Changes
+5 -5
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/core",
"description": "Core API used by Backstage plugins and apps",
"version": "0.6.2",
"version": "0.6.3",
"private": false,
"publishConfig": {
"access": "public",
@@ -29,8 +29,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/config": "^0.1.2",
"@backstage/core-api": "^0.2.10",
"@backstage/config": "^0.1.3",
"@backstage/core-api": "^0.2.11",
"@backstage/theme": "^0.2.3",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -68,8 +68,8 @@
"zen-observable": "^0.8.15"
},
"devDependencies": {
"@backstage/cli": "^0.6.1",
"@backstage/test-utils": "^0.1.7",
"@backstage/cli": "^0.6.2",
"@backstage/test-utils": "^0.1.8",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { Tooltip, TooltipProps } from '@material-ui/core';
import { makeStyles, Tooltip, TooltipProps } from '@material-ui/core';
import React, { useState } from 'react';
import TextTruncate, { TextTruncateProps } from 'react-text-truncate';
@@ -26,8 +26,15 @@ type Props = {
placement?: TooltipProps['placement'];
};
const useStyles = makeStyles({
container: {
overflow: 'visible !important',
},
});
export const OverflowTooltip = (props: Props) => {
const [hover, setHover] = useState(false);
const classes = useStyles();
const handleToggled = (truncated: boolean) => {
setHover(truncated);
@@ -43,6 +50,7 @@ export const OverflowTooltip = (props: Props) => {
text={props.text}
line={props.line}
onToggled={handleToggled}
containerClassName={classes.container}
/>
</Tooltip>
);
+164
View File
@@ -1,5 +1,169 @@
# @backstage/create-app
## 0.3.11
### Patch Changes
- 4594f7efc: Add the google analytics scripts in the `index.html` template for new applications.
To apply this change to an existing application, change the following in `packages\app\public\index.html`:
```diff
<title><%= app.title %></title>
+ <% if (app.googleAnalyticsTrackingId && typeof app.googleAnalyticsTrackingId
+ === 'string') { %>
+ <script
+ async
+ src="https://www.googletagmanager.com/gtag/js?id=<%= app.googleAnalyticsTrackingId %>"
+ ></script>
+ <script>
+ window.dataLayer = window.dataLayer || [];
+ function gtag() {
+ dataLayer.push(arguments);
+ }
+ gtag('js', new Date());
+
+ gtag('config', '<%= app.googleAnalyticsTrackingId %>');
+ </script>
+ <% } %>
</head>
```
- 08fa2176a: **BREAKING CHANGE**
The Scaffolder and Catalog plugins have been migrated to partially require use of the [new composability API](https://backstage.io/docs/plugins/composability). The Scaffolder used to register its pages using the deprecated route registration plugin API, but those registrations have been removed. This means you now need to add the Scaffolder plugin page to the app directly.
The Catalog plugin has also been migrated to use an [external route reference](https://backstage.io/docs/plugins/composability#binding-external-routes-in-the-app) to dynamically link to the create component page. This means you need to migrate the catalog plugin to use the new extension components, as well as bind the external route.
Apply the following changes to `packages/app/src/App.tsx`:
```diff
-import { Router as CatalogRouter } from '@backstage/plugin-catalog';
+import {
+ catalogPlugin,
+ CatalogIndexPage,
+ CatalogEntityPage,
+} from '@backstage/plugin-catalog';
+import { scaffolderPlugin, ScaffolderPage } from '@backstage/plugin-scaffolder';
# The following addition to the app config allows the catalog plugin to link to the
# component creation page, i.e. the scaffolder. You can chose a different target if you want to.
const app = createApp({
apis,
plugins: Object.values(plugins),
+ bindRoutes({ bind }) {
+ bind(catalogPlugin.externalRoutes, {
+ createComponent: scaffolderPlugin.routes.root,
+ });
+ }
});
# Apply these changes within FlatRoutes. It is important to have migrated to using FlatRoutes
# for this to work, if you haven't done that yet, see the previous entries in this changelog.
- <Route
- path="/catalog"
- element={<CatalogRouter EntityPage={EntityPage} />}
- />
+ <Route path="/catalog" element={<CatalogIndexPage />} />
+ <Route
+ path="/catalog/:namespace/:kind/:name"
+ element={<CatalogEntityPage />}
+ >
+ <EntityPage />
+ </Route>
<Route path="/docs" element={<DocsRouter />} />
+ <Route path="/create" element={<ScaffolderPage />} />
```
The scaffolder has been redesigned to be horizontally scalable and to persistently store task state and execution logs in the database. Component registration has moved from the frontend into a separate registration step executed by the `TaskWorker`. This requires that a `CatalogClient` is passed to the scaffolder backend instead of the old `CatalogEntityClient`.
The default catalog client comes from the `@backstage/catalog-client`, which you need to add as a dependency in `packages/backend/package.json`.
Once the dependency has been added, apply the following changes to`packages/backend/src/plugins/scaffolder.ts`:
```diff
import {
CookieCutter,
createRouter,
Preparers,
Publishers,
CreateReactAppTemplater,
Templaters,
- CatalogEntityClient,
} from '@backstage/plugin-scaffolder-backend';
+import { CatalogClient } from '@backstage/catalog-client';
const discovery = SingleHostDiscovery.fromConfig(config);
-const entityClient = new CatalogEntityClient({ discovery });
+const catalogClient = new CatalogClient({ discoveryApi: discovery })
return await createRouter({
preparers,
templaters,
publishers,
logger,
config,
dockerClient,
- entityClient,
database,
+ catalogClient,
});
```
See the `@backstage/scaffolder-backend` changelog for more information about this change.
- Updated dependencies [ec504e7b4]
- Updated dependencies [3a58084b6]
- Updated dependencies [a5f42cf66]
- Updated dependencies [e488f0502]
- Updated dependencies [e799e74d4]
- Updated dependencies [dc12852c9]
- Updated dependencies [a5f42cf66]
- Updated dependencies [a8953a9c9]
- Updated dependencies [f37992797]
- Updated dependencies [347137ccf]
- Updated dependencies [d0760ecdf]
- Updated dependencies [1407b34c6]
- Updated dependencies [d6593abe6]
- Updated dependencies [bad21a085]
- Updated dependencies [e8e35fb5f]
- Updated dependencies [9615e68fb]
- Updated dependencies [e780e119c]
- Updated dependencies [437bac549]
- Updated dependencies [9f2b3a26e]
- Updated dependencies [49f9b7346]
- Updated dependencies [1c06cb312]
- Updated dependencies [968b588f7]
- Updated dependencies [3a58084b6]
- Updated dependencies [2499f6cde]
- Updated dependencies [5469a9761]
- Updated dependencies [a1f5e6545]
- Updated dependencies [60d1bc3e7]
- Updated dependencies [2c1f2a7c2]
- Updated dependencies [6266ddd11]
- @backstage/plugin-auth-backend@0.3.2
- @backstage/core@0.6.3
- @backstage/plugin-scaffolder@0.6.0
- @backstage/plugin-scaffolder-backend@0.8.0
- @backstage/test-utils@0.1.8
- @backstage/plugin-catalog@0.4.0
- @backstage/plugin-catalog-import@0.4.2
- @backstage/plugin-techdocs@0.5.8
- @backstage/plugin-techdocs-backend@0.6.2
- @backstage/plugin-explore@0.2.7
- @backstage/plugin-api-docs@0.4.7
- @backstage/catalog-model@0.7.2
- @backstage/cli@0.6.2
- @backstage/plugin-tech-radar@0.3.6
- @backstage/plugin-app-backend@0.3.8
- @backstage/plugin-catalog-backend@0.6.3
- @backstage/config@0.1.3
- @backstage/plugin-circleci@0.2.10
- @backstage/plugin-github-actions@0.3.4
- @backstage/plugin-lighthouse@0.2.12
- @backstage/plugin-search@0.3.2
## 0.3.10
### Patch Changes
+28 -28
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/create-app",
"description": "Create app package for Backstage",
"version": "0.3.10",
"version": "0.3.11",
"private": false,
"publishConfig": {
"access": "public"
@@ -44,33 +44,33 @@
"ts-node": "^8.6.2"
},
"peerDependencies": {
"@backstage/backend-common": "^0.5.4",
"@backstage/catalog-client": "^0.3.6",
"@backstage/catalog-model": "^0.7.1",
"@backstage/cli": "^0.6.1",
"@backstage/config": "^0.1.2",
"@backstage/core": "^0.6.2",
"@backstage/plugin-api-docs": "^0.4.6",
"@backstage/plugin-app-backend": "^0.3.7",
"@backstage/plugin-auth-backend": "^0.3.1",
"@backstage/plugin-catalog": "^0.3.2",
"@backstage/plugin-catalog-backend": "^0.6.2",
"@backstage/plugin-catalog-import": "^0.4.1",
"@backstage/plugin-circleci": "^0.2.9",
"@backstage/plugin-explore": "^0.2.6",
"@backstage/plugin-github-actions": "^0.3.3",
"@backstage/plugin-lighthouse": "^0.2.11",
"@backstage/plugin-proxy-backend": "^0.2.4",
"@backstage/plugin-rollbar-backend": "^0.1.7",
"@backstage/plugin-scaffolder": "^0.5.1",
"@backstage/plugin-search": "^0.3.1",
"@backstage/plugin-scaffolder-backend": "^0.7.1",
"@backstage/plugin-tech-radar": "^0.3.5",
"@backstage/plugin-techdocs": "^0.5.7",
"@backstage/plugin-techdocs-backend": "^0.6.1",
"@backstage/plugin-user-settings": "^0.2.6",
"@backstage/test-utils": "^0.1.7",
"@backstage/theme": "^0.2.3"
"@backstage/backend-common": "*",
"@backstage/catalog-client": "*",
"@backstage/catalog-model": "*",
"@backstage/cli": "*",
"@backstage/config": "*",
"@backstage/core": "*",
"@backstage/plugin-api-docs": "*",
"@backstage/plugin-app-backend": "*",
"@backstage/plugin-auth-backend": "*",
"@backstage/plugin-catalog": "*",
"@backstage/plugin-catalog-backend": "*",
"@backstage/plugin-catalog-import": "*",
"@backstage/plugin-circleci": "*",
"@backstage/plugin-explore": "*",
"@backstage/plugin-github-actions": "*",
"@backstage/plugin-lighthouse": "*",
"@backstage/plugin-proxy-backend": "*",
"@backstage/plugin-rollbar-backend": "*",
"@backstage/plugin-scaffolder": "*",
"@backstage/plugin-search": "*",
"@backstage/plugin-scaffolder-backend": "*",
"@backstage/plugin-tech-radar": "*",
"@backstage/plugin-techdocs": "*",
"@backstage/plugin-techdocs-backend": "*",
"@backstage/plugin-user-settings": "*",
"@backstage/test-utils": "*",
"@backstage/theme": "*"
},
"nodemonConfig": {
"watch": "./src",
@@ -48,6 +48,22 @@
}
</style>
<title><%= app.title %></title>
<% if (app.googleAnalyticsTrackingId && typeof app.googleAnalyticsTrackingId
=== 'string') { %>
<script
async
src="https://www.googletagmanager.com/gtag/js?id=<%= app.googleAnalyticsTrackingId %>"
></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', '<%= app.googleAnalyticsTrackingId %>');
</script>
<% } %>
</head>
<body style="margin: 0;">
<noscript>You need to enable JavaScript to run this app.</noscript>
+22
View File
@@ -1,5 +1,27 @@
# @backstage/dev-utils
## 0.1.12
### Patch Changes
- 5aa4ceea6: Make sure to provide dummy routes for all external routes of plugins given to DevApp
- Updated dependencies [3a58084b6]
- Updated dependencies [e799e74d4]
- Updated dependencies [dc12852c9]
- Updated dependencies [d0760ecdf]
- Updated dependencies [1407b34c6]
- Updated dependencies [88f1f1b60]
- Updated dependencies [bad21a085]
- Updated dependencies [9615e68fb]
- Updated dependencies [49f9b7346]
- Updated dependencies [5c2e2863f]
- Updated dependencies [3a58084b6]
- Updated dependencies [2c1f2a7c2]
- @backstage/core@0.6.3
- @backstage/test-utils@0.1.8
- @backstage/plugin-catalog-react@0.1.0
- @backstage/catalog-model@0.7.2
## 0.1.11
### Patch Changes
+6 -6
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/dev-utils",
"description": "Utilities for developing Backstage plugins.",
"version": "0.1.11",
"version": "0.1.12",
"private": false,
"publishConfig": {
"access": "public",
@@ -29,10 +29,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core": "^0.6.2",
"@backstage/catalog-model": "^0.7.1",
"@backstage/plugin-catalog-react": "^0.0.4",
"@backstage/test-utils": "^0.1.7",
"@backstage/core": "^0.6.3",
"@backstage/catalog-model": "^0.7.2",
"@backstage/plugin-catalog-react": "^0.1.0",
"@backstage/test-utils": "^0.1.8",
"@backstage/theme": "^0.2.3",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -47,7 +47,7 @@
"react-router-dom": "6.0.0-beta.0"
},
"devDependencies": {
"@backstage/cli": "^0.6.1",
"@backstage/cli": "^0.6.2",
"@types/jest": "^26.0.7",
"@types/node": "^12.0.0"
},
+31 -14
View File
@@ -14,26 +14,30 @@
* limitations under the License.
*/
import { hot } from 'react-hot-loader';
import React, { ComponentType, ReactNode } from 'react';
import ReactDOM from 'react-dom';
import BookmarkIcon from '@material-ui/icons/Bookmark';
import {
AlertDisplay,
AnyApiFactory,
ApiFactory,
attachComponentData,
createApp,
SidebarPage,
createPlugin,
createRouteRef,
FlatRoutes,
IconComponent,
OAuthRequestDialog,
RouteRef,
Sidebar,
SidebarItem,
SidebarPage,
SidebarSpacer,
ApiFactory,
createPlugin,
AlertDisplay,
OAuthRequestDialog,
AnyApiFactory,
IconComponent,
FlatRoutes,
attachComponentData,
} from '@backstage/core';
import { Box } from '@material-ui/core';
import BookmarkIcon from '@material-ui/icons/Bookmark';
import SentimentDissatisfiedIcon from '@material-ui/icons/SentimentDissatisfied';
import React, { ComponentType, ReactNode } from 'react';
import ReactDOM from 'react-dom';
import { hot } from 'react-hot-loader';
import { Route } from 'react-router';
const GatheringRoute: (props: {
path: string;
@@ -128,9 +132,22 @@ class DevAppBuilder {
* Build a DevApp component using the resources registered so far
*/
build(): ComponentType<{}> {
const dummyRouteRef = createRouteRef({ title: 'Page of another plugin' });
const DummyPage = () => <Box p={3}>Page belonging to another plugin.</Box>;
attachComponentData(DummyPage, 'core.mountPoint', dummyRouteRef);
const app = createApp({
apis: this.apis,
plugins: this.plugins,
bindRoutes: ({ bind }) => {
for (const plugin of this.plugins ?? []) {
const targets: Record<string, RouteRef<any>> = {};
for (const routeKey of Object.keys(plugin.externalRoutes)) {
targets[routeKey] = dummyRouteRef;
}
bind(plugin.externalRoutes, targets);
}
},
});
const AppProvider = app.getProvider();
@@ -145,13 +162,13 @@ class DevAppBuilder {
<AlertDisplay />
<OAuthRequestDialog />
{this.rootChildren}
<AppRouter>
<SidebarPage>
{sidebar}
<FlatRoutes>
{this.routes}
{deprecatedAppRoutes}
<Route path="/_external_route" element={<DummyPage />} />
</FlatRoutes>
</SidebarPage>
</AppRouter>
+11
View File
@@ -1,5 +1,16 @@
# @backstage/techdocs-common
## 0.4.2
### Patch Changes
- 2499f6cde: Add support for assuming role in AWS integrations
- 1e4ddd71d: Fix AWS, GCS and Azure publisher to work on Windows.
- Updated dependencies [bad21a085]
- Updated dependencies [a1f5e6545]
- @backstage/catalog-model@0.7.2
- @backstage/config@0.1.3
## 0.4.1
### Patch Changes
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/techdocs-common",
"description": "Common functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli",
"version": "0.4.1",
"version": "0.4.2",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -39,8 +39,8 @@
"@azure/identity": "^1.2.2",
"@azure/storage-blob": "^12.4.0",
"@backstage/backend-common": "^0.5.4",
"@backstage/catalog-model": "^0.7.1",
"@backstage/config": "^0.1.2",
"@backstage/catalog-model": "^0.7.2",
"@backstage/config": "^0.1.3",
"@backstage/integration": "^0.5.0",
"@google-cloud/storage": "^5.6.0",
"@types/dockerode": "^3.2.1",
@@ -60,7 +60,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/cli": "^0.6.1",
"@backstage/cli": "^0.6.2",
"@types/fs-extra": "^9.0.5",
"@types/git-url-parse": "^9.0.0",
"@types/js-yaml": "^3.12.5",
@@ -15,12 +15,13 @@
*/
import { Entity, EntityName } from '@backstage/catalog-model';
import { Config } from '@backstage/config';
import aws from 'aws-sdk';
import aws, { Credentials } from 'aws-sdk';
import { ManagedUpload } from 'aws-sdk/clients/s3';
import express from 'express';
import fs from 'fs-extra';
import JSON5 from 'json5';
import createLimiter from 'p-limit';
import { CredentialsOptions } from 'aws-sdk/lib/credentials';
import path from 'path';
import { Readable } from 'stream';
import { Logger } from 'winston';
@@ -59,14 +60,34 @@ export class AwsS3Publish implements PublisherBase {
// https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/loading-node-credentials-shared.html
// 3. IAM Roles for EC2
// https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/loading-node-credentials-iam.html
const credentials = config.getOptionalConfig(
const credentialsConfig = config.getOptionalConfig(
'techdocs.publisher.awsS3.credentials',
);
let accessKeyId = undefined;
let secretAccessKey = undefined;
if (credentials) {
accessKeyId = credentials.getOptionalString('accessKeyId');
secretAccessKey = credentials.getOptionalString('secretAccessKey');
let credentials: Credentials | CredentialsOptions | undefined = undefined;
if (credentialsConfig) {
const roleArn = credentialsConfig.getOptionalString('roleArn');
if (roleArn && aws.config.credentials instanceof Credentials) {
credentials = new aws.ChainableTemporaryCredentials({
masterCredentials: aws.config.credentials as Credentials,
params: {
RoleSessionName: 'backstage-aws-techdocs-s3-publisher',
RoleArn: roleArn,
},
});
} else {
accessKeyId = credentialsConfig.getOptionalString('accessKeyId');
secretAccessKey = credentialsConfig.getOptionalString(
'secretAccessKey',
);
if (accessKeyId && secretAccessKey) {
credentials = {
accessKeyId,
secretAccessKey,
};
}
}
}
// AWS Region is an optional config. If missing, default AWS env variable AWS_REGION
@@ -74,14 +95,7 @@ export class AwsS3Publish implements PublisherBase {
const region = config.getOptionalString('techdocs.publisher.awsS3.region');
const storageClient = new aws.S3({
...(credentials &&
accessKeyId &&
secretAccessKey && {
credentials: {
accessKeyId,
secretAccessKey,
},
}),
credentials,
...(region && {
region,
}),
+11
View File
@@ -1,5 +1,16 @@
# @backstage/test-utils
## 0.1.8
### Patch Changes
- dc12852c9: Allow `ExternalRouteRef` instances to be passed as a route ref to `mountedRoutes`.
- Updated dependencies [3a58084b6]
- Updated dependencies [1407b34c6]
- Updated dependencies [b6c4f485d]
- Updated dependencies [3a58084b6]
- @backstage/core-api@0.2.11
## 0.1.7
### Patch Changes
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/test-utils",
"description": "Utilities to test Backstage plugins and apps.",
"version": "0.1.7",
"version": "0.1.8",
"private": false,
"publishConfig": {
"access": "public",
@@ -29,7 +29,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core-api": "^0.2.7",
"@backstage/core-api": "^0.2.11",
"@backstage/test-utils-core": "^0.1.1",
"@backstage/theme": "^0.2.3",
"@material-ui/core": "^4.11.0",
@@ -45,7 +45,7 @@
"zen-observable": "^0.8.15"
},
"devDependencies": {
"@backstage/cli": "^0.6.0",
"@backstage/cli": "^0.6.2",
"@types/jest": "^26.0.7",
"@types/node": "^12.0.0"
},
+24
View File
@@ -1,5 +1,29 @@
# @backstage/plugin-api-docs
## 0.4.7
### Patch Changes
- d6593abe6: Remove domain column from `HasSystemsCard` and system from `HasComponentsCard`,
`HasSubcomponentsCard`, and `HasApisCard`.
- 437bac549: Make the description column in the catalog table and api-docs table use up as
much space as possible before hiding overflowing text.
- 5469a9761: Changes made in CatalogTable and ApiExplorerTable for using the OverflowTooltip component for truncating large description and showing tooltip on hover-over.
- Updated dependencies [3a58084b6]
- Updated dependencies [e799e74d4]
- Updated dependencies [d0760ecdf]
- Updated dependencies [1407b34c6]
- Updated dependencies [88f1f1b60]
- Updated dependencies [bad21a085]
- Updated dependencies [9615e68fb]
- Updated dependencies [49f9b7346]
- Updated dependencies [5c2e2863f]
- Updated dependencies [3a58084b6]
- Updated dependencies [2c1f2a7c2]
- @backstage/core@0.6.3
- @backstage/plugin-catalog-react@0.1.0
- @backstage/catalog-model@0.7.2
## 0.4.6
### Patch Changes
+7 -7
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-api-docs",
"version": "0.4.6",
"version": "0.4.7",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -30,9 +30,9 @@
},
"dependencies": {
"@asyncapi/react-component": "^0.18.2",
"@backstage/catalog-model": "^0.7.1",
"@backstage/core": "^0.6.2",
"@backstage/plugin-catalog-react": "^0.0.4",
"@backstage/catalog-model": "^0.7.2",
"@backstage/core": "^0.6.3",
"@backstage/plugin-catalog-react": "^0.1.0",
"@backstage/theme": "^0.2.3",
"@material-icons/font": "^1.0.2",
"@material-ui/core": "^4.11.0",
@@ -49,9 +49,9 @@
"swagger-ui-react": "^3.37.2"
},
"devDependencies": {
"@backstage/cli": "^0.6.1",
"@backstage/dev-utils": "^0.1.11",
"@backstage/test-utils": "^0.1.7",
"@backstage/cli": "^0.6.2",
"@backstage/dev-utils": "^0.1.12",
"@backstage/test-utils": "^0.1.8",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
@@ -99,6 +99,7 @@ const columns: TableColumn<EntityRow>[] = [
placement="bottom-start"
/>
),
width: 'auto',
},
{
title: 'Tags',
@@ -20,6 +20,7 @@ import {
InfoCard,
Link,
Progress,
TableColumn,
WarningPanel,
} from '@backstage/core';
import {
@@ -28,12 +29,20 @@ import {
useRelatedEntities,
} from '@backstage/plugin-catalog-react';
import React from 'react';
import { apiEntityColumns } from './presets';
import { createSpecApiTypeColumn } from './presets';
type Props = {
variant?: 'gridItem';
};
const columns: TableColumn<ApiEntity>[] = [
EntityTable.columns.createEntityRefColumn({ defaultKind: 'API' }),
EntityTable.columns.createOwnerColumn(),
EntityTable.columns.createSpecLifecycleColumn(),
createSpecApiTypeColumn(),
EntityTable.columns.createMetadataDescriptionColumn(),
];
export const HasApisCard = ({ variant = 'gridItem' }: Props) => {
const { entity } = useEntity();
const { entities, loading, error } = useRelatedEntities(entity, {
@@ -73,7 +82,7 @@ export const HasApisCard = ({ variant = 'gridItem' }: Props) => {
</Link>
</div>
}
columns={apiEntityColumns}
columns={columns}
entities={entities as ApiEntity[]}
/>
);
+8
View File
@@ -1,5 +1,13 @@
# @backstage/plugin-app-backend
## 0.3.8
### Patch Changes
- 1c06cb312: Clarify troubleshooting steps for schema serialization issues.
- Updated dependencies [a1f5e6545]
- @backstage/config@0.1.3
## 0.3.7
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-app-backend",
"version": "0.3.7",
"version": "0.3.8",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,7 +31,7 @@
"dependencies": {
"@backstage/backend-common": "^0.5.3",
"@backstage/config-loader": "^0.5.1",
"@backstage/config": "^0.1.2",
"@backstage/config": "^0.1.3",
"@types/express": "^4.17.6",
"express": "^4.17.1",
"express-promise-router": "^3.0.3",
@@ -40,7 +40,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.6.0",
"@backstage/cli": "^0.6.2",
"@types/supertest": "^2.0.8",
"msw": "^0.20.5",
"supertest": "^4.0.2"
+10
View File
@@ -1,5 +1,15 @@
# @backstage/plugin-auth-backend
## 0.3.2
### Patch Changes
- ec504e7b4: Fix for refresh token being lost during Microsoft login.
- Updated dependencies [bad21a085]
- Updated dependencies [a1f5e6545]
- @backstage/catalog-model@0.7.2
- @backstage/config@0.1.3
## 0.3.1
### Patch Changes
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-auth-backend",
"version": "0.3.1",
"version": "0.3.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,8 +31,8 @@
"dependencies": {
"@backstage/backend-common": "^0.5.4",
"@backstage/catalog-client": "^0.3.6",
"@backstage/catalog-model": "^0.7.1",
"@backstage/config": "^0.1.2",
"@backstage/catalog-model": "^0.7.2",
"@backstage/config": "^0.1.3",
"@types/express": "^4.17.6",
"@types/passport": "^1.0.3",
"compression": "^1.7.4",
@@ -66,7 +66,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.6.1",
"@backstage/cli": "^0.6.2",
"@types/body-parser": "^1.19.0",
"@types/cookie-parser": "^1.4.2",
"@types/express-session": "^1.17.2",
@@ -54,12 +54,12 @@ export class GithubAuthProvider implements OAuthHandlers {
},
(
accessToken: any,
refreshToken: any,
_refreshToken: any,
params: any,
fullProfile: any,
done: PassportDoneCallback<OAuthResult>,
) => {
done(undefined, { fullProfile, params, accessToken, refreshToken });
done(undefined, { fullProfile, params, accessToken });
},
);
}
@@ -51,12 +51,12 @@ export class GitlabAuthProvider implements OAuthHandlers {
},
(
accessToken: any,
refreshToken: any,
_refreshToken: any,
params: any,
fullProfile: any,
done: PassportDoneCallback<OAuthResult>,
) => {
done(undefined, { fullProfile, params, accessToken, refreshToken });
done(undefined, { fullProfile, params, accessToken });
},
);
}
@@ -72,7 +72,7 @@ export class MicrosoftAuthProvider implements OAuthHandlers {
fullProfile: passport.Profile,
done: PassportDoneCallback<OAuthResult, PrivateInfo>,
) => {
done(undefined, { fullProfile, accessToken, refreshToken, params });
done(undefined, { fullProfile, accessToken, params }, { refreshToken });
},
);
}
+10
View File
@@ -1,5 +1,15 @@
# @backstage/plugin-catalog-backend
## 0.6.3
### Patch Changes
- 2499f6cde: Add support for assuming role in AWS integrations
- Updated dependencies [bad21a085]
- Updated dependencies [a1f5e6545]
- @backstage/catalog-model@0.7.2
- @backstage/config@0.1.3
## 0.6.2
### Patch Changes
+13
View File
@@ -334,6 +334,19 @@ export interface Config {
}>;
};
/**
* AwsOrganizationCloudAccountProcessor configuration
*/
awsOrganization?: {
provider: {
/**
* The role to be assumed by this processor
*
*/
roleArn?: string;
};
};
/**
* MicrosoftGraphOrgReaderProcessor configuration
*/
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-catalog-backend",
"version": "0.6.2",
"version": "0.6.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,8 +31,8 @@
"dependencies": {
"@azure/msal-node": "^1.0.0-beta.3",
"@backstage/backend-common": "^0.5.4",
"@backstage/catalog-model": "^0.7.1",
"@backstage/config": "^0.1.2",
"@backstage/catalog-model": "^0.7.2",
"@backstage/config": "^0.1.3",
"@backstage/integration": "^0.5.0",
"@octokit/graphql": "^4.5.8",
"@types/express": "^4.17.6",
@@ -59,8 +59,8 @@
"yup": "^0.29.3"
},
"devDependencies": {
"@backstage/cli": "^0.6.1",
"@backstage/test-utils": "^0.1.7",
"@backstage/cli": "^0.6.2",
"@backstage/test-utils": "^0.1.8",
"@types/core-js": "^2.5.4",
"@types/git-url-parse": "^9.0.0",
"@types/lodash": "^4.14.151",
@@ -15,10 +15,14 @@
*/
import { AwsOrganizationCloudAccountProcessor } from './AwsOrganizationCloudAccountProcessor';
import * as winston from 'winston';
describe('AwsOrganizationCloudAccountProcessor', () => {
describe('readLocation', () => {
const processor = new AwsOrganizationCloudAccountProcessor();
const processor = new AwsOrganizationCloudAccountProcessor({
provider: {},
logger: winston.createLogger(),
});
const location = { type: 'aws-cloud-accounts', target: '' };
const emit = jest.fn();
const listAccounts = jest.fn();
@@ -14,11 +14,17 @@
* limitations under the License.
*/
import { LocationSpec, ResourceEntityV1alpha1 } from '@backstage/catalog-model';
import AWS, { Organizations } from 'aws-sdk';
import AWS, { Credentials, Organizations } from 'aws-sdk';
import { Account, ListAccountsResponse } from 'aws-sdk/clients/organizations';
import * as results from './results';
import { CatalogProcessor, CatalogProcessorEmit } from './types';
import { Config } from '@backstage/config';
import { Logger } from 'winston';
import {
AwsOrganizationProviderConfig,
readAwsOrganizationConfig,
} from './awsOrganization/config';
const AWS_ORGANIZATION_REGION = 'us-east-1';
const LOCATION_TYPE = 'aws-cloud-accounts';
@@ -33,9 +39,39 @@ const ORGANIZATION_ANNOTATION: string = 'amazonaws.com/organization-id';
* If custom authentication is needed, it can be achieved by configuring the global AWS.credentials object.
*/
export class AwsOrganizationCloudAccountProcessor implements CatalogProcessor {
logger: Logger;
organizations: Organizations;
constructor() {
provider: AwsOrganizationProviderConfig;
static fromConfig(config: Config, options: { logger: Logger }) {
const c = config.getOptionalConfig('catalog.processors.awsOrganization');
return new AwsOrganizationCloudAccountProcessor({
...options,
provider: c ? readAwsOrganizationConfig(c) : {},
});
}
constructor(options: {
provider: AwsOrganizationProviderConfig;
logger: Logger;
}) {
this.provider = options.provider;
this.logger = options.logger;
let credentials = undefined;
if (
this.provider.roleArn !== undefined &&
AWS.config.credentials instanceof Credentials
) {
credentials = new AWS.ChainableTemporaryCredentials({
masterCredentials: AWS.config.credentials as Credentials,
params: {
RoleSessionName: 'backstage-aws-organization-processor',
RoleArn: this.provider.roleArn,
},
});
}
this.organizations = new AWS.Organizations({
credentials,
region: AWS_ORGANIZATION_REGION,
}); // Only available in us-east-1
}
@@ -0,0 +1,33 @@
/*
* Copyright 2020 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ConfigReader } from '@backstage/config';
import { readAwsOrganizationConfig } from './config';
describe('readAwsOrganizationConfig', () => {
it('applies all of the defaults', () => {
const config = {
provider: {
roleArn: 'aws::arn::foo',
},
};
const actual = readAwsOrganizationConfig(new ConfigReader(config));
const expected = {
roleArn: 'aws::arn::foo',
};
expect(actual).toEqual(expected);
});
});
@@ -14,20 +14,25 @@
* limitations under the License.
*/
import { useApi } from '@backstage/core';
import { catalogApiRef } from '@backstage/plugin-catalog-react';
import { CircularProgress, useTheme } from '@material-ui/core';
import React from 'react';
import { useAsync } from 'react-use';
import { Config } from '@backstage/config';
export const AllServicesCount = () => {
const theme = useTheme();
const catalogApi = useApi(catalogApiRef);
const { value, loading } = useAsync(() => catalogApi.getEntities());
if (loading) {
return <CircularProgress size={theme.spacing(2)} />;
}
return <span>{value ?? length ?? '-'}</span>;
/**
* The configuration parameters for a single AWS Organization Processor
*/
export type AwsOrganizationProviderConfig = {
/**
* The role to assume for the processor.
*/
roleArn?: string;
};
export function readAwsOrganizationConfig(
config: Config,
): AwsOrganizationProviderConfig {
const providerConfig = config.getOptionalConfig('provider');
const roleArn = providerConfig?.getOptionalString('roleArn');
return {
roleArn,
};
}
@@ -60,6 +60,16 @@ export async function createRouter(
res.status(200).json(entities.map(fieldMapper));
})
.post('/entities', async (req, res) => {
/*
* NOTE: THIS METHOD IS DEPRECATED AND NOT RECOMMENDED TO USE
*
* Posting entities to this method has unclear semantics and will not
* properly subject them to limitations, processing, or resolution of
* relations.
*
* It stays around in the service for the time being, but may be
* removed or change semantics at any time without prior notice.
*/
const body = await requireRequestBody(req);
const [result] = await entitiesCatalog.batchAddOrUpdateEntities([
{ entity: body as Entity, relations: [] },
+22
View File
@@ -1,5 +1,27 @@
# @backstage/plugin-catalog-import
## 0.4.2
### Patch Changes
- a8953a9c9: This updates the `catalog-import` plugin to omit the default metadata namespace
field and also use the short form entity reference format for selected group owners.
- 968b588f7: Allows the CodeOwnersProcessor to set the owner automatically within the catalog-import plugin. This adds an additional checkbox that overrides the group selector and will omit the owner option in the generated catalog file yaml.
- Updated dependencies [3a58084b6]
- Updated dependencies [e799e74d4]
- Updated dependencies [d0760ecdf]
- Updated dependencies [1407b34c6]
- Updated dependencies [88f1f1b60]
- Updated dependencies [bad21a085]
- Updated dependencies [9615e68fb]
- Updated dependencies [49f9b7346]
- Updated dependencies [5c2e2863f]
- Updated dependencies [3a58084b6]
- Updated dependencies [2c1f2a7c2]
- @backstage/core@0.6.3
- @backstage/plugin-catalog-react@0.1.0
- @backstage/catalog-model@0.7.2
## 0.4.1
### Patch Changes
+7 -7
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-catalog-import",
"version": "0.4.1",
"version": "0.4.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -30,11 +30,11 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.7.1",
"@backstage/catalog-model": "^0.7.2",
"@backstage/catalog-client": "^0.3.6",
"@backstage/core": "^0.6.2",
"@backstage/core": "^0.6.3",
"@backstage/integration": "^0.5.0",
"@backstage/plugin-catalog-react": "^0.0.4",
"@backstage/plugin-catalog-react": "^0.1.0",
"@backstage/theme": "^0.2.3",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -51,9 +51,9 @@
"yaml": "^1.10.0"
},
"devDependencies": {
"@backstage/cli": "^0.6.1",
"@backstage/dev-utils": "^0.1.11",
"@backstage/test-utils": "^0.1.7",
"@backstage/cli": "^0.6.2",
"@backstage/dev-utils": "^0.1.12",
"@backstage/test-utils": "^0.1.8",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/react-hooks": "^3.3.0",
@@ -15,7 +15,15 @@
*/
import { ConfigApi } from '@backstage/core';
import { Box, StepLabel, TextField, Typography } from '@material-ui/core';
import {
Box,
Checkbox,
FormControlLabel,
FormHelperText,
StepLabel,
TextField,
Typography,
} from '@material-ui/core';
import React from 'react';
import { BackButton } from '../Buttons';
import { StepFinishImportLocation } from '../StepFinishImportLocation';
@@ -167,6 +175,7 @@ export function defaultGenerateStepper(
defaultTitle={title}
defaultBody={body}
renderFormFields={({
values,
control,
errors,
groupsLoading,
@@ -219,22 +228,47 @@ export function defaultGenerateStepper(
required
/>
<AutocompleteTextField
name="owner"
control={control}
errors={errors}
options={groups || []}
loading={groupsLoading}
loadingText="Loading groups…"
helperText="Select an owner from the list or enter a reference to a Group or a User"
errorHelperText="required value"
textFieldProps={{
label: 'Entity Owner',
placeholder: 'Group:default/my-group',
}}
rules={{ required: true }}
required
{!values.useCodeowners && (
<AutocompleteTextField
name="owner"
control={control}
errors={errors}
options={groups || []}
loading={groupsLoading}
loadingText="Loading groups…"
helperText="Select an owner from the list or enter a reference to a Group or a User"
errorHelperText="required value"
textFieldProps={{
label: 'Entity Owner',
placeholder: 'my-group',
}}
rules={{ required: true }}
required
/>
)}
<FormControlLabel
control={
<Checkbox
name="useCodeowners"
inputRef={register}
onChange={(_, value) => {
if (value) {
control.setValue('owner', '');
}
}}
/>
}
label={
<>
Use <em>CODEOWNERS</em> file as Entity Owner
</>
}
/>
<FormHelperText>
WARNING: This may fail is no CODEOWNERS file is found at
the target location.
</FormHelperText>
</>
)}
/>
@@ -21,7 +21,10 @@ import { act, render, RenderResult } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { AnalyzeResult, catalogImportApiRef } from '../../api';
import { StepPrepareCreatePullRequest } from './StepPrepareCreatePullRequest';
import {
generateEntities,
StepPrepareCreatePullRequest,
} from './StepPrepareCreatePullRequest';
describe('<StepPrepareCreatePullRequest />', () => {
const catalogImportApi: jest.Mocked<typeof catalogImportApiRef.T> = {
@@ -60,6 +63,7 @@ describe('<StepPrepareCreatePullRequest />', () => {
kind: 'Component',
metadata: {
name: 'my-component',
namespace: 'default',
},
spec: {
owner: 'my-owner',
@@ -282,6 +286,46 @@ spec:
renderFormFieldsFn.mock.calls[
renderFormFieldsFn.mock.calls.length - 1
][0],
).toMatchObject({ groups: ['Group:my-group'], groupsLoading: false });
).toMatchObject({ groups: ['my-group'], groupsLoading: false });
});
describe('generateEntities', () => {
it.each([[undefined], [null]])(
'should not include blank namespace for %s',
namespace => {
expect(
generateEntities(
[{ metadata: { namespace: namespace as any } }],
'my-component',
'group-1',
),
).toEqual([
expect.objectContaining({
metadata: expect.not.objectContaining({
namespace: 'default',
}),
}),
]);
},
);
it.each([['default'], ['my-namespace']])(
'should include explicit namespace %s',
namespace => {
expect(
generateEntities(
[{ metadata: { namespace } }],
'my-component',
'group-1',
),
).toEqual([
expect.objectContaining({
metadata: expect.objectContaining({
namespace,
}),
}),
]);
},
);
});
});
@@ -14,13 +14,16 @@
* limitations under the License.
*/
import { Entity, serializeEntityRef } from '@backstage/catalog-model';
import { Entity } from '@backstage/catalog-model';
import { useApi } from '@backstage/core';
import { catalogApiRef } from '@backstage/plugin-catalog-react';
import {
catalogApiRef,
formatEntityRefTitle,
} from '@backstage/plugin-catalog-react';
import { Box, FormHelperText, Grid, Typography } from '@material-ui/core';
import { makeStyles } from '@material-ui/core/styles';
import React, { useCallback, useState } from 'react';
import { UseFormMethods } from 'react-hook-form';
import { UnpackNestedValue, UseFormMethods } from 'react-hook-form';
import { useAsync } from 'react-use';
import YAML from 'yaml';
import { AnalyzeResult, catalogImportApiRef } from '../../api';
@@ -45,6 +48,7 @@ type FormData = {
body: string;
componentName: string;
owner: string;
useCodeowners: boolean;
};
type Props = {
@@ -60,16 +64,17 @@ type Props = {
renderFormFields: (
props: Pick<UseFormMethods<FormData>, 'errors' | 'register' | 'control'> & {
values: UnpackNestedValue<FormData>;
groups: string[];
groupsLoading: boolean;
},
) => React.ReactNode;
};
function generateEntities(
export function generateEntities(
entities: PartialEntity[],
componentName: string,
owner: string,
owner?: string,
): Entity[] {
return entities.map(e => ({
...e,
@@ -78,11 +83,10 @@ function generateEntities(
metadata: {
...e.metadata,
name: componentName,
namespace: e.metadata?.namespace ?? 'default',
},
spec: {
...e.spec,
owner,
...(owner ? { owner } : {}),
},
}));
}
@@ -107,8 +111,9 @@ export const StepPrepareCreatePullRequest = ({
filter: { kind: 'group' },
});
// TODO: defaultKind (=group), defaultNamespace (=same as entity)
return groupEntities.items.map(e => serializeEntityRef(e) as string).sort();
return groupEntities.items
.map(e => formatEntityRefTitle(e, { defaultKind: 'group' }))
.sort();
});
const handleResult = useCallback(
@@ -186,10 +191,12 @@ export const StepPrepareCreatePullRequest = ({
(analyzeResult.generatedEntities[0]?.spec?.owner as string) || '',
componentName:
analyzeResult.generatedEntities[0]?.metadata?.name || '',
useCodeowners: false,
}}
render={({ values, errors, control, register }) => (
<>
{renderFormFields({
values,
errors,
register,
control,
+24
View File
@@ -1,5 +1,29 @@
# @backstage/plugin-catalog-react
## 0.1.0
### Minor Changes
- d0760ecdf: Moved common useStarredEntities hook to plugin-catalog-react
### Patch Changes
- 88f1f1b60: Truncate and show ellipsis with tooltip if content of
`createMetadataDescriptionColumn` is too wide.
- 9615e68fb: Forward link styling of `EntityRefLink` and `EnriryRefLinks` into the underling
`Link`.
- 5c2e2863f: Added the proper type parameters to entityRouteRef.
- Updated dependencies [3a58084b6]
- Updated dependencies [e799e74d4]
- Updated dependencies [1407b34c6]
- Updated dependencies [bad21a085]
- Updated dependencies [9615e68fb]
- Updated dependencies [49f9b7346]
- Updated dependencies [3a58084b6]
- Updated dependencies [2c1f2a7c2]
- @backstage/core@0.6.3
- @backstage/catalog-model@0.7.2
## 0.0.4
### Patch Changes
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-catalog-react",
"version": "0.0.4",
"version": "0.1.0",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -29,8 +29,8 @@
},
"dependencies": {
"@backstage/catalog-client": "^0.3.6",
"@backstage/catalog-model": "^0.7.1",
"@backstage/core": "^0.6.2",
"@backstage/catalog-model": "^0.7.2",
"@backstage/core": "^0.6.3",
"@material-ui/core": "^4.11.0",
"@types/react": "^16.9",
"react": "^16.13.1",
@@ -39,9 +39,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.6.1",
"@backstage/dev-utils": "^0.1.11",
"@backstage/test-utils": "^0.1.7",
"@backstage/cli": "^0.6.2",
"@backstage/dev-utils": "^0.1.12",
"@backstage/test-utils": "^0.1.8",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/react-hooks": "^3.3.0",
@@ -26,7 +26,7 @@ export const EntityProvider = ({ entity, children }: EntityProviderProps) => (
<EntityContext.Provider
value={{
entity,
loading: Boolean(entity),
loading: !Boolean(entity),
error: undefined,
}}
>
@@ -20,7 +20,7 @@ import {
RELATION_OWNED_BY,
RELATION_PART_OF,
} from '@backstage/catalog-model';
import { TableColumn } from '@backstage/core';
import { OverflowTooltip, TableColumn } from '@backstage/core';
import React from 'react';
import { getEntityRelations } from '../../utils';
import {
@@ -139,6 +139,12 @@ export function createMetadataDescriptionColumn<
return {
title: 'Description',
field: 'metadata.description',
render: entity => (
<OverflowTooltip
text={entity.metadata.description}
placement="bottom-start"
/>
),
width: 'auto',
};
}
@@ -74,7 +74,7 @@ describe('systemEntityColumns', () => {
expect(getByText('my-namespace/my-system')).toBeInTheDocument();
expect(getByText('my-namespace/my-domain')).toBeInTheDocument();
expect(getByText('Test')).toBeInTheDocument();
expect(getByText('Some description')).toBeInTheDocument();
expect(getByText(/Some/)).toBeInTheDocument();
});
});
});
@@ -131,7 +131,7 @@ describe('componentEntityColumns', () => {
expect(getByText('Test')).toBeInTheDocument();
expect(getByText('production')).toBeInTheDocument();
expect(getByText('service')).toBeInTheDocument();
expect(getByText('Some description')).toBeInTheDocument();
expect(getByText(/Some/)).toBeInTheDocument();
});
});
});
+1
View File
@@ -16,3 +16,4 @@
export { EntityContext, useEntity, useEntityFromUrl } from './useEntity';
export { useEntityCompoundName } from './useEntityCompoundName';
export { useRelatedEntities } from './useRelatedEntities';
export { useStarredEntities } from './useStarredEntities';

Some files were not shown because too many files have changed in this diff Show More