Merge branch 'master' of https://github.com/backstage/backstage into pr-draft

This commit is contained in:
Lykke Axlin
2021-09-28 08:44:45 +02:00
303 changed files with 5645 additions and 1689 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-common': patch
---
The `subscribe` method on the `Config` returned by `loadBackendConfig` is now forwarded through `getConfig` and `getOptionalConfig`.
+40
View File
@@ -0,0 +1,40 @@
---
'@backstage/create-app': patch
---
Added the default `ScmAuth` implementation to the app.
To apply this change to an existing app, head to `packages/app/apis.ts`, import `ScmAuth` from `@backstage/integration-react`, and add a `ScmAuth.createDefaultApiFactory()` to your list of APIs:
```diff
import {
ScmIntegrationsApi,
scmIntegrationsApiRef,
+ ScmAuth,
} from '@backstage/integration-react';
export const apis: AnyApiFactory[] = [
...
+ ScmAuth.createDefaultApiFactory(),
...
];
```
If you have integrations towards SCM providers other than the default ones (github.com, gitlab.com, etc.), you will want to create a custom `ScmAuth` factory instead, for example like this:
```ts
createApiFactory({
api: scmAuthApiRef,
deps: {
gheAuthApi: gheAuthApiRef,
githubAuthApi: githubAuthApiRef,
},
factory: ({ githubAuthApi, gheAuthApi }) =>
ScmAuth.merge(
ScmAuth.forGithub(githubAuthApi),
ScmAuth.forGithub(gheAuthApi, {
host: 'ghe.example.com',
}),
),
});
```
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend': patch
---
Fixed a bug where internal references within the catalog were broken when new entities where added through entity providers, such as registering a new location or adding one in configuration. These broken references then caused some entities to be incorrectly marked as orphaned and prevented refresh from working properly.
-45
View File
@@ -1,45 +0,0 @@
---
'@backstage/plugin-catalog-import': minor
---
Add initial support for customizing the catalog import page.
It is now possible to pass a custom layout to the import page, as it's already
supported by the search page. If no custom layout is passed, the default layout
is used.
```typescript
<Route path="/catalog-import" element={<CatalogImportPage />}>
<Page themeId="home">
<Header title="Register an existing component" />
<Content>
<ContentHeader title="Start tracking your components">
<SupportButton>
Start tracking your component in Backstage by adding it to the
software catalog.
</SupportButton>
</ContentHeader>
<Grid container spacing={2} direction="row-reverse">
<Grid item xs={12} md={4} lg={6} xl={8}>
Hello World
</Grid>
<Grid item xs={12} md={8} lg={6} xl={4}>
<ImportStepper />
</Grid>
</Grid>
</Content>
</Page>
</Route>
```
Previously it was possible to disable and customize the automatic pull request
feature by passing options to `<CatalogImportPage>` (`pullRequest.disable` and
`pullRequest.preparePullRequest`). This functionality is moved to the
`CatalogImportApi` which now provides an optional `preparePullRequest()`
function. The function can either be overridden to generate a different content
for the pull request, or removed to disable this feature.
The export of the long term deprecated legacy `<Router>` is removed, migrate to
`<CatalogImportPage>` instead.
+36
View File
@@ -0,0 +1,36 @@
---
'@backstage/plugin-catalog-import': minor
---
Switched to using the `ScmAuthApi` for authentication rather than GitHub auth. If you are instantiating your `CatalogImportClient` manually you now need to pass in an instance of `ScmAuthApi` instead.
Also be sure to register the `scmAuthApiRef` from the `@backstage/integration-react` in your app:
```ts
import { ScmAuth } from '@backstage/integration-react';
// in packages/app/apis.ts
const apis = [
// ... other APIs
ScmAuth.createDefaultApiFactory();
// OR
createApiFactory({
api: scmAuthApiRef,
deps: {
gheAuthApi: gheAuthApiRef,
githubAuthApi: githubAuthApiRef,
},
factory: ({ githubAuthApi, gheAuthApi }) =>
ScmAuth.merge(
ScmAuth.forGithub(githubAuthApi),
ScmAuth.forGithub(gheAuthApi, {
host: 'ghe.example.com',
}),
),
});
]
```
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli': patch
---
The `create-plugin` command now prefers dependency versions ranges that are already in the lockfile.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/integration': patch
---
Support selective GitHub app installation for GHE
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/catalog-client': patch
---
Update `AddLocationResponse` to optionally return `exists` to signal that the location already exists, this is only returned when calling `addLocation` in dryRun.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-catalog-backend': patch
---
Update `createLocation` to optionally return `exists` to signal that the location already exists, this is only returned for dry runs.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/cli': patch
---
Disabled ECMAScript transforms in app and backend builds in order to reduce bundle size and runtime performance. For the rationale and a full list of syntax that is no longer transformed, see https://github.com/alangpierce/sucrase#transforms. This also enables TypeScripts `useDefineForClassFields` flag by default, which in rare occasions could cause build failures. For instructions on how to mitigate issues due to the flag, see the [TypeScript documentation](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#the-usedefineforclassfields-flag-and-the-declare-property-modifier).
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-common': patch
---
Fix an issue where filtering in search doesn't work correctly for Bitbucket.
-37
View File
@@ -1,37 +0,0 @@
---
'@backstage/create-app': patch
---
This change adds an API endpoint for requesting a catalog refresh at `/refresh`, which is activated if a `RefreshService` is passed to `createRouter`.
The creation of the router has been abstracted behind the `CatalogBuilder` to simplify usage and future changes. The following **changes are required** to your `catalog.ts` for the refresh endpoint to function.
```diff
- import {
- CatalogBuilder,
- createRouter,
- } from '@backstage/plugin-catalog-backend';
+ import { CatalogBuilder } from '@backstage/plugin-catalog-backend';
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
const builder = await CatalogBuilder.create(env);
- const {
- entitiesCatalog,
- locationAnalyzer,
- processingEngine,
- locationService,
- } = await builder.build();
+ const { processingEngine, router } = await builder.build();
await processingEngine.start();
- return await createRouter({
- entitiesCatalog,
- locationAnalyzer,
- locationService,
- logger: env.logger,
- config: env.config,
- });
+ return router;
}
```
-22
View File
@@ -1,22 +0,0 @@
---
'@backstage/create-app': patch
---
Switched required engine from Node.js 12 or 14, to 14 or 16.
To apply these changes to an existing app, switch out the following in the root `package.json`:
```diff
"engines": {
- "node": "12 || 14"
+ "node": "14 || 16"
},
```
Also get rid of the entire `engines` object in `packages/backend/package.json`, as it is redundant:
```diff
- "engines": {
- "node": "12 || 14"
- },
```
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-catalog': patch
---
Updates the `AboutCard` with a refresh button that allows the entity to be scheduled for refresh.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-techdocs': patch
---
Added a check for the TechDocs annotation on the entity
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/core-components': patch
---
Stop forcing `target="_blank"` in the `SupportButton` but instead use the default logic of the `Link` component, that opens external targets in a new window and relative targets in the same window.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-catalog-backend-module-ldap': patch
---
Alters LDAP processor to handle one SearchEntry at a time
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli': patch
---
Fix duplication checks to stop looking for the old core packages, and to allow some explicitly
+89
View File
@@ -0,0 +1,89 @@
---
'@backstage/integration-react': patch
---
Added `ScmAuthApi` along with the implementation `ScmAuth`. The `ScmAuthApi` provides methods for client-side authentication towards multiple different source code management services simultaneously.
When requesting credentials you supply a URL along with the same options as the other `OAuthApi`s, and optionally a request for additional high-level scopes.
For example like this:
```ts
const { token } = await scmAuthApi.getCredentials({
url: 'https://ghe.example.com/backstage/backstage',
additionalScope: {
repoWrite: true,
},
});
```
The instantiation of the API can either be done with a default factory that adds support for the public providers (github.com, gitlab.com, etc.):
```ts
// in packages/app/apis.ts
ScmAuth.createDefaultApiFactory();
```
Or with a more custom setup that can add support for additional providers, for example like this:
```ts
createApiFactory({
api: scmAuthApiRef,
deps: {
gheAuthApi: gheAuthApiRef,
githubAuthApi: githubAuthApiRef,
},
factory: ({ githubAuthApi, gheAuthApi }) =>
ScmAuth.merge(
ScmAuth.forGithub(githubAuthApi),
ScmAuth.forGithub(gheAuthApi, {
host: 'ghe.example.com',
}),
),
});
```
The additional `gheAuthApiRef` utility API can be defined either inside the app itself if it's only used for this purpose, for inside an internal common package for APIs, such as `@internal/apis`:
```ts
const gheAuthApiRef: ApiRef<OAuthApi & ProfileInfoApi & SessionApi> =
createApiRef({
id: 'internal.auth.ghe',
});
```
And then implemented using the `GithubAuth` class from `@backstage/core-app-api`:
```ts
createApiFactory({
api: githubAuthApiRef,
deps: {
discoveryApi: discoveryApiRef,
oauthRequestApi: oauthRequestApiRef,
configApi: configApiRef,
},
factory: ({ discoveryApi, oauthRequestApi, configApi }) =>
GithubAuth.create({
provider: {
id: 'ghe',
icon: ...,
title: 'GHE'
},
discoveryApi,
oauthRequestApi,
defaultScopes: ['read:user'],
environment: configApi.getOptionalString('auth.environment'),
}),
})
```
Finally you also need to add and configure another GitHub provider to the `auth-backend` using the provider ID `ghe`:
```ts
// Add the following options to `createRouter` in packages/backend/src/plugins/auth.ts
providerFactories: {
ghe: createGithubProvider(),
},
```
Other providers follow the same steps, but you will want to use the appropriate auth API implementation in the frontend, such as for example `GitlabAuth`.
-7
View File
@@ -1,7 +0,0 @@
---
'@backstage/plugin-catalog-backend': minor
---
Add API endpoint for requesting a catalog refresh at `/refresh`, which is activated if a `RefreshService` is passed to `createRouter`.
The new method is used to trigger a refresh of an entity in an as localized was as possible, usually by refreshing the parent location.
+11
View File
@@ -0,0 +1,11 @@
---
'@backstage/plugin-catalog-backend': minor
---
Introduced a new `CatalogProcessorCache` that is available to catalog processors. It allows arbitrary values to be saved that will then be visible during the next run. The cache is scoped to each individual processor and entity, but is shared across processing steps in a single processor.
The cache is available as a new argument to each of the processing steps, except for `validateEntityKind` and `handleError`.
This also introduces an optional `getProcessorName` to the `CatalogProcessor` interface, which is used to provide a stable identifier for the processor. While it is currently optional it will move to be required in the future.
The breaking part of this change is the modification of the `state` field in the `EntityProcessingRequest` and `EntityProcessingResult` types. This is unlikely to have any impact as the `state` field was previously unused, but could require some minor updates.
-7
View File
@@ -1,7 +0,0 @@
---
'@backstage/create-app': patch
---
Bumped the default `@spotify/prettier-config` dependency to `^11.0.0`.
This is an optional upgrade, but you may be interested in doing the same, to get the most modern lint rules out there.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-circleci': patch
---
Swapped over to using Luxon as opposed to DayJS in the CircleCI plugin as part of the single Date library improvements.
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/catalog-client': minor
'@backstage/plugin-catalog-react': minor
---
Extends the `CatalogClient` interface with a `refreshEntity` method.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/cli': patch
---
Restrict imports on the form `../../plugins/x/src`
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-kubernetes': patch
---
Added a check for the Kubernetes annotation on the entity
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/plugin-api-docs': patch
'@backstage/plugin-catalog-react': patch
---
This makes Type and Lifecycle columns consistent for all table cases and adds a new line in Description column for better readability
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-git-release-manager': patch
---
Remove 'refresh' icon from success dialog's OK-CTA. User feedback deemed it confusing.
-19
View File
@@ -1,19 +0,0 @@
---
'@backstage/backend-common': patch
'@backstage/catalog-model': patch
'@backstage/cli': patch
'@backstage/config': patch
'@backstage/core-components': patch
'@backstage/plugin-catalog-backend': patch
'@backstage/plugin-catalog-backend-module-ldap': patch
'@backstage/plugin-catalog-backend-module-msgraph': patch
'@backstage/plugin-catalog-react': patch
'@backstage/plugin-circleci': patch
'@backstage/plugin-kafka-backend': patch
'@backstage/plugin-kubernetes-backend': patch
'@backstage/plugin-rollbar': patch
'@backstage/plugin-rollbar-backend': patch
'@backstage/plugin-search-backend-module-pg': patch
---
Bump `lodash` to remediate `SNYK-JS-LODASH-590103` security vulnerability
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-techdocs': patch
---
Make techdocs context search bar width adjust on smaller screens.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-auth-backend': patch
---
Update OAuth refresh handler to pass updated refresh token to ensure cookie is updated with new value.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/cli': patch
---
Switched the Jest YAML transform from `yaml-jest` to `jest-transform-yaml`, which works with newer versions of Node.js.
-7
View File
@@ -1,7 +0,0 @@
---
'@backstage/plugin-kubernetes': patch
'@backstage/plugin-kubernetes-backend': patch
'@backstage/plugin-kubernetes-common': patch
---
Provide access to the Kubernetes dashboard when viewing a specific resource
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog': patch
---
Update AboutCard to only render refresh button if the entity is managed by an url location.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-catalog-import': patch
---
The import form is now aware of locations that already exist. It lists them separately and shows a button for triggering a refresh.
+54 -49
View File
@@ -1,49 +1,54 @@
| Organization | Contact | Description of Use |
| ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Spotify](https://www.spotify.com) | [@leemills83](https://github.com/leemills83) | Main interface towards all of Spotify's infrastructure and technical documentation. |
| [bol.com](https://www.bol.com) | [@sagacity](https://github.com/sagacity) | Initial work being done to unify platform tooling. |
| [DFDS](https://www.dfds.com) | [@carlsendk](https://github.com/carlsendk) | V2 self-service platform. |
| [Roadie](https://roadie.io) | [@dtuite](https://github.com/dtuite) | Hosted, managed Backstage with easy set-up |
| [Roku](https://www.roku.com) | [@timurista](https://github.com/timurista) | Initial work on Cloud engineering service platform. |
| [SDA SE](https://sda.se) | [@Fox32](https://github.com/Fox32) | Central place for developing and sharing services in our insurance ecosystem. |
| [H-E-B](https://www.heb.com) | [@german-j-rodriguez](https://github.com/german-j-rodriguez) | Initial work on Engineering Portal service platform. |
| [American Airlines](https://www.aa.com) | [@paulpach](https://github.com/paulpach) | Central place for developers to develop and maintain applications |
| [Kiwi.com](https://kiwi.com) | [@aexvir](https://github.com/aexvir) | Replacing the frontend of [The Zoo](https://github.com/kiwicom/the-zoo), their service registry. |
| [Voi](https://www.voiscooters.com/) | [@K-Phoen](https://github.com/K-Phoen) | Developer portal, main gateway to our infrastructure, documentation and internal tooling. |
| [Talkdesk](https://www.talkdesk.com) | [@jaime-talkdesk](https://github.com/jaime-talkdesk) | Initial work for Engineering Portal and Self Provisioning to R&D |
| [Wealthsimple](https://www.wealthsimple.com) | [@andrewthauer](https://github.com/andrewthauer) | Developer portal, service catalog, documentation and tooling |
| [Grab](https://www.grab.com) | [@althafh](https://github.com/althafh) | Initial work as a unified interface for all of Grab's internal tooling |
| [Telenor Sweden](https://www.telenor.se) | [@O5ten](https://github.com/O5ten) | Building a developer portal for scaffolding projects towards our unified build environment and microservice stacks |
| [Fiverr](https://www.fiverr.com) | [@nirga](https://github.com/nirga) | Unifying separate tools that developers are using today (i.e. monitoring, dead letter queues management, etc.) into a single platform. |
| [Zalando SE](https://www.zalando.de) | [@leviferreira](https://github.com/leviferreira) | Building V2 of the Internal Development Portal. |
| [LegalZoom](https://legalzoom.com) | [@backjo](https://github.com/backjo) | Developer portal - hub for all engineering projects and metadata. |
| [Expedia Group](https://www.expediagroup.com) | [Mike Turner](mailto:miturner@expediagroup.com), [Sneha Kumar](mailto:snkumar@expediagroup.com), [@guillermomanzo](https://github.com/guillermomanzo), [Erik Lindgren](https://github.com/lindgren) | EG Common Developer Toolkit |
| [Paddle.com](https://paddle.com) | [Ioannis Georgoulas](https://github.com/geototti21) | Developer portal (Tech Docs, Service Catalog, Internal Tooling), we use vanilla Backstage FE and custom BE implementation in Go |
| [Acast.com](https://acast.com) | [Olle Lundberg](https://github.com/lndbrg) | Developer portal with tech docs, service catalog and a bunch of other internal tooling |
| [Lunar](https://lunar.app) | [Jacob Valdemar](https://github.com/JacobValdemar) | Internal developer portal for service overview and insights, API documentation, technical guides, onboarding guides and RFC's. |
| [Trendyol](https://trendyol.com) | [Gamze Senturk](https://github.com/gmzsenturk), [Mert Can Bilgic](https://github.com/mertcb) | The Developer Portal has been called `Pandora`. Provides an overview of Trendyol tech ecosystem. TechDocs, Catalog, Custom Plugins and Theme. |
| [Peloton](https://www.onepeloton.com/) | [Jim Haughwout](https://github.com/JimHaughwout) | Creating our first developer portal and tech-docs. Exploring Service Catalog, Tech Insights and Cost Insights as well. |
| [TELUS](https://telus.com) | [Seb Barre](https://github.com/sbarre) | The Go-to place to find answers about development and delivery at TELUS. |
| [Brex](https://www.brex.com/) | [Vamsi Chitters](https://github.com/vamsikc) | A centralized UI to understand how a service fits in the whole Brex architecture and manage a teams engineering dependencies. |
| [Oriflame](https://www.oriflame.com/) | [Oriflame](https://github.com/oriflame) | Internal developer portal for services, single page apps and packages overview, API documentation, technical guides, tech-radar and more. |
| [Booz Allen Hamilton](https://www.boozallen.com/) | [Jason Miller](https://github.com/JasonMiller-BAH) | Developer portal for a full-stack software development ecosystem that accelerates consistent and repeatable Modern Software Development practices for internal innovation and investments. |
| [Netflix](https://www.netflix.com/) | [bleathem](https://github.com/bleathem) | Our Backstage implementation will be the front door to a unified experience connecting our internal platform products across important workflows with integrated knowledge and support. |
| [b.well](https://www.icanbwell.com/) | [Jacob Rosales](https://github.com/jrosales) | Foundation for our engineering portal and cloud insights. |
| [PagerDuty](https://www.pagerduty.com/) | [Mark Shaw](https://github.com/markshawtoronto) | Developer portal, initially focused on software templates and tech-docs. |
| [MoonShiner](https://moonshiner.at) | [Fabian Hippmann](https://github.com/FabianHippmann) | Developer portal - helps us keep track of our customer projects, onboard new developers & improve our development process 🌕🚀🧑‍🚀 |
| [FundApps](https://www.fundapps.co/) | [Elliot Greenwood](https://github.com/egnwd) | Developer Portal - A place for us to keep track of our projects and documentation for all services and processes |
| [DAZN](https://dazn.com/) | [Lou Bichard](https://twitter.com/loujaybee), [Marco Crivellaro](https://github.com/crivetechie), [Alex Hollerith](mailto:alex.hollerith@dazn.com) | Ingesting all of DAZN's repos for the catalog, migrating our internal platform apps (pull request boards, release information, inner source marketplace etc) to Backstage plugins (where applicable). |
| [HelloFresh](https://www.hellofresh.de/) | [@iammuho](https://github.com/iammuho), [@ElenaForester](https://github.com/ElenaForester), [@diegomarangoni](https://github.com/diegomarangoni) | Our developer portal at HelloFresh - Spread across an organisation of 500+ engineers globally. |
| [FactSet](https://www.factset.com/) | [@kuangp](https://github.com/kuangp) | Developer portal to provide discoverability to all internal components, APIs, documentation, and scaffold templates with integrations to our internal infrastructure tools. |
| [Workrise](https://www.workrise.com/) | [Michael Rode](https://github.com/michaelrode) | Developer portal, main gateway to our infrastructure, documentation and internal tooling. |
| [RedVentures](https://www.redventures.com/) | [Chris Diaz](https://github.com/codingdiaz) | Developer portal that brings everything an engineer needs to provide value into a single pane of glass. |
| [MavTek](https://www.mavtek.com/) | [@fgascon](https://github.com/fgascon) | Developer portal focused on standardizing practices, centralizing documentation and streamlining developer practices. |
| [QuintoAndar](https://www.quintoandar.com.br/) | [@quintoandar](https://github.com/quintoandar) | Developer portal, services catalog and centralization of service metrics. |
| [empathy.co](https://empathy.co/) | [@guillermotti](https://github.com/guillermotti) | Developer portal for tech docs, service catalog, plugin discovery and much more. |
| [creditas.com](https://creditas.com/) | [@aureliosaraiva](https://github.com/aureliosaraiva) [@Creditas](https://github.com/creditas) | Centralization of all services, standards, documentation, etc. We started the deployment process. |
| [Prisjakt](https://www.prisjakt.nu) / [PriceSpy](https://pricespy.co.uk) | [@kennylindahl](https://github.com/kennylindahl) | Internal developer portal - Documentation, scaffolding, software catalog, TechRadar, Gitlab org data integration |
| [Powerspike](https://powerspike.tv/) | [@trelore](https://github.com/trelore) | Developer portal for documentation of core libraries and repositories. |
| [2U](https://2u.com) | [Andrew Thal](https://github.com/athal7) | Development team home-base, promoting service discoverability, resource dependencies, and tech radar |
| [Taxfix](https://taxfix.de/) | [Sami Ur Rehman](https://github.com/samiurrehman92) | Developer's portal with software catalog at it's core. Hosts API Specs, Tech Docs, Tech Radar and some custom plugins. |
| [Busuu](https://busuu.com/) | [Adam Tester](https://github.com/adamtester) | Developer portal with service catalog, API docs, Event docs, service templating, and cost insights. |
| [Loadsmart](https://loadsmart.com/) | [Loadsmart](https://github.com/loadsmart) | Improve services visibility and operations for service owners and developers. |
| Organization | Contact | Description of Use |
| ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Spotify](https://www.spotify.com) | [@leemills83](https://github.com/leemills83) | Main interface towards all of Spotify's infrastructure and technical documentation. |
| [bol.com](https://www.bol.com) | [@sagacity](https://github.com/sagacity) | Initial work being done to unify platform tooling. |
| [DFDS](https://www.dfds.com) | [@carlsendk](https://github.com/carlsendk) | V2 self-service platform. |
| [Roadie](https://roadie.io) | [@dtuite](https://github.com/dtuite) | Hosted, managed Backstage with easy set-up |
| [Roku](https://www.roku.com) | [@timurista](https://github.com/timurista) | Initial work on Cloud engineering service platform. |
| [SDA SE](https://sda.se) | [@Fox32](https://github.com/Fox32) | Central place for developing and sharing services in our insurance ecosystem. |
| [H-E-B](https://www.heb.com) | [@german-j-rodriguez](https://github.com/german-j-rodriguez) | Initial work on Engineering Portal service platform. |
| [American Airlines](https://www.aa.com) | [@paulpach](https://github.com/paulpach) | Central place for developers to develop and maintain applications |
| [Kiwi.com](https://kiwi.com) | [@aexvir](https://github.com/aexvir) | Replacing the frontend of [The Zoo](https://github.com/kiwicom/the-zoo), their service registry. |
| [Voi](https://www.voiscooters.com/) | [@K-Phoen](https://github.com/K-Phoen) | Developer portal, main gateway to our infrastructure, documentation and internal tooling. |
| [Talkdesk](https://www.talkdesk.com) | [@jaime-talkdesk](https://github.com/jaime-talkdesk) | Initial work for Engineering Portal and Self Provisioning to R&D |
| [Wealthsimple](https://www.wealthsimple.com) | [@andrewthauer](https://github.com/andrewthauer) | Developer portal, service catalog, documentation and tooling |
| [Grab](https://www.grab.com) | [@althafh](https://github.com/althafh) | Initial work as a unified interface for all of Grab's internal tooling |
| [Telenor Sweden](https://www.telenor.se) | [@O5ten](https://github.com/O5ten) | Building a developer portal for scaffolding projects towards our unified build environment and microservice stacks |
| [Fiverr](https://www.fiverr.com) | [@nirga](https://github.com/nirga) | Unifying separate tools that developers are using today (i.e. monitoring, dead letter queues management, etc.) into a single platform. |
| [Zalando SE](https://www.zalando.de) | [@leviferreira](https://github.com/leviferreira) | Building V2 of the Internal Development Portal. |
| [LegalZoom](https://legalzoom.com) | [@backjo](https://github.com/backjo) | Developer portal - hub for all engineering projects and metadata. |
| [Expedia Group](https://www.expediagroup.com) | [Mike Turner](mailto:miturner@expediagroup.com), [Sneha Kumar](mailto:snkumar@expediagroup.com), [@guillermomanzo](https://github.com/guillermomanzo), [Erik Lindgren](https://github.com/lindgren) | EG Common Developer Toolkit |
| [Paddle.com](https://paddle.com) | [Ioannis Georgoulas](https://github.com/geototti21) | Developer portal (Tech Docs, Service Catalog, Internal Tooling), we use vanilla Backstage FE and custom BE implementation in Go |
| [Acast.com](https://acast.com) | [Olle Lundberg](https://github.com/lndbrg) | Developer portal with tech docs, service catalog and a bunch of other internal tooling |
| [Lunar](https://lunar.app) | [Jacob Valdemar](https://github.com/JacobValdemar) | Internal developer portal for service overview and insights, API documentation, technical guides, onboarding guides and RFC's. |
| [Trendyol](https://trendyol.com) | [Gamze Senturk](https://github.com/gmzsenturk), [Mert Can Bilgic](https://github.com/mertcb) | The Developer Portal has been called `Pandora`. Provides an overview of Trendyol tech ecosystem. TechDocs, Catalog, Custom Plugins and Theme. |
| [Peloton](https://www.onepeloton.com/) | [Jim Haughwout](https://github.com/JimHaughwout) | Creating our first developer portal and tech-docs. Exploring Service Catalog, Tech Insights and Cost Insights as well. |
| [TELUS](https://telus.com) | [Seb Barre](https://github.com/sbarre) | The Go-to place to find answers about development and delivery at TELUS. |
| [Brex](https://www.brex.com/) | [Vamsi Chitters](https://github.com/vamsikc) | A centralized UI to understand how a service fits in the whole Brex architecture and manage a teams engineering dependencies. |
| [Oriflame](https://www.oriflame.com/) | [Oriflame](https://github.com/oriflame) | Internal developer portal for services, single page apps and packages overview, API documentation, technical guides, tech-radar and more. |
| [Booz Allen Hamilton](https://www.boozallen.com/) | [Jason Miller](https://github.com/JasonMiller-BAH) | Developer portal for a full-stack software development ecosystem that accelerates consistent and repeatable Modern Software Development practices for internal innovation and investments. |
| [Netflix](https://www.netflix.com/) | [bleathem](https://github.com/bleathem) | Our Backstage implementation will be the front door to a unified experience connecting our internal platform products across important workflows with integrated knowledge and support. |
| [b.well](https://www.icanbwell.com/) | [Jacob Rosales](https://github.com/jrosales) | Foundation for our engineering portal and cloud insights. |
| [PagerDuty](https://www.pagerduty.com/) | [Mark Shaw](https://github.com/markshawtoronto) | Developer portal, initially focused on software templates and tech-docs. |
| [MoonShiner](https://moonshiner.at) | [Fabian Hippmann](https://github.com/FabianHippmann) | Developer portal - helps us keep track of our customer projects, onboard new developers & improve our development process 🌕🚀🧑‍🚀 |
| [FundApps](https://www.fundapps.co/) | [Elliot Greenwood](https://github.com/egnwd) | Developer Portal - A place for us to keep track of our projects and documentation for all services and processes |
| [DAZN](https://dazn.com/) | [Lou Bichard](https://twitter.com/loujaybee), [Marco Crivellaro](https://github.com/crivetechie), [Alex Hollerith](mailto:alex.hollerith@dazn.com) | Ingesting all of DAZN's repos for the catalog, migrating our internal platform apps (pull request boards, release information, inner source marketplace etc) to Backstage plugins (where applicable). |
| [HelloFresh](https://www.hellofresh.de/) | [@iammuho](https://github.com/iammuho), [@ElenaForester](https://github.com/ElenaForester), [@diegomarangoni](https://github.com/diegomarangoni) | Our developer portal at HelloFresh - Spread across an organisation of 500+ engineers globally. |
| [FactSet](https://www.factset.com/) | [@kuangp](https://github.com/kuangp) | Developer portal to provide discoverability to all internal components, APIs, documentation, and scaffold templates with integrations to our internal infrastructure tools. |
| [Workrise](https://www.workrise.com/) | [Michael Rode](https://github.com/michaelrode) | Developer portal, main gateway to our infrastructure, documentation and internal tooling. |
| [RedVentures](https://www.redventures.com/) | [Chris Diaz](https://github.com/codingdiaz) | Developer portal that brings everything an engineer needs to provide value into a single pane of glass. |
| [MavTek](https://www.mavtek.com/) | [@fgascon](https://github.com/fgascon) | Developer portal focused on standardizing practices, centralizing documentation and streamlining developer practices. |
| [QuintoAndar](https://www.quintoandar.com.br/) | [@quintoandar](https://github.com/quintoandar) | Developer portal, services catalog and centralization of service metrics. |
| [empathy.co](https://empathy.co/) | [@guillermotti](https://github.com/guillermotti) | Developer portal for tech docs, service catalog, plugin discovery and much more. |
| [creditas.com](https://creditas.com/) | [@aureliosaraiva](https://github.com/aureliosaraiva) [@Creditas](https://github.com/creditas) | Centralization of all services, standards, documentation, etc. We started the deployment process. |
| [Prisjakt](https://www.prisjakt.nu) / [PriceSpy](https://pricespy.co.uk) | [@kennylindahl](https://github.com/kennylindahl) | Internal developer portal - Documentation, scaffolding, software catalog, TechRadar, Gitlab org data integration |
| [Powerspike](https://powerspike.tv/) | [@trelore](https://github.com/trelore) | Developer portal for documentation of core libraries and repositories. |
| [2U](https://2u.com) | [Andrew Thal](https://github.com/athal7) | Development team home-base, promoting service discoverability, resource dependencies, and tech radar |
| [Taxfix](https://taxfix.de/) | [Sami Ur Rehman](https://github.com/samiurrehman92) | Developer's portal with software catalog at it's core. Hosts API Specs, Tech Docs, Tech Radar and some custom plugins. |
| [Busuu](https://busuu.com/) | [Adam Tester](https://github.com/adamtester) | Developer portal with service catalog, API docs, Event docs, service templating, and cost insights. |
| [Loadsmart](https://loadsmart.com/) | [Loadsmart](https://github.com/loadsmart) | Improve services visibility and operations for service owners and developers. |
| [Monzo](https://monzo.com/) | [@WillSewell](https://github.com/WillSewell), [@joechrisellis](https://github.com/joechrisellis) | Developer portal showing metadata and docs for over 2000 microservices. We have built a number of plugins such as a UI for our system to measure [software excellence](https://monzo.com/blog/2021/09/15/how-we-measure-software-excellence), and a UI to show deployment and config change events. |
| [Vaimo](https://www.vaimo.com) | [@vaimo-magnus](https://github.com/vaimo-magnus) | Developer Portal for our developers at Vaimo, currently docs and self-service towards our internal PaaS based on k8s. Plans to extend the catalog into Projects, Environments etc |
| [Wayfair](https://www.wayfair.com) | [@fransan](https://github.com/fransan), [@errskipower](https://github.com/errskipower), [@hrrs](https://github.com/hrrs) | Developer portal for service catalog, technical documentation, and APIs. |
| [CircleHD](https://www.circlehd.com) | [@circlehddev](https://github.com/circlehddev) | Developer Portal for internal dev team across the globe |
| [CastDesk](https://castdesk.com) | [@circlehddev](https://github.com/circlehddev) | Developer Portal for internal dev team across the globe |
+12
View File
@@ -102,6 +102,18 @@ Signed-off-by: Jane Smith <jane.smith@example.com>
Note: If you have already pushed you branch to a remote, you might have to force push: `git push -f` after the rebase.
### Using GitHub Desktop?
If you are using the GitHub Desktop client, you need to manually add the `Signed-off-by` line to the Description field on the Changes tab before committing:
```
Awesome description (commit message)
Signed-off-by: Jane Smith <jane.smith@example.com>
```
In case you forgot to add the line to your most recent commit, you can amend the commit message from the History tab before pushing your branch (GitHub Desktop 2.9 or later).
## Creating Changesets
We use [changesets](https://github.com/atlassian/changesets) to help us prepare releases. They help us make sure that every package affected by a change gets a proper version number and an entry in its `CHANGELOG.md`. To make the process of generating releases easy, it helps when contributors include changesets with their pull requests.
@@ -23,7 +23,7 @@ function inject_config() {
# escape ' and " twice, for both sed and json
local config_escaped_1
config_escaped_1="$(echo "$config" | jq -cM . | sed -e 's/[\\"\x27]/\\&/g')" # \x27 = '
config_escaped_1="$(echo "$config" | jq -cM . | sed -e 's/[\\"'\'']/\\&/g')"
# escape / and & for sed
local config_escaped_2
config_escaped_2="$(echo "$config_escaped_1" | sed -e 's/[\/&]/\\&/g')"
@@ -188,9 +188,9 @@ Assuming you follow the common plugin structure, the changes to your front-end m
```diff
// plugins/internal-plugin/src/api.ts
- import {createApiRef} from '@backstage/core';
+ import {createApiRef, IdentityApi} from '@backstage/core';
import {Config} from '@backstage/config';
- import { createApiRef } from '@backstage/core-plugin-api';
+ import { createApiRef, IdentityApi } from '@backstage/core-plugin-api';
import { Config } from '@backstage/config';
// ...
type MyApiOptions = {
@@ -237,14 +237,14 @@ import {
createApiFactory,
createPlugin,
+ identityApiRef,
} from '@backstage/core';
import {mypluginPageRouteRef} from './routeRefs';
import {MyApi, myApiRef} from './api';
} from '@backstage/core-plugin-api';
import { myPluginPageRouteRef } from './routeRefs';
import { MyApi, myApiRef } from './api';
export const plugin = createPlugin({
id: 'my-plugin',
routes: {
mainPage: mypluginPageRouteRef,
mainPage: myPluginPageRouteRef,
},
apis: [
createApiFactory({
@@ -253,9 +253,9 @@ export const plugin = createPlugin({
configApi: configApiRef,
+ identityApi: identityApiRef,
},
- factory: ({configApi}) =>
- factory: ({ configApi }) =>
- new MyApi({ configApi }),
+ factory: ({configApi, identityApi}) =>
+ factory: ({ configApi, identityApi }) =>
+ new MyApi({ configApi, identityApi }),
}),
],
+2 -2
View File
@@ -5,8 +5,8 @@ sidebar_label: Auth0
description: Adding Auth0 as an authentication provider in Backstage
---
The Backstage `core-api` package comes with an Auth0 authentication provider
that can authenticate users using OAuth.
The Backstage `core-plugin-api` package comes with an Auth0 authentication
provider that can authenticate users using OAuth.
## Create an Auth0 Application
+2 -2
View File
@@ -5,8 +5,8 @@ sidebar_label: GitHub
description: Adding GitHub OAuth as an authentication provider in Backstage
---
The Backstage `core-api` package comes with a GitHub authentication provider
that can authenticate users using GitHub or GitHub Enterprise OAuth.
The Backstage `core-plugin-api` package comes with a GitHub authentication
provider that can authenticate users using GitHub or GitHub Enterprise OAuth.
## Create an OAuth App on GitHub
+2 -2
View File
@@ -5,8 +5,8 @@ sidebar_label: GitLab
description: Adding GitLab OAuth as an authentication provider in Backstage
---
The Backstage `core-api` package comes with a GitLab authentication provider
that can authenticate users using GitLab OAuth.
The Backstage `core-plugin-api` package comes with a GitLab authentication
provider that can authenticate users using GitLab OAuth.
## Create an OAuth App on GitLab
+2 -2
View File
@@ -5,8 +5,8 @@ sidebar_label: Google
description: Adding Google OAuth as an authentication provider in Backstage
---
The Backstage `core-api` package comes with a Google authentication provider
that can authenticate users using Google OAuth.
The Backstage `core-plugin-api` package comes with a Google authentication
provider that can authenticate users using Google OAuth.
## Create OAuth Credentials
+2 -2
View File
@@ -5,8 +5,8 @@ sidebar_label: Azure
description: Adding Microsoft Azure as an authentication provider in Backstage
---
The Backstage `core-api` package comes with a Microsoft authentication provider
that can authenticate users using Azure OAuth.
The Backstage `core-plugin-api` package comes with a Microsoft authentication
provider that can authenticate users using Azure OAuth.
## Create an App Registration on Azure
+2 -2
View File
@@ -5,8 +5,8 @@ sidebar_label: Okta
description: Adding Okta OAuth as an authentication provider in Backstage
---
The Backstage `core-api` package comes with a Okta authentication provider that
can authenticate users using Okta OpenID Connect.
The Backstage `core-plugin-api` package comes with a Okta authentication
provider that can authenticate users using Okta OpenID Connect.
## Create an Application on Okta
+2 -2
View File
@@ -5,8 +5,8 @@ sidebar_label: OneLogin
description: Adding OneLogin OIDC as an authentication provider in Backstage
---
The Backstage `core-api` package comes with a OneLogin authentication provider
that can authenticate users using OpenID Connect.
The Backstage `core-plugin-api` package comes with a OneLogin authentication
provider that can authenticate users using OpenID Connect.
## Create an Application on OneLogin
@@ -23,7 +23,7 @@ Locations are added to the catalog under the `catalog.locations` key:
catalog:
locations:
- type: url
target: https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/artist-lookup-component.yaml
target: https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/components/artist-lookup-component.yaml
```
The `url` type locations are handled by a standard processor included with the
+53
View File
@@ -217,3 +217,56 @@ techdocs:
[beta-migrate-bug]:
https://github.com/backstage/backstage/issues/new?assignees=&labels=bug&template=bug_template.md&title=[TechDocs]%20Unable%20to%20run%20beta%20migration
[using-cloud-storage]: ./using-cloud-storage.md
## How to implement your own TechDocs APIs
The TechDocs plugin provides implementations of two primary APIs by default: the
[TechDocsStorageApi](https://github.com/backstage/backstage/blob/55114cfeb7045e3e5eeeaf67546b58964f4adcc7/plugins/techdocs/src/api.ts#L33),
which is responsible for talking to TechDocs storage to fetch files to render,
and
[TechDocsApi](https://github.com/backstage/backstage/blob/55114cfeb7045e3e5eeeaf67546b58964f4adcc7/plugins/techdocs/src/api.ts#L49),
which is responsible for talking to techdocs-backend.
There may be occasions where you need to implement these two APIs yourself, to
customize them to your own needs. The purpose of this guide is to walk you
through how to do that in two steps.
1. Implement the `TechDocsStorageApi` and `TechDocsApi` interfaces according to
your needs.
```typescript
export class TechDocsCustomStorageApi implements TechDocsStorageApi {
// your implementation
}
export class TechDocsCustomApiClient implements TechDocsApi {
// your implementation
}
```
2. Override the API refs `techdocsStorageApiRef` and `techdocsApiRef` with your
new implemented APIs in the `App.tsx` using `ApiFactories`.
[Read more about App APIs](https://backstage.io/docs/api/utility-apis#app-apis).
```typescript
const app = createApp({
apis: [
// TechDocsStorageApi
createApiFactory({
api: techdocsStorageApiRef,
deps: { discoveryApi: discoveryApiRef, configApi: configApiRef },
factory({ discoveryApi, configApi }) {
return new TechDocsCustomStorageApi({ discoveryApi, configApi });
},
}),
// TechDocsApi
createApiFactory({
api: techdocsApiRef,
deps: { discoveryApi: discoveryApiRef },
factory({ discoveryApi }) {
return new TechDocsCustomApiClient({ discoveryApi });
},
}),
],
});
```
+4 -4
View File
@@ -166,12 +166,12 @@ are separated out into their own folder, see further down.
plugin and [techdocs-cli](https://github.com/backstage/techdocs-cli).
- [`test-utils/`](https://github.com/backstage/backstage/tree/master/packages/test-utils) -
This package contains specific testing facilities used when testing
`core-api`.
This package contains more general purpose testing facilities for testing a
Backstage App or its plugins.
- [`test-utils-core/`](https://github.com/backstage/backstage/tree/master/packages/test-utils-core) -
This package contains more general purpose testing facilities for testing a
Backstage App.
This package contains specific testing facilities used when testing Backstage
core internals.
- [`theme/`](https://github.com/backstage/backstage/tree/master/packages/theme) -
Holds the Backstage Theme.
+57 -5
View File
@@ -11,12 +11,12 @@ catalog entities located in Bitbucket. The processor will crawl your Bitbucket
account and register entities matching the configured path. This can be useful
as an alternative to static locations or manually adding things to the catalog.
> Note: The Bitbucket Discovery Processor currently only supports a self-hosted
> Bitbucket Server, and not the hosted Bitbucket Cloud product.
## Self-hosted Bitbucket Server
To use the discovery processor, you'll need a Bitbucket integration
[set up](locations.md) with a `BITBUCKET_TOKEN` and a `BITBUCKET_API_BASE_URL`.
Then you can add a location target to the catalog configuration:
To use the discovery processor with a self-hosted Bitbucket Server, you'll need
a Bitbucket integration [set up](locations.md) with a `BITBUCKET_TOKEN` and a
`BITBUCKET_API_BASE_URL`. Then you can add a location target to the catalog
configuration:
```yaml
catalog:
@@ -44,6 +44,58 @@ The target is composed of four parts:
will result in:
`https://bitbucket.mycompany.com/projects/my-project/repos/service-a/catalog-info.yaml`.
## Bitbucket Cloud
To use the discovery processor with Bitbucket Cloud, you'll need a Bitbucket
integration [set up](locations.md) with a `username` and an `appPassword`. Then
you can add a location target to the catalog configuration:
```yaml
catalog:
locations:
- type: bitbucket-discovery
target: https://bitbucket.org/workspaces/my-workspace
```
Note the `bitbucket-discovery` type, as this is not a regular `url` processor.
The target is composed of the following parts:
- The base URL for Bitbucket, `https://bitbucket.org`
- The workspace name to scan (following the `workspaces/` path part), which must
match a workspace accessible with the username of your integration.
- (Optional) The project key to scan (following the `projects/` path part),
which accepts \* wildcard tokens. If omitted, repositories from all projects
in the workspace are included.
- (Optional) The repository blob to scan (following the `repos/` path part),
which accepts \* wildcard tokens. If omitted, all repositories in the
workspace are included.
- (Optional) The `catalogPath` query argument to specify the location within
each repository to find the catalog YAML file. This will usually be
`/catalog-info.yaml` or a similar variation for catalog files stored in the
root directory of each repository. If omitted, the default value
`catalog-info.yaml` will be used.
- (Optional) The `q` query argument to be passed through to Bitbucket for
filtering results via the API. This is the most flexible option and will
reduce the amount of API calls if you have a large workspace.
[See here for the specification](https://developer.atlassian.com/bitbucket/api/2/reference/meta/filtering)
for the query argument (will be passed as the `q` query parameter).
Examples:
- `https://bitbucket.org/workspaces/my-workspace/projects/my-project` will find
all repositories in the `my-project` project in the `my-workspace` workspace.
- `https://bitbucket.org/workspaces/my-workspace/repos/service-*` will find all
repositories starting with `service-` in the `my-workspace` workspace.
- `https://bitbucket.org/workspaces/my-workspace/projects/apis-*/repos/service-*`
will find all repositories starting with `service-`, in all projects starting
with `apis-` in the `my-workspace` workspace.
- `https://bitbucket.org/workspaces/my-workspace?q=project.key ~ "my-project"`
will find all repositories in a project containing `my-project` in its key.
- `https://bitbucket.org/workspaces/my-workspace?catalogPath=my/nested/path/catalog.yaml`
will find all repositories in the `my-workspace` workspace and use the catalog
file at `my/nested/path/catalog.yaml`.
## Custom repository processing
The Bitbucket Discovery Processor will by default emit a location for each
+18 -7
View File
@@ -49,17 +49,28 @@ When using a custom pattern, the target is composed of three parts:
## GitHub API Rate Limits
GitHub
[rate limits](https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting)
API requests to 5,000 per hour (or more for Enterprise accounts). The default
Backstage catalog backend refreshes data every 100 seconds, which issues an API
request for each discovered location.
GitHub [rate limits] API requests to 5,000 per hour (or more for Enterprise
accounts). The default Backstage catalog backend refreshes data every 100
seconds, which issues an API request for each discovered location.
This means if you have more than ~140 catalog entities, you may get throttled by
rate limiting. This will soon be resolved once catalog refreshes make use of
ETags; to work around this in the meantime, you can change the refresh rate of
the catalog in your `packages/backend/src/plugins/catalog.ts` file, or configure
Backstage to use the [github-apps plugin](../../plugins/github-apps.md).
the catalog in your `packages/backend/src/plugins/catalog.ts` file:
```typescript
const builder = await CatalogBuilder.create(env);
// For example, to refresh every 5 minutes (300 seconds).
builder.setRefreshIntervalSeconds(300);
```
Alternatively, or additionally, you can configure [github-apps] authentication
which carries a much higher rate limit at GitHub.
This is true for any method of adding GitHub entities to the catalog, but
especially easy to hit with automatic discovery.
[rate limits]:
https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting
[github-apps]: ../../plugins/github-apps.md
+4 -2
View File
@@ -60,5 +60,7 @@ preferred.
## Authentication with GitHub Apps
Alternatively, Backstage can use GitHub Apps for backend authentication. This
has higher rate limits, and a clearer authorization model. See the
[github-apps plugin](../../plugins/github-apps.md) for how to set this up.
has higher rate limits, and a clearer authorization model. See [github-apps] for
how to set this up.
[github-apps]: ../../plugins/github-apps.md
+5
View File
@@ -0,0 +1,5 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
registry "https://registry.npmjs.org/"
network-timeout 300000
+9
View File
@@ -0,0 +1,9 @@
---
title: Bugsnag
author: roadie.io
authorUrl: https://roadie.io/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=bugsnag
category: Monitoring
description: View and monitor Bugsnag errors.
documentation: https://roadie.io/backstage/plugins/bugsnag/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=bugsnag
iconUrl: https://roadie.io/images/logos/bugsnag.png
npmPackageName: '@roadiehq/backstage-plugin-bugsnag'
+1 -1
View File
@@ -16,7 +16,7 @@
"lock:check": "yarn-lock-check"
},
"devDependencies": {
"@spotify/prettier-config": "^11.0.0",
"@spotify/prettier-config": "^12.0.0",
"docusaurus": "^2.0.0-alpha.70",
"js-yaml": "^4.1.0",
"prettier": "^2.4.1",
+4 -4
View File
@@ -909,10 +909,10 @@
resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd"
integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==
"@spotify/prettier-config@^11.0.0":
version "11.0.0"
resolved "https://registry.npmjs.org/@spotify/prettier-config/-/prettier-config-11.0.0.tgz#d91e0546a8c1c0f7299e2edc7e44306e9be210f6"
integrity sha512-dOI13j1uHMZkRxhZuge/ugOE7Aqcg7Nxki932lDZuXyY4G8CGxkc/66PeQ8pR4PCzThHORXo7Ptvau6bh101lQ==
"@spotify/prettier-config@^12.0.0":
version "12.0.0"
resolved "https://registry.npmjs.org/@spotify/prettier-config/-/prettier-config-12.0.0.tgz#936ca5e977cfccbccd1731ab98b1f2bf65852b5d"
integrity sha512-64WWqE40U/WwWV8iIQBseTU+b2t+SdJSyQoCLdVPCKM9uf7KOjRivVwXe4KlWoV3y7duNSGuB2UgWhkXzscVmQ==
"@types/cheerio@^0.22.8":
version "0.22.23"
+1 -1
View File
@@ -69,7 +69,7 @@
"fs-extra": "9.1.0",
"husky": "^6.0.0",
"lerna": "^4.0.0",
"lint-staged": "^10.1.0",
"lint-staged": "^11.1.2",
"prettier": "^2.2.1",
"recursive-readdir": "^2.2.2",
"shx": "^0.3.2",
+42
View File
@@ -1,5 +1,47 @@
# example-app
## 0.2.47
### Patch Changes
- Updated dependencies
- @backstage/plugin-explore@0.3.17
- @backstage/core-components@0.5.0
- @backstage/plugin-catalog-import@0.6.0
- @backstage/plugin-catalog-graph@0.1.1
- @backstage/cli@0.7.13
- @backstage/plugin-catalog@0.6.16
- @backstage/plugin-user-settings@0.3.6
- @backstage/plugin-circleci@0.2.24
- @backstage/plugin-catalog-react@0.5.0
- @backstage/plugin-api-docs@0.6.9
- @backstage/catalog-model@0.9.3
- @backstage/plugin-rollbar@0.3.15
- @backstage/plugin-techdocs@0.11.3
- @backstage/plugin-kubernetes@0.4.14
- @backstage/core-app-api@0.1.14
- @backstage/integration-react@0.1.10
- @backstage/plugin-badges@0.2.10
- @backstage/plugin-cloudbuild@0.2.24
- @backstage/plugin-code-coverage@0.1.12
- @backstage/plugin-cost-insights@0.11.7
- @backstage/plugin-gcp-projects@0.3.5
- @backstage/plugin-github-actions@0.4.19
- @backstage/plugin-graphiql@0.2.17
- @backstage/plugin-home@0.4.1
- @backstage/plugin-jenkins@0.5.7
- @backstage/plugin-kafka@0.2.16
- @backstage/plugin-lighthouse@0.2.26
- @backstage/plugin-newrelic@0.3.5
- @backstage/plugin-org@0.3.24
- @backstage/plugin-pagerduty@0.3.14
- @backstage/plugin-scaffolder@0.11.5
- @backstage/plugin-search@0.4.12
- @backstage/plugin-sentry@0.3.22
- @backstage/plugin-shortcuts@0.1.9
- @backstage/plugin-tech-radar@0.4.8
- @backstage/plugin-todo@0.1.11
## 0.2.46
### Patch Changes
+37 -37
View File
@@ -1,46 +1,46 @@
{
"name": "example-app",
"version": "0.2.46",
"version": "0.2.47",
"private": true,
"bundled": true,
"dependencies": {
"@backstage/catalog-model": "^0.9.2",
"@backstage/cli": "^0.7.12",
"@backstage/core-app-api": "^0.1.13",
"@backstage/core-components": "^0.4.2",
"@backstage/catalog-model": "^0.9.3",
"@backstage/cli": "^0.7.13",
"@backstage/core-app-api": "^0.1.14",
"@backstage/core-components": "^0.5.0",
"@backstage/core-plugin-api": "^0.1.8",
"@backstage/integration-react": "^0.1.9",
"@backstage/plugin-api-docs": "^0.6.8",
"@backstage/plugin-badges": "^0.2.9",
"@backstage/plugin-catalog": "^0.6.15",
"@backstage/plugin-catalog-graph": "^0.1.0",
"@backstage/plugin-catalog-import": "^0.5.21",
"@backstage/plugin-catalog-react": "^0.4.6",
"@backstage/plugin-circleci": "^0.2.23",
"@backstage/plugin-cloudbuild": "^0.2.23",
"@backstage/plugin-code-coverage": "^0.1.11",
"@backstage/plugin-cost-insights": "^0.11.6",
"@backstage/plugin-explore": "^0.3.16",
"@backstage/plugin-gcp-projects": "^0.3.4",
"@backstage/plugin-github-actions": "^0.4.18",
"@backstage/plugin-graphiql": "^0.2.16",
"@backstage/plugin-home": "^0.4.0",
"@backstage/plugin-jenkins": "^0.5.6",
"@backstage/plugin-kafka": "^0.2.15",
"@backstage/plugin-kubernetes": "^0.4.13",
"@backstage/plugin-lighthouse": "^0.2.25",
"@backstage/plugin-newrelic": "^0.3.4",
"@backstage/plugin-org": "^0.3.23",
"@backstage/plugin-pagerduty": "0.3.13",
"@backstage/plugin-rollbar": "^0.3.14",
"@backstage/plugin-scaffolder": "^0.11.4",
"@backstage/plugin-search": "^0.4.11",
"@backstage/plugin-sentry": "^0.3.21",
"@backstage/plugin-shortcuts": "^0.1.8",
"@backstage/plugin-tech-radar": "^0.4.7",
"@backstage/plugin-techdocs": "^0.11.2",
"@backstage/plugin-todo": "^0.1.10",
"@backstage/plugin-user-settings": "^0.3.5",
"@backstage/integration-react": "^0.1.10",
"@backstage/plugin-api-docs": "^0.6.9",
"@backstage/plugin-badges": "^0.2.10",
"@backstage/plugin-catalog": "^0.6.16",
"@backstage/plugin-catalog-graph": "^0.1.1",
"@backstage/plugin-catalog-import": "^0.6.0",
"@backstage/plugin-catalog-react": "^0.5.0",
"@backstage/plugin-circleci": "^0.2.24",
"@backstage/plugin-cloudbuild": "^0.2.24",
"@backstage/plugin-code-coverage": "^0.1.12",
"@backstage/plugin-cost-insights": "^0.11.7",
"@backstage/plugin-explore": "^0.3.17",
"@backstage/plugin-gcp-projects": "^0.3.5",
"@backstage/plugin-github-actions": "^0.4.19",
"@backstage/plugin-graphiql": "^0.2.17",
"@backstage/plugin-home": "^0.4.1",
"@backstage/plugin-jenkins": "^0.5.7",
"@backstage/plugin-kafka": "^0.2.16",
"@backstage/plugin-kubernetes": "^0.4.14",
"@backstage/plugin-lighthouse": "^0.2.26",
"@backstage/plugin-newrelic": "^0.3.5",
"@backstage/plugin-org": "^0.3.24",
"@backstage/plugin-pagerduty": "0.3.14",
"@backstage/plugin-rollbar": "^0.3.15",
"@backstage/plugin-scaffolder": "^0.11.5",
"@backstage/plugin-search": "^0.4.12",
"@backstage/plugin-sentry": "^0.3.22",
"@backstage/plugin-shortcuts": "^0.1.9",
"@backstage/plugin-tech-radar": "^0.4.8",
"@backstage/plugin-techdocs": "^0.11.3",
"@backstage/plugin-todo": "^0.1.11",
"@backstage/plugin-user-settings": "^0.3.6",
"@backstage/search-common": "^0.2.0",
"@backstage/theme": "^0.2.10",
"@material-ui/core": "^4.12.2",
+3
View File
@@ -17,6 +17,7 @@
import {
ScmIntegrationsApi,
scmIntegrationsApiRef,
ScmAuth,
} from '@backstage/integration-react';
import {
costInsightsApiRef,
@@ -41,6 +42,8 @@ export const apis: AnyApiFactory[] = [
factory: ({ configApi }) => ScmIntegrationsApi.fromConfig(configApi),
}),
ScmAuth.createDefaultApiFactory(),
createApiFactory({
api: graphQlBrowseApiRef,
deps: { errorApi: errorApiRef, githubAuthApi: githubAuthApiRef },
+9
View File
@@ -1,5 +1,14 @@
# @backstage/backend-common
## 0.9.4
### Patch Changes
- febddedcb2: Bump `lodash` to remediate `SNYK-JS-LODASH-590103` security vulnerability
- Updated dependencies
- @backstage/integration@0.6.5
- @backstage/config@0.1.10
## 0.9.3
### Patch Changes
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-common",
"description": "Common functionality library for Backstage backends",
"version": "0.9.3",
"version": "0.9.4",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -30,10 +30,10 @@
},
"dependencies": {
"@backstage/cli-common": "^0.1.3",
"@backstage/config": "^0.1.9",
"@backstage/config": "^0.1.10",
"@backstage/config-loader": "^0.6.8",
"@backstage/errors": "^0.1.2",
"@backstage/integration": "^0.6.4",
"@backstage/integration": "^0.6.5",
"@google-cloud/storage": "^5.8.0",
"@octokit/rest": "^18.5.3",
"@types/cors": "^2.8.6",
@@ -77,7 +77,7 @@
}
},
"devDependencies": {
"@backstage/cli": "^0.7.12",
"@backstage/cli": "^0.7.13",
"@backstage/test-utils": "^0.1.17",
"@types/archiver": "^5.1.0",
"@types/compression": "^1.7.0",
+135
View File
@@ -0,0 +1,135 @@
/*
* Copyright 2020 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Logger } from 'winston';
import { ConfigReader } from '@backstage/config';
import { ObservableConfigProxy } from './config';
describe('ObservableConfigProxy', () => {
const errLogger = {
error: (message: string) => {
throw new Error(message);
},
} as unknown as Logger;
it('should notify subscribers', () => {
const config = new ObservableConfigProxy(errLogger);
const fn = jest.fn();
const sub = config.subscribe(fn);
expect(config.getOptionalNumber('x')).toBe(undefined);
config.setConfig(new ConfigReader({}));
expect(fn).toHaveBeenCalledTimes(1);
expect(config.getOptionalNumber('x')).toBe(undefined);
config.setConfig(new ConfigReader({ x: 1 }));
expect(fn).toHaveBeenCalledTimes(2);
expect(config.getOptionalNumber('x')).toBe(1);
config.setConfig(new ConfigReader({ x: 3 }));
expect(fn).toHaveBeenCalledTimes(3);
sub.unsubscribe();
expect(config.getOptionalNumber('x')).toBe(3);
config.setConfig(new ConfigReader({ x: 5 }));
expect(fn).toHaveBeenCalledTimes(3);
expect(config.getOptionalNumber('x')).toBe(5);
});
it('should forward subscriptions', () => {
const config1 = new ObservableConfigProxy(errLogger);
const fn1 = jest.fn();
const fn2 = jest.fn();
const fn3 = jest.fn();
const config2 = config1.getConfig('a');
const config3 = config2.getConfig('b');
const sub1 = config1.subscribe(fn1);
const sub2 = config2.subscribe!(fn2);
const sub3 = config3.subscribe!(fn3);
expect(config1.getOptionalNumber('x')).toBe(undefined);
expect(config2.getOptionalNumber('x')).toBe(undefined);
expect(config3.getOptionalNumber('x')).toBe(undefined);
config1.setConfig(new ConfigReader({}));
expect(fn1).toHaveBeenCalledTimes(1);
expect(fn2).toHaveBeenCalledTimes(1);
expect(fn3).toHaveBeenCalledTimes(1);
expect(config1.getOptionalNumber('x')).toBe(undefined);
expect(config2.getOptionalNumber('x')).toBe(undefined);
expect(config3.getOptionalNumber('x')).toBe(undefined);
config1.setConfig(new ConfigReader({ x: 1, a: { x: 2, b: { x: 3 } } }));
expect(fn1).toHaveBeenCalledTimes(2);
expect(fn2).toHaveBeenCalledTimes(2);
expect(fn3).toHaveBeenCalledTimes(2);
expect(config1.getNumber('x')).toBe(1);
expect(config2.getNumber('x')).toBe(2);
expect(config3.getNumber('x')).toBe(3);
sub1.unsubscribe();
sub2.unsubscribe();
sub3.unsubscribe();
config1.setConfig(new ConfigReader({ x: 4, a: { x: 5, b: { x: 6 } } }));
expect(fn1).toHaveBeenCalledTimes(2);
expect(fn2).toHaveBeenCalledTimes(2);
expect(fn3).toHaveBeenCalledTimes(2);
expect(config1.getNumber('x')).toBe(4);
expect(config2.getNumber('x')).toBe(5);
expect(config3.getNumber('x')).toBe(6);
config1.setConfig(new ConfigReader({}));
expect(() => config1.getNumber('x')).toThrow(
"Missing required config value at 'x'",
);
expect(() => config2.getNumber('x')).toThrow(
"Missing required config value at 'a'",
);
expect(() => config3.getNumber('x')).toThrow(
"Missing required config value at 'a'",
);
config1.setConfig(
new ConfigReader({ x: 's', a: { x: 's', b: { x: 's' } } }),
);
expect(() => config1.getNumber('x')).toThrow(
"Unable to convert config value for key 'x' in 'mock-config' to a number",
);
expect(() => config2.getNumber('x')).toThrow(
"Unable to convert config value for key 'a.x' in 'mock-config' to a number",
);
expect(() => config3.getNumber('x')).toThrow(
"Unable to convert config value for key 'a.b.x' in 'mock-config' to a number",
);
});
it('should make sub configs available as expected', () => {
const config = new ObservableConfigProxy(errLogger);
config.setConfig(new ConfigReader({ a: { x: 1 } }));
expect(config.getConfig('a')).toBeDefined();
expect(config.getConfig('a').getNumber('x')).toBe(1);
expect(config.getConfig('a').getOptionalNumber('x')).toBe(1);
expect(config.getOptionalConfig('a')?.getNumber('x')).toBe(1);
expect(config.getOptionalConfig('a')?.getOptionalNumber('x')).toBe(1);
expect(config.getOptionalConfig('b')).toBeUndefined();
expect(() => config.getConfig('b')).toBeDefined();
expect(() => config.getConfig('b').get()).toThrow();
});
});
+49 -18
View File
@@ -21,14 +21,25 @@ import { findPaths } from '@backstage/cli-common';
import { Config, ConfigReader, JsonValue } from '@backstage/config';
import { loadConfig } from '@backstage/config-loader';
class ObservableConfigProxy implements Config {
export class ObservableConfigProxy implements Config {
private config: Config = new ConfigReader({});
private readonly subscribers: (() => void)[] = [];
constructor(private readonly logger: Logger) {}
constructor(
private readonly logger: Logger,
private readonly parent?: ObservableConfigProxy,
private parentKey?: string,
) {
if (parent && !parentKey) {
throw new Error('parentKey is required if parent is set');
}
}
setConfig(config: Config) {
if (this.parent) {
throw new Error('immutable');
}
this.config = config;
for (const subscriber of this.subscribers) {
try {
@@ -40,6 +51,10 @@ class ObservableConfigProxy implements Config {
}
subscribe(onChange: () => void): { unsubscribe: () => void } {
if (this.parent) {
return this.parent.subscribe(onChange);
}
this.subscribers.push(onChange);
return {
unsubscribe: () => {
@@ -51,53 +66,69 @@ class ObservableConfigProxy implements Config {
};
}
private select(required: true): Config;
private select(required: false): Config | undefined;
private select(required: boolean): Config | undefined {
if (this.parent && this.parentKey) {
if (required) {
return this.parent.select(true).getConfig(this.parentKey);
}
return this.parent.select(false)?.getOptionalConfig(this.parentKey);
}
return this.config;
}
has(key: string): boolean {
return this.config.has(key);
return this.select(false)?.has(key) ?? false;
}
keys(): string[] {
return this.config.keys();
return this.select(false)?.keys() ?? [];
}
get<T = JsonValue>(key?: string): T {
return this.config.get(key);
return this.select(true).get(key);
}
getOptional<T = JsonValue>(key?: string): T | undefined {
return this.config.getOptional(key);
return this.select(false)?.getOptional(key);
}
getConfig(key: string): Config {
return this.config.getConfig(key);
return new ObservableConfigProxy(this.logger, this, key);
}
getOptionalConfig(key: string): Config | undefined {
return this.config.getOptionalConfig(key);
if (this.select(false)?.has(key)) {
return new ObservableConfigProxy(this.logger, this, key);
}
return undefined;
}
getConfigArray(key: string): Config[] {
return this.config.getConfigArray(key);
return this.select(true).getConfigArray(key);
}
getOptionalConfigArray(key: string): Config[] | undefined {
return this.config.getOptionalConfigArray(key);
return this.select(false)?.getOptionalConfigArray(key);
}
getNumber(key: string): number {
return this.config.getNumber(key);
return this.select(true).getNumber(key);
}
getOptionalNumber(key: string): number | undefined {
return this.config.getOptionalNumber(key);
return this.select(false)?.getOptionalNumber(key);
}
getBoolean(key: string): boolean {
return this.config.getBoolean(key);
return this.select(true).getBoolean(key);
}
getOptionalBoolean(key: string): boolean | undefined {
return this.config.getOptionalBoolean(key);
return this.select(false)?.getOptionalBoolean(key);
}
getString(key: string): string {
return this.config.getString(key);
return this.select(true).getString(key);
}
getOptionalString(key: string): string | undefined {
return this.config.getOptionalString(key);
return this.select(false)?.getOptionalString(key);
}
getStringArray(key: string): string[] {
return this.config.getStringArray(key);
return this.select(true).getStringArray(key);
}
getOptionalStringArray(key: string): string[] | undefined {
return this.config.getOptionalStringArray(key);
return this.select(false)?.getOptionalStringArray(key);
}
}
+1 -1
View File
@@ -21,7 +21,7 @@
*/
export * from './cache';
export * from './config';
export { loadBackendConfig } from './config';
export * from './database';
export * from './discovery';
export * from './hot';
@@ -360,6 +360,20 @@ describe('BitbucketUrlReader', () => {
);
});
it('works in nested folders', async () => {
const result = await bitbucketProcessor.search(
'https://bitbucket.org/backstage/mock/src/master/docs/index.*',
);
expect(result.etag).toBe('12ab34cd56ef');
expect(result.files.length).toBe(1);
expect(result.files[0].url).toBe(
'https://bitbucket.org/backstage/mock/src/master/docs/index.md',
);
await expect(result.files[0].content()).resolves.toEqual(
Buffer.from('# Test\n'),
);
});
it('throws NotModifiedError when same etag', async () => {
await expect(
bitbucketProcessor.search(
@@ -422,6 +436,20 @@ describe('BitbucketUrlReader', () => {
);
});
it('works in nested folders', async () => {
const result = await hostedBitbucketProcessor.search(
'https://bitbucket.mycompany.net/projects/backstage/repos/mock/browse/docs/index.*?at=master',
);
expect(result.etag).toBe('12ab34cd56ef');
expect(result.files.length).toBe(1);
expect(result.files[0].url).toBe(
'https://bitbucket.mycompany.net/projects/backstage/repos/mock/browse/docs/index.md?at=master',
);
await expect(result.files[0].content()).resolves.toEqual(
Buffer.from('# Test\n'),
);
});
it('throws NotModifiedError when same etag', async () => {
await expect(
hostedBitbucketProcessor.search(
@@ -14,6 +14,7 @@
* limitations under the License.
*/
import { NotFoundError, NotModifiedError } from '@backstage/errors';
import {
BitbucketIntegration,
getBitbucketDefaultBranch,
@@ -26,18 +27,16 @@ import fetch from 'cross-fetch';
import parseGitUrl from 'git-url-parse';
import { Minimatch } from 'minimatch';
import { Readable } from 'stream';
import { NotFoundError, NotModifiedError } from '@backstage/errors';
import { stripFirstDirectoryFromPath } from './tree/util';
import {
ReadTreeResponseFactory,
ReaderFactory,
ReadTreeOptions,
ReadTreeResponse,
ReadTreeResponseFactory,
ReadUrlOptions,
ReadUrlResponse,
SearchOptions,
SearchResponse,
UrlReader,
ReadUrlResponse,
ReadUrlOptions,
} from './types';
/**
@@ -154,7 +153,7 @@ export class BitbucketUrlReader implements UrlReader {
const tree = await this.readTree(treeUrl, {
etag: options?.etag,
filter: path => matcher.match(stripFirstDirectoryFromPath(path)),
filter: path => matcher.match(path),
});
const files = await tree.files();
+24
View File
@@ -1,5 +1,29 @@
# example-backend
## 0.2.47
### Patch Changes
- Updated dependencies
- @backstage/plugin-catalog-backend@0.14.0
- @backstage/integration@0.6.5
- @backstage/catalog-client@0.4.0
- @backstage/catalog-model@0.9.3
- @backstage/backend-common@0.9.4
- @backstage/config@0.1.10
- @backstage/plugin-kafka-backend@0.2.10
- @backstage/plugin-kubernetes-backend@0.3.16
- @backstage/plugin-rollbar-backend@0.1.15
- @backstage/plugin-search-backend-module-pg@0.2.1
- example-app@0.2.47
- @backstage/plugin-auth-backend@0.4.1
- @backstage/plugin-badges-backend@0.1.10
- @backstage/plugin-code-coverage-backend@0.1.11
- @backstage/plugin-jenkins-backend@0.1.5
- @backstage/plugin-scaffolder-backend@0.15.6
- @backstage/plugin-techdocs-backend@0.10.3
- @backstage/plugin-todo-backend@0.1.12
## 0.2.46
### Patch Changes
+20 -20
View File
@@ -1,6 +1,6 @@
{
"name": "example-backend",
"version": "0.2.46",
"version": "0.2.47",
"main": "dist/index.cjs.js",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -24,35 +24,35 @@
"migrate:create": "knex migrate:make -x ts"
},
"dependencies": {
"@backstage/backend-common": "^0.9.3",
"@backstage/catalog-client": "^0.3.17",
"@backstage/catalog-model": "^0.9.1",
"@backstage/config": "^0.1.8",
"@backstage/integration": "^0.6.4",
"@backstage/backend-common": "^0.9.4",
"@backstage/catalog-client": "^0.4.0",
"@backstage/catalog-model": "^0.9.3",
"@backstage/config": "^0.1.10",
"@backstage/integration": "^0.6.5",
"@backstage/plugin-app-backend": "^0.3.16",
"@backstage/plugin-auth-backend": "^0.4.0",
"@backstage/plugin-badges-backend": "^0.1.9",
"@backstage/plugin-catalog-backend": "^0.13.8",
"@backstage/plugin-code-coverage-backend": "^0.1.10",
"@backstage/plugin-auth-backend": "^0.4.1",
"@backstage/plugin-badges-backend": "^0.1.10",
"@backstage/plugin-catalog-backend": "^0.14.0",
"@backstage/plugin-code-coverage-backend": "^0.1.11",
"@backstage/plugin-graphql-backend": "^0.1.9",
"@backstage/plugin-jenkins-backend": "^0.1.4",
"@backstage/plugin-kubernetes-backend": "^0.3.15",
"@backstage/plugin-kafka-backend": "^0.2.9",
"@backstage/plugin-jenkins-backend": "^0.1.5",
"@backstage/plugin-kubernetes-backend": "^0.3.16",
"@backstage/plugin-kafka-backend": "^0.2.10",
"@backstage/plugin-proxy-backend": "^0.2.12",
"@backstage/plugin-rollbar-backend": "^0.1.14",
"@backstage/plugin-scaffolder-backend": "^0.15.5",
"@backstage/plugin-rollbar-backend": "^0.1.15",
"@backstage/plugin-scaffolder-backend": "^0.15.6",
"@backstage/plugin-scaffolder-backend-module-rails": "^0.1.5",
"@backstage/plugin-search-backend": "^0.2.6",
"@backstage/plugin-search-backend-node": "^0.4.2",
"@backstage/plugin-search-backend-module-elasticsearch": "^0.0.4",
"@backstage/plugin-search-backend-module-pg": "^0.2.0",
"@backstage/plugin-techdocs-backend": "^0.10.2",
"@backstage/plugin-todo-backend": "^0.1.11",
"@backstage/plugin-search-backend-module-pg": "^0.2.1",
"@backstage/plugin-techdocs-backend": "^0.10.3",
"@backstage/plugin-todo-backend": "^0.1.12",
"@gitbeaker/node": "^30.2.0",
"@octokit/rest": "^18.5.3",
"azure-devops-node-api": "^11.0.1",
"dockerode": "^3.2.1",
"example-app": "^0.2.46",
"example-app": "^0.2.47",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
"express-prom-bundle": "^6.3.6",
@@ -64,7 +64,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/cli": "^0.7.12",
"@backstage/cli": "^0.7.13",
"@types/dockerode": "^3.2.1",
"@types/express": "^4.17.6",
"@types/express-serve-static-core": "^4.17.5"
+13
View File
@@ -1,5 +1,18 @@
# @backstage/catalog-client
## 0.4.0
### Minor Changes
- dbcaa6387a: Extends the `CatalogClient` interface with a `refreshEntity` method.
### Patch Changes
- 9ef2987a83: Update `AddLocationResponse` to optionally return `exists` to signal that the location already exists, this is only returned when calling `addLocation` in dryRun.
- Updated dependencies
- @backstage/catalog-model@0.9.3
- @backstage/config@0.1.10
## 0.3.19
### Patch Changes
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/catalog-client",
"description": "An isomorphic client for the catalog backend",
"version": "0.3.19",
"version": "0.4.0",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -30,13 +30,13 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.9.2",
"@backstage/config": "^0.1.9",
"@backstage/catalog-model": "^0.9.3",
"@backstage/config": "^0.1.10",
"@backstage/errors": "^0.1.2",
"cross-fetch": "^3.0.6"
},
"devDependencies": {
"@backstage/cli": "^0.7.11",
"@backstage/cli": "^0.7.13",
"@types/jest": "^26.0.7",
"msw": "^0.29.0"
},
+9
View File
@@ -1,5 +1,14 @@
# @backstage/catalog-model
## 0.9.3
### Patch Changes
- d42566c5c9: Loosen constraints on what's a valid catalog entity tag name (include + and #)
- febddedcb2: Bump `lodash` to remediate `SNYK-JS-LODASH-590103` security vulnerability
- Updated dependencies
- @backstage/config@0.1.10
## 0.9.2
### Patch Changes
+1
View File
@@ -50,6 +50,7 @@ export class CommonValidatorFunctions {
isValidSuffix: (value: string) => boolean,
): boolean;
static isValidString(value: unknown): boolean;
static isValidTag(value: unknown): boolean;
static isValidUrl(value: unknown): boolean;
}
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/catalog-model",
"description": "Types and validators that help describe the model of a Backstage Catalog",
"version": "0.9.2",
"version": "0.9.3",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -30,7 +30,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/config": "^0.1.9",
"@backstage/config": "^0.1.10",
"@backstage/errors": "^0.1.2",
"@types/json-schema": "^7.0.5",
"@types/yup": "^0.29.8",
@@ -41,7 +41,7 @@
"yup": "^0.29.3"
},
"devDependencies": {
"@backstage/cli": "^0.7.11",
"@backstage/cli": "^0.7.13",
"@types/express": "^4.17.6",
"@types/jest": "^26.0.7",
"@types/lodash": "^4.14.151",
@@ -78,6 +78,10 @@ export class FieldFormatEntityPolicy implements EntityPolicy {
expectation =
'a string that is sequences of [a-z0-9] separated by [-], at most 63 characters in total';
break;
case 'isValidTag':
expectation =
'a string that is sequences of [a-z0-9+#] separated by [-], at most 63 characters in total';
break;
case 'isValidAnnotationValue':
expectation = 'a string';
break;
@@ -162,6 +162,31 @@ describe('CommonValidatorFunctions', () => {
expect(CommonValidatorFunctions.isValidDnsLabel(value)).toBe(result);
});
it.each([
// These are identical to isValidDnsLabel
[null, false],
[7, false],
['', false],
['a', true],
['a-b', true],
['-a-b', false],
['a-b-', false],
['a--b', false],
['a_b', false],
[`${'a'.repeat(63)}`, true],
[`${'a'.repeat(64)}`, false],
// Tags can have other characters though
['a+b', true],
['+a+b', true],
['a+b+', true],
['a++b', true],
['c++', true],
['c#', true],
['#c++', true],
])(`isValidTag %p ? %p`, (value, result) => {
expect(CommonValidatorFunctions.isValidTag(value)).toBe(result);
});
it.each([
[null, false],
[7, false],
@@ -95,6 +95,20 @@ export class CommonValidatorFunctions {
);
}
/**
* Checks that the value is a valid tag.
*
* @param value - The value to check
*/
static isValidTag(value: unknown): boolean {
return (
typeof value === 'string' &&
value.length >= 1 &&
value.length <= 63 &&
/^[a-z0-9+#]+(\-[a-z0-9+#]+)*$/.test(value)
);
}
/**
* Checks that the value is a valid URL.
*
@@ -27,7 +27,7 @@ const defaultValidators: Validators = {
isValidLabelValue: KubernetesValidatorFunctions.isValidLabelValue,
isValidAnnotationKey: KubernetesValidatorFunctions.isValidAnnotationKey,
isValidAnnotationValue: KubernetesValidatorFunctions.isValidAnnotationValue,
isValidTag: CommonValidatorFunctions.isValidDnsLabel,
isValidTag: CommonValidatorFunctions.isValidTag,
};
/** @public */
+11
View File
@@ -1,5 +1,16 @@
# @backstage/cli
## 0.7.13
### Patch Changes
- c0c51c9710: Disabled ECMAScript transforms in app and backend builds in order to reduce bundle size and runtime performance. For the rationale and a full list of syntax that is no longer transformed, see https://github.com/alangpierce/sucrase#transforms. This also enables TypeScripts `useDefineForClassFields` flag by default, which in rare occasions could cause build failures. For instructions on how to mitigate issues due to the flag, see the [TypeScript documentation](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#the-usedefineforclassfields-flag-and-the-declare-property-modifier).
- e9f332a51c: Restrict imports on the form `../../plugins/x/src`
- febddedcb2: Bump `lodash` to remediate `SNYK-JS-LODASH-590103` security vulnerability
- 050797c5b3: Switched the Jest YAML transform from `yaml-jest` to `jest-transform-yaml`, which works with newer versions of Node.js.
- Updated dependencies
- @backstage/config@0.1.10
## 0.7.12
### Patch Changes
+7 -7
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/cli",
"description": "CLI for developing Backstage plugins and apps",
"version": "0.7.12",
"version": "0.7.13",
"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.3",
"@backstage/config": "^0.1.9",
"@backstage/config": "^0.1.10",
"@backstage/config-loader": "^0.6.8",
"@hot-loader/react-dom": "^16.13.0",
"@lerna/package-graph": "^4.0.0",
@@ -117,12 +117,12 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/backend-common": "^0.9.3",
"@backstage/config": "^0.1.9",
"@backstage/core-components": "^0.4.2",
"@backstage/backend-common": "^0.9.4",
"@backstage/config": "^0.1.10",
"@backstage/core-components": "^0.5.0",
"@backstage/core-plugin-api": "^0.1.8",
"@backstage/core-app-api": "^0.1.13",
"@backstage/dev-utils": "^0.2.9",
"@backstage/core-app-api": "^0.1.14",
"@backstage/dev-utils": "^0.2.10",
"@backstage/test-utils": "^0.1.17",
"@backstage/theme": "^0.2.10",
"@types/diff": "^5.0.0",
@@ -30,8 +30,9 @@ import {
getCodeownersFilePath,
} from '../../lib/codeowners';
import { paths } from '../../lib/paths';
import { packageVersions } from '../../lib/version';
import { Task, templatingTask } from '../../lib/tasks';
import { Lockfile } from '../../lib/versioning';
import { createPackageVersionProvider } from '../../lib/version';
const exec = promisify(execCb);
@@ -262,6 +263,13 @@ export default async (cmd: Command) => {
? await fs.readJson(paths.resolveTargetRoot('lerna.json'))
: { version: '0.1.0' };
let lockfile: Lockfile | undefined;
try {
lockfile = await Lockfile.load(paths.resolveTargetRoot('yarn.lock'));
} catch (error) {
console.warn(`No yarn.lock available, ${error}`);
}
Task.log();
Task.log('Creating the plugin...');
@@ -288,7 +296,7 @@ export default async (cmd: Command) => {
privatePackage,
npmRegistry,
},
packageVersions,
createPackageVersionProvider(lockfile),
);
Task.section('Moving to final location');
+11 -3
View File
@@ -27,13 +27,21 @@ export const includedFilter = (name: string) =>
// Packages that are not allowed to have any duplicates
const FORBID_DUPLICATES = [
/^@backstage\/core$/,
/^@backstage\/core-api$/,
/^@backstage\/core-app-api$/,
/^@backstage\/plugin-/,
];
// There are some packages that ARE explicitly allowed to have duplicates since
// they handle that appropriately. This takes precedence over FORBID_DUPLICATES
// above.
const ALLOW_DUPLICATES = [
/^@backstage\/core-plugin-api$/,
/^@backstage\/plugin-catalog-react$/,
];
export const forbiddenDuplicatesFilter = (name: string) =>
FORBID_DUPLICATES.some(pattern => pattern.test(name));
FORBID_DUPLICATES.some(pattern => pattern.test(name)) &&
!ALLOW_DUPLICATES.some(pattern => pattern.test(name));
export default async (cmd: Command) => {
const fix = Boolean(cmd.fix);
+7 -6
View File
@@ -24,7 +24,7 @@ import handlebars from 'handlebars';
import recursiveReadDir from 'recursive-readdir';
import { paths } from '../paths';
import { FileDiff } from './types';
import { packageVersions } from '../../lib/version';
import { createPackageVersionProvider } from '../../lib/version';
export type TemplatedFile = {
path: string;
@@ -40,14 +40,15 @@ async function readTemplateFile(
if (!templateFile.endsWith('.hbs')) {
return contents;
}
const packageVersionProvider = createPackageVersionProvider(undefined);
return handlebars.compile(contents)(templateVars, {
helpers: {
version(name: keyof typeof packageVersions) {
if (name in packageVersions) {
return packageVersions[name];
}
throw new Error(`No version available for package ${name}`);
versionQuery(name: string, hint: string | unknown) {
return packageVersionProvider(
name,
typeof hint === 'string' ? hint : undefined,
);
},
},
});
+3 -3
View File
@@ -34,7 +34,7 @@ describe('templatingTask', () => {
// Files content
const testFileContent = 'testing';
const testVersionFileContent =
"version: {{pluginVersion}} {{version 'mock-pkg'}}";
"version: {{pluginVersion}} {{versionQuery 'mock-pkg'}}";
mockFs({
[tmplDir]: {
@@ -52,7 +52,7 @@ describe('templatingTask', () => {
{
pluginVersion: '0.0.0',
},
{ 'mock-pkg': '0.1.2' },
() => '^0.1.2',
);
await expect(
@@ -60,6 +60,6 @@ describe('templatingTask', () => {
).resolves.toBe(testFileContent);
await expect(
fs.readFile(resolvePath(destDir, 'sub/version.txt'), 'utf8'),
).resolves.toBe('version: 0.0.0 0.1.2');
).resolves.toBe('version: 0.0.0 ^0.1.2');
});
});
+6 -6
View File
@@ -69,7 +69,7 @@ export async function templatingTask(
templateDir: string,
destinationDir: string,
context: any,
versions: { [name: string]: string },
versionProvider: (name: string, versionHint?: string) => string,
) {
const files = await recursive(templateDir).catch(error => {
throw new Error(`Failed to read template directory: ${error.message}`);
@@ -90,11 +90,11 @@ export async function templatingTask(
{ name: basename(destination), ...context },
{
helpers: {
version(name: string) {
if (versions[name]) {
return versions[name];
}
throw new Error(`No version available for package ${name}`);
versionQuery(name: string, versionHint: string | unknown) {
return versionProvider(
name,
typeof versionHint === 'string' ? versionHint : undefined,
);
},
},
},
+72
View File
@@ -0,0 +1,72 @@
/*
* Copyright 2020 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import mockFs from 'mock-fs';
import { createPackageVersionProvider } from './version';
import { Lockfile } from './versioning';
// eslint-disable-next-line monorepo/no-internal-import
import corePluginApiPkg from '@backstage/core-plugin-api/package.json';
describe('createPackageVersionProvider', () => {
afterEach(() => {
mockFs.restore();
});
it('should provide package versions', async () => {
mockFs({
'yarn.lock': `
"a@^0.1.0":
version "0.1.5"
"b@^0.2.0","b@*","b@^0.2.1":
version "0.2.5"
"c@^0.1.4":
version "0.1.8"
"c@^0.2.4":
version "0.2.8"
"c@^0.3.4":
version "0.3.8"
"@types/t@^1.1.0","@types/t@*","@types/t@^1.2.3":
version "1.4.5"
"@backstage/cli@*":
version "1.1.5"
`,
});
const lockfile = await Lockfile.load('yarn.lock');
const provider = createPackageVersionProvider(lockfile);
expect(provider('a', '0.1.5')).toBe('^0.1.0');
expect(provider('b', '1.0.0')).toBe('*');
expect(provider('c', '0.1.0')).toBe('^0.1.0');
expect(provider('c', '0.1.6')).toBe('^0.1.4');
expect(provider('c', '0.2.0')).toBe('^0.2.0');
expect(provider('c', '0.2.6')).toBe('^0.2.4');
expect(provider('c', '0.3.0-rc1')).toBe('0.3.0-rc1');
expect(provider('c', '0.3.0')).toBe('^0.3.0');
expect(provider('c', '0.3.6')).toBe('^0.3.4');
expect(provider('@backstage/cli')).toBe('*');
expect(provider('@backstage/core-plugin-api')).toBe(
`^${corePluginApiPkg.version}`,
);
expect(provider('@types/t', '1.4.2')).toBe('*');
});
});
+36 -1
View File
@@ -15,7 +15,9 @@
*/
import fs from 'fs-extra';
import semver from 'semver';
import { paths } from './paths';
import { Lockfile } from './versioning';
/* eslint-disable import/no-extraneous-dependencies,monorepo/no-internal-import */
/*
@@ -41,7 +43,7 @@ import { version as devUtils } from '@backstage/dev-utils/package.json';
import { version as testUtils } from '@backstage/test-utils/package.json';
import { version as theme } from '@backstage/theme/package.json';
export const packageVersions = {
export const packageVersions: Record<string, string> = {
'@backstage/backend-common': backendCommon,
'@backstage/cli': cli,
'@backstage/config': config,
@@ -60,3 +62,36 @@ export function findVersion() {
export const version = findVersion();
export const isDev = fs.pathExistsSync(paths.resolveOwn('src'));
export function createPackageVersionProvider(lockfile?: Lockfile) {
return (name: string, versionHint?: string) => {
const packageVersion = packageVersions[name];
const targetVersion = versionHint || packageVersion;
if (!targetVersion) {
throw new Error(`No version available for package ${name}`);
}
const lockfileEntries = lockfile?.get(name);
if (
name.startsWith('@types/') &&
lockfileEntries?.some(entry => entry.range === '*')
) {
return '*';
}
const validRanges = lockfileEntries?.filter(entry =>
semver.satisfies(targetVersion, entry.range),
);
const highestRange = validRanges?.slice(-1)[0];
if (highestRange?.range) {
return highestRange?.range;
}
if (packageVersion) {
return `^${packageVersion}`;
}
if (semver.parse(versionHint)?.prerelease.length) {
return versionHint!;
}
return `^${versionHint}`;
};
}
@@ -23,20 +23,20 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^{{version '@backstage/backend-common'}}",
"@backstage/config": "^{{version '@backstage/config'}}",
"@types/express": "^4.17.6",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
"winston": "^3.2.1",
"cross-fetch": "^3.0.6",
"yn": "^4.0.0"
"@backstage/backend-common": "{{versionQuery '@backstage/backend-common'}}",
"@backstage/config": "{{versionQuery '@backstage/config'}}",
"@types/express": "{{versionQuery '@types/express' '4.17.6'}}",
"express": "{{versionQuery 'express' '4.17.1'}}",
"express-promise-router": "{{versionQuery 'express-promise-router' '4.1.0'}}",
"winston": "{{versionQuery 'winston' '3.2.1'}}",
"cross-fetch": "{{versionQuery 'cross-fetch' '3.0.6'}}",
"yn": "{{versionQuery 'yn' '4.0.0'}}"
},
"devDependencies": {
"@backstage/cli": "^{{version '@backstage/cli'}}",
"@types/supertest": "^2.0.8",
"supertest": "^4.0.2",
"msw": "^0.29.0"
"@backstage/cli": "{{versionQuery '@backstage/cli'}}",
"@types/supertest": "{{versionQuery '@types/supertest' '2.0.8'}}",
"supertest": "{{versionQuery 'supertest' '4.0.2'}}",
"msw": "{{versionQuery 'msw' '0.29.0'}}"
},
"files": [
"dist"
@@ -24,28 +24,28 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core-components": "^{{version '@backstage/core-components'}}",
"@backstage/core-plugin-api": "^{{version '@backstage/core-plugin-api'}}",
"@backstage/theme": "^{{version '@backstage/theme'}}",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.57",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-use": "^17.2.4"
"@backstage/core-components": "{{versionQuery '@backstage/core-components'}}",
"@backstage/core-plugin-api": "{{versionQuery '@backstage/core-plugin-api'}}",
"@backstage/theme": "{{versionQuery '@backstage/theme'}}",
"@material-ui/core": "{{versionQuery '@material-ui/core' '4.12.2'}}",
"@material-ui/icons": "{{versionQuery '@material-ui/icons' '4.9.1'}}",
"@material-ui/lab": "{{versionQuery '@material-ui/lab' '4.0.0-alpha.57'}}",
"react": "{{versionQuery 'react' '16.13.1'}}",
"react-dom": "{{versionQuery 'react-dom' '16.13.1'}}",
"react-use": "{{versionQuery 'react-use' '17.2.4'}}"
},
"devDependencies": {
"@backstage/cli": "^{{version '@backstage/cli'}}",
"@backstage/core-app-api": "^{{version '@backstage/core-app-api'}}",
"@backstage/dev-utils": "^{{version '@backstage/dev-utils'}}",
"@backstage/test-utils": "^{{version '@backstage/test-utils'}}",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"msw": "^0.29.0",
"cross-fetch": "^3.0.6"
"@backstage/cli": "{{versionQuery '@backstage/cli'}}",
"@backstage/core-app-api": "{{versionQuery '@backstage/core-app-api'}}",
"@backstage/dev-utils": "{{versionQuery '@backstage/dev-utils'}}",
"@backstage/test-utils": "{{versionQuery '@backstage/test-utils'}}",
"@testing-library/jest-dom": "{{versionQuery '@testing-library/jest-dom' '5.10.1'}}",
"@testing-library/react": "{{versionQuery '@testing-library/react' '11.2.5'}}",
"@testing-library/user-event": "{{versionQuery '@testing-library/user-event' '13.1.8'}}",
"@types/jest": "{{versionQuery '@types/jest' '26.0.7'}}",
"@types/node": "{{versionQuery '@types/node' '14.14.32'}}",
"msw": "{{versionQuery 'msw' '0.29.0'}}",
"cross-fetch": "{{versionQuery 'cross-fetch' '3.0.6'}}"
},
"files": [
"dist"
+8
View File
@@ -1,5 +1,13 @@
# @backstage/codemods
## 0.1.15
### Patch Changes
- Updated dependencies
- @backstage/core-components@0.5.0
- @backstage/core-app-api@0.1.14
## 0.1.14
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/codemods",
"description": "A collection of codemods for Backstage projects",
"version": "0.1.14",
"version": "0.1.15",
"private": false,
"publishConfig": {
"access": "public",
+6
View File
@@ -1,5 +1,11 @@
# @backstage/config
## 0.1.10
### Patch Changes
- febddedcb2: Bump `lodash` to remediate `SNYK-JS-LODASH-590103` security vulnerability
## 0.1.9
### 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.9",
"version": "0.1.10",
"private": false,
"publishConfig": {
"access": "public",
+8
View File
@@ -1,5 +1,13 @@
# @backstage/core-app-api
## 0.1.14
### Patch Changes
- Updated dependencies
- @backstage/core-components@0.5.0
- @backstage/config@0.1.10
## 0.1.13
### Patch Changes
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/core-app-api",
"description": "Core app API used by Backstage apps",
"version": "0.1.13",
"version": "0.1.14",
"private": false,
"publishConfig": {
"access": "public",
@@ -29,8 +29,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core-components": "^0.4.2",
"@backstage/config": "^0.1.9",
"@backstage/core-components": "^0.5.0",
"@backstage/config": "^0.1.10",
"@backstage/core-plugin-api": "^0.1.8",
"@backstage/theme": "^0.2.10",
"@backstage/version-bridge": "^0.1.0",
@@ -45,7 +45,7 @@
"zen-observable": "^0.8.15"
},
"devDependencies": {
"@backstage/cli": "^0.7.12",
"@backstage/cli": "^0.7.13",
"@backstage/test-utils": "^0.1.17",
"@backstage/test-utils-core": "^0.1.2",
"@testing-library/jest-dom": "^5.10.1",
@@ -90,11 +90,6 @@ export const defaultConfigLoader: AppConfigLoader = async (
return configs;
};
// createApp is defined in core, and not core-api, since we need access
// to the components inside core to provide defaults.
// The actual implementation of the app class still lives in core-api,
// as it needs to be used by dev- and test-utils.
export function OptionallyWrapInRouter({ children }: PropsWithChildren<{}>) {
if (useInRouterContext()) {
return <>{children}</>;
+15
View File
@@ -1,5 +1,20 @@
# @backstage/core-components
## 0.5.0
### Minor Changes
- 537bd04005: Fixed a popup-blocking bug affecting iOS Safari in SignInPage.tsx by ensuring that the popup occurs in the same tick as the tap/click
### Patch Changes
- c0eb1fb9df: Allow to configure zooming for `<DependencyGraph>`. `zoom` can either be
`enabled`, `disabled`, or `enable-on-click`. The latter requires the user to
click into the diagram to enable zooming.
- febddedcb2: Bump `lodash` to remediate `SNYK-JS-LODASH-590103` security vulnerability
- Updated dependencies
- @backstage/config@0.1.10
## 0.4.2
### Patch Changes
+25 -1
View File
@@ -162,12 +162,36 @@ type DependencyEdge<T = CustomType> = T & {
label?: string;
};
// Warning: (ae-forgotten-export) The symbol "DependencyGraphProps" needs to be exported by the entry point index.d.ts
// Warning: (ae-missing-release-tag) "DependencyGraph" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export function DependencyGraph(props: DependencyGraphProps): JSX.Element;
// Warning: (ae-missing-release-tag) "DependencyGraphProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export type DependencyGraphProps = React_2.SVGProps<SVGSVGElement> & {
edges: DependencyEdge[];
nodes: DependencyNode[];
direction?: Direction;
align?: Alignment;
nodeMargin?: number;
edgeMargin?: number;
rankMargin?: number;
paddingX?: number;
paddingY?: number;
acyclicer?: 'greedy';
ranker?: Ranker;
labelPosition?: LabelPosition;
labelOffset?: number;
edgeRanks?: number;
edgeWeight?: number;
renderNode?: RenderNodeFunction;
renderLabel?: RenderLabelFunction;
defs?: SVGDefsElement | SVGDefsElement[];
zoom?: 'enabled' | 'disabled' | 'enable-on-click';
};
declare namespace DependencyGraphTypes {
export {
DependencyEdge,
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/core-components",
"description": "Core components used by Backstage plugins and apps",
"version": "0.4.2",
"version": "0.5.0",
"private": false,
"publishConfig": {
"access": "public",
@@ -29,7 +29,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/config": "^0.1.9",
"@backstage/config": "^0.1.10",
"@backstage/core-plugin-api": "^0.1.8",
"@backstage/errors": "^0.1.2",
"@backstage/theme": "^0.2.10",
@@ -70,8 +70,8 @@
"zen-observable": "^0.8.15"
},
"devDependencies": {
"@backstage/core-app-api": "^0.1.13",
"@backstage/cli": "^0.7.12",
"@backstage/core-app-api": "^0.1.14",
"@backstage/cli": "^0.7.13",
"@backstage/test-utils": "^0.1.17",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
@@ -51,6 +51,32 @@ export const Default = () => (
</div>
);
export const ZoomDisabled = () => (
<div style={containerStyle}>
<DependencyGraph
nodes={exampleNodes}
edges={exampleEdges}
style={graphStyle}
paddingX={50}
paddingY={50}
zoom="disabled"
/>
</div>
);
export const ZoomEnableOnClick = () => (
<div style={containerStyle}>
<DependencyGraph
nodes={exampleNodes}
edges={exampleEdges}
style={graphStyle}
paddingX={50}
paddingY={50}
zoom="enable-on-click"
/>
</div>
);
export const BottomToTop = () => (
<div style={containerStyle}>
<DependencyGraph

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