Merge remote-tracking branch 'backstage/master' into erikengervall/grm-minor-corrections

This commit is contained in:
Erik Engervall
2021-05-17 13:26:20 +02:00
291 changed files with 9497 additions and 908 deletions
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/cli': patch
---
Add context for versions:bump on what version it was bumped to. Updated tests for the same.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-explore': patch
---
Add "Organization" tab with a diagram
-7
View File
@@ -1,7 +0,0 @@
---
'@backstage/cli': patch
'@backstage/create-app': patch
'@backstage/plugin-catalog-graphql': patch
---
chore: bump `ts-node` versions to 9.1.1
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/catalog-model': patch
---
Renamed parameters to input in template schema
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-scaffolder-backend': patch
---
The apiBaseUrl setting for Bitbucket Server integrations will now be used when it is set. Otherwise, it will default back to the host setting.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-scaffolder': patch
---
Show error on task page if task does not exist.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-badges-backend': patch
---
Fix generated badge links
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/catalog-model': patch
---
Add the `status` field to the Entity envelope
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/cli': patch
---
update plugins created to use react-use 17.2.4
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/config-loader': patch
---
Updated dependencies
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-org': patch
---
Paginate group members to only display 50 members maximum.
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/plugin-git-release-manager': patch
'@backstage/plugin-ilert': patch
---
[ImgBot] Optimize images
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend': patch
---
Skip adding entries to the `entities_search` table if their `key` exceeds a length limit.
-7
View File
@@ -1,7 +0,0 @@
---
'@backstage/core': patch
'@backstage/plugin-api-docs': patch
---
Fix state persisted in the URL make search input in the table toolbar lose their
focus.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/catalog-model': patch
---
Improve error messages when schema validation fails
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-scaffolder-backend': patch
---
Move `jest-when` to the dev dependencies
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/core': patch
---
Add count of older messages when multiple messages exist in AlertDisplay
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-techdocs': patch
---
Bug fix on sidebar position when Tab-Bar is enabled
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-github-deployments': patch
---
Support GHE by properly parsing enterprise instance hosts
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-techdocs': patch
---
Handle URLs with a `#hash` correctly when rewriting link URLs.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/techdocs-common': patch
---
Fixed a bug that prevented loading static assets from GCS, S3, Azure, and OpenStackSwift whose keys contain spaces or other special characters.
-44
View File
@@ -1,44 +0,0 @@
---
'@backstage/core': patch
'@backstage/core-api': patch
'@backstage/integration-react': patch
'@backstage/plugin-api-docs': patch
'@backstage/plugin-badges': patch
'@backstage/plugin-bitrise': patch
'@backstage/plugin-catalog': patch
'@backstage/plugin-catalog-import': patch
'@backstage/plugin-catalog-react': patch
'@backstage/plugin-circleci': patch
'@backstage/plugin-cloudbuild': patch
'@backstage/plugin-code-coverage': patch
'@backstage/plugin-config-schema': patch
'@backstage/plugin-cost-insights': patch
'@backstage/plugin-explore': patch
'@backstage/plugin-fossa': patch
'@backstage/plugin-gcp-projects': patch
'@backstage/plugin-github-actions': patch
'@backstage/plugin-github-deployments': patch
'@backstage/plugin-gitops-profiles': patch
'@backstage/plugin-graphiql': patch
'@backstage/plugin-jenkins': patch
'@backstage/plugin-kafka': patch
'@backstage/plugin-kubernetes': patch
'@backstage/plugin-lighthouse': patch
'@backstage/plugin-newrelic': patch
'@backstage/plugin-org': patch
'@backstage/plugin-pagerduty': patch
'@backstage/plugin-register-component': patch
'@backstage/plugin-rollbar': patch
'@backstage/plugin-scaffolder': patch
'@backstage/plugin-search': patch
'@backstage/plugin-sentry': patch
'@backstage/plugin-sonarqube': patch
'@backstage/plugin-splunk-on-call': patch
'@backstage/plugin-tech-radar': patch
'@backstage/plugin-techdocs': patch
'@backstage/plugin-todo': patch
'@backstage/plugin-user-settings': patch
'@backstage/plugin-welcome': patch
---
chore: bump `react-use` dependency in all packages
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-kubernetes-backend': patch
---
Add possibility to configure TLS verification for `gke` type clusters
+1
View File
@@ -16,6 +16,7 @@
/plugins/search-* @backstage/techdocs-core
/plugins/techdocs @backstage/techdocs-core
/plugins/techdocs-backend @backstage/techdocs-core
/plugins/ilert @yacut
/packages/search-common @backstage/techdocs-core
/packages/techdocs-common @backstage/techdocs-core
/.changeset/cost-insights-* @backstage/silver-lining
+2
View File
@@ -167,6 +167,7 @@ mailto
maintainership
makefile
md
memcache
microsite
middleware
minikube
@@ -177,6 +178,7 @@ mkdocs
monorepo
monorepos
msw
mysql
namespace
namespaced
namespaces
+1
View File
@@ -0,0 +1 @@
_
+4
View File
@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
yarn lint-staged
+1 -1
View File
@@ -27,5 +27,5 @@ People that have made significant contributions to the project and earned write
- Andrew Thauer - Wealthsimple (GitHub: [andrewthauer](https://github.com/andrewthauer))
- Oliver Sand - SDA SE (GitHub: [Fox32](https://github.com/Fox32))
- David Tuite - Roadie (GitHub: [dtuite](https://github.com/dtuite))
- Adam Harvey - DXC Technology (GitHub: [adamdmharvey](https://github.com/adamdmharvey))
- Adam Harvey - Cisco (GitHub: [adamdmharvey](https://github.com/adamdmharvey))
- Dominik Henneke - SDA SE (GitHub: [dhenneke](https://github.com/dhenneke))
+7
View File
@@ -81,6 +81,13 @@ proxy:
headers:
Authorization: ${SENTRY_TOKEN}
'/ilert':
target: https://api.ilert.com
allowedMethods: ['GET', 'POST', 'PUT']
allowedHeaders: ['Authorization']
headers:
Authorization: ${ILERT_AUTH_HEADER}
organization:
name: My Company
@@ -23,6 +23,7 @@ we recommend that you name them `catalog-info.yaml`.
- [Common to All Kinds: The Envelope](#common-to-all-kinds-the-envelope)
- [Common to All Kinds: The Metadata](#common-to-all-kinds-the-metadata)
- [Common to All Kinds: Relations](#common-to-all-kinds-relations)
- [Common to All Kinds: Status](#common-to-all-kinds-status)
- [Kind: Component](#kind-component)
- [Kind: Template](#kind-template)
- [Kind: API](#kind-api)
@@ -396,6 +397,54 @@ with it (such as the default kind being `Group` if not specified).
See the [well-known relations section](well-known-relations.md) for a list of
well-known / common relations and their semantics.
## Common to All Kinds: Status
The `status` root field is a read-only set of statuses, pertaining to the
current state or health of the entity, described in the
[well-known statuses section](well-known-statuses.md). Each status field
contains a specific blob of data that describes some aspect of the state of the
entity, as seen from the point of view of some specific system. Different
systems may contribute to this status object, under their own respective keys.
The current main use case for this field is for the ingestion processes of the
catalog itself to convey information about failures and warnings back to the
user.
A status field as part of a single entity that's read out of the API may look as
follows.
```js
{
// ...
"status": {
"backstage.io/catalog-processing": {
"errors": []
}
},
"spec": {
// ...
}
}
```
The keys of the `status` object are arbitrary strings. We recommend that any
statuses that are not strictly private within the organization be namespaced to
avoid collisions. Statuses emitted by Backstage core processes will for example
be prefixed with `backstage.io/` as in the example above.
The values of the `status` object are currently left unrestricted, except that
they must be objects. We reserve the right to extend this model in the future,
such that some fields of those value objects gain standardized meaning. We may
for example want to add a standard concept of "severity" or "level" to these.
Entity descriptor YAML files are not supposed to contain this field. Instead,
catalog processors analyze the entity descriptor data and its surroundings, and
deduce status entries that are then attached onto the entity as read from the
catalog.
See the [well-known statuses section](well-known-statuses.md) for a list of
well-known / common relations and their semantics.
## Kind: Component
Describes the following entity kind:
@@ -1,6 +1,7 @@
---
id: extending-the-model
title: Extending the model
# prettier-ignore
description: Documentation on extending the catalog model
---
@@ -301,9 +302,9 @@ Example intents:
> "We have this concept of service maintainership, separate from ownership, that
> we would like to make relations to individual users for."
> We feel that we want to explicitly model the team-to-global-department mapping
> as a relation, because it is core to our org setup and we frequently query for
> it.
> "We feel that we want to explicitly model the team-to-global-department
> mapping as a relation, because it is core to our org setup and we frequently
> query for it."
Any processor can emit relations for entities as they are being processed, and
new processors can be added when building the backend catalog using the
@@ -349,3 +350,21 @@ If you want to extend the use of an established relation type in a way that has
an effect outside of your organization, reach out to the Backstage maintainers
or a support partner to discuss risk/impact. It may even be that one end of the
relation could be considered for addition to the core.
## Adding a New Status field
Example intents:
> "We would like to convey entity statuses through the catalog in a generic way,
> as an integration layer. Our monitoring and alerting system has a plugin with
> Backstage, and it would be useful if the entity's status field contained the
> current alert state close to the actual entity data for anyone to consume.
While we are considering a mechanism for contributing generic statuses to
entities, no such mechanism has yet been built. If you are interested in that
topic, [this issue](https://github.com/backstage/backstage/issues/2292) contains
more context.
But in general, errors emitted (and exceptions thrown) by any processor
including custom ones, end up in the [well known key](well-known-statuses.md)
for ingestion status.
@@ -0,0 +1,51 @@
---
id: well-known-statuses
title: Well-known Status fields of Catalog Entities
sidebar_label: Well-known Statuses
# prettier-ignore
description: Lists a number of well known entity statuses, that have defined semantics. They can be attached to catalog entities and consumed by plugins as needed.
---
This section lists a number of well known
[entity status fields](descriptor-format.md#common-to-all-kinds-status), that
have defined semantics. They can be attached to catalog entities and consumed by
plugins as needed.
If you are looking to extend the set of statuses, see
[Extending the model](extending-the-model.md).
## Common Fields
The values of statuses are currently left unrestricted, except that they must be
objects. They therefore currently formally have no common fields.
We reserve the right to extend this model in the future, such that some fields
of those value objects gain standardized meaning. We may for example want to add
a standard concept of "severity" or "level" to these.
## Statuses
This is a (non-exhaustive) list of statuses that are known to be in active use.
### `backstage.io/catalog-processing`
Contains the current status of the catalog's ingestion of this entity. Errors
that may appear here include inability to read from the remote SCM provider,
syntax errors in the YAML file, and similar.
Note that the entity data itself may be of an older version, when errors are
present. The ingestion system keeps the old, valid entity data untouched when
possible, so the errors described in this state may not seem to align with the
rest of the entity, because they pertain to a remote that could not be
successfully ingested. This is normal.
```yaml
# Example:
status:
backstage.io/catalog-processing:
errors: []
```
This status is in active development and its format will change unexpectedly. Do
not consume it in your own code until such a time that this documentation has
been updated.
+15
View File
@@ -0,0 +1,15 @@
---
title: iLert
author: iLert
authorUrl: https://www.ilert.com
category: Monitoring
description: iLert is a platform for alerting, on-call management and uptime monitoring targeted at DevOps and IT teams.
documentation: https://github.com/backstage/backstage/tree/master/plugins/ilert
iconUrl: https://avatars.githubusercontent.com/u/13230510?s=200&v=4
npmPackageName: '@backstage/plugin-ilert'
tags:
- monitoring
- errors
- alerting
- uptime
- on-call
+1
View File
@@ -40,6 +40,7 @@
"features/software-catalog/references",
"features/software-catalog/well-known-annotations",
"features/software-catalog/well-known-relations",
"features/software-catalog/well-known-statuses",
"features/software-catalog/extending-the-model",
"features/software-catalog/external-integrations",
"features/software-catalog/software-catalog-api"
@@ -1,13 +1 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="500px" height="500px" viewBox="0 0 500 500" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Export</title>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="ship" transform="translate(249.680798, 211.000000) scale(-1, 1) translate(-249.680798, -211.000000) translate(35.680798, -39.000000)" fill-rule="nonzero">
<g id="Flamez" transform="translate(279.925187, 455.280081) rotate(-90.000000) translate(-279.925187, -455.280081) translate(235.660848, 411.639183)">
<path d="M77.6240648,9.79348504 C64.5660848,-3.26449501 42.8017456,-3.26449501 29.7437656,9.79348504 C11.6072319,27.9300187 0.725685786,80.8882481 8.85963511e-15,83.064682 C8.85963511e-15,84.5154302 8.85963511e-15,85.241116 0.725685786,85.9668017 C2.17643392,86.6924875 3.62780549,86.6924875 5.07855362,86.6924875 C7.25498753,85.9668017 60.213217,75.810318 78.3497506,56.9487219 C91.4077307,43.8901185 91.4077307,22.8514651 77.6240648,9.79348504 Z" id="Path" fill="#F79548"></path>
<path d="M75.4476309,10.5185474 C68.9183292,3.98924564 58.036783,3.98924564 51.5074813,10.5185474 C42.0766833,19.9493454 36.9981297,46.0659289 36.9981297,46.7916147 C36.9981297,47.5173005 36.9981297,48.2423628 37.7238155,48.2423628 C38.4495012,48.9680486 38.4495012,48.9680486 39.1745636,48.9680486 C40.6253117,48.9680486 66.7418953,43.1644327 75.4476309,34.458697 C81.9769327,27.9300187 81.9769327,17.0478491 75.4476309,10.5185474 Z" id="Path" fill="#FCBB76"></path>
</g>
<path d="M216.186409,55.2394015 C218.49257,55.2394015 220.58047,56.1742348 222.091833,57.6855981 C223.534498,59.128263 224.451854,61.0962436 224.532269,63.2779325 L224.53803,63.5910224 L224.53803,91.005836 L353.369587,261.704121 C354.323776,262.968115 354.87911,264.447677 355.019478,265.965658 C355.159883,267.484039 354.88511,269.040862 354.179061,270.458806 C353.472845,271.876805 352.395871,273.033852 351.099552,273.836436 C349.895645,274.581806 348.502551,275.021453 347.041547,275.080457 L346.703242,275.087282 L224.53803,275.087282 L224.53803,303.904613 L346.684539,303.904613 C348.308638,303.904613 349.858968,304.375354 351.174692,305.21426 C352.490519,306.053232 353.571696,307.260417 354.25731,308.732969 C354.942424,310.205367 355.16974,311.809443 354.964363,313.356104 C354.77365,314.792333 354.20983,316.179047 353.29311,317.364769 L353.075304,317.634761 L309.451382,369.468132 C307.930114,371.274871 305.719044,372.349921 303.368443,372.436371 L303.061097,372.44202 L124.602244,372.44202 C122.240117,372.44202 119.994057,371.442358 118.41433,369.699238 L118.212103,369.467679 L74.5886595,317.634759 C73.5428392,316.392134 72.9047814,314.903039 72.6994228,313.356514 C72.494029,311.809724 72.7214803,310.205497 73.4066556,308.732969 C74.0917295,307.260659 75.1726391,306.053772 76.4882065,305.214939 C77.7099169,304.435952 79.1339993,303.974371 80.6313862,303.912406 L80.9781796,303.905237 L207.834788,303.905237 L207.834788,274.720698 L106.28616,274.720698 C103.979999,274.720698 101.892098,273.785865 100.380735,272.274502 C98.8693719,270.763138 97.9345387,268.675238 97.9345387,266.369077 C97.9345387,233.249109 111.496611,180.759139 130.891816,138.720038 C142.0216,114.595575 154.255888,95.1994886 167.266567,81.0803824 C183.02715,63.976526 199.471354,55.2394015 216.186409,55.2394015 Z M328.739655,320.607855 L98.9224399,320.607855 L128.488453,355.738155 L299.173642,355.738155 L328.739655,320.607855 Z M224.53803,118.732589 L224.53803,258.384663 L329.936488,258.384663 L224.53803,118.732589 Z M207.834165,73.0839035 C187.31365,78.5957312 165.169959,104.292863 146.058313,145.71761 C129.135086,182.399574 116.887708,227.020442 114.917014,258.016833 L114.917014,258.016833 L207.834165,258.016833 Z" id="Shape" stroke="#DDDDDD" stroke-width="2" fill="#E8E8E8" transform="translate(213.840829, 213.840711) rotate(45.000000) translate(-213.840829, -213.840711) "></path>
</g>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="500" height="500" version="1.1" viewBox="0 0 500 500"><title>Export</title><g id="Page-1" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="ship" fill-rule="nonzero" transform="translate(249.680798, 211.000000) scale(-1, 1) translate(-249.680798, -211.000000) translate(35.680798, -39.000000)"><g id="Flamez" transform="translate(279.925187, 455.280081) rotate(-90.000000) translate(-279.925187, -455.280081) translate(235.660848, 411.639183)"><path id="Path" fill="#F79548" d="M77.6240648,9.79348504 C64.5660848,-3.26449501 42.8017456,-3.26449501 29.7437656,9.79348504 C11.6072319,27.9300187 0.725685786,80.8882481 8.85963511e-15,83.064682 C8.85963511e-15,84.5154302 8.85963511e-15,85.241116 0.725685786,85.9668017 C2.17643392,86.6924875 3.62780549,86.6924875 5.07855362,86.6924875 C7.25498753,85.9668017 60.213217,75.810318 78.3497506,56.9487219 C91.4077307,43.8901185 91.4077307,22.8514651 77.6240648,9.79348504 Z"/><path id="Path" fill="#FCBB76" d="M75.4476309,10.5185474 C68.9183292,3.98924564 58.036783,3.98924564 51.5074813,10.5185474 C42.0766833,19.9493454 36.9981297,46.0659289 36.9981297,46.7916147 C36.9981297,47.5173005 36.9981297,48.2423628 37.7238155,48.2423628 C38.4495012,48.9680486 38.4495012,48.9680486 39.1745636,48.9680486 C40.6253117,48.9680486 66.7418953,43.1644327 75.4476309,34.458697 C81.9769327,27.9300187 81.9769327,17.0478491 75.4476309,10.5185474 Z"/></g><path id="Shape" fill="#E8E8E8" stroke="#DDD" stroke-width="2" d="M216.186409,55.2394015 C218.49257,55.2394015 220.58047,56.1742348 222.091833,57.6855981 C223.534498,59.128263 224.451854,61.0962436 224.532269,63.2779325 L224.53803,63.5910224 L224.53803,91.005836 L353.369587,261.704121 C354.323776,262.968115 354.87911,264.447677 355.019478,265.965658 C355.159883,267.484039 354.88511,269.040862 354.179061,270.458806 C353.472845,271.876805 352.395871,273.033852 351.099552,273.836436 C349.895645,274.581806 348.502551,275.021453 347.041547,275.080457 L346.703242,275.087282 L224.53803,275.087282 L224.53803,303.904613 L346.684539,303.904613 C348.308638,303.904613 349.858968,304.375354 351.174692,305.21426 C352.490519,306.053232 353.571696,307.260417 354.25731,308.732969 C354.942424,310.205367 355.16974,311.809443 354.964363,313.356104 C354.77365,314.792333 354.20983,316.179047 353.29311,317.364769 L353.075304,317.634761 L309.451382,369.468132 C307.930114,371.274871 305.719044,372.349921 303.368443,372.436371 L303.061097,372.44202 L124.602244,372.44202 C122.240117,372.44202 119.994057,371.442358 118.41433,369.699238 L118.212103,369.467679 L74.5886595,317.634759 C73.5428392,316.392134 72.9047814,314.903039 72.6994228,313.356514 C72.494029,311.809724 72.7214803,310.205497 73.4066556,308.732969 C74.0917295,307.260659 75.1726391,306.053772 76.4882065,305.214939 C77.7099169,304.435952 79.1339993,303.974371 80.6313862,303.912406 L80.9781796,303.905237 L207.834788,303.905237 L207.834788,274.720698 L106.28616,274.720698 C103.979999,274.720698 101.892098,273.785865 100.380735,272.274502 C98.8693719,270.763138 97.9345387,268.675238 97.9345387,266.369077 C97.9345387,233.249109 111.496611,180.759139 130.891816,138.720038 C142.0216,114.595575 154.255888,95.1994886 167.266567,81.0803824 C183.02715,63.976526 199.471354,55.2394015 216.186409,55.2394015 Z M328.739655,320.607855 L98.9224399,320.607855 L128.488453,355.738155 L299.173642,355.738155 L328.739655,320.607855 Z M224.53803,118.732589 L224.53803,258.384663 L329.936488,258.384663 L224.53803,118.732589 Z M207.834165,73.0839035 C187.31365,78.5957312 165.169959,104.292863 146.058313,145.71761 C129.135086,182.399574 116.887708,227.020442 114.917014,258.016833 L114.917014,258.016833 L207.834165,258.016833 Z" transform="translate(213.840829, 213.840711) rotate(45.000000) translate(-213.840829, -213.840711)"/></g></g></svg>

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

+1
View File
@@ -37,6 +37,7 @@ nav:
- Entity References: 'features/software-catalog/references.md'
- Well-known Annotations: 'features/software-catalog/well-known-annotations.md'
- Well-known Relations: 'features/software-catalog/well-known-relations.md'
- Well-known Statuses: 'features/software-catalog/well-known-statuses.md'
- Extending the model: 'features/software-catalog/extending-the-model.md'
- External integrations: 'features/software-catalog/external-integrations.md'
- API: 'features/software-catalog/api.md'
+3 -7
View File
@@ -30,7 +30,8 @@
"prettier:check": "prettier --check .",
"lerna": "lerna",
"storybook": "yarn workspace storybook start",
"build-storybook": "yarn workspace storybook build-storybook"
"build-storybook": "yarn workspace storybook build-storybook",
"prepare": "husky install"
},
"workspaces": {
"packages": [
@@ -60,18 +61,13 @@
"command-exists": "^1.2.9",
"concurrently": "^6.0.0",
"fs-extra": "^9.0.0",
"husky": "^4.2.3",
"husky": "^6.0.0",
"lerna": "^4.0.0",
"lint-staged": "^10.1.0",
"prettier": "^2.2.1",
"recursive-readdir": "^2.2.2",
"shx": "^0.3.2"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"prettier": "@spotify/prettier-config",
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
+52
View File
@@ -1,5 +1,57 @@
# example-app
## 0.2.28
### Patch Changes
- Updated dependencies [062bbf90f]
- Updated dependencies [2cd70e164]
- Updated dependencies [0b033d07b]
- Updated dependencies [3be844496]
- Updated dependencies [5542de095]
- Updated dependencies [10c008a3a]
- Updated dependencies [81ef1d57b]
- Updated dependencies [ea21d46f0]
- Updated dependencies [e3fc89df6]
- Updated dependencies [f59a945b7]
- Updated dependencies [889d89b6e]
- Updated dependencies [16be1d093]
- Updated dependencies [3f988cb63]
- Updated dependencies [675a569a9]
- @backstage/core@0.7.9
- @backstage/integration-react@0.1.2
- @backstage/plugin-api-docs@0.4.13
- @backstage/plugin-badges@0.2.1
- @backstage/plugin-catalog@0.5.7
- @backstage/plugin-catalog-import@0.5.6
- @backstage/plugin-catalog-react@0.1.6
- @backstage/plugin-circleci@0.2.14
- @backstage/plugin-cloudbuild@0.2.14
- @backstage/plugin-code-coverage@0.1.3
- @backstage/plugin-cost-insights@0.9.1
- @backstage/plugin-explore@0.3.5
- @backstage/plugin-gcp-projects@0.2.6
- @backstage/plugin-github-actions@0.4.6
- @backstage/plugin-graphiql@0.2.11
- @backstage/plugin-jenkins@0.4.3
- @backstage/plugin-kafka@0.2.7
- @backstage/plugin-kubernetes@0.4.4
- @backstage/plugin-lighthouse@0.2.16
- @backstage/plugin-newrelic@0.2.7
- @backstage/plugin-org@0.3.13
- @backstage/plugin-pagerduty@0.3.4
- @backstage/plugin-rollbar@0.3.5
- @backstage/plugin-scaffolder@0.9.4
- @backstage/plugin-search@0.3.6
- @backstage/plugin-sentry@0.3.10
- @backstage/plugin-shortcuts@0.1.2
- @backstage/plugin-tech-radar@0.3.11
- @backstage/plugin-techdocs@0.9.2
- @backstage/plugin-todo@0.1.1
- @backstage/plugin-user-settings@0.2.10
- @backstage/cli@0.6.11
- @backstage/catalog-model@0.7.9
## 0.2.27
### Patch Changes
+36 -36
View File
@@ -1,42 +1,42 @@
{
"name": "example-app",
"version": "0.2.27",
"version": "0.2.28",
"private": true,
"bundled": true,
"dependencies": {
"@backstage/catalog-model": "^0.7.8",
"@backstage/cli": "^0.6.10",
"@backstage/core": "^0.7.8",
"@backstage/integration-react": "^0.1.1",
"@backstage/plugin-api-docs": "^0.4.12",
"@backstage/plugin-badges": "^0.2.0",
"@backstage/plugin-catalog": "^0.5.6",
"@backstage/plugin-catalog-import": "^0.5.5",
"@backstage/plugin-catalog-react": "^0.1.5",
"@backstage/plugin-circleci": "^0.2.13",
"@backstage/plugin-cloudbuild": "^0.2.13",
"@backstage/plugin-code-coverage": "^0.1.2",
"@backstage/plugin-cost-insights": "^0.9.0",
"@backstage/plugin-explore": "^0.3.4",
"@backstage/plugin-gcp-projects": "^0.2.5",
"@backstage/plugin-github-actions": "^0.4.5",
"@backstage/plugin-graphiql": "^0.2.10",
"@backstage/plugin-jenkins": "^0.4.2",
"@backstage/plugin-kafka": "^0.2.6",
"@backstage/plugin-kubernetes": "^0.4.3",
"@backstage/plugin-lighthouse": "^0.2.15",
"@backstage/plugin-newrelic": "^0.2.6",
"@backstage/plugin-org": "^0.3.12",
"@backstage/plugin-pagerduty": "0.3.3",
"@backstage/plugin-rollbar": "^0.3.4",
"@backstage/plugin-scaffolder": "^0.9.3",
"@backstage/plugin-search": "^0.3.5",
"@backstage/plugin-sentry": "^0.3.9",
"@backstage/plugin-shortcuts": "^0.1.1",
"@backstage/plugin-tech-radar": "^0.3.10",
"@backstage/plugin-techdocs": "^0.9.1",
"@backstage/plugin-todo": "^0.1.0",
"@backstage/plugin-user-settings": "^0.2.8",
"@backstage/catalog-model": "^0.7.9",
"@backstage/cli": "^0.6.11",
"@backstage/core": "^0.7.9",
"@backstage/integration-react": "^0.1.2",
"@backstage/plugin-api-docs": "^0.4.13",
"@backstage/plugin-badges": "^0.2.1",
"@backstage/plugin-catalog": "^0.5.7",
"@backstage/plugin-catalog-import": "^0.5.6",
"@backstage/plugin-catalog-react": "^0.1.6",
"@backstage/plugin-circleci": "^0.2.14",
"@backstage/plugin-cloudbuild": "^0.2.14",
"@backstage/plugin-code-coverage": "^0.1.3",
"@backstage/plugin-cost-insights": "^0.9.1",
"@backstage/plugin-explore": "^0.3.5",
"@backstage/plugin-gcp-projects": "^0.2.6",
"@backstage/plugin-github-actions": "^0.4.6",
"@backstage/plugin-graphiql": "^0.2.11",
"@backstage/plugin-jenkins": "^0.4.3",
"@backstage/plugin-kafka": "^0.2.7",
"@backstage/plugin-kubernetes": "^0.4.4",
"@backstage/plugin-lighthouse": "^0.2.16",
"@backstage/plugin-newrelic": "^0.2.7",
"@backstage/plugin-org": "^0.3.13",
"@backstage/plugin-pagerduty": "0.3.4",
"@backstage/plugin-rollbar": "^0.3.5",
"@backstage/plugin-scaffolder": "^0.9.4",
"@backstage/plugin-search": "^0.3.6",
"@backstage/plugin-sentry": "^0.3.10",
"@backstage/plugin-shortcuts": "^0.1.2",
"@backstage/plugin-tech-radar": "^0.3.11",
"@backstage/plugin-techdocs": "^0.9.2",
"@backstage/plugin-todo": "^0.1.1",
"@backstage/plugin-user-settings": "^0.2.10",
"@backstage/theme": "^0.2.7",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -56,11 +56,11 @@
"zen-observable": "^0.8.15"
},
"devDependencies": {
"@backstage/test-utils": "^0.1.10",
"@backstage/test-utils": "^0.1.11",
"@testing-library/cypress": "^7.0.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^12.0.7",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/jquery": "^3.3.34",
"@types/node": "^14.14.32",
+57
View File
@@ -1,5 +1,62 @@
# @backstage/backend-common
## 0.8.0
### Minor Changes
- 22fd8ce2a: Introducing: a standard API for App Integrators to configure cache stores and Plugin Developers to interact with them.
Two cache stores are currently supported.
- `memory`, which is a very simple in-memory key/value store, intended for local development.
- `memcache`, which can be used to connect to a memcache host.
Configuring and working with cache stores is very similar to the process for database connections.
```yaml
backend:
cache:
store: memcache
connection: user:pass@cache.example.com:11211
```
```typescript
import { CacheManager } from '@backstage/backend-common';
// Instantiating a cache client for a plugin.
const cacheManager = CacheManager.fromConfig(config);
const somePluginCache = cacheManager.forPlugin('somePlugin');
const cacheClient = somePluginCache.getClient();
// Using the cache client:
const cachedValue = await cacheClient.get('someKey');
if (cachedValue) {
return cachedValue;
} else {
const someValue = await someExpensiveProcess();
await cacheClient.set('someKey', someValue);
}
await cacheClient.delete('someKey');
```
Cache clients deal with TTLs in milliseconds. A TTL can be provided as a defaultTtl when getting a client, or may be passed when setting specific objects. If no TTL is provided, data will be persisted indefinitely.
```typescript
// Getting a client with a default TTL
const cacheClient = somePluginCache.getClient({
defaultTtl: 3600000,
});
// Setting a TTL on a per-object basis.
cacheClient.set('someKey', data, { ttl: 3600000 });
```
Configuring a cache store is optional. Even when no cache store is configured, the cache manager will dutifully pass plugins a manager that resolves a cache client that does not actually write or read any data.
### Patch Changes
- f9fb4a205: Prep work for mysql support in backend-common
## 0.7.0
### Minor Changes
+19
View File
@@ -16,6 +16,7 @@ import { GithubCredentialsProvider } from '@backstage/integration';
import { GitHubIntegration } from '@backstage/integration';
import { GitLabIntegration } from '@backstage/integration';
import * as http from 'http';
import { JsonValue } from '@backstage/config';
import { Knex } from 'knex';
import { Logger } from 'winston';
import { MergeResult } from 'isomorphic-git';
@@ -62,6 +63,19 @@ export class BitbucketUrlReader implements UrlReader {
toString(): string;
}
// @public
export interface CacheClient {
delete(key: string): Promise<void>;
get(key: string): Promise<JsonValue | undefined>;
set(key: string, value: JsonValue, options?: CacheSetOptions): Promise<void>;
}
// @public
export class CacheManager {
forPlugin(pluginId: string): PluginCacheManager;
static fromConfig(config: Config): CacheManager;
}
// @public (undocumented)
export const coloredFormat: winston.Logform.Format;
@@ -238,6 +252,11 @@ export function loadBackendConfig(options: Options): Promise<Config>;
// @public
export function notFoundHandler(): RequestHandler;
// @public
export type PluginCacheManager = {
getClient: (options?: ClientOptions) => CacheClient;
};
// @public
export interface PluginDatabaseManager {
getClient(): Promise<Knex>;
+14
View File
@@ -68,6 +68,20 @@ export interface Config {
connection: string | object;
};
/** Cache connection configuration, select cache type using the `store` field */
cache?:
| {
store: 'memory';
}
| {
store: 'memcache';
/**
* A memcache connection string in the form `user:pass@host:port`.
* @secret
*/
connection: string;
};
cors?: {
origin?: string | string[];
methods?: string | string[];
+8 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-common",
"description": "Common functionality library for Backstage backends",
"version": "0.7.0",
"version": "0.8.0",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -51,6 +51,8 @@
"git-url-parse": "^11.4.4",
"helmet": "^4.0.0",
"isomorphic-git": "^1.8.0",
"keyv": "^4.0.3",
"keyv-memcache": "^1.2.5",
"knex": "^0.95.1",
"lodash": "^4.17.15",
"logform": "^2.1.1",
@@ -62,7 +64,8 @@
"stoppable": "^1.1.0",
"tar": "^6.0.5",
"unzipper": "^0.10.11",
"winston": "^3.2.1"
"winston": "^3.2.1",
"yn": "^4.0.0"
},
"peerDependencies": {
"pg-connection-string": "^2.3.0"
@@ -73,8 +76,8 @@
}
},
"devDependencies": {
"@backstage/cli": "^0.6.10",
"@backstage/test-utils": "^0.1.10",
"@backstage/cli": "^0.6.11",
"@backstage/test-utils": "^0.1.11",
"@types/archiver": "^5.1.0",
"@types/compression": "^1.7.0",
"@types/concat-stream": "^1.6.0",
@@ -94,6 +97,7 @@
"jest": "^26.0.1",
"mock-fs": "^4.13.0",
"msw": "^0.21.2",
"mysql2": "^2.2.5",
"recursive-readdir": "^2.2.2",
"supertest": "^6.1.3"
},
+126
View File
@@ -0,0 +1,126 @@
/*
* Copyright 2021 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { DefaultCacheClient } from './CacheClient';
import Keyv from 'keyv';
describe('CacheClient', () => {
let client: Keyv;
const b64 = (k: string) => Buffer.from(k).toString('base64');
beforeEach(() => {
client = new Keyv();
client.get = jest.fn();
client.set = jest.fn();
client.delete = jest.fn();
});
afterEach(() => jest.resetAllMocks());
describe('CacheClient.get', () => {
it('calls client with normalized key', async () => {
const sut = new DefaultCacheClient({ client });
const key = 'somekey';
await sut.get(key);
expect(client.get).toHaveBeenCalledWith(b64(key));
});
it('calls client with normalized key (very long key)', async () => {
const sut = new DefaultCacheClient({ client });
const key = 'x'.repeat(251);
await sut.get(key);
const spy = client.get as jest.Mock;
const actualKey = spy.mock.calls[0][0];
expect(actualKey).not.toEqual(b64(key));
expect(actualKey.length).toBeLessThan(250);
});
it('rejects on underlying error', async () => {
const sut = new DefaultCacheClient({ client });
const expectedError = new Error('Some runtime error');
client.get = jest.fn().mockRejectedValue(expectedError);
return expect(sut.get('someKey')).rejects.toEqual(expectedError);
});
it('resolves what underlying client resolves', async () => {
const sut = new DefaultCacheClient({ client });
const expectedValue = 'some value';
client.get = jest.fn().mockResolvedValue(expectedValue);
const actualValue = await sut.get('someKey');
return expect(actualValue).toEqual(expectedValue);
});
});
describe('CacheClient.set', () => {
it('calls client with normalized key', async () => {
const sut = new DefaultCacheClient({ client });
const key = 'somekey';
await sut.set(key, {});
const spy = client.set as jest.Mock;
const actualKey = spy.mock.calls[0][0];
expect(actualKey).toEqual(b64(key));
});
it('passes ttl to client when given', async () => {
const sut = new DefaultCacheClient({ client });
const expectedTtl = 3600;
await sut.set('someKey', {}, { ttl: expectedTtl });
const spy = client.set as jest.Mock;
const actualTtl = spy.mock.calls[0][2];
expect(actualTtl).toEqual(expectedTtl);
});
it('rejects on underlying error if configured', async () => {
const sut = new DefaultCacheClient({ client });
const expectedError = new Error('Some runtime error');
client.set = jest.fn().mockRejectedValue(expectedError);
return expect(sut.set('someKey', {})).rejects.toEqual(expectedError);
});
});
describe('CacheClient.delete', () => {
it('calls client with normalized key', async () => {
const sut = new DefaultCacheClient({ client });
const key = 'somekey';
await sut.delete(key);
const spy = client.delete as jest.Mock;
const actualKey = spy.mock.calls[0][0];
expect(actualKey).toEqual(b64(key));
});
it('rejects on underlying error if configured', async () => {
const sut = new DefaultCacheClient({ client });
const expectedError = new Error('Some runtime error');
client.delete = jest.fn().mockRejectedValue(expectedError);
return expect(sut.delete('someKey')).rejects.toEqual(expectedError);
});
});
});
+101
View File
@@ -0,0 +1,101 @@
/*
* Copyright 2021 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { JsonValue } from '@backstage/config';
import { createHash } from 'crypto';
import Keyv from 'keyv';
type CacheClientArgs = {
client: Keyv;
};
type CacheSetOptions = {
/**
* Optional TTL in milliseconds. Defaults to the TTL provided when the client
* was set up (or no TTL if none are provided).
*/
ttl?: number;
};
/**
* A pre-configured, storage agnostic cache client suitable for use by
* Backstage plugins.
*/
export interface CacheClient {
/**
* Reads data from a cache store for the given key. If no data was found,
* returns undefined.
*/
get(key: string): Promise<JsonValue | undefined>;
/**
* Writes the given data to a cache store, associated with the given key. An
* optional TTL may also be provided, otherwise it defaults to the TTL that
* was provided when the client was instantiated.
*/
set(key: string, value: JsonValue, options?: CacheSetOptions): Promise<void>;
/**
* Removes the given key from the cache store.
*/
delete(key: string): Promise<void>;
}
/**
* A basic, concrete implementation of the CacheClient, suitable for almost
* all uses in Backstage.
*/
export class DefaultCacheClient implements CacheClient {
private readonly client: Keyv;
constructor({ client }: CacheClientArgs) {
this.client = client;
}
async get(key: string): Promise<JsonValue | undefined> {
const k = this.getNormalizedKey(key);
return await this.client.get(k);
}
async set(
key: string,
value: JsonValue,
opts: CacheSetOptions = {},
): Promise<void> {
const k = this.getNormalizedKey(key);
await this.client.set(k, value, opts.ttl);
}
async delete(key: string): Promise<void> {
const k = this.getNormalizedKey(key);
await this.client.delete(k);
}
/**
* Ensures keys are well-formed for any/all cache stores.
*/
private getNormalizedKey(candidateKey: string): string {
// Remove potentially invalid characters.
const wellFormedKey = Buffer.from(candidateKey).toString('base64');
// Memcache in particular doesn't do well with keys > 250 bytes.
if (wellFormedKey.length < 250) {
return wellFormedKey;
}
return createHash('md5').update(candidateKey).digest('base64');
}
}
+166
View File
@@ -0,0 +1,166 @@
/*
* Copyright 2021 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ConfigReader } from '@backstage/config';
import Keyv from 'keyv';
/* @ts-expect-error */
import KeyvMemcache from 'keyv-memcache';
import { DefaultCacheClient } from './CacheClient';
import { CacheManager } from './CacheManager';
import { NoStore } from './NoStore';
jest.createMockFromModule('keyv');
jest.mock('keyv');
jest.createMockFromModule('keyv-memcache');
jest.mock('keyv-memcache');
jest.mock('./CacheClient', () => {
return {
DefaultCacheClient: jest.fn(),
};
});
describe('CacheManager', () => {
const defaultConfigOptions = {
backend: {
cache: {
store: 'memory',
},
},
};
const defaultConfig = () => new ConfigReader(defaultConfigOptions);
afterEach(() => jest.resetAllMocks());
describe('CacheManager.fromConfig', () => {
it('accesses the backend.cache key', () => {
const getOptionalString = jest.fn();
const config = defaultConfig();
config.getOptionalString = getOptionalString;
CacheManager.fromConfig(config);
expect(getOptionalString.mock.calls[0][0]).toEqual('backend.cache.store');
expect(getOptionalString.mock.calls[1][0]).toEqual(
'backend.cache.connection',
);
});
it('does not require the backend.cache key', () => {
const config = new ConfigReader({ backend: {} });
expect(() => {
CacheManager.fromConfig(config);
}).not.toThrowError();
});
it('throws on unknown cache store', () => {
const config = new ConfigReader({
backend: { cache: { store: 'notreal' } },
});
expect(() => {
CacheManager.fromConfig(config);
}).toThrowError();
});
});
describe('CacheManager.forPlugin', () => {
const manager = CacheManager.fromConfig(defaultConfig());
it('connects to a cache store scoped to the plugin', async () => {
const pluginId = 'test1';
manager.forPlugin(pluginId).getClient();
const client = DefaultCacheClient as jest.Mock;
expect(client).toHaveBeenCalledTimes(1);
});
it('provides different plugins different cache clients', async () => {
const plugin1Id = 'test1';
const plugin2Id = 'test2';
const expectedTtl = 3600;
manager.forPlugin(plugin1Id).getClient({ defaultTtl: expectedTtl });
manager.forPlugin(plugin2Id).getClient({ defaultTtl: expectedTtl });
const client = DefaultCacheClient as jest.Mock;
const cache = (Keyv as unknown) as jest.Mock;
expect(cache).toHaveBeenCalledTimes(2);
expect(client).toHaveBeenCalledTimes(2);
const plugin1CallArgs = cache.mock.calls[0];
const plugin2CallArgs = cache.mock.calls[1];
expect(plugin1CallArgs[0].namespace).not.toEqual(
plugin2CallArgs[0].namespace,
);
});
});
describe('CacheManager.forPlugin stores', () => {
it('returns none client when no cache is configured', () => {
const manager = CacheManager.fromConfig(
new ConfigReader({ backend: {} }),
);
const expectedNamespace = 'test-plugin';
manager.forPlugin(expectedNamespace).getClient();
const cache = (Keyv as unknown) as jest.Mock;
const mockCalls = cache.mock.calls.splice(-1);
const callArgs = mockCalls[0];
expect(callArgs[0].store).toBeInstanceOf(NoStore);
});
it('returns memory client when explicitly configured', () => {
const manager = CacheManager.fromConfig(defaultConfig());
const expectedTtl = 3600;
const expectedNamespace = 'test-plugin';
manager
.forPlugin(expectedNamespace)
.getClient({ defaultTtl: expectedTtl });
const cache = (Keyv as unknown) as jest.Mock;
const mockCalls = cache.mock.calls.splice(-1);
const callArgs = mockCalls[0];
expect(callArgs[0]).toMatchObject({
ttl: expectedTtl,
namespace: expectedNamespace,
});
});
it('returns a memcache client when configured', () => {
const expectedHost = '127.0.0.1:11211';
const manager = CacheManager.fromConfig(
new ConfigReader({
backend: {
cache: {
store: 'memcache',
connection: expectedHost,
},
},
}),
);
const expectedTtl = 3600;
manager.forPlugin('test').getClient({ defaultTtl: expectedTtl });
const cache = (Keyv as unknown) as jest.Mock;
const mockCacheCalls = cache.mock.calls.splice(-1);
expect(mockCacheCalls[0][0]).toMatchObject({
ttl: expectedTtl,
});
expect(mockCacheCalls[0][0].store).toBeInstanceOf(KeyvMemcache);
const memcache = KeyvMemcache as jest.Mock;
const mockMemcacheCalls = memcache.mock.calls.splice(-1);
expect(mockMemcacheCalls[0][0]).toEqual(expectedHost);
});
});
});
+114
View File
@@ -0,0 +1,114 @@
/*
* Copyright 2021 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Config } from '@backstage/config';
import Keyv from 'keyv';
// @ts-expect-error
import KeyvMemcache from 'keyv-memcache';
import { DefaultCacheClient, CacheClient } from './CacheClient';
import { NoStore } from './NoStore';
import { PluginCacheManager } from './types';
/**
* Implements a Cache Manager which will automatically create new cache clients
* for plugins when requested. All requested cache clients are created with the
* connection details provided.
*/
export class CacheManager {
/**
* Keys represent supported `backend.cache.store` values, mapped to factories
* that return Keyv instances appropriate to the store.
*/
private readonly storeFactories = {
memcache: this.getMemcacheClient,
memory: this.getMemoryClient,
none: this.getNoneClient,
};
private readonly store: keyof CacheManager['storeFactories'];
private readonly connection: string;
/**
* Creates a new CacheManager instance by reading from the `backend` config
* section, specifically the `.cache` key.
*
* @param config The loaded application configuration.
*/
static fromConfig(config: Config): CacheManager {
// If no `backend.cache` config is provided, instantiate the CacheManager
// with a "NoStore" cache client.
const store = config.getOptionalString('backend.cache.store') || 'none';
const connectionString =
config.getOptionalString('backend.cache.connection') || '';
return new CacheManager(store, connectionString);
}
private constructor(store: string, connectionString: string) {
if (!this.storeFactories.hasOwnProperty(store)) {
throw new Error(`Unknown cache store: ${store}`);
}
this.store = store as keyof CacheManager['storeFactories'];
this.connection = connectionString;
}
/**
* Generates a CacheManagerInstance for consumption by plugins.
*
* @param pluginId The plugin that the cache manager should be created for. Plugin names should be unique.
*/
forPlugin(pluginId: string): PluginCacheManager {
return {
getClient: (opts = {}): CacheClient => {
const concreteClient = this.getClientWithTtl(pluginId, opts.defaultTtl);
return new DefaultCacheClient({
client: concreteClient,
});
},
};
}
private getClientWithTtl(pluginId: string, ttl: number | undefined): Keyv {
return this.storeFactories[this.store].call(this, pluginId, ttl);
}
private getMemcacheClient(
pluginId: string,
defaultTtl: number | undefined,
): Keyv {
return new Keyv({
namespace: pluginId,
ttl: defaultTtl,
store: new KeyvMemcache(this.connection),
});
}
private getMemoryClient(
pluginId: string,
defaultTtl: number | undefined,
): Keyv {
return new Keyv({
namespace: pluginId,
ttl: defaultTtl,
});
}
private getNoneClient(pluginId: string): Keyv {
return new Keyv({
namespace: pluginId,
store: new NoStore(),
});
}
}
+41
View File
@@ -0,0 +1,41 @@
/*
* Copyright 2021 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Storage class compatible with Keyv which always results in a no-op. This is
* used when no cache store is configured in a Backstage backend instance.
*/
export class NoStore extends Map<string, any> {
clear(): void {
return;
}
delete(_key: string): boolean {
return false;
}
get(_key: string) {
return;
}
has(_key: string): boolean {
return false;
}
set(_key: string, _value: any): this {
return this;
}
}
+19
View File
@@ -0,0 +1,19 @@
/*
* Copyright 2021 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export type { CacheClient } from './CacheClient';
export { CacheManager } from './CacheManager';
export type { PluginCacheManager } from './types';
+40
View File
@@ -0,0 +1,40 @@
/*
* 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 { CacheClient } from './CacheClient';
type ClientOptions = {
/**
* An optional default TTL (in milliseconds) to be set when getting a client
* instance. If not provided, data will persist indefinitely by default (or
* can be configured per entry at set-time).
*/
defaultTtl?: number;
};
/**
* The PluginCacheManager manages access to cache stores that Plugins get.
*/
export type PluginCacheManager = {
/**
* getClient provides backend plugins cache connections for itself.
*
* The purpose of this method is to allow plugins to get isolated data
* stores so that plugins are discouraged from cache-level integration
* and/or cache key collisions.
*/
getClient: (options?: ClientOptions) => CacheClient;
};
@@ -46,11 +46,11 @@ describe('database connection', () => {
).toBeTruthy();
});
it('tries to create a mysql connection as a passthrough', () => {
it('returns a mysql connection', () => {
expect(() =>
createDatabaseClient(
new ConfigReader({
client: 'mysql',
client: 'mysql2',
connection: {
host: '127.0.0.1',
user: 'foo',
@@ -59,7 +59,7 @@ describe('database connection', () => {
},
}),
),
).toThrowError(/Cannot find module 'mysql'/);
).toBeTruthy();
});
it('accepts overrides', () => {
@@ -14,9 +14,10 @@
* limitations under the License.
*/
import knexFactory, { Knex } from 'knex';
import { Config } from '@backstage/config';
import knexFactory, { Knex } from 'knex';
import { mergeDatabaseConfig } from './config';
import { createMysqlDatabaseClient, ensureMysqlDatabaseExists } from './mysql';
import { createPgDatabaseClient, ensurePgDatabaseExists } from './postgres';
import { createSqliteDatabaseClient } from './sqlite3';
@@ -36,6 +37,8 @@ export function createDatabaseClient(
if (client === 'pg') {
return createPgDatabaseClient(dbConfig, overrides);
} else if (client === 'mysql' || client === 'mysql2') {
return createMysqlDatabaseClient(dbConfig, overrides);
} else if (client === 'sqlite3') {
return createSqliteDatabaseClient(dbConfig, overrides);
}
@@ -60,6 +63,8 @@ export async function ensureDatabaseExists(
if (client === 'pg') {
return ensurePgDatabaseExists(dbConfig, ...databases);
} else if (client === 'mysql' || client === 'mysql2') {
return ensureMysqlDatabaseExists(dbConfig, ...databases);
}
return undefined;
@@ -0,0 +1,188 @@
/*
* 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 { Config, ConfigReader } from '@backstage/config';
import {
buildMysqlDatabaseConfig,
createMysqlDatabaseClient,
getMysqlConnectionConfig,
parseMysqlConnectionString,
} from './mysql';
describe('mysql', () => {
const createMockConnection = () => ({
host: 'acme',
user: 'foo',
password: 'bar',
database: 'foodb',
});
const createMockConnectionString = () => 'mysql://foo:bar@acme:3306/foodb';
const createConfig = (connection: any): Config =>
new ConfigReader({ client: 'mysql2', connection });
describe('buildMysqlDatabaseConfig', () => {
it('builds a mysql config', () => {
const mockConnection = createMockConnection();
expect(buildMysqlDatabaseConfig(createConfig(mockConnection))).toEqual({
client: 'mysql2',
connection: mockConnection,
useNullAsDefault: true,
});
});
it('builds a connection string config', () => {
const mockConnectionString = createMockConnectionString();
expect(
buildMysqlDatabaseConfig(createConfig(mockConnectionString)),
).toEqual({
client: 'mysql2',
connection: mockConnectionString,
useNullAsDefault: true,
});
});
it('overrides the database name', () => {
const mockConnection = createMockConnection();
expect(
buildMysqlDatabaseConfig(createConfig(mockConnection), {
connection: { database: 'other_db' },
}),
).toEqual({
client: 'mysql2',
connection: {
...mockConnection,
database: 'other_db',
},
useNullAsDefault: true,
});
});
it('adds additional config settings', () => {
const mockConnection = createMockConnection();
expect(
buildMysqlDatabaseConfig(createConfig(mockConnection), {
connection: { database: 'other_db' },
pool: { min: 0, max: 7 },
debug: true,
}),
).toEqual({
client: 'mysql2',
connection: {
...mockConnection,
database: 'other_db',
},
useNullAsDefault: true,
pool: { min: 0, max: 7 },
debug: true,
});
});
it('overrides the database from connection string', () => {
const mockConnectionString = createMockConnectionString();
const mockConnection = createMockConnection();
expect(
buildMysqlDatabaseConfig(createConfig(mockConnectionString), {
connection: { database: 'other_db' },
}),
).toEqual({
client: 'mysql2',
connection: {
...mockConnection,
port: 3306,
database: 'other_db',
},
useNullAsDefault: true,
});
});
});
describe('getMysqlConnectionConfig', () => {
it('returns the connection object back', () => {
const mockConnection = createMockConnection();
const config = createConfig(mockConnection);
expect(getMysqlConnectionConfig(config)).toEqual(mockConnection);
});
it('does not parse the connection string', () => {
const mockConnection = createMockConnection();
const config = createConfig(mockConnection);
expect(getMysqlConnectionConfig(config, true)).toEqual(mockConnection);
});
it('automatically parses the connection string', () => {
const mockConnection = createMockConnection();
const mockConnectionString = createMockConnectionString();
const config = createConfig(mockConnectionString);
expect(getMysqlConnectionConfig(config)).toEqual({
...mockConnection,
port: 3306,
});
});
it('parses the connection string', () => {
const mockConnection = createMockConnection();
const mockConnectionString = createMockConnectionString();
const config = createConfig(mockConnectionString);
expect(getMysqlConnectionConfig(config, true)).toEqual({
...mockConnection,
port: 3306,
});
});
});
describe('createMysqlDatabaseClient', () => {
it('creates a mysql knex instance', () => {
expect(
createMysqlDatabaseClient(
createConfig({
host: 'acme',
user: 'foo',
password: 'bar',
database: 'foodb',
}),
),
).toBeTruthy();
});
});
describe('parseMysqlConnectionString', () => {
it('parses a connection string uri', () => {
expect(
parseMysqlConnectionString(
'mysql://u:pass@foobar:3307/dbname?ssl=require',
),
).toEqual({
host: 'foobar',
user: 'u',
password: 'pass',
port: 3307,
database: 'dbname',
ssl: 'require',
});
});
});
});
@@ -0,0 +1,161 @@
/*
* 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 { Config } from '@backstage/config';
import { InputError } from '@backstage/errors';
import knexFactory, { Knex } from 'knex';
import { mergeDatabaseConfig } from './config';
import yn from 'yn';
/**
* Creates a knex mysql database connection
*
* @param dbConfig The database config
* @param overrides Additional options to merge with the config
*/
export function createMysqlDatabaseClient(
dbConfig: Config,
overrides?: Knex.Config,
) {
const knexConfig = buildMysqlDatabaseConfig(dbConfig, overrides);
const database = knexFactory(knexConfig);
return database;
}
/**
* Builds a knex mysql database connection
*
* @param dbConfig The database config
* @param overrides Additional options to merge with the config
*/
export function buildMysqlDatabaseConfig(
dbConfig: Config,
overrides?: Knex.Config,
) {
return mergeDatabaseConfig(
dbConfig.get(),
{
connection: getMysqlConnectionConfig(dbConfig, !!overrides),
useNullAsDefault: true,
},
overrides,
);
}
/**
* Gets the mysql connection config
*
* @param dbConfig The database config
* @param parseConnectionString Flag to explicitly control connection string parsing
*/
export function getMysqlConnectionConfig(
dbConfig: Config,
parseConnectionString?: boolean,
): Knex.MySqlConnectionConfig | string {
const connection = dbConfig.get('connection') as any;
const isConnectionString =
typeof connection === 'string' || connection instanceof String;
const autoParse = typeof parseConnectionString !== 'boolean';
const shouldParseConnectionString = autoParse
? isConnectionString
: parseConnectionString && isConnectionString;
return shouldParseConnectionString
? parseMysqlConnectionString(connection as string)
: connection;
}
/**
* Parses a mysql connection string.
*
* e.g. mysql://examplename:somepassword@examplehost:3306/dbname
* @param connectionString The mysql connection string
*/
export function parseMysqlConnectionString(
connectionString: string,
): Knex.MySqlConnectionConfig {
try {
const {
protocol,
username,
password,
port,
hostname,
pathname,
searchParams,
} = new URL(connectionString);
if (protocol !== 'mysql:') {
throw new Error(`Unknown protocol ${protocol}`);
} else if (!username || !password) {
throw new Error(`Missing username/password`);
} else if (!pathname.match(/^\/[^/]+$/)) {
throw new Error(`Expected single path segment`);
}
const result: Knex.MySqlConnectionConfig = {
user: username,
password,
host: hostname,
port: Number(port || 3306),
database: decodeURIComponent(pathname.substr(1)),
};
const ssl = searchParams.get('ssl');
if (ssl) {
result.ssl = ssl;
}
const debug = searchParams.get('debug');
if (debug) {
result.debug = yn(debug);
}
return result;
} catch (e) {
throw new InputError(
`Error while parsing MySQL connection string, ${e}`,
e,
);
}
}
/**
* Creates the missing mysql database if it does not exist
*
* @param dbConfig The database config
* @param databases The names of the databases to create
*/
export async function ensureMysqlDatabaseExists(
dbConfig: Config,
...databases: Array<string>
) {
const admin = createMysqlDatabaseClient(dbConfig, {
connection: {
database: (null as unknown) as string,
},
});
try {
const ensureDatabase = async (database: string) => {
await admin.raw(`CREATE DATABASE IF NOT EXISTS ??`, [database]);
};
await Promise.all(databases.map(ensureDatabase));
} finally {
await admin.destroy();
}
}
+1
View File
@@ -14,6 +14,7 @@
* limitations under the License.
*/
export * from './cache';
export * from './config';
export * from './database';
export * from './discovery';
+31
View File
@@ -1,5 +1,36 @@
# example-backend
## 0.2.28
### Patch Changes
- Updated dependencies [062bbf90f]
- Updated dependencies [22fd8ce2a]
- Updated dependencies [10c008a3a]
- Updated dependencies [82ca1ac22]
- Updated dependencies [f9fb4a205]
- Updated dependencies [9a207f052]
- Updated dependencies [16be1d093]
- Updated dependencies [fd39d4662]
- Updated dependencies [f9f9d633d]
- @backstage/plugin-scaffolder-backend@0.11.1
- @backstage/backend-common@0.8.0
- @backstage/catalog-model@0.7.9
- @backstage/plugin-catalog-backend@0.9.0
- @backstage/plugin-kubernetes-backend@0.3.7
- example-app@0.2.28
- @backstage/plugin-app-backend@0.3.13
- @backstage/plugin-auth-backend@0.3.10
- @backstage/plugin-badges-backend@0.1.4
- @backstage/plugin-code-coverage-backend@0.1.5
- @backstage/plugin-graphql-backend@0.1.8
- @backstage/plugin-kafka-backend@0.2.5
- @backstage/plugin-proxy-backend@0.2.8
- @backstage/plugin-rollbar-backend@0.1.11
- @backstage/plugin-search-backend@0.1.5
- @backstage/plugin-techdocs-backend@0.8.1
- @backstage/plugin-todo-backend@0.1.5
## 0.2.27
### Patch Changes
+19 -19
View File
@@ -1,6 +1,6 @@
{
"name": "example-backend",
"version": "0.2.27",
"version": "0.2.28",
"main": "dist/index.cjs.js",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -27,30 +27,30 @@
"migrate:create": "knex migrate:make -x ts"
},
"dependencies": {
"@backstage/backend-common": "^0.7.0",
"@backstage/backend-common": "^0.8.0",
"@backstage/catalog-client": "^0.3.11",
"@backstage/catalog-model": "^0.7.8",
"@backstage/catalog-model": "^0.7.9",
"@backstage/config": "^0.1.5",
"@backstage/plugin-app-backend": "^0.3.12",
"@backstage/plugin-auth-backend": "^0.3.9",
"@backstage/plugin-badges-backend": "^0.1.3",
"@backstage/plugin-catalog-backend": "^0.8.2",
"@backstage/plugin-code-coverage-backend": "^0.1.4",
"@backstage/plugin-graphql-backend": "^0.1.7",
"@backstage/plugin-kubernetes-backend": "^0.3.6",
"@backstage/plugin-kafka-backend": "^0.2.4",
"@backstage/plugin-proxy-backend": "^0.2.7",
"@backstage/plugin-rollbar-backend": "^0.1.10",
"@backstage/plugin-scaffolder-backend": "^0.11.0",
"@backstage/plugin-search-backend": "^0.1.4",
"@backstage/plugin-app-backend": "^0.3.13",
"@backstage/plugin-auth-backend": "^0.3.10",
"@backstage/plugin-badges-backend": "^0.1.4",
"@backstage/plugin-catalog-backend": "^0.9.0",
"@backstage/plugin-code-coverage-backend": "^0.1.5",
"@backstage/plugin-graphql-backend": "^0.1.8",
"@backstage/plugin-kubernetes-backend": "^0.3.7",
"@backstage/plugin-kafka-backend": "^0.2.5",
"@backstage/plugin-proxy-backend": "^0.2.8",
"@backstage/plugin-rollbar-backend": "^0.1.11",
"@backstage/plugin-scaffolder-backend": "^0.11.1",
"@backstage/plugin-search-backend": "^0.1.5",
"@backstage/plugin-search-backend-node": "^0.1.3",
"@backstage/plugin-techdocs-backend": "^0.8.0",
"@backstage/plugin-todo-backend": "^0.1.4",
"@backstage/plugin-techdocs-backend": "^0.8.1",
"@backstage/plugin-todo-backend": "^0.1.5",
"@gitbeaker/node": "^28.0.2",
"@octokit/rest": "^18.5.3",
"azure-devops-node-api": "^10.1.1",
"dockerode": "^3.2.1",
"example-app": "^0.2.27",
"example-app": "^0.2.28",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
"knex": "^0.95.1",
@@ -60,7 +60,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/cli": "^0.6.10",
"@backstage/cli": "^0.6.11",
"@types/dockerode": "^3.2.1",
"@types/express": "^4.17.6",
"@types/express-serve-static-core": "^4.17.5"
+4 -1
View File
@@ -24,6 +24,7 @@
import Router from 'express-promise-router';
import {
CacheManager,
createServiceBuilder,
getRootLogger,
loadBackendConfig,
@@ -59,11 +60,13 @@ function makeCreateEnv(config: Config) {
root.info(`Created UrlReader ${reader}`);
const databaseManager = SingleConnectionDatabaseManager.fromConfig(config);
const cacheManager = CacheManager.fromConfig(config);
return (plugin: string): PluginEnvironment => {
const logger = root.child({ type: 'plugin', plugin });
const database = databaseManager.forPlugin(plugin);
return { logger, database, config, reader, discovery };
const cache = cacheManager.forPlugin(plugin);
return { logger, cache, database, config, reader, discovery };
};
}
+2
View File
@@ -17,6 +17,7 @@
import { Logger } from 'winston';
import { Config } from '@backstage/config';
import {
PluginCacheManager,
PluginDatabaseManager,
PluginEndpointDiscovery,
UrlReader,
@@ -24,6 +25,7 @@ import {
export type PluginEnvironment = {
logger: Logger;
cache: PluginCacheManager;
database: PluginDatabaseManager;
config: Config;
reader: UrlReader;
+7
View File
@@ -1,5 +1,12 @@
# @backstage/catalog-model
## 0.7.9
### Patch Changes
- 10c008a3a: Renamed parameters to input in template schema
- 16be1d093: Improve error messages when schema validation fails
## 0.7.8
### Patch Changes
+1
View File
@@ -112,6 +112,7 @@ export type Entity = {
metadata: EntityMeta;
spec?: JsonObject;
relations?: EntityRelation[];
status?: Record<string, JsonObject>;
};
// @public
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/catalog-model",
"version": "0.7.8",
"version": "0.7.9",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -39,7 +39,7 @@
"yup": "^0.29.3"
},
"devDependencies": {
"@backstage/cli": "^0.6.10",
"@backstage/cli": "^0.6.11",
"@types/express": "^4.17.6",
"@types/jest": "^26.0.7",
"@types/lodash": "^4.14.151",
@@ -48,6 +48,14 @@ export type Entity = {
* The relations that this entity has with other entities.
*/
relations?: EntityRelation[];
/**
* The current status of the entity, as claimed by various sources.
*
* The keys are implementation defined and the values can be any JSON object
* with semantics that match that implementation.
*/
status?: Record<string, JsonObject>;
};
/**
+4 -4
View File
@@ -42,11 +42,9 @@ export function generateEntityEtag(): string {
* the next version of this entity.
*
* Significance, in this case, means that we do not compare generated fields
* such as uid, etag and generation, and we only check that no new annotations
* are added or existing annotations were changed (since they are effectively
* merged when doing updates).
* such as uid, etag and generation.
*
* Note that this comparison does NOT take state, relations or similar into
* Note that this comparison does NOT take status, relations or similar into
* account. It only compares the actual input entity data, i.e. metadata and
* spec.
*
@@ -86,7 +84,9 @@ export function entityHasChanges(previous: Entity, next: Entity): boolean {
// Remove things that we explicitly do not compare
delete e1.relations;
delete e1.status;
delete e2.relations;
delete e2.status;
return !lodash.isEqual(e1, e2);
}
@@ -62,6 +62,15 @@
"items": {
"$ref": "common#relation"
}
},
"status": {
"type": "object",
"description": "The current status of the entity, as claimed by various sources.",
"patternProperties": {
"^.+$": {
"$ref": "common#status"
}
}
}
}
}
@@ -29,7 +29,7 @@
"$id": "#relation",
"type": "object",
"description": "A directed relation from one entity to another.",
"required": ["type", "source", "target"],
"required": ["type", "target"],
"additionalProperties": false,
"properties": {
"type": {
@@ -38,13 +38,16 @@
"pattern": "^\\w+$",
"description": "The type of relation."
},
"source": {
"$ref": "#reference"
},
"target": {
"$ref": "#reference"
}
}
},
"status": {
"$id": "#status",
"type": "object",
"description": "A specific status of an entity.",
"additionalProperties": true
}
}
}
+8
View File
@@ -1,5 +1,13 @@
# @backstage/cli
## 0.6.11
### Patch Changes
- 2cd70e164: Add context for versions:bump on what version it was bumped to. Updated tests for the same.
- 3be844496: chore: bump `ts-node` versions to 9.1.1
- e3fc89df6: update plugins created to use react-use 17.2.4
## 0.6.10
### Patch Changes
+5 -5
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/cli",
"description": "CLI for developing Backstage plugins and apps",
"version": "0.6.10",
"version": "0.6.11",
"private": false,
"publishConfig": {
"access": "public"
@@ -117,11 +117,11 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/backend-common": "^0.7.0",
"@backstage/backend-common": "^0.8.0",
"@backstage/config": "^0.1.5",
"@backstage/core": "^0.7.8",
"@backstage/dev-utils": "^0.1.13",
"@backstage/test-utils": "^0.1.10",
"@backstage/core": "^0.7.9",
"@backstage/dev-utils": "^0.1.14",
"@backstage/test-utils": "^0.1.11",
"@backstage/theme": "^0.2.7",
"@types/diff": "^5.0.0",
"@types/express": "^4.17.6",
@@ -39,7 +39,7 @@
"@backstage/test-utils": "^{{version '@backstage/test-utils'}}",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^12.0.7",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"msw": "^0.21.2",
+1 -1
View File
@@ -36,7 +36,7 @@
"ajv": "^7.0.3",
"fs-extra": "^9.0.0",
"json-schema": "^0.3.0",
"json-schema-merge-allof": "^0.7.0",
"json-schema-merge-allof": "^0.8.1",
"typescript-json-schema": "^0.49.0",
"yaml": "^1.9.2",
"yup": "^0.29.3"
+7
View File
@@ -1,5 +1,12 @@
# @backstage/core-api
## 0.2.18
### Patch Changes
- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8
- 675a569a9: chore: bump `react-use` dependency in all packages
## 0.2.17
### 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.17",
"version": "0.2.18",
"private": false,
"publishConfig": {
"access": "public",
@@ -42,13 +42,13 @@
"zen-observable": "^0.8.15"
},
"devDependencies": {
"@backstage/cli": "^0.6.9",
"@backstage/test-utils": "^0.1.10",
"@backstage/cli": "^0.6.11",
"@backstage/test-utils": "^0.1.11",
"@backstage/test-utils-core": "^0.1.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^3.3.0",
"@testing-library/user-event": "^12.0.7",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"@types/zen-observable": "^0.8.0",
+13
View File
@@ -1,5 +1,18 @@
# @backstage/core
## 0.7.9
### Patch Changes
- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8
- 889d89b6e: Fix state persisted in the URL make search input in the table toolbar lose their
focus.
- 3f988cb63: Add count of older messages when multiple messages exist in AlertDisplay
- 675a569a9: chore: bump `react-use` dependency in all packages
- Updated dependencies [062bbf90f]
- Updated dependencies [675a569a9]
- @backstage/core-api@0.2.18
## 0.7.8
### Patch Changes
+5 -5
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/core",
"description": "Core API used by Backstage plugins and apps",
"version": "0.7.8",
"version": "0.7.9",
"private": false,
"publishConfig": {
"access": "public",
@@ -30,7 +30,7 @@
},
"dependencies": {
"@backstage/config": "^0.1.5",
"@backstage/core-api": "^0.2.17",
"@backstage/core-api": "^0.2.18",
"@backstage/errors": "^0.1.1",
"@backstage/theme": "^0.2.7",
"@material-ui/core": "^4.11.0",
@@ -71,11 +71,11 @@
"zen-observable": "^0.8.15"
},
"devDependencies": {
"@backstage/cli": "^0.6.10",
"@backstage/test-utils": "^0.1.10",
"@backstage/cli": "^0.6.11",
"@backstage/test-utils": "^0.1.11",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^12.0.7",
"@testing-library/user-event": "^13.1.8",
"@types/classnames": "^2.2.9",
"@types/d3-selection": "^2.0.0",
"@types/d3-shape": "^2.0.0",
+47 -3
View File
@@ -1,5 +1,52 @@
# @backstage/create-app
## 0.3.22
### Patch Changes
- 3be844496: chore: bump `ts-node` versions to 9.1.1
- Updated dependencies [062bbf90f]
- Updated dependencies [2cd70e164]
- Updated dependencies [0b033d07b]
- Updated dependencies [3be844496]
- Updated dependencies [5542de095]
- Updated dependencies [22fd8ce2a]
- Updated dependencies [10c008a3a]
- Updated dependencies [82ca1ac22]
- Updated dependencies [81ef1d57b]
- Updated dependencies [f9fb4a205]
- Updated dependencies [e3fc89df6]
- Updated dependencies [9a207f052]
- Updated dependencies [889d89b6e]
- Updated dependencies [16be1d093]
- Updated dependencies [fd39d4662]
- Updated dependencies [3f988cb63]
- Updated dependencies [675a569a9]
- @backstage/core@0.7.9
- @backstage/integration-react@0.1.2
- @backstage/test-utils@0.1.11
- @backstage/plugin-api-docs@0.4.13
- @backstage/plugin-catalog@0.5.7
- @backstage/plugin-catalog-import@0.5.6
- @backstage/plugin-explore@0.3.5
- @backstage/plugin-github-actions@0.4.6
- @backstage/plugin-lighthouse@0.2.16
- @backstage/plugin-scaffolder@0.9.4
- @backstage/plugin-scaffolder-backend@0.11.1
- @backstage/plugin-search@0.3.6
- @backstage/plugin-tech-radar@0.3.11
- @backstage/plugin-techdocs@0.9.2
- @backstage/plugin-user-settings@0.2.10
- @backstage/cli@0.6.11
- @backstage/backend-common@0.8.0
- @backstage/catalog-model@0.7.9
- @backstage/plugin-catalog-backend@0.9.0
- @backstage/plugin-app-backend@0.3.13
- @backstage/plugin-auth-backend@0.3.10
- @backstage/plugin-proxy-backend@0.2.8
- @backstage/plugin-rollbar-backend@0.1.11
- @backstage/plugin-techdocs-backend@0.8.1
## 0.3.21
### Patch Changes
@@ -15,8 +62,6 @@
+ import { DockerContainerRunner } from '@backstage/backend-common';
// ...
export default async function createPlugin({
logger,
config,
@@ -76,7 +121,6 @@
+ SingleHostDiscovery,
+ } from '@backstage/backend-common';
export default async function createPlugin({
logger,
config,
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/create-app",
"description": "Create app package for Backstage",
"version": "0.3.21",
"version": "0.3.22",
"private": false,
"publishConfig": {
"access": "public"
+17
View File
@@ -1,5 +1,22 @@
# @backstage/dev-utils
## 0.1.14
### Patch Changes
- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8
- Updated dependencies [062bbf90f]
- Updated dependencies [10c008a3a]
- Updated dependencies [889d89b6e]
- Updated dependencies [16be1d093]
- Updated dependencies [3f988cb63]
- Updated dependencies [675a569a9]
- @backstage/core@0.7.9
- @backstage/integration-react@0.1.2
- @backstage/test-utils@0.1.11
- @backstage/plugin-catalog-react@0.1.6
- @backstage/catalog-model@0.7.9
## 0.1.13
### Patch Changes
+8 -8
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/dev-utils",
"description": "Utilities for developing Backstage plugins.",
"version": "0.1.13",
"version": "0.1.14",
"private": false,
"publishConfig": {
"access": "public",
@@ -29,17 +29,17 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core": "^0.7.0",
"@backstage/catalog-model": "^0.7.3",
"@backstage/integration-react": "^0.1.1",
"@backstage/plugin-catalog-react": "^0.1.1",
"@backstage/test-utils": "^0.1.8",
"@backstage/core": "^0.7.9",
"@backstage/catalog-model": "^0.7.9",
"@backstage/integration-react": "^0.1.2",
"@backstage/plugin-catalog-react": "^0.1.6",
"@backstage/test-utils": "^0.1.11",
"@backstage/theme": "^0.2.3",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^12.0.7",
"@testing-library/user-event": "^13.1.8",
"@types/react": "^16.9",
"react": "^16.12.0",
"react-dom": "^16.12.0",
@@ -48,7 +48,7 @@
"react-router-dom": "6.0.0-beta.0"
},
"devDependencies": {
"@backstage/cli": "^0.6.3",
"@backstage/cli": "^0.6.11",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32"
},
+13
View File
@@ -0,0 +1,13 @@
# @backstage/integration-react
## 0.1.2
### Patch Changes
- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8
- 675a569a9: chore: bump `react-use` dependency in all packages
- Updated dependencies [062bbf90f]
- Updated dependencies [889d89b6e]
- Updated dependencies [3f988cb63]
- Updated dependencies [675a569a9]
- @backstage/core@0.7.9
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/integration-react",
"version": "0.1.1",
"version": "0.1.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,7 +21,7 @@
},
"dependencies": {
"@backstage/config": "^0.1.2",
"@backstage/core": "^0.7.0",
"@backstage/core": "^0.7.9",
"@backstage/integration": "^0.5.0",
"@backstage/theme": "^0.2.3",
"@material-ui/core": "^4.11.0",
@@ -32,12 +32,12 @@
"react-use": "^17.2.4"
},
"devDependencies": {
"@backstage/cli": "^0.6.3",
"@backstage/dev-utils": "^0.1.13",
"@backstage/test-utils": "^0.1.8",
"@backstage/cli": "^0.6.11",
"@backstage/dev-utils": "^0.1.14",
"@backstage/test-utils": "^0.1.11",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^12.0.7",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"msw": "^0.21.2",
+12
View File
@@ -1,5 +1,17 @@
# @backstage/techdocs-common
## 0.6.1
### Patch Changes
- e04f1ccfb: Fixed a bug that prevented loading static assets from GCS, S3, Azure, and OpenStackSwift whose keys contain spaces or other special characters.
- Updated dependencies [22fd8ce2a]
- Updated dependencies [10c008a3a]
- Updated dependencies [f9fb4a205]
- Updated dependencies [16be1d093]
- @backstage/backend-common@0.8.0
- @backstage/catalog-model@0.7.9
## 0.6.0
### Minor 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.6.0",
"version": "0.6.1",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -38,8 +38,8 @@
"dependencies": {
"@azure/identity": "^1.2.2",
"@azure/storage-blob": "^12.4.0",
"@backstage/backend-common": "^0.7.0",
"@backstage/catalog-model": "^0.7.8",
"@backstage/backend-common": "^0.8.0",
"@backstage/catalog-model": "^0.7.9",
"@backstage/config": "^0.1.5",
"@backstage/errors": "^0.1.1",
"@backstage/integration": "^0.5.2",
@@ -60,7 +60,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/cli": "^0.6.10",
"@backstage/cli": "^0.6.11",
"@types/fs-extra": "^9.0.5",
"@types/git-url-parse": "^9.0.0",
"@types/js-yaml": "^4.0.0",
+9
View File
@@ -1,5 +1,14 @@
# @backstage/test-utils
## 0.1.11
### Patch Changes
- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8
- Updated dependencies [062bbf90f]
- Updated dependencies [675a569a9]
- @backstage/core-api@0.2.18
## 0.1.10
### Patch Changes
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/test-utils",
"description": "Utilities to test Backstage plugins and apps.",
"version": "0.1.10",
"version": "0.1.11",
"private": false,
"publishConfig": {
"access": "public",
@@ -29,13 +29,13 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core-api": "^0.2.16",
"@backstage/core-api": "^0.2.18",
"@backstage/test-utils-core": "^0.1.1",
"@backstage/theme": "^0.2.3",
"@material-ui/core": "^4.11.0",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^12.0.7",
"@testing-library/user-event": "^13.1.8",
"@types/react": "^16.9",
"msw": "^0.21.3",
"react": "^16.12.0",
@@ -45,7 +45,7 @@
"zen-observable": "^0.8.15"
},
"devDependencies": {
"@backstage/cli": "^0.6.7",
"@backstage/cli": "^0.6.11",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32"
},
+18
View File
@@ -1,5 +1,23 @@
# @backstage/plugin-api-docs
## 0.4.13
### Patch Changes
- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8
- 889d89b6e: Fix state persisted in the URL make search input in the table toolbar lose their
focus.
- 675a569a9: chore: bump `react-use` dependency in all packages
- Updated dependencies [062bbf90f]
- Updated dependencies [10c008a3a]
- Updated dependencies [889d89b6e]
- Updated dependencies [16be1d093]
- Updated dependencies [3f988cb63]
- Updated dependencies [675a569a9]
- @backstage/core@0.7.9
- @backstage/plugin-catalog-react@0.1.6
- @backstage/catalog-model@0.7.9
## 0.4.12
### Patch Changes
+8 -8
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-api-docs",
"version": "0.4.12",
"version": "0.4.13",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -30,9 +30,9 @@
},
"dependencies": {
"@asyncapi/react-component": "^0.23.0",
"@backstage/catalog-model": "^0.7.7",
"@backstage/core": "^0.7.8",
"@backstage/plugin-catalog-react": "^0.1.4",
"@backstage/catalog-model": "^0.7.9",
"@backstage/core": "^0.7.9",
"@backstage/plugin-catalog-react": "^0.1.6",
"@backstage/theme": "^0.2.7",
"@material-icons/font": "^1.0.2",
"@material-ui/core": "^4.11.0",
@@ -49,12 +49,12 @@
"swagger-ui-react": "^3.37.2"
},
"devDependencies": {
"@backstage/cli": "^0.6.10",
"@backstage/dev-utils": "^0.1.13",
"@backstage/test-utils": "^0.1.10",
"@backstage/cli": "^0.6.11",
"@backstage/dev-utils": "^0.1.14",
"@backstage/test-utils": "^0.1.11",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^12.0.7",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"@types/swagger-ui-react": "^3.23.3",
+8
View File
@@ -1,5 +1,13 @@
# @backstage/plugin-app-backend
## 0.3.13
### Patch Changes
- Updated dependencies [22fd8ce2a]
- Updated dependencies [f9fb4a205]
- @backstage/backend-common@0.8.0
## 0.3.12
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-app-backend",
"version": "0.3.12",
"version": "0.3.13",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -29,7 +29,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.7.0",
"@backstage/backend-common": "^0.8.0",
"@backstage/config-loader": "^0.6.1",
"@backstage/config": "^0.1.5",
"@types/express": "^4.17.6",
@@ -40,7 +40,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.6.10",
"@backstage/cli": "^0.6.11",
"@types/supertest": "^2.0.8",
"msw": "^0.20.5",
"supertest": "^6.1.3"
+13
View File
@@ -1,5 +1,18 @@
# @backstage/plugin-auth-backend
## 0.3.10
### Patch Changes
- Updated dependencies [062bbf90f]
- Updated dependencies [22fd8ce2a]
- Updated dependencies [10c008a3a]
- Updated dependencies [f9fb4a205]
- Updated dependencies [16be1d093]
- @backstage/test-utils@0.1.11
- @backstage/backend-common@0.8.0
- @backstage/catalog-model@0.7.9
## 0.3.9
### Patch Changes
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-auth-backend",
"version": "0.3.9",
"version": "0.3.10",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -29,12 +29,12 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.7.0",
"@backstage/backend-common": "^0.8.0",
"@backstage/catalog-client": "^0.3.11",
"@backstage/catalog-model": "^0.7.8",
"@backstage/catalog-model": "^0.7.9",
"@backstage/config": "^0.1.5",
"@backstage/errors": "^0.1.1",
"@backstage/test-utils": "^0.1.10",
"@backstage/test-utils": "^0.1.11",
"@types/express": "^4.17.6",
"@types/passport": "^1.0.3",
"compression": "^1.7.4",
@@ -68,7 +68,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.6.10",
"@backstage/cli": "^0.6.11",
"@types/body-parser": "^1.19.0",
"@types/cookie-parser": "^1.4.2",
"@types/express-session": "^1.17.2",
+11
View File
@@ -1,5 +1,16 @@
# @backstage/plugin-badges-backend
## 0.1.4
### Patch Changes
- Updated dependencies [22fd8ce2a]
- Updated dependencies [10c008a3a]
- Updated dependencies [f9fb4a205]
- Updated dependencies [16be1d093]
- @backstage/backend-common@0.8.0
- @backstage/catalog-model@0.7.9
## 0.1.3
### Patch Changes
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-badges-backend",
"version": "0.1.3",
"version": "0.1.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -30,9 +30,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.7.0",
"@backstage/backend-common": "^0.8.0",
"@backstage/catalog-client": "^0.3.11",
"@backstage/catalog-model": "^0.7.8",
"@backstage/catalog-model": "^0.7.9",
"@backstage/config": "^0.1.5",
"@backstage/errors": "^0.1.1",
"@types/express": "^4.17.6",
@@ -45,7 +45,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.6.10",
"@backstage/cli": "^0.6.11",
"@types/supertest": "^2.0.8",
"supertest": "^6.1.3"
},
+24
View File
@@ -65,4 +65,28 @@ describe('BadgeFactories', () => {
expect(badge.kind).toEqual('entity');
}
});
it('returns valid link for entity', () => {
const entity: Entity = {
apiVersion: 'v1',
kind: 'service',
metadata: {
name: 'test',
},
};
const context: BadgeContext = {
badgeUrl: '/dummy/url',
config,
entity,
};
expect.assertions(Object.keys(badgeFactories).length);
for (const badgeFactory of Object.values(badgeFactories)) {
const badge = badgeFactory.createBadge(context);
expect(badge.link).toContain(
'http://localhost/catalog/default/service/test',
);
}
});
});
+2 -2
View File
@@ -24,8 +24,8 @@ function appTitle(context: BadgeContext): string {
function entityUrl(context: BadgeContext): string {
const e = context.entity!;
const entityUri = `${e.kind}/${
e.metadata.namespace || ENTITY_DEFAULT_NAMESPACE
const entityUri = `${e.metadata.namespace || ENTITY_DEFAULT_NAMESPACE}/${
e.kind
}/${e.metadata.name}`;
const catalogUrl = `${context.config.getString('app.baseUrl')}/catalog`;
return `${catalogUrl}/${entityUri}`.toLowerCase();
+16
View File
@@ -1,5 +1,21 @@
# @backstage/plugin-badges
## 0.2.1
### Patch Changes
- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8
- 675a569a9: chore: bump `react-use` dependency in all packages
- Updated dependencies [062bbf90f]
- Updated dependencies [10c008a3a]
- Updated dependencies [889d89b6e]
- Updated dependencies [16be1d093]
- Updated dependencies [3f988cb63]
- Updated dependencies [675a569a9]
- @backstage/core@0.7.9
- @backstage/plugin-catalog-react@0.1.6
- @backstage/catalog-model@0.7.9
## 0.2.0
### Minor Changes
+8 -8
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-badges",
"version": "0.2.0",
"version": "0.2.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,10 +20,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.7.6",
"@backstage/core": "^0.7.8",
"@backstage/catalog-model": "^0.7.9",
"@backstage/core": "^0.7.9",
"@backstage/errors": "^0.1.1",
"@backstage/plugin-catalog-react": "^0.1.3",
"@backstage/plugin-catalog-react": "^0.1.6",
"@backstage/theme": "^0.2.7",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -34,12 +34,12 @@
"react-use": "^17.2.4"
},
"devDependencies": {
"@backstage/cli": "^0.6.10",
"@backstage/dev-utils": "^0.1.13",
"@backstage/test-utils": "^0.1.10",
"@backstage/cli": "^0.6.11",
"@backstage/dev-utils": "^0.1.14",
"@backstage/test-utils": "^0.1.11",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^12.0.7",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"cross-fetch": "^3.0.6",
+16
View File
@@ -1,5 +1,21 @@
# @backstage/plugin-bitrise
## 0.1.3
### Patch Changes
- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8
- 675a569a9: chore: bump `react-use` dependency in all packages
- Updated dependencies [062bbf90f]
- Updated dependencies [10c008a3a]
- Updated dependencies [889d89b6e]
- Updated dependencies [16be1d093]
- Updated dependencies [3f988cb63]
- Updated dependencies [675a569a9]
- @backstage/core@0.7.9
- @backstage/plugin-catalog-react@0.1.6
- @backstage/catalog-model@0.7.9
## 0.1.2
### Patch Changes
+8 -8
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-bitrise",
"version": "0.1.2",
"version": "0.1.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,9 +20,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.7.2",
"@backstage/core": "^0.7.8",
"@backstage/plugin-catalog-react": "^0.1.2",
"@backstage/catalog-model": "^0.7.9",
"@backstage/core": "^0.7.9",
"@backstage/plugin-catalog-react": "^0.1.6",
"@backstage/theme": "^0.2.7",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -37,12 +37,12 @@
"recharts": "^1.8.5"
},
"devDependencies": {
"@backstage/cli": "^0.6.10",
"@backstage/dev-utils": "^0.1.13",
"@backstage/test-utils": "^0.1.10",
"@backstage/cli": "^0.6.11",
"@backstage/dev-utils": "^0.1.14",
"@backstage/test-utils": "^0.1.11",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^12.0.7",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"@types/recharts": "^1.8.15",
+24
View File
@@ -1,5 +1,29 @@
# @backstage/plugin-catalog-backend
## 0.9.0
### Minor Changes
- 9a207f052: Port `GithubOrgReaderProcessor` to support configuration via
[`integrations`](https://backstage.io/docs/integrations/github/locations) in
addition to [`catalog.processors.githubOrg.providers`](https://backstage.io/docs/integrations/github/org#configuration).
The `integrations` package supports authentication with both personal access
tokens and GitHub apps.
This deprecates the `catalog.processors.githubOrg.providers` configuration.
A [`integrations` configuration](https://backstage.io/docs/integrations/github/locations)
for the same host takes precedence over the provider configuration.
You might need to add additional scopes for the credentials.
### Patch Changes
- Updated dependencies [22fd8ce2a]
- Updated dependencies [10c008a3a]
- Updated dependencies [f9fb4a205]
- Updated dependencies [16be1d093]
- @backstage/backend-common@0.8.0
- @backstage/catalog-model@0.7.9
## 0.8.2
### Patch Changes
+2
View File
@@ -114,6 +114,8 @@ export interface Config {
processors?: {
/**
* GithubOrgReaderProcessor configuration
*
* @deprecated Configure a GitHub integration instead.
*/
githubOrg?: {
/**

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