Merge branch 'master' of github.com:backstage/backstage into remove-github-restriction
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/techdocs-common': patch
|
||||
---
|
||||
|
||||
Fix validation of mkdocs.yml docs_dir
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/backend-test-utils': patch
|
||||
---
|
||||
|
||||
Make sure that the unique databases names generated by `TestDatabases.create()`
|
||||
don't collide.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/catalog-client': patch
|
||||
---
|
||||
|
||||
Export `CatalogRequestOptions` type
|
||||
@@ -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.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-jenkins-backend': patch
|
||||
---
|
||||
|
||||
Update `@backstage/backend-common` to `^0.8.6`
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/core-app-api': patch
|
||||
---
|
||||
|
||||
Fix a bug in `FlatRoutes` that prevented outlets from working with the root route, as well as matching root routes too broadly.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-kubernetes-backend': patch
|
||||
---
|
||||
|
||||
Adds ability to send an ExternalId with the assume role request to AWS
|
||||
@@ -1,15 +0,0 @@
|
||||
---
|
||||
'@backstage/backend-common': patch
|
||||
---
|
||||
|
||||
It's possible to customize the request logging handler when building the service. For example in your `backend`
|
||||
|
||||
```
|
||||
const service = createServiceBuilder(module)
|
||||
.loadConfig(config)
|
||||
.setRequestLoggingHandler((logger?: Logger): RequestHandler => {
|
||||
const actualLogger = (logger || getRootLogger()).child({
|
||||
type: 'incomingRequest',
|
||||
});
|
||||
return expressWinston.logger({ ...
|
||||
```
|
||||
@@ -1,8 +0,0 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
'@backstage/test-utils': patch
|
||||
'@backstage/plugin-api-docs': patch
|
||||
'@backstage/plugin-catalog': patch
|
||||
---
|
||||
|
||||
Updated the layout of catalog and API index pages to handle smaller screen sizes. This adds responsive wrappers to the entity tables, and switches filters to a drawer when width-constrained. If you have created a custom catalog or API index page, you will need to update the page structure to match the updated [catalog customization](https://backstage.io/docs/features/software-catalog/catalog-customization) documentation.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
chore: bump `eslint` to `7.30.0`
|
||||
@@ -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`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-sonarqube': minor
|
||||
---
|
||||
|
||||
Use IdentityApi to provide Auth Token for SonarQubeClient Api calls
|
||||
@@ -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.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-catalog': patch
|
||||
---
|
||||
|
||||
Export `CatalogClientWrapper` class
|
||||
@@ -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" />
|
||||
```
|
||||
@@ -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.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
'@backstage/create-app': patch
|
||||
---
|
||||
|
||||
Migrate to using `webpack@5` 🎉
|
||||
@@ -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.
|
||||
@@ -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" />
|
||||
```
|
||||
@@ -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": "*",
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-api-docs': patch
|
||||
---
|
||||
|
||||
Support deep linking in OpenAPI definitions.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
---
|
||||
|
||||
- Move out the `cookiecutter` templating to its own module that is depended on by the `scaffolder-backend` plugin. No breaking change yet, but we will drop first class support for `cookiecutter` in the future and it will become an opt-in feature.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/techdocs-common': patch
|
||||
---
|
||||
|
||||
Add link to https://backstage.io/docs/features/techdocs/configuration in the log warning message about updating techdocs.generate key.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
Handle error responses in `getTechDocsMetadata` and `getEntityMetadata` such that `<TechDocsPageHeader>` doesn't throw errors.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
---
|
||||
|
||||
Fix for `SidebarItem` matching the active route too broadly.
|
||||
@@ -1,8 +0,0 @@
|
||||
---
|
||||
'@backstage/create-app': patch
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
---
|
||||
|
||||
Moved sample software templates to the [backstage/software-templates](https://github.com/backstage/software-templates) repository. If you previously referenced the sample templates straight from `scaffolder-backend` plugin in the main [backstage/backstage](https://github.com/backstage/backstage) repository in your `app-config.yaml`, these references will need to be updated.
|
||||
|
||||
See https://github.com/backstage/software-templates
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/dev-utils': patch
|
||||
---
|
||||
|
||||
Allow custom theme for dev app.
|
||||
@@ -1,5 +1,6 @@
|
||||
abc
|
||||
accessors
|
||||
Anddddd
|
||||
Apdex
|
||||
api
|
||||
Api
|
||||
@@ -74,6 +75,7 @@ dockerode
|
||||
Docusaurus
|
||||
env
|
||||
Env
|
||||
elasticsearch
|
||||
esbuild
|
||||
eslint
|
||||
etag
|
||||
@@ -221,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'
|
||||
|
||||
@@ -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
@@ -1,5 +1,3 @@
|
||||
{
|
||||
"ignoredFiles": [
|
||||
"docs/assets/**/*.svg"
|
||||
]
|
||||
"ignoredFiles": ["docs/assets/**/*.svg"]
|
||||
}
|
||||
|
||||
+44
-40
@@ -1,40 +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 team’s 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. |
|
||||
| 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 team’s 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
@@ -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
|
||||
|
||||
@@ -63,3 +63,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
@@ -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.
|
||||
|
||||
@@ -256,6 +256,8 @@ scaffolder:
|
||||
# defaultAuthor:
|
||||
# name: Scaffolder
|
||||
# email: scaffolder@backstage.io
|
||||
# Use to customize the default commit message when new components are created
|
||||
# defaultCommitMessage: 'Initial commit'
|
||||
github:
|
||||
token: ${GITHUB_TOKEN}
|
||||
visibility: public # or 'internal' or 'private'
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ metadata:
|
||||
url: https://discord.com/invite/EBHEGzX
|
||||
annotations:
|
||||
github.com/project-slug: backstage/backstage
|
||||
backstage.io/techdocs-ref: url:https://github.com/backstage/backstage
|
||||
backstage.io/techdocs-ref: dir:.
|
||||
lighthouse.com/website-url: https://backstage.io
|
||||
spec:
|
||||
type: library
|
||||
|
||||
@@ -5,7 +5,7 @@ image](https://backstage.io/docs/getting-started/deployment-docker); this
|
||||
tutorial shows how to deploy that Docker image to AWS using Elastic Container
|
||||
Registry (ECR) and Elastic Kubernetes Service (EKS). Amazon also supports
|
||||
deployments with Helm, covered in the [Helm
|
||||
Kubernetes](../kubernetes/basic_kubernetes_example_with_helm) example.
|
||||
Kubernetes](../../kubernetes/basic_kubernetes_example_with_helm) example.
|
||||
|
||||
The basic workflow for this method is to build a Backstage Docker image, upload
|
||||
the new version to a container registry, and update a Kubernetes deployment with
|
||||
|
||||
@@ -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;
|
||||
}>;
|
||||
|
||||
@@ -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)._
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -252,13 +250,9 @@ an example:
|
||||
Backstage Search isn't a search engine itself, rather, it provides an interface
|
||||
between your Backstage instance and a
|
||||
[Search Engine](./concepts.md#search-engines) of your choice. Currently, we only
|
||||
support one, an in-memory search Engine called Lunr. It can be instantiated like
|
||||
this:
|
||||
|
||||
```typescript
|
||||
const searchEngine = new LunrSearchEngine({ logger });
|
||||
const indexBuilder = new IndexBuilder({ logger, searchEngine });
|
||||
```
|
||||
support two engines, an in-memory search Engine called Lunr and ElasticSearch.
|
||||
See [Search Engines](./search-engines.md) documentation for more information how
|
||||
to configure these in your Backstage instance.
|
||||
|
||||
Backstage Search can be used to power search of anything! Plugins like the
|
||||
Catalog offer default [collators](./concepts.md#collators) (e.g.
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
---
|
||||
id: search-engines
|
||||
title: Search Engines
|
||||
description: Choosing and configuring your search engine for Backstage
|
||||
---
|
||||
|
||||
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
|
||||
[search backend documentation.](./getting-started.md#Backend)
|
||||
|
||||
Provided search engine implementations have their own way of constructing
|
||||
queries, which may be something you want to modify. Alterations to the querying
|
||||
logic of a search engine can be made by providing your own implementation of a
|
||||
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());
|
||||
```
|
||||
|
||||
## Lunr
|
||||
|
||||
Lunr search engine is enabled by default for your backstage instance if you have
|
||||
not done additional changes to the scaffolded app.
|
||||
|
||||
Lunr can be instantiated like this:
|
||||
|
||||
```typescript
|
||||
// app/backend/src/plugins/search.ts
|
||||
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
|
||||
querying out of the box. Available configuration options enable usage of either
|
||||
AWS or Elastic.co hosted solutions, or a custom self-hosted solution.
|
||||
|
||||
Similarly to Lunr above, ElasticSearch can be set up like this:
|
||||
|
||||
```typescript
|
||||
// app/backend/src/plugins/search.ts
|
||||
const searchEngine = await ElasticSearchSearchEngine.initialize({
|
||||
logger,
|
||||
config,
|
||||
});
|
||||
const indexBuilder = new IndexBuilder({ logger, searchEngine });
|
||||
```
|
||||
|
||||
For the engine to be available, your backend package needs a dependency into
|
||||
package `@backstage/plugin-search-backend-module-elasticsearch`.
|
||||
|
||||
ElasticSearch needs some additional configuration before it is ready to use
|
||||
within your instance. The configuration options are documented in the
|
||||
[configuration schema definition file.](https://github.com/backstage/backstage/blob/master/plugins/search-backend-module-elasticsearch/config.d.ts)
|
||||
|
||||
The underlying functionality is using official ElasticSearch client version 7.x,
|
||||
meaning that ElasticSearch version 7 is the only one confirmed to be supported.
|
||||
|
||||
## Example configurations
|
||||
|
||||
### AWS
|
||||
|
||||
Using AWS hosted ElasticSearch the only configuration option 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 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)
|
||||
|
||||
#### 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
|
||||
```
|
||||
@@ -36,7 +36,7 @@ export const CustomCatalogPage = ({
|
||||
<PageWithHeader title={`${orgName} Catalog`} themeId="home">
|
||||
<Content>
|
||||
<ContentHeader title="Components">
|
||||
<CreateComponentButton />
|
||||
<CreateButton title="Create Component" to={link} />
|
||||
<SupportButton>All your software catalog entities</SupportButton>
|
||||
</ContentHeader>
|
||||
<EntityListProvider>
|
||||
@@ -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 />} />
|
||||
```
|
||||
|
||||
@@ -63,12 +63,18 @@ the `app-config.yaml` of a Backstage installation.
|
||||
# Example:
|
||||
metadata:
|
||||
annotations:
|
||||
backstage.io/techdocs-ref: url:https://github.com/backstage/backstage/tree/master
|
||||
backstage.io/techdocs-ref: dir:.
|
||||
```
|
||||
|
||||
The value of this annotation is a location reference string (see above). If this
|
||||
annotation is specified, it is expected to point to a repository that the
|
||||
TechDocs system can read and generate docs from.
|
||||
The value of this annotation informs _where_ TechDocs source content is stored
|
||||
so that it can be read and docs can be generated from it. Most commonly, it's
|
||||
written as a path, relative to the location of the `catalog-info.yaml` itself,
|
||||
where the associated `mkdocs.yml` file can be found.
|
||||
|
||||
In unusual situations where the documentation for a catalog entity does not live
|
||||
alongside the entity's source code, the value of this annotation can point to an
|
||||
absolute URL, matching the location reference string format outlined above, for
|
||||
example: `url:https://github.com/backstage/backstage/tree/master`
|
||||
|
||||
### backstage.io/view-url, backstage.io/edit-url
|
||||
|
||||
|
||||
@@ -33,9 +33,12 @@ scaffolder:
|
||||
|
||||
### Disabling Docker in Docker situation (Optional)
|
||||
|
||||
Software Templates use
|
||||
[Cookiecutter](https://github.com/cookiecutter/cookiecutter) as a templating
|
||||
library. By default it will use the
|
||||
Software templates use the `fetch:template` action by default, which requires no
|
||||
external dependencies and offers a
|
||||
[Cookiecutter-compatible mode](https://backstage.io/docs/features/software-templates/builtin-actions#using-cookiecuttercompat-mode).
|
||||
There is also a `fetch:cookiecutter` action, which uses
|
||||
[Cookiecutter](https://github.com/cookiecutter/cookiecutter) directly for
|
||||
templating. By default, the `fetch:cookiecutter` action will use the
|
||||
[scaffolder-backend/Cookiecutter](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend/scripts/Cookiecutter.dockerfile)
|
||||
docker image.
|
||||
|
||||
|
||||
@@ -24,13 +24,13 @@ techdocs:
|
||||
|
||||
runIn: 'docker'
|
||||
|
||||
# techdocs.generator.dockerImage can be used to control the docker image used during documentation generation. This can be useful
|
||||
# (Optional) techdocs.generator.dockerImage can be used to control the docker image used during documentation generation. This can be useful
|
||||
# if you want to use MkDocs plugins or other packages that are not included in the default techdocs-container (spotify/techdocs).
|
||||
# NOTE: This setting is only used when techdocs.generator.runIn is set to 'docker'.
|
||||
|
||||
dockerImage: 'spotify/techdocs'
|
||||
|
||||
# techdocs.generator.pullImage can be used to disable pulling the latest docker image by default. This can be useful when you are
|
||||
# (Optional) techdocs.generator.pullImage can be used to disable pulling the latest docker image by default. This can be useful when you are
|
||||
# using a custom techdocs.generator.dockerImage and you have a custom docker login requirement. For example, you need to login to
|
||||
# AWS ECR to pull the docker image.
|
||||
# NOTE: Disabling this requires the docker image was pulled by other means before running the techdocs generator.
|
||||
|
||||
@@ -66,9 +66,7 @@ Update your component's entity description by adding the following lines to its
|
||||
```yaml
|
||||
metadata:
|
||||
annotations:
|
||||
backstage.io/techdocs-ref: url:https://github.com/org/repo
|
||||
# Or
|
||||
# backstage.io/techdocs-ref: url:https://github.com/org/repo/tree/branchName/subFolder
|
||||
backstage.io/techdocs-ref: dir:.
|
||||
```
|
||||
|
||||
The
|
||||
|
||||
@@ -35,38 +35,64 @@ In your Backstage instance's `app-config.yaml`, set `techdocs.builder` from
|
||||
`'local'` to `'external'`. By doing this, TechDocs will not try to generate
|
||||
docs. Look at [TechDocs configuration](configuration.md) for reference.
|
||||
|
||||
## How to use URL Reader in TechDocs Prepare step?
|
||||
## How to understand techdocs-ref annotation values
|
||||
|
||||
If TechDocs is configured to generate docs, it will first download the
|
||||
repository associated with the `backstage.io/techdocs-ref` annotation defined in
|
||||
the Entity's `catalog-info.yaml` file. This is also called the
|
||||
If TechDocs is configured to generate docs, it will first download source files
|
||||
based on the value of the `backstage.io/techdocs-ref` annotation defined in the
|
||||
Entity's `catalog-info.yaml` file. This is also called the
|
||||
[Prepare](./concepts.md#techdocs-preparer) step.
|
||||
|
||||
There are two kinds of preparers or two ways of downloading these source files
|
||||
We strongly recommend that the `backstage.io/techdocs-ref` annotation in each
|
||||
documented catalog entity's `catalog-info.yaml` be set to `dir:.` in almost all
|
||||
situations. This is because TechDocs is aligned with the "docs like code"
|
||||
philosophy, whereby documentation should be authored and managed alongside the
|
||||
source code of the underlying software itself.
|
||||
|
||||
- Preparer 1: Doing a `git clone` of the repository (also known as Common Git
|
||||
Preparer)
|
||||
- Preparer 2: Downloading an archive.zip or equivalent of the repository (also
|
||||
known as URL Reader)
|
||||
When you see `dir:.`, you can translate it to mean:
|
||||
|
||||
If `backstage.io/techdocs-ref` is equal to any of these -
|
||||
- That the documentation source code lives in the same location as the
|
||||
`catalog-info.yaml` file.
|
||||
- That, in particular, the `mkdocs.yml` file is a sibling of `catalog-info.yaml`
|
||||
(meaning, it is in the same directory)
|
||||
- And that all of the source content of the documentation would be available if
|
||||
one were to download the directory containing those two files (as well as all
|
||||
sub-directories).
|
||||
|
||||
1. `github:https://githubhost.com/org/repo`
|
||||
2. `gitlab:https://gitlabhost.com/org/repo`
|
||||
3. `bitbucket:https://bitbuckethost.com/project/repo`
|
||||
4. `azure/api:https://azurehost.com/org/project`
|
||||
The directory tree of the entity would look something like this:
|
||||
|
||||
Then Common Git Preparer will be used i.e. a `git clone`. But the URL Reader is
|
||||
a much faster way to do this step. Convert the `backstage.io/techdocs-ref`
|
||||
values to the following -
|
||||
```
|
||||
├── catalog-info.yaml
|
||||
├── mkdocs.yml
|
||||
└── docs
|
||||
└── index.md
|
||||
```
|
||||
|
||||
1. `url:https://githubhost.com/org/repo/tree/<branch_name>`
|
||||
2. `url:https://gitlabhost.com/org/repo/tree/<branch_name>`
|
||||
3. `url:https://bitbuckethost.com/project/repo/src/<branch_name>`
|
||||
4. `url:https://azurehost.com/organization/project/_git/repository`
|
||||
If, for example, you wanted to keep a lean root directory, you could place your
|
||||
`mkdocs.yml` file in a subdirectory and update the `backstage.io/techdocs-ref`
|
||||
annotation value accordingly, e.g. to `dir:./sub-folder`:
|
||||
|
||||
Note that you can also provide a path to a non-root directory inside the
|
||||
repository which contains the `docs/` directory.
|
||||
```
|
||||
├── catalog-info.yaml
|
||||
└── sub-folder
|
||||
├── mkdocs.yml
|
||||
└── docs
|
||||
└── index.md
|
||||
```
|
||||
|
||||
In rare situations where your TechDocs source content is managed and stored in a
|
||||
location completely separate from your `catalog-info.yaml`, you can instead
|
||||
specify a URL location reference, the exact value of which will vary based on
|
||||
the source code hosting provider. Notice that instead of the `dir:` prefix, the
|
||||
`url:` prefix is used instead. For example:
|
||||
|
||||
- **GitHub**: `url:https://githubhost.com/org/repo/tree/<branch_name>`
|
||||
- **GitLab**: `url:https://gitlabhost.com/org/repo/tree/<branch_name>`
|
||||
- **Bitbucket**: `url:https://bitbuckethost.com/project/repo/src/<branch_name>`
|
||||
- **Azure**: `url:https://azurehost.com/organization/project/_git/repository`
|
||||
|
||||
Note, just as it's possible to specify a subdirectory with the `dir:` prefix,
|
||||
you can also provide a path to a non-root directory inside the repository which
|
||||
contains the `mkdocs.yml` file and `docs/` directory.
|
||||
|
||||
e.g.
|
||||
`url:https://github.com/backstage/backstage/tree/master/plugins/techdocs-backend/examples/documented-component`
|
||||
|
||||
@@ -35,7 +35,7 @@ If you want more control over the theme, and for example customize font sizes
|
||||
and margins, you can use the lower-level `createThemeOverrides` function
|
||||
exported by [@backstage/theme](https://www.npmjs.com/package/@backstage/theme)
|
||||
in combination with
|
||||
[createMuiTheme](https://material-ui.com/customization/theming/#createmuitheme-options-args-theme)
|
||||
[createTheme](https://material-ui.com/customization/theming/#createmuitheme-options-args-theme)
|
||||
from [@material-ui/core](https://www.npmjs.com/package/@material-ui/core). See
|
||||
the
|
||||
[@backstage/theme source](https://github.com/backstage/backstage/tree/master/packages/theme/src)
|
||||
|
||||
@@ -24,11 +24,9 @@ an easier path to make Pull Requests.
|
||||
Backstage provides the `@backstage/create-app` package to scaffold standalone
|
||||
instances of Backstage. You will need to have
|
||||
[Node.js](https://nodejs.org/en/download/) Active LTS Release installed
|
||||
(currently v14), [Yarn](https://classic.yarnpkg.com/en/docs/install) and
|
||||
[Python](https://www.python.org/downloads/) (although you likely have it
|
||||
already). You will also need to have
|
||||
[Docker](https://docs.docker.com/engine/install/) installed to use some features
|
||||
like Software Templates and TechDocs.
|
||||
(currently v14) and [Yarn](https://classic.yarnpkg.com/en/docs/install). You
|
||||
will also need to have [Docker](https://docs.docker.com/engine/install/)
|
||||
installed to use some features like Software Templates and TechDocs.
|
||||
|
||||
Using `npx` you can then run the following to create an app in a chosen
|
||||
subdirectory of your current working directory:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -39,8 +39,8 @@ If you have specific questions about the roadmap, please create an
|
||||
|
||||
### How to read the roadmap
|
||||
|
||||
The Backstage roadmap lays out both [“what’s next”](#What’s-next) and
|
||||
[“future work”](#Future-work). With "next" we mean features planned for release
|
||||
The Backstage roadmap lays out both [“what’s next”](#whats-next) and
|
||||
[“future work”](#future-work). With "next" we mean features planned for release
|
||||
within the ongoing quarter starting in July until September 2021 included. With
|
||||
"future" we mean features in the radar, but not yet scheduled.
|
||||
|
||||
@@ -113,7 +113,7 @@ The following features are planned for release:
|
||||
- **Connecting identity to ownership to prepare for role-based access control
|
||||
([RBAC](https://en.wikipedia.org/wiki/Role-based_access_control)):** This is a
|
||||
first step to supporting RBAC for the software catalog (see the
|
||||
[future work section](#Future-work) for further details). Provide each entity
|
||||
[future work section](#future-work) for further details). Provide each entity
|
||||
within the software catalog with a recognized owner.
|
||||
- **Catalog performance improvements through improved caching:** Fix the
|
||||
performance gaps in the catalog processor, which currently doesn’t have a
|
||||
@@ -147,7 +147,7 @@ the maintainers’ radar, with clear interest expressed by the community.
|
||||
visual guidelines and templates, especially navigation across plug-ins and
|
||||
portal functionalities.
|
||||
- **Catalog composability (routing):** Follow up development after the RFC
|
||||
planned for the ongoing quarter (see [what’s next](#What’s-next) for further
|
||||
planned for the ongoing quarter (see [what’s next](#whats-next) for further
|
||||
details).
|
||||
- **Catalog-import improvements:** Provide a faster (scalability) and better
|
||||
(more features like move/rename) way to import entities into the Software
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -99,15 +99,14 @@ You may tweak these components, rename them and/or replace them completely.
|
||||
|
||||
## Connecting the plugin to the Backstage app
|
||||
|
||||
There are three things needed for a Backstage app to start making use of a
|
||||
plugin.
|
||||
There are two things needed for a Backstage app to start making use of a plugin.
|
||||
|
||||
1. Add plugin as dependency in `app/package.json`
|
||||
2. Import and use one or more plugin extensions, for example in
|
||||
`app/src/App.tsx`.
|
||||
|
||||
Luckily these three steps happen automatically when you create a plugin with the
|
||||
Backstage CLI.
|
||||
Luckily both of these steps happen automatically when you create a plugin with
|
||||
the Backstage CLI.
|
||||
|
||||
## Talking to the outside world
|
||||
|
||||
|
||||
+1
-1
@@ -2,5 +2,5 @@
|
||||
"packages": ["packages/*", "plugins/*"],
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"version": "0.1.1"
|
||||
"version": "0.1.0"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
---
|
||||
title: Software Templates is now in Beta
|
||||
author: Ben Lambert, Spotify
|
||||
authorURL: https://github.com/benjdlambert
|
||||
authorImageURL: https://avatars.githubusercontent.com/u/3645856?v=4
|
||||
---
|
||||
|
||||

|
||||
|
||||
**TLDR**; At a high level, Backstage performs three main jobs: [Create, Manage, and Explore](https://backstage.io/blog/2021/05/20/adopting-backstage#three-jobs-create-manage-explore). Throughout the year, we’ve been focussed on improving the stability and scalability of these areas while enhancing the feature sets based upon requests from the community. Software Templates — which enable push-button deployments with all your standards and best practices built-in — is our first feature-complete release candidate to graduate to beta. Read on to learn how this release improves template customization and flexibility, as well as performance.
|
||||
|
||||
<!--truncate-->
|
||||
|
||||
Let’s rewind a little bit, around a year in fact. Backstage had been open sourced, and we released our first version of Software Templates and our Scaffolder plugin.
|
||||
|
||||
In case you missed it, [Software Templates](https://backstage.io/blog/2020/08/05/announcing-backstage-software-templates) are part of the Create feature set, where you can set up Backstage to give your engineers the ability to spin up a new microservice, website, or any other software component with your organization’s best practices built-in, right from the start.
|
||||
|
||||
Back when we released the first version of these templates, with the `apiVersion` `backstage.io/v1alpha1`, they were a little restrictive in what they could do. The generated repository could only have one template source and it was restricted to only being [cookiecutter](https://github.com/cookiecutter/cookiecutter) templates. And it had to fit into the three stages of templating which was `Prepare`, `Template`, and `Publish`.
|
||||
|
||||
We [opened up for feedback](https://github.com/backstage/backstage/issues/2771) from the community knowing that this wasn’t going to be the final version, but something of a stepping stone to where we want to be in the future.
|
||||
|
||||
And now we come to today…
|
||||
|
||||
## Anddddd… Action(s)! 🎬
|
||||
|
||||
Following the removal of the previously deprecated `backstage.io/v1alpha1` templates, today we’re officially announcing the beta version of Software Templates, or `backstage.io/v1beta2`.
|
||||
|
||||
With it comes an entirely new architecture to the Software Templates functionality, and a load of new exciting features, which I’ll dig into a little deeper.
|
||||
|
||||
### Template actions
|
||||
|
||||
We’ve totally opened up the ability to compose your own workflows for each Template that you have registered in Software Templates. This means no restrictions on where your template skeleton is kept, and no restrictions on what your workflow should look like.
|
||||
|
||||
Template Actions are customizable JavaScript functions that allow you to extend the capabilities of the Software Templates by adding your own business logic or reusing some of our Built-In actions.
|
||||
|
||||

|
||||
|
||||
_An example of the new template syntax with steps and parameters_
|
||||
|
||||
The workflow for Software Templates are now step-based, and each Software Template can have a customizable amount of steps which will in turn call these new actions.
|
||||
|
||||

|
||||
|
||||
_An example of a Template with customizable steps_
|
||||
|
||||
These actions are very heavily inspired by GitHub Actions and GitHub Workflows, and we’ve given back a lot of control to the template authors so they can build the boilerplate and push the code however they want.
|
||||
|
||||
### Custom UI extensions
|
||||
|
||||
A large part of the Software Templates feature is the form that we use to collect user input which is then passed on to these new actions. Sometimes, it makes sense that Template Authors want to provide their own React components which can be rendered in the frontend to maybe do some more complex things like calling internal APIs to provide autocomplete.
|
||||
|
||||
This is now possible with the new `ScaffolderFieldExtensions`.
|
||||
|
||||

|
||||
|
||||
_An example of `ScaffolderFieldExtension` is the `OwnerPicker` component which can automatically add options and suggest typeahead with data from an async API request_
|
||||
|
||||
Template Authors can create their own components to provide data to the custom actions in any way you see fit, and even override our own built in ones too like the `RepoUrlPicker`.
|
||||
|
||||
### Horizontal scalability
|
||||
|
||||
The Scaffolder Service and Software Templates are now horizontally scalable, coordinating work between your deployed backend machines. This means now that the number of instances of the `@backstage/plugin-scaffolder-backend` plugin you have, is the same amount of jobs that you can have in parallel. This ensures that your tasks are handled quickly and reliably, while providing great feedback in the process.
|
||||
|
||||
## Try out the new templates
|
||||
|
||||
We’re still on the journey to making the Software Templates a great user experience for both authors and developers — but we’re not done yet, so watch this space for new exciting features to come!
|
||||
|
||||
In the meantime, make sure to visit the documentation for [building templates](https://backstage.io/docs/features/software-templates/adding-templates) or creating your own [custom actions](https://backstage.io/docs/features/software-templates/writing-custom-actions).
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 116 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 260 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 287 KiB |
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: XCMetrics
|
||||
author: Spotify
|
||||
authorUrl: https://github.com/spotify
|
||||
category: Monitoring
|
||||
description: Discover valuable insights hiding inside Xcode’s build logs.
|
||||
documentation: https://xcmetrics.io/
|
||||
iconUrl: img/xcmetrics-icon.png
|
||||
npmPackageName: '@backstage/plugin-xcmetrics'
|
||||
@@ -212,9 +212,9 @@ class Index extends React.Component {
|
||||
Backstage Software Templates{' '}
|
||||
<a
|
||||
title="Submit feedback for this feature. Click to learn more about this release."
|
||||
href="https://backstage.io/blog/2020/08/05/announcing-backstage-software-templates"
|
||||
href="https://backstage.io/blog/2021/07/26/software-templates-are-now-in-beta"
|
||||
>
|
||||
(alpha)
|
||||
(beta)
|
||||
</a>
|
||||
</Block.Subtitle>
|
||||
<Block.Title small>Standards can set you free</Block.Title>
|
||||
@@ -292,7 +292,7 @@ class Index extends React.Component {
|
||||
Build your own software templates
|
||||
</ActionBlock.Title>
|
||||
<ActionBlock.Link
|
||||
href={`https://github.com/backstage/backstage/blob/master/docs/features/software-templates/index.md`}
|
||||
href={`https://backstage.io/docs/features/software-templates`}
|
||||
>
|
||||
Contribute
|
||||
</ActionBlock.Link>
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -288,6 +288,16 @@ td {
|
||||
.tocToggler {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.docsSliderActive .toc section .navGroups {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.docsSliderActive.docsNavContainer {
|
||||
background-color: #121212;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* content */
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
@@ -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'
|
||||
|
||||
@@ -38,9 +38,14 @@
|
||||
"packages": [
|
||||
"packages/*",
|
||||
"plugins/*"
|
||||
],
|
||||
"nohoist": [
|
||||
"**/@storybook/**",
|
||||
"**/@storybook"
|
||||
]
|
||||
},
|
||||
"resolutions": {
|
||||
"**/@graphql-codegen/cli/**/ws": "^7.4.6",
|
||||
"**/@roadiehq/**/@backstage/core": "*",
|
||||
"**/@roadiehq/**/@backstage/plugin-catalog": "*",
|
||||
"**/@roadiehq/**/@backstage/catalog-model": "*",
|
||||
@@ -54,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",
|
||||
|
||||
@@ -1,5 +1,87 @@
|
||||
# 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
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-scaffolder@0.10.2
|
||||
- @backstage/core-components@0.2.0
|
||||
- @backstage/plugin-catalog@0.6.9
|
||||
- @backstage/plugin-catalog-react@0.4.0
|
||||
- @backstage/cli@0.7.6
|
||||
- @backstage/core-app-api@0.1.6
|
||||
- @backstage/core-plugin-api@0.1.4
|
||||
- @backstage/integration-react@0.1.5
|
||||
- @backstage/theme@0.2.9
|
||||
- @backstage/plugin-api-docs@0.6.4
|
||||
- @backstage/plugin-badges@0.2.6
|
||||
- @backstage/plugin-catalog-import@0.5.15
|
||||
- @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-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
|
||||
|
||||
## 0.2.37
|
||||
|
||||
### Patch Changes
|
||||
|
||||
+41
-39
@@ -1,47 +1,49 @@
|
||||
{
|
||||
"name": "example-app",
|
||||
"version": "0.2.37",
|
||||
"version": "0.2.40",
|
||||
"private": true,
|
||||
"bundled": true,
|
||||
"dependencies": {
|
||||
"@backstage/catalog-model": "^0.9.0",
|
||||
"@backstage/cli": "^0.7.4",
|
||||
"@backstage/core-app-api": "^0.1.3",
|
||||
"@backstage/core-components": "^0.1.5",
|
||||
"@backstage/core-plugin-api": "^0.1.3",
|
||||
"@backstage/integration-react": "^0.1.4",
|
||||
"@backstage/plugin-api-docs": "^0.6.2",
|
||||
"@backstage/plugin-badges": "^0.2.5",
|
||||
"@backstage/plugin-catalog": "^0.6.7",
|
||||
"@backstage/plugin-catalog-import": "^0.5.13",
|
||||
"@backstage/plugin-catalog-react": "^0.3.0",
|
||||
"@backstage/plugin-circleci": "^0.2.19",
|
||||
"@backstage/plugin-cloudbuild": "^0.2.19",
|
||||
"@backstage/plugin-code-coverage": "^0.1.7",
|
||||
"@backstage/plugin-cost-insights": "^0.11.0",
|
||||
"@backstage/plugin-explore": "^0.3.10",
|
||||
"@backstage/plugin-gcp-projects": "^0.3.0",
|
||||
"@backstage/plugin-github-actions": "^0.4.13",
|
||||
"@backstage/plugin-graphiql": "^0.2.12",
|
||||
"@backstage/plugin-jenkins": "^0.5.0",
|
||||
"@backstage/plugin-kafka": "^0.2.11",
|
||||
"@backstage/plugin-kubernetes": "^0.4.8",
|
||||
"@backstage/plugin-lighthouse": "^0.2.20",
|
||||
"@backstage/plugin-newrelic": "^0.3.0",
|
||||
"@backstage/plugin-org": "^0.3.17",
|
||||
"@backstage/plugin-pagerduty": "0.3.8",
|
||||
"@backstage/plugin-rollbar": "^0.3.9",
|
||||
"@backstage/plugin-scaffolder": "^0.10.1",
|
||||
"@backstage/plugin-search": "^0.4.3",
|
||||
"@backstage/plugin-sentry": "^0.3.15",
|
||||
"@backstage/plugin-shortcuts": "^0.1.4",
|
||||
"@backstage/plugin-tech-radar": "^0.4.1",
|
||||
"@backstage/plugin-techdocs": "^0.10.0",
|
||||
"@backstage/plugin-todo": "^0.1.5",
|
||||
"@backstage/plugin-user-settings": "^0.3.0",
|
||||
"@backstage/theme": "^0.2.8",
|
||||
"@material-ui/core": "^4.11.0",
|
||||
"@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",
|
||||
"@material-ui/lab": "4.0.0-alpha.45",
|
||||
"@octokit/rest": "^18.5.3",
|
||||
"@roadiehq/backstage-plugin-buildkite": "^1.0.6",
|
||||
"@roadiehq/backstage-plugin-github-insights": "^1.1.20",
|
||||
@@ -58,7 +60,7 @@
|
||||
"zen-observable": "^0.8.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/test-utils": "^0.1.14",
|
||||
"@backstage/test-utils": "^0.1.16",
|
||||
"@testing-library/cypress": "^7.0.1",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
@@ -66,7 +68,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",
|
||||
|
||||
@@ -98,7 +98,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"
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -40,6 +40,8 @@ import {
|
||||
isKind,
|
||||
EntityHasResourcesCard,
|
||||
EntityOrphanWarning,
|
||||
EntityProcessingErrorsPanel,
|
||||
hasCatalogProcessingErrors,
|
||||
isOrphan,
|
||||
} from '@backstage/plugin-catalog';
|
||||
import {
|
||||
@@ -135,6 +137,13 @@ const EntityLayoutWrapper = (props: { children?: ReactNode }) => {
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* NOTE: This page is designed to work on small screens such as mobile devices.
|
||||
* This is based on Material UI Grid. If breakpoints are used, each grid item must set the `xs` prop to a column size or to `true`,
|
||||
* since this does not default. If no breakpoints are used, the items will equitably share the asvailable space.
|
||||
* https://material-ui.com/components/grid/#basic-grid.
|
||||
*/
|
||||
|
||||
export const cicdContent = (
|
||||
<EntitySwitch>
|
||||
<EntitySwitch.Case if={isJenkinsAvailable}>
|
||||
@@ -224,6 +233,14 @@ const overviewContent = (
|
||||
</EntitySwitch.Case>
|
||||
</EntitySwitch>
|
||||
|
||||
<EntitySwitch>
|
||||
<EntitySwitch.Case if={hasCatalogProcessingErrors}>
|
||||
<Grid item xs={12}>
|
||||
<EntityProcessingErrorsPanel />
|
||||
</Grid>
|
||||
</EntitySwitch.Case>
|
||||
</EntitySwitch>
|
||||
|
||||
<Grid item md={8} xs={12}>
|
||||
<EntityAboutCard variant="gridItem" />
|
||||
</Grid>
|
||||
@@ -292,10 +309,10 @@ const serviceEntityPage = (
|
||||
|
||||
<EntityLayout.Route path="/api" title="API">
|
||||
<Grid container spacing={3} alignItems="stretch">
|
||||
<Grid item md={6}>
|
||||
<Grid item xs={12} md={6}>
|
||||
<EntityProvidedApisCard />
|
||||
</Grid>
|
||||
<Grid item md={6}>
|
||||
<Grid item xs={12} md={6}>
|
||||
<EntityConsumedApisCard />
|
||||
</Grid>
|
||||
</Grid>
|
||||
@@ -303,10 +320,10 @@ const serviceEntityPage = (
|
||||
|
||||
<EntityLayout.Route path="/dependencies" title="Dependencies">
|
||||
<Grid container spacing={3} alignItems="stretch">
|
||||
<Grid item md={6}>
|
||||
<Grid item xs={12} md={6}>
|
||||
<EntityDependsOnComponentsCard variant="gridItem" />
|
||||
</Grid>
|
||||
<Grid item md={6}>
|
||||
<Grid item xs={12} md={6}>
|
||||
<EntityDependsOnResourcesCard variant="gridItem" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
@@ -431,15 +448,17 @@ const apiPage = (
|
||||
<EntityLayoutWrapper>
|
||||
<EntityLayout.Route path="/" title="Overview">
|
||||
<Grid container spacing={3}>
|
||||
<Grid item md={6}>
|
||||
<Grid item xs={12}>
|
||||
<EntityAboutCard />
|
||||
</Grid>
|
||||
<Grid container item md={12}>
|
||||
<Grid item md={6}>
|
||||
<EntityProvidingComponentsCard />
|
||||
</Grid>
|
||||
<Grid item md={6}>
|
||||
<EntityConsumingComponentsCard />
|
||||
<Grid item xs={12}>
|
||||
<Grid container>
|
||||
<Grid item xs={12} md={6}>
|
||||
<EntityProvidingComponentsCard />
|
||||
</Grid>
|
||||
<Grid item xs={12} md={6}>
|
||||
<EntityConsumingComponentsCard />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -14,35 +14,88 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { makeStyles, Theme, Grid, List, Paper } from '@material-ui/core';
|
||||
|
||||
import Pagination from '@material-ui/lab/Pagination';
|
||||
import { CatalogResultListItem } from '@backstage/plugin-catalog';
|
||||
import {
|
||||
SearchBar,
|
||||
SearchFilter,
|
||||
SearchResult,
|
||||
SearchType,
|
||||
DefaultResultListItem,
|
||||
} from '@backstage/plugin-search';
|
||||
import { Content, Header, Lifecycle, Page } from '@backstage/core-components';
|
||||
import { DocsResultListItem } from '@backstage/plugin-techdocs';
|
||||
import { SearchResultSet } from '@backstage/search-common';
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) => ({
|
||||
bar: {
|
||||
padding: theme.spacing(1, 0),
|
||||
},
|
||||
filters: {
|
||||
padding: theme.spacing(2),
|
||||
},
|
||||
filter: {
|
||||
'& + &': {
|
||||
marginTop: theme.spacing(2.5),
|
||||
},
|
||||
},
|
||||
filters: {
|
||||
padding: theme.spacing(2),
|
||||
},
|
||||
}));
|
||||
|
||||
// TODO: Move this into the search plugin once pagination is natively supported.
|
||||
// See: https://github.com/backstage/backstage/issues/6062
|
||||
const SearchResultList = ({ results }: SearchResultSet) => {
|
||||
const pageSize = 10;
|
||||
const [page, setPage] = useState(1);
|
||||
const changePage = (_: any, pageIndex: number) => {
|
||||
setPage(pageIndex);
|
||||
};
|
||||
const pageAmount = Math.ceil((results.length || 0) / pageSize);
|
||||
return (
|
||||
<>
|
||||
<List>
|
||||
{results
|
||||
.slice(pageSize * (page - 1), pageSize * page)
|
||||
.map(({ type, document }) => {
|
||||
switch (type) {
|
||||
case 'software-catalog':
|
||||
return (
|
||||
<CatalogResultListItem
|
||||
key={document.location}
|
||||
result={document}
|
||||
/>
|
||||
);
|
||||
case 'techdocs':
|
||||
return (
|
||||
<DocsResultListItem
|
||||
key={document.location}
|
||||
result={document}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<DefaultResultListItem
|
||||
key={document.location}
|
||||
result={document}
|
||||
/>
|
||||
);
|
||||
}
|
||||
})}
|
||||
</List>
|
||||
<Pagination
|
||||
count={pageAmount}
|
||||
page={page}
|
||||
onChange={changePage}
|
||||
showFirstButton
|
||||
showLastButton
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const SearchPage = () => {
|
||||
const classes = useStyles();
|
||||
|
||||
return (
|
||||
<Page themeId="home">
|
||||
<Header title="Search" subtitle={<Lifecycle alpha />} />
|
||||
@@ -55,6 +108,11 @@ const SearchPage = () => {
|
||||
</Grid>
|
||||
<Grid item xs={3}>
|
||||
<Paper className={classes.filters}>
|
||||
<SearchType
|
||||
values={['techdocs', 'software-catalog']}
|
||||
name="type"
|
||||
defaultValue="software-catalog"
|
||||
/>
|
||||
<SearchFilter.Select
|
||||
className={classes.filter}
|
||||
name="kind"
|
||||
@@ -69,28 +127,7 @@ const SearchPage = () => {
|
||||
</Grid>
|
||||
<Grid item xs={9}>
|
||||
<SearchResult>
|
||||
{({ results }) => (
|
||||
<List>
|
||||
{results.map(({ type, document }) => {
|
||||
switch (type) {
|
||||
case 'software-catalog':
|
||||
return (
|
||||
<CatalogResultListItem
|
||||
key={document.location}
|
||||
result={document}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<DefaultResultListItem
|
||||
key={document.location}
|
||||
result={document}
|
||||
/>
|
||||
);
|
||||
}
|
||||
})}
|
||||
</List>
|
||||
)}
|
||||
{({ results }) => <SearchResultList results={results} />}
|
||||
</SearchResult>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# @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
|
||||
|
||||
- f25357273: Implement the etag functionality in the `readUrl` method of `FetchUrlReader`.
|
||||
- bdd6ab5f1: It's possible to customize the request logging handler when building the service. For example in your `backend`
|
||||
|
||||
```
|
||||
const service = createServiceBuilder(module)
|
||||
.loadConfig(config)
|
||||
.setRequestLoggingHandler((logger?: Logger): RequestHandler => {
|
||||
const actualLogger = (logger || getRootLogger()).child({
|
||||
type: 'incomingRequest',
|
||||
});
|
||||
return expressWinston.logger({ ...
|
||||
```
|
||||
|
||||
## 0.8.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/backend-common",
|
||||
"description": "Common functionality library for Backstage backends",
|
||||
"version": "0.8.6",
|
||||
"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",
|
||||
@@ -62,7 +62,7 @@
|
||||
"raw-body": "^2.4.1",
|
||||
"selfsigned": "^1.10.7",
|
||||
"stoppable": "^1.1.0",
|
||||
"tar": "^6.0.5",
|
||||
"tar": "^6.1.2",
|
||||
"unzipper": "^0.10.11",
|
||||
"winston": "^3.2.1",
|
||||
"yn": "^4.0.0"
|
||||
@@ -76,8 +76,8 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.7.4",
|
||||
"@backstage/test-utils": "^0.1.12",
|
||||
"@backstage/cli": "^0.7.7",
|
||||
"@backstage/test-utils": "^0.1.15",
|
||||
"@types/archiver": "^5.1.0",
|
||||
"@types/compression": "^1.7.0",
|
||||
"@types/concat-stream": "^1.6.0",
|
||||
|
||||
+4
-4
@@ -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,
|
||||
|
||||
@@ -15,12 +15,16 @@
|
||||
*/
|
||||
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { NotFoundError, NotModifiedError } from '@backstage/errors';
|
||||
import { msw } from '@backstage/test-utils';
|
||||
import { rest } from 'msw';
|
||||
import { setupServer } from 'msw/node';
|
||||
import { getVoidLogger } from '../logging';
|
||||
import { FetchUrlReader } from './FetchUrlReader';
|
||||
import { DefaultReadTreeResponseFactory } from './tree';
|
||||
|
||||
const fetchUrlReader = new FetchUrlReader();
|
||||
|
||||
describe('FetchUrlReader', () => {
|
||||
const worker = setupServer();
|
||||
|
||||
@@ -30,6 +34,39 @@ describe('FetchUrlReader', () => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
worker.use(
|
||||
rest.get('https://backstage.io/some-resource', (req, res, ctx) => {
|
||||
if (req.headers.get('if-none-match') === 'foo') {
|
||||
return res(
|
||||
ctx.status(304),
|
||||
ctx.set('Content-Type', 'text/plain'),
|
||||
ctx.set('etag', 'foo'),
|
||||
);
|
||||
}
|
||||
|
||||
return res(
|
||||
ctx.status(200),
|
||||
ctx.set('Content-Type', 'text/plain'),
|
||||
ctx.set('etag', 'foo'),
|
||||
ctx.body('content foo'),
|
||||
);
|
||||
}),
|
||||
);
|
||||
|
||||
worker.use(
|
||||
rest.get('https://backstage.io/not-exists', (_req, res, ctx) => {
|
||||
return res(ctx.status(404));
|
||||
}),
|
||||
);
|
||||
|
||||
worker.use(
|
||||
rest.get('https://backstage.io/error', (_req, res, ctx) => {
|
||||
return res(ctx.status(500), ctx.body('An internal error occured'));
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('factory should create a single entry with a predicate that matches config', async () => {
|
||||
const entries = FetchUrlReader.factory({
|
||||
config: new ConfigReader({
|
||||
@@ -70,4 +107,55 @@ describe('FetchUrlReader', () => {
|
||||
expect(predicate(new URL('https://a.examples.org:700/test'))).toBe(true);
|
||||
expect(predicate(new URL('https://a.b.examples.org:700/test'))).toBe(true);
|
||||
});
|
||||
|
||||
describe('read', () => {
|
||||
it('should return etag from the response', async () => {
|
||||
const buffer = await fetchUrlReader.read(
|
||||
'https://backstage.io/some-resource',
|
||||
);
|
||||
expect(buffer.toString()).toBe('content foo');
|
||||
});
|
||||
|
||||
it('should throw NotFound if server responds with 404', async () => {
|
||||
await expect(
|
||||
fetchUrlReader.read('https://backstage.io/not-exists'),
|
||||
).rejects.toThrow(NotFoundError);
|
||||
});
|
||||
|
||||
it('should throw Error if server responds with 500', async () => {
|
||||
await expect(
|
||||
fetchUrlReader.read('https://backstage.io/error'),
|
||||
).rejects.toThrow(Error);
|
||||
});
|
||||
});
|
||||
|
||||
describe('readUrl', () => {
|
||||
it('should throw NotModified if server responds with 304', async () => {
|
||||
await expect(
|
||||
fetchUrlReader.readUrl('https://backstage.io/some-resource', {
|
||||
etag: 'foo',
|
||||
}),
|
||||
).rejects.toThrow(NotModifiedError);
|
||||
});
|
||||
|
||||
it('should return etag from the response', async () => {
|
||||
const response = await fetchUrlReader.readUrl(
|
||||
'https://backstage.io/some-resource',
|
||||
);
|
||||
expect(response.etag).toBe('foo');
|
||||
expect((await response.buffer()).toString()).toEqual('content foo');
|
||||
});
|
||||
|
||||
it('should throw NotFound if server responds with 404', async () => {
|
||||
await expect(
|
||||
fetchUrlReader.readUrl('https://backstage.io/not-exists'),
|
||||
).rejects.toThrow(NotFoundError);
|
||||
});
|
||||
|
||||
it('should throw Error if server responds with 500', async () => {
|
||||
await expect(
|
||||
fetchUrlReader.readUrl('https://backstage.io/error'),
|
||||
).rejects.toThrow(Error);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { NotFoundError, NotModifiedError } from '@backstage/errors';
|
||||
import fetch from 'cross-fetch';
|
||||
import { NotFoundError } from '@backstage/errors';
|
||||
import {
|
||||
ReaderFactory,
|
||||
ReadTreeResponse,
|
||||
@@ -57,15 +57,34 @@ export class FetchUrlReader implements UrlReader {
|
||||
};
|
||||
|
||||
async read(url: string): Promise<Buffer> {
|
||||
const response = await this.readUrl(url);
|
||||
return response.buffer();
|
||||
}
|
||||
|
||||
async readUrl(
|
||||
url: string,
|
||||
options?: ReadUrlOptions,
|
||||
): Promise<ReadUrlResponse> {
|
||||
let response: Response;
|
||||
try {
|
||||
response = await fetch(url);
|
||||
response = await fetch(url, {
|
||||
headers: {
|
||||
...(options?.etag && { 'If-None-Match': options.etag }),
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
throw new Error(`Unable to read ${url}, ${e}`);
|
||||
}
|
||||
|
||||
if (response.status === 304) {
|
||||
throw new NotModifiedError();
|
||||
}
|
||||
|
||||
if (response.ok) {
|
||||
return Buffer.from(await response.text());
|
||||
return {
|
||||
buffer: async () => Buffer.from(await response.text()),
|
||||
etag: response.headers.get('ETag') ?? undefined,
|
||||
};
|
||||
}
|
||||
|
||||
const message = `could not read ${url}, ${response.status} ${response.statusText}`;
|
||||
@@ -75,15 +94,6 @@ export class FetchUrlReader implements UrlReader {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
async readUrl(
|
||||
url: string,
|
||||
_options?: ReadUrlOptions,
|
||||
): Promise<ReadUrlResponse> {
|
||||
// TODO etag is not implemented yet.
|
||||
const buffer = await this.read(url);
|
||||
return { buffer: async () => buffer };
|
||||
}
|
||||
|
||||
async readTree(): Promise<ReadTreeResponse> {
|
||||
throw new Error('FetchUrlReader does not implement readTree');
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,5 +1,18 @@
|
||||
# example-backend
|
||||
|
||||
## 0.2.38
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-kubernetes-backend@0.3.11
|
||||
- @backstage/catalog-client@0.3.17
|
||||
- @backstage/plugin-auth-backend@0.3.18
|
||||
- @backstage/plugin-jenkins-backend@0.1.2
|
||||
- @backstage/backend-common@0.8.7
|
||||
- @backstage/plugin-techdocs-backend@0.9.0
|
||||
- @backstage/plugin-scaffolder-backend@0.14.1
|
||||
|
||||
## 0.2.37
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "example-backend",
|
||||
"version": "0.2.37",
|
||||
"version": "0.2.38",
|
||||
"main": "dist/index.cjs.js",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -27,27 +27,29 @@
|
||||
"migrate:create": "knex migrate:make -x ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.8.6",
|
||||
"@backstage/catalog-client": "^0.3.16",
|
||||
"@backstage/backend-common": "^0.8.7",
|
||||
"@backstage/catalog-client": "^0.3.17",
|
||||
"@backstage/catalog-model": "^0.9.0",
|
||||
"@backstage/config": "^0.1.5",
|
||||
"@backstage/integration": "^0.5.8",
|
||||
"@backstage/plugin-app-backend": "^0.3.15",
|
||||
"@backstage/plugin-auth-backend": "^0.3.17",
|
||||
"@backstage/plugin-auth-backend": "^0.3.18",
|
||||
"@backstage/plugin-badges-backend": "^0.1.8",
|
||||
"@backstage/plugin-catalog-backend": "^0.13.0",
|
||||
"@backstage/plugin-code-coverage-backend": "^0.1.8",
|
||||
"@backstage/plugin-graphql-backend": "^0.1.8",
|
||||
"@backstage/plugin-jenkins-backend": "^0.1.1",
|
||||
"@backstage/plugin-kubernetes-backend": "^0.3.10",
|
||||
"@backstage/plugin-jenkins-backend": "^0.1.2",
|
||||
"@backstage/plugin-kubernetes-backend": "^0.3.11",
|
||||
"@backstage/plugin-kafka-backend": "^0.2.8",
|
||||
"@backstage/plugin-proxy-backend": "^0.2.9",
|
||||
"@backstage/plugin-rollbar-backend": "^0.1.13",
|
||||
"@backstage/plugin-scaffolder-backend": "^0.14.0",
|
||||
"@backstage/plugin-scaffolder-backend": "^0.14.1",
|
||||
"@backstage/plugin-scaffolder-backend-module-rails": "^0.1.3",
|
||||
"@backstage/plugin-search-backend": "^0.2.3",
|
||||
"@backstage/plugin-search-backend-node": "^0.4.0",
|
||||
"@backstage/plugin-techdocs-backend": "^0.8.7",
|
||||
"@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",
|
||||
"@octokit/rest": "^18.5.3",
|
||||
@@ -63,7 +65,7 @@
|
||||
"winston": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.7.4",
|
||||
"@backstage/cli": "^0.7.5",
|
||||
"@types/dockerode": "^3.2.1",
|
||||
"@types/express": "^4.17.6",
|
||||
"@types/express-serve-static-core": "^4.17.5"
|
||||
|
||||
@@ -13,21 +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 { DefaultTechDocsCollator } from '@backstage/plugin-techdocs-backend';
|
||||
import { Logger } from 'winston';
|
||||
import { PluginEnvironment } from '../types';
|
||||
import { DefaultCatalogCollator } from '@backstage/plugin-catalog-backend';
|
||||
|
||||
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 = 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
|
||||
@@ -37,6 +71,11 @@ export default async function createPlugin({
|
||||
collator: new DefaultCatalogCollator({ discovery }),
|
||||
});
|
||||
|
||||
indexBuilder.addCollator({
|
||||
defaultRefreshIntervalSeconds: 600,
|
||||
collator: new DefaultTechDocsCollator({ discovery, logger }),
|
||||
});
|
||||
|
||||
// The scheduler controls when documents are gathered from collators and sent
|
||||
// to the search engine for indexing.
|
||||
const { scheduler } = await indexBuilder.build();
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
# @backstage/catalog-client
|
||||
|
||||
## 0.3.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 11c370af2: Support filtering entities via property existence
|
||||
|
||||
## 0.3.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 71c936eb6: Export `CatalogRequestOptions` type
|
||||
|
||||
## 0.3.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user