Merge branch 'master' into techdocs-common/case-sensitive-migration

Signed-off-by: Eric Peterson <ericpeterson@spotify.com>
This commit is contained in:
Eric Peterson
2021-08-12 11:27:43 +02:00
635 changed files with 9792 additions and 6037 deletions
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/backend-common': patch
'@backstage/cli': patch
---
bump node-tar version to the latest
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/backend-test-utils': patch
---
Make sure that the unique databases names generated by `TestDatabases.create()`
don't collide.
+18
View File
@@ -0,0 +1,18 @@
---
'@backstage/plugin-techdocs': patch
---
Expose a new composable `TechDocsIndexPage` and a `DefaultTechDocsHome` with support for starring docs and filtering on owned, starred, owner, and tags.
You can migrate to the new UI view by making the following changes in your `App.tsx`:
```diff
- <Route path="/docs" element={<TechdocsPage />} />
+ <Route path="/docs" element={<TechDocsIndexPage />}>
+ <DefaultTechDocsHome />
+ </Route>
+ <Route
+ path="/docs/:namespace/:kind/:name/*"
+ element={<TechDocsReaderPage />}
+ />
```
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/cli': patch
---
Keep track of filtered configuration values when running frontend in development mode.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-common': patch
---
Use a more informative error message when URL reading isn't allowed due to no reader matching the target URL.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/create-app': patch
---
fix typo in the comments of EntityPage component
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-kubernetes-backend': patch
---
Adds ability to send an ExternalId with the assume role request to AWS
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-catalog': patch
---
Fix bug with re-rendering the EntityRoutes when the entity changes but the route does not
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-xcmetrics': patch
---
New page for browsing all builds with filtering and pagination capabilities
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder': patch
---
Added UI Schema support for array items for example, support EntityPicker within an array field
+22
View File
@@ -0,0 +1,22 @@
---
'@backstage/plugin-scaffolder': patch
---
- Adds a new field `EntityNamePicker` that can be used in scaffolder templates to accept and validate an entity name. This field is registered by default, and can be used in templates by setting the `ui:field` property to `EntityNamePicker`. If you've customized your scaffolder field extensions, you can include this one by adding it when registering the scaffolder route:
```diff
import {
ScaffolderFieldExtensions,
+ EntityNamePickerFieldExtension,
} from '@backstage/plugin-scaffolder';
<Route path="/create" element={<ScaffolderPage />}>
<ScaffolderFieldExtensions>
{/* ...custom field extensions... */}
+ <EntityNamePickerFieldExtension />
</ScaffolderFieldExtensions>
</Route>;
```
- Adds a new generic field `TextValuePicker` to be used when writing custom field extensions that use a standard UI with custom validation. An example of doing this can be found in `packages/app/src/components/scaffolder/customScaffolderExtensions.tsx`.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/config': patch
---
Add warning when trying to access configuration values that have been filtered out by visibility.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/core-app-api': patch
---
Add support for serving the app with a base path other than `/`, which is enabled by including the path in `app.baseUrl`.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-sonarqube': minor
---
Use IdentityApi to provide Auth Token for SonarQubeClient Api calls
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/core-components': patch
'@backstage/core-plugin-api': patch
---
Switched frontend identity code to use `token` instead of the deprecated `idToken` field
+25
View File
@@ -0,0 +1,25 @@
---
'@backstage/core-app-api': patch
'@backstage/core-components': patch
'@backstage/core-plugin-api': patch
'@backstage/dev-utils': patch
'@backstage/test-utils': patch
'@backstage/test-utils-core': patch
'@backstage/plugin-api-docs': patch
'@backstage/plugin-catalog': patch
'@backstage/plugin-catalog-import': patch
'@backstage/plugin-catalog-react': patch
'@backstage/plugin-cost-insights': patch
'@backstage/plugin-explore': patch
'@backstage/plugin-git-release-manager': patch
'@backstage/plugin-lighthouse': patch
'@backstage/plugin-pagerduty': patch
'@backstage/plugin-rollbar': patch
'@backstage/plugin-scaffolder': patch
'@backstage/plugin-search': patch
'@backstage/plugin-sentry': patch
'@backstage/plugin-tech-radar': patch
'@backstage/plugin-techdocs': patch
---
Switched `@types/react` dependency to request `*` rather than a specific version.
+12
View File
@@ -0,0 +1,12 @@
---
'@backstage/create-app': patch
---
Updated the index page redirect to work with apps served on a different base path than `/`.
To apply this change to an existing app, remove the `/` prefix from the target route in the `Navigate` element in `packages/app/src/App.tsx`:
```diff
-<Navigate key="/" to="/catalog" />
+<Navigate key="/" to="catalog" />
```
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/integration': patch
---
Adds an allow list of GitHub installations
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-techdocs': patch
---
Switch `EventSource` implementation with header support from a Node.js API-based one to an XHR-based one.
+18
View File
@@ -0,0 +1,18 @@
---
'@backstage/create-app': patch
---
Use new composable `TechDocsIndexPage` and `DefaultTechDocsHome`
Make the following changes to your `App.tsx` to migrate existing apps:
```diff
- <Route path="/docs" element={<TechdocsPage />} />
+ <Route path="/docs" element={<TechDocsIndexPage />}>
+ <DefaultTechDocsHome />
+ </Route>
+ <Route
+ path="/docs/:namespace/:kind/:name/*"
+ element={<TechDocsReaderPage />}
+ />
```
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-kubernetes-backend': patch
---
Add configuration option to the kubernetes object types. Config option is under `kubernetes.resources`. Defaults to ['pods', 'services', 'configmaps', 'deployments', 'replicasets', 'horizontalpodautoscalers', 'ingresses']
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/integration': patch
---
Fixed bug for comparing Organization name in `GithubCredentialsProvider`
-8
View File
@@ -1,8 +0,0 @@
---
'@backstage/core-components': patch
'@backstage/plugin-api-docs': patch
'@backstage/plugin-catalog': patch
'@backstage/plugin-scaffolder': patch
---
Move the `CreateComponentButton` from the catalog plugin to the `core-components` & rename it to `CreateButton` to be reused inside the api-docs plugin & scaffolder plugin, but also future plugins. Additionally, improve responsiveness of `CreateButton` & `SupportButton` by shrinking them to `IconButtons` on smaller screens.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-search-backend-module-elasticsearch': patch
---
Fix to allow optionally reading `auth` parameter for custom hosted ElasticSearch instances. Also remove `bearer` auth config since it's currently unsupported.
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/plugin-search-backend-module-pg': patch
---
Add `plugin-search-backend-module-pg` providing a postgres based search engine.
See the [README of `search-backend-module-pg`](https://github.com/backstage/backstage/blob/master/plugins/search-backend-module-pg/README.md) for usage instructions.
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/plugin-search': patch
---
Change `<SearchType>` design to follow Figma and be similar to existing multi
selects in Backstage.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/integration': patch
---
Remove repo restriction from GitHub credentials provider
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/cli': patch
'@backstage/create-app': patch
---
Migrate to using `webpack@5` 🎉
+34
View File
@@ -0,0 +1,34 @@
---
'@backstage/create-app': patch
---
Add a complete prettier setup to the created project. Prettier used to only be added as a dependency to create apps, but there wasn't a complete setup included that makes it easy to run prettier. That has now changed, and the new `prettier:check` command can be used to check the formatting of the files in your created project.
To apply this change to an existing app, a couple of changes need to be made.
Create a `.prettierignore` file at the root of your repository with the following contents:
```
dist
dist-types
coverage
.vscode
```
Next update the root `package.json` by bumping the prettier version and adding the new `prettier:check` command:
```diff
"scripts": {
...
+ "prettier:check": "prettier --check .",
...
},
...
"dependencies": {
...
- "prettier": "^1.19.1"
+ "prettier": "^2.3.2"
}
```
Finally run `yarn prettier --write .` on your project to update the existing formatting.
+12
View File
@@ -0,0 +1,12 @@
---
'@backstage/create-app': patch
---
Removed the `/` prefix in the catalog `SidebarItem` element, as it is no longer needed.
To apply this change to an existing app, remove the `/` prefix from the catalog and any other sidebar items in `packages/app/src/components/Root/Root.ts`:
```diff
-<SidebarItem icon={HomeIcon} to="/catalog" text="Home" />
+<SidebarItem icon={HomeIcon} to="catalog" text="Home" />
```
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/config-loader': patch
---
Add option to populate the `filteredKeys` property when processing configuration with a schema.
+12
View File
@@ -0,0 +1,12 @@
---
'@backstage/create-app': patch
---
Switched `@types/react-dom` dependency to of the app package to request `*` rather than a specific version.
To apply this change to an existing app, change the following in `packages/app/package.json`:
```diff
- "@types/react-dom": "^16.9.8",
+ "@types/react-dom": "*",
```
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-api-docs': patch
---
Support deep linking in OpenAPI definitions.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-scaffolder-backend': patch
---
Add the `scaffolder.defaultCommitMessage`, which defaults to `Initial commit`, so it can be customized.
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/plugin-catalog': patch
'@backstage/plugin-catalog-react': patch
---
Move and rename `FavoriteEntity` component to `catalog-react`
-13
View File
@@ -1,13 +0,0 @@
---
'@backstage/core-components': patch
'@backstage/plugin-cost-insights': patch
'@backstage/plugin-fossa': patch
'@backstage/plugin-kubernetes': patch
'@backstage/plugin-lighthouse': patch
'@backstage/plugin-pagerduty': patch
'@backstage/plugin-sonarqube': patch
'@backstage/plugin-splunk-on-call': patch
'@backstage/plugin-techdocs': patch
---
Fix All Material UI Warnings
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-techdocs': patch
---
Avoid sanitize safe links in the header of document pages.
-16
View File
@@ -1,16 +0,0 @@
---
'@backstage/techdocs-common': minor
---
TechDocs has dropped all support for the long-ago deprecated git-based common
prepares as well as all corresponding values in `backstage.io/techdocs-ref`
annotations.
Entities whose `backstage.io/techdocs-ref` annotation values still begin with
`github:`, `gitlab:`, `bitbucket:`, or `azure/api:` will no longer be generated
by TechDocs. Be sure to update these values so that they align with their
expected format and your usage of TechDocs.
For details, see [this explainer on TechDocs ref annotation values][how].
[how]: https://backstage.io/docs/features/techdocs/how-to-guides#how-to-understand-techdocs-ref-annotation-values
-10
View File
@@ -1,10 +0,0 @@
---
'@backstage/plugin-techdocs-backend': patch
'@backstage/plugin-scaffolder-backend': patch
'@backstage/create-app': patch
---
The recommended value for a `backstage.io/techdocs-ref` annotation is now
`dir:.`, indicating "documentation source files are located in the same
directory relative to the catalog entity." Note that `url:<location>` values
are still supported.
@@ -1,7 +0,0 @@
---
'@backstage/create-app': patch
---
Update `techdocs.generators` with the latest `techdocs.generator` config in `app-config.yaml`. See
https://backstage.io/docs/features/techdocs/configuration for reference and relevant PR
https://github.com/backstage/backstage/pull/6071/files for the changes.
@@ -0,0 +1,19 @@
---
'@backstage/techdocs-common': patch
---
Stale TechDocs content (files that had previously been published but which have
since been removed) is now removed from storage at publish-time. This is now
supported by the following publishers:
- Google GCS
- AWS S3
- Azure Blob Storage
You may need to apply a greater level of permissions (e.g. the ability to
delete objects in your storage provider) to any credentials/accounts used by
the TechDocs CLI or TechDocs backend in order for this change to take effect.
For more details, see [#6132][issue-ref].
[issue-ref]: https://github.com/backstage/backstage/issues/6132
-71
View File
@@ -1,71 +0,0 @@
---
'@backstage/search-common': patch
'@backstage/plugin-search-backend-node': patch
---
Implements configuration and indexing functionality for ElasticSearch search engine. Adds indexing, searching and default translator for ElasticSearch and modifies default backend example-app to use ES if it is configured.
## Example configurations:
### AWS
Using AWS hosted ElasticSearch the only configuration options needed is the URL to the ElasticSearch service. The implementation assumes
that environment variables for AWS access key id and secret access key are defined in accordance to the [default AWS credential chain.](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-credentials-node.html).
```yaml
search:
elasticsearch:
provider: aws
node: https://my-backstage-search-asdfqwerty.eu-west-1.es.amazonaws.com
```
### Elastic.co
Elastic Cloud hosted ElasticSearch uses a Cloud ID to determine the instance of hosted ElasticSearch to connect to. Additionally, username and password needs to be provided either directly or using environment variables like defined in [Backstage documentation.](https://backstage.io/docs/conf/writing#includes-and-dynamic-data)
```yaml
search:
elasticsearch:
provider: elastic
cloudId: backstage-elastic:asdfqwertyasdfqwertyasdfqwertyasdfqwerty==
auth:
username: elastic
password: changeme
```
### Others
Other ElasticSearch instances can be connected to by using standard ElasticSearch authentication methods and exposed URL, provided that the cluster supports that. The configuration options needed are the URL to the node and authentication information. Authentication can be handled by either providing username/password or and API key or a bearer token. In case both username/password combination and one of the tokens are provided, token takes precedence. For more information how to create an API key, see [Elastic documentation on API keys](https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-api-key.html) and how to create a bearer token, see [Elastic documentation on tokens.](https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-service-token.html)
#### Configuration examples
##### With username and password
```yaml
search:
elasticsearch:
node: http://localhost:9200
auth:
username: elastic
password: changeme
```
##### With bearer token
```yaml
search:
elasticsearch:
node: http://localhost:9200
auth:
bearer: token
```
##### With API key
```yaml
search:
elasticsearch:
node: http://localhost:9200
auth:
apiKey: base64EncodedKey
```
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/core-components': patch
---
Fix for `SidebarItem` matching the active route too broadly.
+1
View File
@@ -223,6 +223,7 @@ Routable
rst
rsync
ruleset
runbook
sam
sanitization
scaffolded
@@ -50,4 +50,5 @@ jobs:
# projetToken intentionally shared to allow collaborators to run Chromatic on forks
# https://www.chromatic.com/docs/custom-ci-provider#run-chromatic-on-external-forks-of-open-source-projects
projectToken: 9tzak77m9nj
storybookBuildDir: 'packages/storybook/dist'
workingDir: 'packages/storybook'
storybookBuildDir: 'dist'
+7
View File
@@ -25,6 +25,13 @@ jobs:
name: Node ${{ matrix.node-version }} on ${{ matrix.os }}
steps:
# In order to have the create-app template function as if it was downloaded from NPM
# we need to make sure we checkout files with LF line endings only
- name: Set git to use LF
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- uses: actions/checkout@v2
- name: use node.js ${{ matrix.node-version }}
+1 -3
View File
@@ -1,5 +1,3 @@
{
"ignoredFiles": [
"docs/assets/**/*.svg"
]
"ignoredFiles": ["docs/assets/**/*.svg"]
}
+44 -43
View File
@@ -1,43 +1,44 @@
| 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) | [Erdogan Oksuz](https://github.com/erdoganoksuz) | 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. |
| 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) | [Erdogan Oksuz](https://github.com/erdoganoksuz) | 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 |
+1 -1
View File
@@ -116,7 +116,7 @@ In general, changesets are not needed for the documentation, build utilities, co
1. Run `yarn changeset`
2. Select which packages you want to include a changeset for
3. Select impact of change that you're introducing (patch, minor, or major)
3. Select impact of change that you're introducing, using `minor` for breaking changes and `patch` otherwise. We do not use `major` changes while packages are at version `0.x`.
4. Add generated changeset to Git
5. Push the commit with your changeset to the branch associated with your PR
6. Accept our gratitude for making the release process easier on the maintainers
+6 -2
View File
@@ -2,8 +2,6 @@
# [Backstage](https://backstage.io)
_During the month of July the majority of the maintainers will be on summer vacation 🏖️ Development will continue as usual, but expect a slower pace for discussions and PR reviews. Why not take this opportunity to [build a plugin](https://backstage.io/docs/plugins/)?_
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![CNCF Status](https://img.shields.io/badge/cncf%20status-sandbox-blue.svg)](https://www.cncf.io/projects)
[![Main CI Build](https://github.com/backstage/backstage/workflows/Main%20Master%20Build/badge.svg)](https://github.com/backstage/backstage/actions?query=workflow%3A%22Main+Master+Build%22)
@@ -63,3 +61,9 @@ Check out [the documentation](https://backstage.io/docs/getting-started) on how
Copyright 2020-2021 © The Backstage Authors. All rights reserved. The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation, please see our Trademark Usage page: https://www.linuxfoundation.org/trademark-usage
Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
## Security
Please report sensitive security issues via Spotify's [bug-bounty program](https://hackerone.com/spotify) rather than GitHub.
For further details please see our complete [security release process](SECURITY.md).
+17
View File
@@ -9,3 +9,20 @@
## Reporting a Vulnerability
Please report sensitive security issues via Spotify's [bug-bounty program](https://hackerone.com/spotify) rather than GitHub.
If you have questions about a potential vulnerability, please reach out on Discord by asking for a maintainer in the `#support` channel, or via direct message to a maintainer.
## Remediation and Notification Process
Vulnerabilities are handled and published through [GitHub Security Advisories](https://docs.github.com/en/code-security/security-advisories/about-github-security-advisories).
In the event of a vulnerability the runbook for the maintainers is as follows:
1. Create a [new draft security advisory](https://github.com/backstage/backstage/security/advisories/new). The values and descriptions don't need to be perfect to begin with as they can be edited later. For severity, use the "Assess severity using CVSS" and refer to [the guide](https://www.first.org/cvss/v3.1/user-guide) for help.
2. Request a CVE identification number. It can take up to 72h for one to be assigned so be sure to do this early on.
3. If there is not already a patch for the vulnerability, collaborate on one in a private fork:
1. Head to the security advisory on GitHub and [create a private fork](https://docs.github.com/en/code-security/security-advisories/collaborating-in-a-temporary-private-fork-to-resolve-a-security-vulnerability)
1. [Invite any collaborators](https://docs.github.com/en/code-security/security-advisories/adding-a-collaborator-to-a-security-advisory) from outside the maintainer team that should be part of creating a fix.
1. Create one or multiple Pull Requests with fixes towards the fork. Note that these PRs will not have CI checks run on them, so more care should be taken to run local validation. The PRs are also not merged like normal PRs, but are instead merged straight into the main repo all at once when the merge button is hit on the security advisory.
4. Once the fix is ready in a PR or private fork and it is time to release it, there are a couple of options. Either merge into the main branch with a changeset and wait for a regular release, or do a quick release by manually bumping the version in `package.json` of the affected package, along with a manual `CHANGELOG.md` entry. Note that a quick release will only work if the package does not have any other pending changes that depend on pending changes in other packages, so be sure to manually check that first, and fall back to an early regular release if needed. In general it's best to stick with the regular release flow, with the quick release being used only for time sensitive fixes.
5. Finalize and publish the security advisory. Note that once you hit the publish button it's no longer possible to edit the advisory. Just like the CVE number this can take up to 72h, and expect it to be slower than the CVE number request.
+1 -3
View File
@@ -244,9 +244,7 @@ export interface OAuthProviderHandlers {
req: express.Request,
options: Record<string, string>,
): Promise<RedirectInfo>;
handler(
req: express.Request,
): Promise<{
handler(req: express.Request): Promise<{
response: AuthResponse<OAuthProviderInfo>;
refreshToken?: string;
}>;
-2
View File
@@ -4,8 +4,6 @@ title: Search Architecture
description: Documentation on Search Architecture
---
# Search Architecture
> _This architecture has not been fully implemented yet. Find our milestones to
> follow our progress and help contribute on the
> [Search Roadmap](./README.md#project-roadmap)._
-2
View File
@@ -4,8 +4,6 @@ title: Search Concepts
description: Documentation on Backstage Search Concepts
---
# Search Concepts
Backstage Search lets you find the right information you are looking for in the
Backstage ecosystem.
-2
View File
@@ -4,8 +4,6 @@ title: Getting Started with Search
description: How to set up and install Backstage Search
---
# Getting Started
Search functions as a plugin to Backstage, so you will need to use Backstage to
use Search.
+33 -19
View File
@@ -4,8 +4,6 @@ title: Search Engines
description: Choosing and configuring your search engine for Backstage
---
# Search Engines
Backstage supports 2 search engines by default, an in-memory engine called Lunr
and ElasticSearch. You can configure your own search engines by implementing the
provided interface as mentioned in the
@@ -18,7 +16,7 @@ QueryTranslator interface. This modification can be done without touching
provided search engines by using the exposed setter to set the modified query
translator into the instance.
```
```typescript
const searchEngine = new LunrSearchEngine({ logger });
searchEngine.setTranslator(new MyNewAndBetterQueryTranslator());
```
@@ -36,6 +34,35 @@ const searchEngine = new LunrSearchEngine({ logger });
const indexBuilder = new IndexBuilder({ logger, searchEngine });
```
## Postgres
The Postgres based search engine only requires that postgres being configured as
the database engine for Backstage. Therefore it targets setups that want to
avoid maintaining another external service like elastic search. The search
provides decent results and performs well with ten thousands of indexed
documents. The connection to postgres is established via the database manager
also used by other plugins.
> **Important**: The search plugin requires at least Postgres 11!
To use the `PgSearchEngine`, make sure that you have a Postgres database
configured and make the following changes to your backend:
1. Add a dependency on `@backstage/plugin-search-backend-module-pg` to your
backend's `package.json`.
2. Initialize the search engine. It is recommended to initialize it with a
fallback to the lunr search engine if you are running Backstage for
development locally with SQLite:
```typescript
// In packages/backend/src/plugins/search.ts
// Initialize a connection to a search engine.
const searchEngine = (await PgSearchEngine.supported(database))
? await PgSearchEngine.from({ database })
: new LunrSearchEngine({ logger });
```
## ElasticSearch
Backstage supports ElasticSearch search engine connections, indexing and
@@ -103,12 +130,9 @@ Other ElasticSearch instances can be connected to by using standard
ElasticSearch authentication methods and exposed URL, provided that the cluster
supports that. The configuration options needed are the URL to the node and
authentication information. Authentication can be handled by either providing
username/password or an API key or a bearer token. In case both
username/password combination and one of the tokens are provided, token takes
precedence. For more information how to create an API key, see
[Elastic documentation on API keys](https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-api-key.html),
and how to create a bearer token see
[Elastic documentation on tokens.](https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-service-token.html)
username/password or an API key. For more information how to create an API key,
see
[Elastic documentation on API keys](https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-api-key.html).
#### Configuration examples
@@ -123,16 +147,6 @@ search:
password: changeme
```
##### With bearer token
```yaml
search:
elasticsearch:
node: http://localhost:9200
auth:
bearer: token
```
##### With API key
```yaml
@@ -187,7 +187,7 @@ new `CustomCatalogIndexPage`.
# packages/app/src/App.tsx
const routes = (
<FlatRoutes>
<Navigate key="/" to="/catalog" />
<Navigate key="/" to="catalog" />
- <Route path="/catalog" element={<CatalogIndexPage />} />
+ <Route path="/catalog" element={<CustomCatalogIndexPage />} />
```
@@ -57,6 +57,30 @@ if the original location delegates to another location. A common case is, that a
location is registered as `bootstrap:bootstrap` which means that it is part of
the `app-config.yaml` of a Backstage installation.
### backstage.io/orphan
This annotation is either absent, or present with the exact _string_ value
`"true"`. It should never be added manually. Instead, the catalog itself injects
the annotation as part of its processing loops, on entities that are found to
have no registered locations or config locations that keep them "active" /
"alive".
For example, suppose that the user first registers a location URL pointing to a
`Location` kind entity, which in turn refers to two `Component` kind entities in
two other files nearby. The end result is that the catalog contains those three
entities. Now suppose that the user edits the original `Location` entity to only
refer to the first of the `Component` kind entities. This will intentionally
_not_ lead to the other `Component` entity to be removed from the catalog (for
safety reasons). Instead, it gains this orphan marker annotation, to make it
clear that user action is required to completely remove it, if desired.
```yaml
# Example:
metadata:
annotations:
backstage.io/orphan: 'true'
```
### backstage.io/techdocs-ref
```yaml
@@ -61,7 +61,7 @@ If you do not prefer (3a) and optionally like to use a service account, you can
follow these steps.
Create a new Service Account and a key associated with it. In roles of the
service account, use "Storage Admin".
service account, use "Storage Object Admin".
If you want to create a custom role, make sure to include both `get` and
`create` permissions for both "Objects" and "Buckets". See
@@ -143,6 +143,8 @@ permissions to:
- `s3:ListBucket` to retrieve bucket metadata
- `s3:PutObject` to upload files to the bucket
- `s3:DeleteObject` and `s3:DeleteObjectVersion` to delete stale content during
re-publishing
To _read_ TechDocs from the S3 bucket the IAM policy needs to have at a minimum
permissions to:
@@ -345,6 +347,10 @@ techdocs:
accountKey: ${TECHDOCS_AZURE_BLOB_STORAGE_ACCOUNT_KEY}
```
In either case, the account or credentials used to access your container and all
TechDocs objects underneath it should have the `Storage Blog Data Owner` role
applied, in order to read, write, and delete objects as needed.
**4. That's it!**
Your Backstage app is now ready to use Azure Blob Storage for TechDocs, to store
+5 -7
View File
@@ -56,13 +56,11 @@ matching repository is processed.
repository.
```typescript
const customRepositoryParser: BitbucketRepositoryParser = async function* customRepositoryParser({
client,
repository,
}) {
// Custom logic for interpret the matching repository.
// See defaultRepositoryParser for an example
};
const customRepositoryParser: BitbucketRepositoryParser =
async function* customRepositoryParser({ client, repository }) {
// Custom logic for interpret the matching repository.
// See defaultRepositoryParser for an example
};
const processor = BitbucketDiscoveryProcessor.fromConfig(env.config, {
parser: customRepositoryParser,
-8
View File
@@ -312,14 +312,6 @@ configuration.
Stability: `1`
### `register-component` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/register-component/)
A frontend plugin that allows the user to register entity locations in the
catalog.
Stability: `0`. This plugin is likely to be replaced by a generic entity import
plugin instead.
### `scaffolder` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/scaffolder/)
The frontend scaffolder plugin where one can browse templates and initiate
+20
View File
@@ -89,6 +89,26 @@ integrations:
- $include: example-backstage-app-credentials.yaml
```
### Limiting the GitHub App installations
If you want to limit the GitHub app installations visible to backstage you may
optionally include the `allowedInstallationOwners` option.
```yaml
appId: 1
allowedInstallationOwners: ['GlobexCorp']
clientId: client id
clientSecret: client secret
webhookSecret: webhook secret
privateKey: |
-----BEGIN RSA PRIVATE KEY-----
...Key content...
-----END RSA PRIVATE KEY-----
```
This will result in backstage preventing the use of any installation that is not
within the allow list.
### Permissions for pull requests
These are the minimum permissions required for creating a pull request with
+1 -1
View File
@@ -2,5 +2,5 @@
"packages": ["packages/*", "plugins/*"],
"npmClient": "yarn",
"useWorkspaces": true,
"version": "0.1.1"
"version": "0.1.0"
}
+9
View File
@@ -0,0 +1,9 @@
---
title: XCMetrics
author: Spotify
authorUrl: https://github.com/spotify
category: Monitoring
description: Discover valuable insights hiding inside Xcodes build logs.
documentation: https://xcmetrics.io/
iconUrl: img/xcmetrics-icon.png
npmPackageName: '@backstage/plugin-xcmetrics'
+2 -1
View File
@@ -80,7 +80,8 @@
"features/search/search-overview",
"features/search/getting-started",
"features/search/concepts",
"features/search/architecture"
"features/search/architecture",
"features/search/search-engines"
]
},
{
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

+1
View File
@@ -64,6 +64,7 @@ nav:
- Getting Started: 'features/search/getting-started.md'
- Concepts: 'features/search/concepts.md'
- Search Architecture: 'features/search/architecture.md'
- Search Engines: 'features/search/search-engines.md'
- TechDocs:
- Overview: 'features/techdocs/README.md'
- Getting Started: 'features/techdocs/getting-started.md'
+5
View File
@@ -38,6 +38,10 @@
"packages": [
"packages/*",
"plugins/*"
],
"nohoist": [
"**/@storybook/**",
"**/@storybook"
]
},
"resolutions": {
@@ -55,6 +59,7 @@
"@microsoft/api-extractor-model": "^7.13.3"
},
"devDependencies": {
"@types/webpack": "^5.28.0",
"@changesets/cli": "^2.14.0",
"@octokit/openapi-types": "^2.2.0",
"@spotify/prettier-config": "^10.0.0",
+41
View File
@@ -1,5 +1,46 @@
# example-app
## 0.2.40
### Patch Changes
- Updated dependencies
- @backstage/cli@0.7.7
- @backstage/plugin-catalog@0.6.10
- @backstage/core-components@0.3.0
- @backstage/core-plugin-api@0.1.5
- @backstage/plugin-api-docs@0.6.5
- @backstage/plugin-scaffolder@0.10.3
- @backstage/plugin-search@0.4.6
- @backstage/plugin-cost-insights@0.11.3
- @backstage/plugin-kubernetes@0.4.10
- @backstage/plugin-lighthouse@0.2.22
- @backstage/plugin-pagerduty@0.3.10
- @backstage/plugin-techdocs@0.10.3
- @backstage/search-common@0.1.3
- @backstage/core-app-api@0.1.7
- @backstage/integration-react@0.1.6
- @backstage/plugin-badges@0.2.7
- @backstage/plugin-catalog-import@0.5.16
- @backstage/plugin-catalog-react@0.4.1
- @backstage/plugin-circleci@0.2.21
- @backstage/plugin-cloudbuild@0.2.21
- @backstage/plugin-code-coverage@0.1.9
- @backstage/plugin-explore@0.3.12
- @backstage/plugin-gcp-projects@0.3.2
- @backstage/plugin-github-actions@0.4.15
- @backstage/plugin-graphiql@0.2.14
- @backstage/plugin-jenkins@0.5.2
- @backstage/plugin-kafka@0.2.13
- @backstage/plugin-newrelic@0.3.2
- @backstage/plugin-org@0.3.19
- @backstage/plugin-rollbar@0.3.11
- @backstage/plugin-sentry@0.3.17
- @backstage/plugin-shortcuts@0.1.6
- @backstage/plugin-tech-radar@0.4.4
- @backstage/plugin-todo@0.1.7
- @backstage/plugin-user-settings@0.3.3
## 0.2.39
### Patch Changes
+38 -37
View File
@@ -1,45 +1,45 @@
{
"name": "example-app",
"version": "0.2.39",
"version": "0.2.40",
"private": true,
"bundled": true,
"dependencies": {
"@backstage/catalog-model": "^0.9.0",
"@backstage/cli": "^0.7.6",
"@backstage/core-app-api": "^0.1.6",
"@backstage/core-components": "^0.2.0",
"@backstage/core-plugin-api": "^0.1.4",
"@backstage/integration-react": "^0.1.5",
"@backstage/plugin-api-docs": "^0.6.4",
"@backstage/plugin-badges": "^0.2.6",
"@backstage/plugin-catalog": "^0.6.9",
"@backstage/plugin-catalog-import": "^0.5.15",
"@backstage/plugin-catalog-react": "^0.4.0",
"@backstage/plugin-circleci": "^0.2.20",
"@backstage/plugin-cloudbuild": "^0.2.20",
"@backstage/plugin-code-coverage": "^0.1.8",
"@backstage/plugin-cost-insights": "^0.11.2",
"@backstage/plugin-explore": "^0.3.11",
"@backstage/plugin-gcp-projects": "^0.3.1",
"@backstage/plugin-github-actions": "^0.4.14",
"@backstage/plugin-graphiql": "^0.2.13",
"@backstage/plugin-jenkins": "^0.5.1",
"@backstage/plugin-kafka": "^0.2.12",
"@backstage/plugin-kubernetes": "^0.4.9",
"@backstage/plugin-lighthouse": "^0.2.21",
"@backstage/plugin-newrelic": "^0.3.1",
"@backstage/plugin-org": "^0.3.18",
"@backstage/plugin-pagerduty": "0.3.9",
"@backstage/plugin-rollbar": "^0.3.10",
"@backstage/plugin-scaffolder": "^0.10.2",
"@backstage/plugin-search": "^0.4.5",
"@backstage/plugin-sentry": "^0.3.16",
"@backstage/plugin-shortcuts": "^0.1.5",
"@backstage/plugin-tech-radar": "^0.4.3",
"@backstage/plugin-techdocs": "^0.10.2",
"@backstage/plugin-todo": "^0.1.6",
"@backstage/plugin-user-settings": "^0.3.2",
"@backstage/search-common": "^0.1.2",
"@backstage/cli": "^0.7.7",
"@backstage/core-app-api": "^0.1.7",
"@backstage/core-components": "^0.3.0",
"@backstage/core-plugin-api": "^0.1.5",
"@backstage/integration-react": "^0.1.6",
"@backstage/plugin-api-docs": "^0.6.5",
"@backstage/plugin-badges": "^0.2.7",
"@backstage/plugin-catalog": "^0.6.10",
"@backstage/plugin-catalog-import": "^0.5.16",
"@backstage/plugin-catalog-react": "^0.4.1",
"@backstage/plugin-circleci": "^0.2.21",
"@backstage/plugin-cloudbuild": "^0.2.21",
"@backstage/plugin-code-coverage": "^0.1.9",
"@backstage/plugin-cost-insights": "^0.11.3",
"@backstage/plugin-explore": "^0.3.12",
"@backstage/plugin-gcp-projects": "^0.3.2",
"@backstage/plugin-github-actions": "^0.4.15",
"@backstage/plugin-graphiql": "^0.2.14",
"@backstage/plugin-jenkins": "^0.5.2",
"@backstage/plugin-kafka": "^0.2.13",
"@backstage/plugin-kubernetes": "^0.4.10",
"@backstage/plugin-lighthouse": "^0.2.22",
"@backstage/plugin-newrelic": "^0.3.2",
"@backstage/plugin-org": "^0.3.19",
"@backstage/plugin-pagerduty": "0.3.10",
"@backstage/plugin-rollbar": "^0.3.11",
"@backstage/plugin-scaffolder": "^0.10.3",
"@backstage/plugin-search": "^0.4.6",
"@backstage/plugin-sentry": "^0.3.17",
"@backstage/plugin-shortcuts": "^0.1.6",
"@backstage/plugin-tech-radar": "^0.4.4",
"@backstage/plugin-techdocs": "^0.10.3",
"@backstage/plugin-todo": "^0.1.7",
"@backstage/plugin-user-settings": "^0.3.3",
"@backstage/search-common": "^0.1.3",
"@backstage/theme": "^0.2.9",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -61,6 +61,7 @@
},
"devDependencies": {
"@backstage/test-utils": "^0.1.16",
"@rjsf/core": "^3.0.0",
"@testing-library/cypress": "^7.0.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
@@ -68,7 +69,7 @@
"@types/jest": "^26.0.7",
"@types/jquery": "^3.3.34",
"@types/node": "^14.14.32",
"@types/react-dom": "^16.9.8",
"@types/react-dom": "*",
"@types/zen-observable": "^0.8.0",
"cross-env": "^7.0.0",
"cypress": "^7.3.0",
+32 -6
View File
@@ -41,10 +41,22 @@ import { GcpProjectsPage } from '@backstage/plugin-gcp-projects';
import { GraphiQLPage } from '@backstage/plugin-graphiql';
import { LighthousePage } from '@backstage/plugin-lighthouse';
import { NewRelicPage } from '@backstage/plugin-newrelic';
import { ScaffolderPage, scaffolderPlugin } from '@backstage/plugin-scaffolder';
import {
ScaffolderPage,
scaffolderPlugin,
ScaffolderFieldExtensions,
RepoUrlPickerFieldExtension,
OwnerPickerFieldExtension,
EntityPickerFieldExtension,
EntityNamePickerFieldExtension,
} from '@backstage/plugin-scaffolder';
import { SearchPage } from '@backstage/plugin-search';
import { TechRadarPage } from '@backstage/plugin-tech-radar';
import { TechdocsPage } from '@backstage/plugin-techdocs';
import {
DefaultTechDocsHome,
TechDocsIndexPage,
TechDocsReaderPage,
} from '@backstage/plugin-techdocs';
import { UserSettingsPage } from '@backstage/plugin-user-settings';
import AlarmIcon from '@material-ui/icons/Alarm';
import React from 'react';
@@ -54,6 +66,7 @@ import { apis } from './apis';
import { Root } from './components/Root';
import { entityPage } from './components/catalog/EntityPage';
import { searchPage } from './components/search/SearchPage';
import { LowerCaseValuePickerFieldExtension } from './components/scaffolder/customScaffolderExtensions';
import { providers } from './identityProviders';
import * as plugins from './plugins';
@@ -98,7 +111,7 @@ const AppRouter = app.getRouter();
const routes = (
<FlatRoutes>
<Navigate key="/" to="/catalog" />
<Navigate key="/" to="catalog" />
<Route path="/catalog" element={<CatalogIndexPage />} />
<Route
path="/catalog/:namespace/:kind/:name"
@@ -107,8 +120,22 @@ const routes = (
{entityPage}
</Route>
<Route path="/catalog-import" element={<CatalogImportPage />} />
<Route path="/docs" element={<TechdocsPage />} />
<Route path="/create" element={<ScaffolderPage />} />
<Route path="/docs" element={<TechDocsIndexPage />}>
<DefaultTechDocsHome />
</Route>
<Route
path="/docs/:namespace/:kind/:name/*"
element={<TechDocsReaderPage />}
/>
<Route path="/create" element={<ScaffolderPage />}>
<ScaffolderFieldExtensions>
<EntityPickerFieldExtension />
<EntityNamePickerFieldExtension />
<RepoUrlPickerFieldExtension />
<OwnerPickerFieldExtension />
<LowerCaseValuePickerFieldExtension />
</ScaffolderFieldExtensions>
</Route>
<Route path="/explore" element={<ExplorePage />} />
<Route
path="/tech-radar"
@@ -116,7 +143,6 @@ const routes = (
/>
<Route path="/graphiql" element={<GraphiQLPage />} />
<Route path="/lighthouse" element={<LighthousePage />} />
<Route path="/api-docs" element={<ApiExplorerPage />} />
<Route path="/gcp-projects" element={<GcpProjectsPage />} />
<Route path="/newrelic" element={<NewRelicPage />} />
+1 -1
View File
@@ -82,7 +82,7 @@ export const Root = ({ children }: PropsWithChildren<{}>) => (
<SidebarSearch />
<SidebarDivider />
{/* Global nav, not org-specific */}
<SidebarItem icon={HomeIcon} to="/catalog" text="Home" />
<SidebarItem icon={HomeIcon} to="catalog" text="Home" />
<SidebarItem icon={ExtensionIcon} to="api-docs" text="APIs" />
<SidebarItem icon={LibraryBooks} to="docs" text="Docs" />
<SidebarItem icon={LayersIcon} to="explore" text="Explore" />
@@ -0,0 +1,34 @@
/*
* Copyright 2021 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { FieldValidation } from '@rjsf/core';
import {
createScaffolderFieldExtension,
TextValuePicker,
scaffolderPlugin,
} from '@backstage/plugin-scaffolder';
export const LowerCaseValuePickerFieldExtension = scaffolderPlugin.provide(
createScaffolderFieldExtension({
name: 'LowerCaseValuePicker',
component: TextValuePicker,
validation: (value: string, validation: FieldValidation) => {
if (value.toLowerCase() !== value) {
validation.addError('Only lowercase values are allowed.');
}
},
}),
);
+10
View File
@@ -1,5 +1,15 @@
# @backstage/backend-common
## 0.8.8
### Patch Changes
- 6aa7c3db7: bump node-tar version to the latest
- Updated dependencies
- @backstage/config@0.1.6
- @backstage/integration@0.5.9
- @backstage/config-loader@0.6.6
## 0.8.7
### Patch Changes
+5 -5
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-common",
"description": "Common functionality library for Backstage backends",
"version": "0.8.7",
"version": "0.8.8",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -30,10 +30,10 @@
},
"dependencies": {
"@backstage/cli-common": "^0.1.2",
"@backstage/config": "^0.1.5",
"@backstage/config-loader": "^0.6.5",
"@backstage/config": "^0.1.6",
"@backstage/config-loader": "^0.6.6",
"@backstage/errors": "^0.1.1",
"@backstage/integration": "^0.5.8",
"@backstage/integration": "^0.5.9",
"@google-cloud/storage": "^5.8.0",
"@octokit/rest": "^18.5.3",
"@types/cors": "^2.8.6",
@@ -76,7 +76,7 @@
}
},
"devDependencies": {
"@backstage/cli": "^0.7.5",
"@backstage/cli": "^0.7.7",
"@backstage/test-utils": "^0.1.15",
"@types/archiver": "^5.1.0",
"@types/compression": "^1.7.0",
+4 -4
View File
@@ -104,7 +104,7 @@ describe('CacheManager', () => {
manager.forPlugin(plugin2Id).getClient({ defaultTtl: expectedTtl });
const client = DefaultCacheClient as jest.Mock;
const cache = (Keyv as unknown) as jest.Mock;
const cache = Keyv as unknown as jest.Mock;
expect(cache).toHaveBeenCalledTimes(2);
expect(client).toHaveBeenCalledTimes(2);
@@ -124,7 +124,7 @@ describe('CacheManager', () => {
const expectedNamespace = 'test-plugin';
manager.forPlugin(expectedNamespace).getClient();
const cache = (Keyv as unknown) as jest.Mock;
const cache = Keyv as unknown as jest.Mock;
const mockCalls = cache.mock.calls.splice(-1);
const callArgs = mockCalls[0];
expect(callArgs[0].store).toBeInstanceOf(NoStore);
@@ -138,7 +138,7 @@ describe('CacheManager', () => {
.forPlugin(expectedNamespace)
.getClient({ defaultTtl: expectedTtl });
const cache = (Keyv as unknown) as jest.Mock;
const cache = Keyv as unknown as jest.Mock;
const mockCalls = cache.mock.calls.splice(-1);
const callArgs = mockCalls[0];
expect(callArgs[0]).toMatchObject({
@@ -162,7 +162,7 @@ describe('CacheManager', () => {
const expectedTtl = 3600;
manager.forPlugin('test').getClient({ defaultTtl: expectedTtl });
const cache = (Keyv as unknown) as jest.Mock;
const cache = Keyv as unknown as jest.Mock;
const mockCacheCalls = cache.mock.calls.splice(-1);
expect(mockCacheCalls[0][0]).toMatchObject({
ttl: expectedTtl,
@@ -110,9 +110,7 @@ export class DatabaseManager {
* @returns Object with client type returned as `client` and boolean representing whether
* or not the client was overridden as `overridden`
*/
private getClientType(
pluginId: string,
): {
private getClientType(pluginId: string): {
client: string;
overridden: boolean;
} {
@@ -149,7 +149,7 @@ export async function ensureMysqlDatabaseExists(
) {
const admin = createMysqlDatabaseClient(dbConfig, {
connection: {
database: (null as unknown) as string,
database: null as unknown as string,
},
});
@@ -78,21 +78,17 @@ describe('AzureUrlReader', () => {
it.each([
{
url:
'https://dev.azure.com/org-name/project-name/_git/repo-name?path=my-template.yaml&version=GBmaster',
url: 'https://dev.azure.com/org-name/project-name/_git/repo-name?path=my-template.yaml&version=GBmaster',
config: createConfig(),
response: expect.objectContaining({
url:
'https://dev.azure.com/org-name/project-name/_apis/git/repositories/repo-name/items?path=my-template.yaml&version=master',
url: 'https://dev.azure.com/org-name/project-name/_apis/git/repositories/repo-name/items?path=my-template.yaml&version=master',
}),
},
{
url:
'https://dev.azure.com/org-name/project-name/_git/repo-name?path=my-template.yaml',
url: 'https://dev.azure.com/org-name/project-name/_git/repo-name?path=my-template.yaml',
config: createConfig(),
response: expect.objectContaining({
url:
'https://dev.azure.com/org-name/project-name/_apis/git/repositories/repo-name/items?path=my-template.yaml',
url: 'https://dev.azure.com/org-name/project-name/_apis/git/repositories/repo-name/items?path=my-template.yaml',
}),
},
{
@@ -129,7 +129,7 @@ export class AzureUrlReader implements UrlReader {
}
return await this.deps.treeResponseFactory.fromZipArchive({
stream: (archiveAzureResponse.body as unknown) as Readable,
stream: archiveAzureResponse.body as unknown as Readable,
etag: commitSha,
filter: options?.filter,
});
@@ -60,13 +60,8 @@ export class BitbucketUrlReader implements UrlReader {
private readonly integration: BitbucketIntegration,
private readonly deps: { treeResponseFactory: ReadTreeResponseFactory },
) {
const {
host,
apiBaseUrl,
token,
username,
appPassword,
} = integration.config;
const { host, apiBaseUrl, token, username, appPassword } =
integration.config;
if (!apiBaseUrl) {
throw new Error(
@@ -138,7 +133,7 @@ export class BitbucketUrlReader implements UrlReader {
}
return await this.deps.treeResponseFactory.fromTarArchive({
stream: (archiveBitbucketResponse.body as unknown) as Readable,
stream: archiveBitbucketResponse.body as unknown as Readable,
subpath: filepath,
etag: lastCommitShortHash,
filter: options?.filter,
@@ -41,9 +41,9 @@ const treeResponseFactory = DefaultReadTreeResponseFactory.create({
config: new ConfigReader({}),
});
const mockCredentialsProvider = ({
const mockCredentialsProvider = {
getCredentials: jest.fn().mockResolvedValue({ headers: {} }),
} as unknown) as GithubCredentialsProvider;
} as unknown as GithubCredentialsProvider;
const githubProcessor = new GithubUrlReader(
new GitHubIntegration(
@@ -39,10 +39,14 @@ import {
ReadUrlResponse,
} from './types';
export type GhRepoResponse = RestEndpointMethodTypes['repos']['get']['response']['data'];
export type GhBranchResponse = RestEndpointMethodTypes['repos']['getBranch']['response']['data'];
export type GhTreeResponse = RestEndpointMethodTypes['git']['getTree']['response']['data'];
export type GhBlobResponse = RestEndpointMethodTypes['git']['getBlob']['response']['data'];
export type GhRepoResponse =
RestEndpointMethodTypes['repos']['get']['response']['data'];
export type GhBranchResponse =
RestEndpointMethodTypes['repos']['getBranch']['response']['data'];
export type GhTreeResponse =
RestEndpointMethodTypes['git']['getTree']['response']['data'];
export type GhBlobResponse =
RestEndpointMethodTypes['git']['getBlob']['response']['data'];
/**
* A processor that adds the ability to read files from GitHub v3 APIs, such as
@@ -195,7 +199,7 @@ export class GithubUrlReader implements UrlReader {
return await this.deps.treeResponseFactory.fromTarArchive({
// TODO(Rugvip): Underlying implementation of fetch will be node-fetch, we probably want
// to stick to using that in exclusively backend code.
stream: (archive.body as unknown) as Readable,
stream: archive.body as unknown as Readable,
subpath,
etag: sha,
filter: options?.filter,
@@ -258,9 +262,7 @@ export class GithubUrlReader implements UrlReader {
}));
}
private async getRepoDetails(
url: string,
): Promise<{
private async getRepoDetails(url: string): Promise<{
repo: GhRepoResponse;
branch: GhBranchResponse;
}> {
@@ -108,36 +108,30 @@ describe('GitlabUrlReader', () => {
it.each([
// Project URLs
{
url:
'https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path/to/file.yaml',
url: 'https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path/to/file.yaml',
config: createConfig(),
response: expect.objectContaining({
url:
'https://gitlab.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile.yaml/raw?ref=branch',
url: 'https://gitlab.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile.yaml/raw?ref=branch',
headers: expect.objectContaining({
'private-token': '',
}),
}),
},
{
url:
'https://gitlab.example.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path/to/file.yaml',
url: 'https://gitlab.example.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path/to/file.yaml',
config: createConfig('0123456789'),
response: expect.objectContaining({
url:
'https://gitlab.example.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile.yaml/raw?ref=branch',
url: 'https://gitlab.example.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile.yaml/raw?ref=branch',
headers: expect.objectContaining({
'private-token': '0123456789',
}),
}),
},
{
url:
'https://gitlab.com/groupA/teams/teamA/repoA/-/blob/branch/my/path/to/file.yaml', // Repo not in subgroup
url: 'https://gitlab.com/groupA/teams/teamA/repoA/-/blob/branch/my/path/to/file.yaml', // Repo not in subgroup
config: createConfig(),
response: expect.objectContaining({
url:
'https://gitlab.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile.yaml/raw?ref=branch',
url: 'https://gitlab.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile.yaml/raw?ref=branch',
}),
},
@@ -170,7 +170,7 @@ export class GitlabUrlReader implements UrlReader {
}
return await this.deps.treeResponseFactory.fromTarArchive({
stream: (archiveGitLabResponse.body as unknown) as Readable,
stream: archiveGitLabResponse.body as unknown as Readable,
subpath: filepath,
etag: commitSha,
filter: options?.filter,
@@ -52,7 +52,11 @@ export class UrlReaderPredicateMux implements UrlReader {
}
}
throw new NotAllowedError(`Reading from '${url}' is not allowed`);
throw new NotAllowedError(
`Reading from '${url}' is not allowed. ` +
`You may need to configure an integration for the target host, or add it ` +
`to the configured list of allowed hosts at 'backend.reading.allow'`,
);
}
async readUrl(
@@ -28,7 +28,7 @@ import {
import { stripFirstDirectoryFromPath } from './util';
// Tar types for `Parse` is not a proper constructor, but it should be
const TarParseStream = (Parse as unknown) as { new (): ParseStream };
const TarParseStream = Parse as unknown as { new (): ParseStream };
const pipeline = promisify(pipelineCb);
+9 -9
View File
@@ -123,9 +123,9 @@ describe('Git', () => {
await git.clone({ url, dir });
const { onAuth } = ((isomorphic.clone as unknown) as jest.Mock<
typeof isomorphic['clone']
>).mock.calls[0][0]!;
const { onAuth } = (
isomorphic.clone as unknown as jest.Mock<typeof isomorphic['clone']>
).mock.calls[0][0]!;
expect(onAuth()).toEqual(auth);
});
@@ -190,9 +190,9 @@ describe('Git', () => {
await git.fetch({ remote, dir });
const { onAuth } = ((isomorphic.fetch as unknown) as jest.Mock<
typeof isomorphic['fetch']
>).mock.calls[0][0]!;
const { onAuth } = (
isomorphic.fetch as unknown as jest.Mock<typeof isomorphic['fetch']>
).mock.calls[0][0]!;
expect(onAuth()).toEqual(auth);
});
@@ -279,9 +279,9 @@ describe('Git', () => {
await git.push({ remote, dir });
const { onAuth } = ((isomorphic.push as unknown) as jest.Mock<
typeof isomorphic['push']
>).mock.calls[0][0]!;
const { onAuth } = (
isomorphic.push as unknown as jest.Mock<typeof isomorphic['push']>
).mock.calls[0][0]!;
expect(onAuth()).toEqual(auth);
});
@@ -154,14 +154,8 @@ export class ServiceBuilderImpl implements ServiceBuilder {
async start(): Promise<http.Server> {
const app = express();
const {
port,
host,
logger,
corsOptions,
httpsSettings,
helmetOptions,
} = this.getOptions();
const { port, host, logger, corsOptions, httpsSettings, helmetOptions } =
this.getOptions();
app.use(helmet(helmetOptions));
if (corsOptions) {
@@ -92,18 +92,17 @@ export class DockerContainerRunner implements ContainerRunner {
Env.push(`${key}=${value}`);
}
const [
{ Error: error, StatusCode: statusCode },
] = await this.dockerClient.run(imageName, args, logStream, {
Volumes,
HostConfig: {
Binds,
},
...(workingDir ? { WorkingDir: workingDir } : {}),
Entrypoint: command,
Env,
...userOptions,
} as Docker.ContainerCreateOptions);
const [{ Error: error, StatusCode: statusCode }] =
await this.dockerClient.run(imageName, args, logStream, {
Volumes,
HostConfig: {
Binds,
},
...(workingDir ? { WorkingDir: workingDir } : {}),
Entrypoint: command,
Env,
...userOptions,
} as Docker.ContainerCreateOptions);
if (error) {
throw new Error(
@@ -71,7 +71,7 @@ describe('TestDatabases', () => {
await input.insert({ x: 'y' }).into('a');
// Look for the mark
const database = 'backstage_plugin_db0';
const database = input.client.config.connection.database;
const output = knexFactory({
client: 'pg',
connection: { host, port, user, password, database },
@@ -105,7 +105,7 @@ describe('TestDatabases', () => {
await input.insert({ x: 'y' }).into('a');
// Look for the mark
const database = 'backstage_plugin_db0';
const database = input.client.config.connection.database;
const output = knexFactory({
client: 'pg',
connection: { host, port, user, password, database },
@@ -139,7 +139,7 @@ describe('TestDatabases', () => {
await input.insert({ x: 'y' }).into('a');
// Look for the mark
const database = 'backstage_plugin_db0';
const database = input.client.config.connection.database;
const output = knexFactory({
client: 'mysql2',
connection: { host, port, user, password, database },
@@ -16,6 +16,7 @@
import { DatabaseManager } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { randomBytes } from 'crypto';
import { Knex } from 'knex';
import { isDockerDisabledForTests } from '../util/isDockerDisabledForTests';
import { startMysqlContainer } from './startMysqlContainer';
@@ -34,7 +35,6 @@ import {
export class TestDatabases {
private readonly instanceById: Map<string, Instance>;
private readonly supportedIds: TestDatabaseId[];
private lastDatabaseIndex: number;
/**
* Creates an empty `TestDatabases` instance, and sets up Jest to clean up
@@ -99,7 +99,6 @@ export class TestDatabases {
private constructor(supportedIds: TestDatabaseId[]) {
this.instanceById = new Map();
this.supportedIds = supportedIds;
this.lastDatabaseIndex = 0;
}
supports(id: TestDatabaseId): boolean {
@@ -142,7 +141,7 @@ export class TestDatabases {
// Ensure that a unique logical database is created in the instance
const connection = await instance.databaseManager
.forPlugin(String(`db${this.lastDatabaseIndex++}`))
.forPlugin(`db${randomBytes(16).toString('hex')}`)
.getClient();
instance.connections.push(connection);
@@ -38,33 +38,31 @@ export type Instance = {
databaseManager: DatabaseManager;
connections: Array<Knex>;
};
export const allDatabases: Record<
TestDatabaseId,
TestDatabaseProperties
> = Object.freeze({
POSTGRES_13: {
name: 'Postgres 13.x',
driver: 'pg',
dockerImageName: 'postgres:13',
connectionStringEnvironmentVariableName:
'BACKSTAGE_TEST_DATABASE_POSTGRES13_CONNECTION_STRING',
},
POSTGRES_9: {
name: 'Postgres 9.x',
driver: 'pg',
dockerImageName: 'postgres:9',
connectionStringEnvironmentVariableName:
'BACKSTAGE_TEST_DATABASE_POSTGRES9_CONNECTION_STRING',
},
MYSQL_8: {
name: 'MySQL 8.x',
driver: 'mysql2',
dockerImageName: 'mysql:8',
connectionStringEnvironmentVariableName:
'BACKSTAGE_TEST_DATABASE_MYSQL8_CONNECTION_STRING',
},
SQLITE_3: {
name: 'SQLite 3.x',
driver: 'sqlite3',
},
});
export const allDatabases: Record<TestDatabaseId, TestDatabaseProperties> =
Object.freeze({
POSTGRES_13: {
name: 'Postgres 13.x',
driver: 'pg',
dockerImageName: 'postgres:13',
connectionStringEnvironmentVariableName:
'BACKSTAGE_TEST_DATABASE_POSTGRES13_CONNECTION_STRING',
},
POSTGRES_9: {
name: 'Postgres 9.x',
driver: 'pg',
dockerImageName: 'postgres:9',
connectionStringEnvironmentVariableName:
'BACKSTAGE_TEST_DATABASE_POSTGRES9_CONNECTION_STRING',
},
MYSQL_8: {
name: 'MySQL 8.x',
driver: 'mysql2',
dockerImageName: 'mysql:8',
connectionStringEnvironmentVariableName:
'BACKSTAGE_TEST_DATABASE_MYSQL8_CONNECTION_STRING',
},
SQLITE_3: {
name: 'SQLite 3.x',
driver: 'sqlite3',
},
});
+1
View File
@@ -48,6 +48,7 @@
"@backstage/plugin-search-backend": "^0.2.3",
"@backstage/plugin-search-backend-node": "^0.4.0",
"@backstage/plugin-search-backend-module-elasticsearch": "^0.0.1",
"@backstage/plugin-search-backend-module-pg": "^0.1.0",
"@backstage/plugin-techdocs-backend": "^0.9.0",
"@backstage/plugin-todo-backend": "^0.1.8",
"@gitbeaker/node": "^30.2.0",
+36 -10
View File
@@ -13,29 +13,55 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { useHotCleanup } from '@backstage/backend-common';
import {
PluginDatabaseManager,
useHotCleanup,
} from '@backstage/backend-common';
import { Config } from '@backstage/config';
import { DefaultCatalogCollator } from '@backstage/plugin-catalog-backend';
import { createRouter } from '@backstage/plugin-search-backend';
import { ElasticSearchSearchEngine } from '@backstage/plugin-search-backend-module-elasticsearch';
import { PgSearchEngine } from '@backstage/plugin-search-backend-module-pg';
import {
IndexBuilder,
LunrSearchEngine,
SearchEngine,
} from '@backstage/plugin-search-backend-node';
import { PluginEnvironment } from '../types';
import { DefaultCatalogCollator } from '@backstage/plugin-catalog-backend';
import { DefaultTechDocsCollator } from '@backstage/plugin-techdocs-backend';
import { ElasticSearchSearchEngine } from '@backstage/plugin-search-backend-module-elasticsearch';
import { Logger } from 'winston';
import { PluginEnvironment } from '../types';
async function createSearchEngine({
logger,
database,
config,
}: {
logger: Logger;
database: PluginDatabaseManager;
config: Config;
}): Promise<SearchEngine> {
if (config.has('search.elasticsearch')) {
return await ElasticSearchSearchEngine.fromConfig({
logger,
config,
});
}
if (await PgSearchEngine.supported(database)) {
return await PgSearchEngine.from({ database });
}
return new LunrSearchEngine({ logger });
}
export default async function createPlugin({
logger,
discovery,
config,
database,
}: PluginEnvironment) {
// Initialize a connection to a search engine.
const searchEngine = config.has('search.elasticsearch')
? await ElasticSearchSearchEngine.fromConfig({
logger,
config,
})
: new LunrSearchEngine({ logger });
const searchEngine = await createSearchEngine({ config, logger, database });
const indexBuilder = new IndexBuilder({ logger, searchEngine });
// Collators are responsible for gathering documents known to plugins. This
+3 -7
View File
@@ -190,7 +190,7 @@ export type EntityEnvelope = {
//
// @public
export function entityEnvelopeSchemaValidator<
T extends EntityEnvelope = EntityEnvelope
T extends EntityEnvelope = EntityEnvelope,
>(schema?: unknown): (data: unknown) => T;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
@@ -333,9 +333,7 @@ export function getEntityName(entity: Entity): EntityName;
// Warning: (ae-missing-release-tag) "getEntitySourceLocation" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function getEntitySourceLocation(
entity: Entity,
): {
export function getEntitySourceLocation(entity: Entity): {
type: string;
target: string;
};
@@ -542,9 +540,7 @@ export function parseEntityRef(
// Warning: (ae-missing-release-tag) "parseLocationReference" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function parseLocationReference(
ref: string,
): {
export function parseLocationReference(ref: string): {
type: string;
target: string;
};
@@ -58,7 +58,7 @@ describe('SchemaValidEntityPolicy', () => {
//
it('rejects wrong root type', async () => {
await expect(policy.enforce((7 as unknown) as Entity)).rejects.toThrow(
await expect(policy.enforce(7 as unknown as Entity)).rejects.toThrow(
/object/,
);
});
+1 -3
View File
@@ -18,9 +18,7 @@ import { EntityName, EntityRef } from '../types';
import { ENTITY_DEFAULT_NAMESPACE } from './constants';
import { Entity } from './Entity';
function parseRefString(
ref: string,
): {
function parseRefString(ref: string): {
kind?: string;
namespace?: string;
name: string;
@@ -30,6 +30,5 @@ export interface ApiEntityV1alpha1 extends Entity {
};
}
export const apiEntityV1alpha1Validator = ajvCompiledJsonSchemaValidator(
schema,
);
export const apiEntityV1alpha1Validator =
ajvCompiledJsonSchemaValidator(schema);
@@ -33,6 +33,5 @@ export interface ComponentEntityV1alpha1 extends Entity {
};
}
export const componentEntityV1alpha1Validator = ajvCompiledJsonSchemaValidator(
schema,
);
export const componentEntityV1alpha1Validator =
ajvCompiledJsonSchemaValidator(schema);

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