Merge branch 'master' into scalable-sidebar-new-implementation

This commit is contained in:
hiba-aldalaty
2021-10-26 10:57:20 +01:00
983 changed files with 22920 additions and 6881 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-kubernetes': patch
---
The Kubernetes plugin will now re-fetch the kubernetes objects every ten seconds (not current configurable), this allows users to track the progress of deployments without refreshing the browser.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-sentry': patch
---
feature: sentry-plugin allows passing search query for listing issues
+9
View File
@@ -0,0 +1,9 @@
---
'@backstage/test-utils': patch
'@backstage/test-utils-core': patch
---
Migrates all utility methods from `test-utils-core` into `test-utils` and delete exports from the old package.
This should have no impact since this package is considered internal and have no usages outside core packages.
Notable changes are that the testing tool `msw.setupDefaultHandlers()` have been deprecated in favour of `setupRequestMockHandlers()`.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-techdocs': patch
---
Reader will now scroll to the top of the page when navigating between pages
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder': patch
---
Surfacing all components of the ScaffolderPage outside of the plugin so you can customize the page
+10
View File
@@ -0,0 +1,10 @@
---
'@backstage/plugin-azure-devops': patch
---
Azure DevOps frontend refactoring items from issue #7641
- Remove backend setup documentation and linked to the Azure DevOps backend plugin for these instructions
- Improved documentation to be easier to expand with new features in the future
- Removed Router based on feedback from maintainers
- Added tests for `getBuildResultComponent` and `getBuildStateComponent` from the BuildTable
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder': patch
---
Scaffolder: Enable back Template action buttons if template fails to execute
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-graphiql': patch
---
Add experimental `experimentalInstallationRecipe` to `package.json`.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/cli': patch
---
add a --from <location> option to the plugin install command
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-azure-devops-backend': patch
---
Added duration (startTime and finishTime) and identity (uniqueName) to the RepoBuild results. Also did a bit of refactoring to help finish up the backend items in issue #7641
-9
View File
@@ -1,9 +0,0 @@
---
'@backstage/plugin-catalog-backend': minor
---
This continues the deprecation of classes used by the legacy catalog engine. New deprecations can be viewed in this [PR](https://github.com/backstage/backstage/pull/7500) or in the API reference documentation.
The `batchAddOrUpdateEntities` method of the `EntitiesCatalog` interface has been marked as optional and is being deprecated. It is still implemented and required to be implemented by the legacy catalog classes, but was never implemented in the new catalog.
This change is only relevant if you are consuming the `EntitiesCatalog` interface directly, in which case you will get a type error that you need to resolve. It can otherwise be ignored.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/cli': patch
---
Bump sucrase to version 3.20.2
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-auth-backend': patch
---
Added extra configuration parameters for active directory file system identity
+26
View File
@@ -0,0 +1,26 @@
---
'@backstage/backend-common': patch
'@backstage/catalog-model': patch
'@backstage/cli': patch
'@backstage/config-loader': patch
'@backstage/core-app-api': patch
'@backstage/errors': patch
'@backstage/search-common': patch
'@backstage/test-utils': patch
'@backstage/plugin-app-backend': patch
'@backstage/plugin-catalog-backend': patch
'@backstage/plugin-catalog-backend-module-ldap': patch
'@backstage/plugin-catalog-graphql': patch
'@backstage/plugin-catalog-react': patch
'@backstage/plugin-config-schema': patch
'@backstage/plugin-scaffolder': patch
'@backstage/plugin-scaffolder-backend': patch
'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch
'@backstage/plugin-scaffolder-backend-module-rails': patch
'@backstage/plugin-scaffolder-backend-module-yeoman': patch
'@backstage/plugin-scaffolder-common': patch
'@backstage/plugin-search': patch
'@backstage/plugin-shortcuts': patch
---
Switch to use the json and observable types from `@backstage/types`
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-code-coverage-backend': patch
---
check for existence of lines property in files
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/techdocs-common': patch
---
Support optional bucketRootPath configuration parameter in S3 and GCS publishers
+8
View File
@@ -0,0 +1,8 @@
---
'@backstage/config': patch
'@backstage/core-app-api': patch
'@backstage/core-plugin-api': patch
'@backstage/plugin-scaffolder-backend': patch
---
Start using the new `@backstage/types` package. Initially, this means using the `Observable` and `Json*` types from there. The types also remain in their old places but deprecated, and will be removed in a future release.
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/config': patch
'@backstage/core-app-api': patch
'@backstage/core-plugin-api': patch
---
Replace usage of test-utils-core with test-utils
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-search-backend-node': patch
---
Handle special case when filter array has single value optimizing Lunr search behaviour.
-7
View File
@@ -1,7 +0,0 @@
---
'@backstage/cli': patch
---
Add an experimental `install <plugin>` command.
Given a `pluginId`, the command looks for NPM packages matching `@backstage/plugin-{pluginId}` or `backstage-plugin-{pluginId}` or `{pluginId}`. It looks for the `experimentalInstallationRecipe` in their `package.json` for the steps of installation. Detailed documentation and API Spec to follow (and to be decided as well).
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-sentry': patch
---
fix: sentry-plugin correction for allowed period values
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/core-components': patch
---
Deprecated `DismissbleBannerClassKey` and fixed the typo to make `DismissableBannerClassKey`
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/errors': patch
---
Add `stringifyError` that is useful for logging e.g. `Something went wrong, ${stringifyError(e)}`
+2
View File
@@ -8,6 +8,7 @@ apis
args
asciidoc
async
Atlassian
automations
autoscaling
Autoscaling
@@ -310,3 +311,4 @@ Zalando
Zhou
zoomable
zsh
Firestore
+2 -2
View File
@@ -140,7 +140,7 @@ jobs:
- name: test changed packages
if: ${{ steps.yarn-lock.outcome == 'success' }}
run: yarn lerna -- run test --since origin/master -- --coverage
run: yarn lerna -- run test --since origin/master -- --coverage --runInBand
env:
BACKSTAGE_TEST_DATABASE_POSTGRES13_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres13.ports[5432] }}
BACKSTAGE_TEST_DATABASE_POSTGRES9_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres9.ports[5432] }}
@@ -149,7 +149,7 @@ jobs:
- name: test all packages (and upload coverage)
if: ${{ steps.yarn-lock.outcome == 'failure' }}
run: |
yarn lerna -- run test -- --coverage
yarn lerna -- run test -- --coverage --runInBand
bash <(curl -s https://codecov.io/bash) -N $(git rev-parse FETCH_HEAD)
env:
BACKSTAGE_TEST_DATABASE_POSTGRES13_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres13.ports[5432] }}
+1 -1
View File
@@ -116,7 +116,7 @@ jobs:
- name: test (and upload coverage)
run: |
yarn lerna -- run test -- --coverage
yarn lerna -- run test -- --coverage --runInBand
bash <(curl -s https://codecov.io/bash)
# Upload code coverage for some specific flags. Also see .codecov.yml
bash <(curl -s https://codecov.io/bash) -f packages/core-app-api/coverage/* -F core-app-api
+61 -56
View File
@@ -1,56 +1,61 @@
| Organization | Contact | Description of Use |
| ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Spotify](https://www.spotify.com) | [@leemills83](https://github.com/leemills83) | Main interface towards all of Spotify's infrastructure and technical documentation. |
| [bol.com](https://www.bol.com) | [@sagacity](https://github.com/sagacity) | Initial work being done to unify platform tooling. |
| [DFDS](https://www.dfds.com) | [@carlsendk](https://github.com/carlsendk) | V2 self-service platform. |
| [Roadie](https://roadie.io) | [@dtuite](https://github.com/dtuite) | Hosted, managed Backstage with easy set-up |
| [Roku](https://www.roku.com) | [@timurista](https://github.com/timurista) | Initial work on Cloud engineering service platform. |
| [SDA SE](https://sda.se) | [@Fox32](https://github.com/Fox32) | Central place for developing and sharing services in our insurance ecosystem. |
| [H-E-B](https://www.heb.com) | [@german-j-rodriguez](https://github.com/german-j-rodriguez) | Initial work on Engineering Portal service platform. |
| [American Airlines](https://www.aa.com) | [@paulpach](https://github.com/paulpach) | Central place for developers to develop and maintain applications |
| [Kiwi.com](https://kiwi.com) | [@aexvir](https://github.com/aexvir) | Replacing the frontend of [The Zoo](https://github.com/kiwicom/the-zoo), their service registry. |
| [Voi](https://www.voiscooters.com/) | [@K-Phoen](https://github.com/K-Phoen) | Developer portal, main gateway to our infrastructure, documentation and internal tooling. |
| [Talkdesk](https://www.talkdesk.com) | [@jaime-talkdesk](https://github.com/jaime-talkdesk) | Initial work for Engineering Portal and Self Provisioning to R&D |
| [Wealthsimple](https://www.wealthsimple.com) | [@andrewthauer](https://github.com/andrewthauer) | Developer portal, service catalog, documentation and tooling |
| [Grab](https://www.grab.com) | [@althafh](https://github.com/althafh) | Initial work as a unified interface for all of Grab's internal tooling |
| [Telenor Sweden](https://www.telenor.se) | [@O5ten](https://github.com/O5ten) | Building a developer portal for scaffolding projects towards our unified build environment and microservice stacks |
| [Fiverr](https://www.fiverr.com) | [@nirga](https://github.com/nirga) | Unifying separate tools that developers are using today (i.e. monitoring, dead letter queues management, etc.) into a single platform. |
| [Zalando SE](https://www.zalando.de) | [@leviferreira](https://github.com/leviferreira) | Building V2 of the Internal Development Portal. |
| [LegalZoom](https://legalzoom.com) | [@backjo](https://github.com/backjo) | Developer portal - hub for all engineering projects and metadata. |
| [Expedia Group](https://www.expediagroup.com) | [Mike Turner](mailto:miturner@expediagroup.com), [Sneha Kumar](mailto:snkumar@expediagroup.com), [@guillermomanzo](https://github.com/guillermomanzo), [Erik Lindgren](https://github.com/lindgren) | EG Common Developer Toolkit |
| [Paddle.com](https://paddle.com) | [Ioannis Georgoulas](https://github.com/geototti21) | Developer portal (Tech Docs, Service Catalog, Internal Tooling), we use vanilla Backstage FE and custom BE implementation in Go |
| [Acast.com](https://acast.com) | [Olle Lundberg](https://github.com/lndbrg) | Developer portal with tech docs, service catalog and a bunch of other internal tooling |
| [Lunar](https://lunar.app) | [Jacob Valdemar](https://github.com/JacobValdemar) | Internal developer portal for service overview and insights, API documentation, technical guides, onboarding guides and RFC's. |
| [Trendyol](https://trendyol.com) | [Gamze Senturk](https://github.com/gmzsenturk), [Mert Can Bilgic](https://github.com/mertcb) | The Developer Portal has been called `Pandora`. Provides an overview of Trendyol tech ecosystem. TechDocs, Catalog, Custom Plugins and Theme. |
| [Peloton](https://www.onepeloton.com/) | [Jim Haughwout](https://github.com/JimHaughwout) | Creating our first developer portal and tech-docs. Exploring Service Catalog, Tech Insights and Cost Insights as well. |
| [TELUS](https://telus.com) | [Seb Barre](https://github.com/sbarre) | The Go-to place to find answers about development and delivery at TELUS. |
| [Brex](https://www.brex.com/) | [Vamsi Chitters](https://github.com/vamsikc) | A centralized UI to understand how a service fits in the whole Brex architecture and manage a teams engineering dependencies. |
| [Oriflame](https://www.oriflame.com/) | [Oriflame](https://github.com/oriflame) | Internal developer portal for services, single page apps and packages overview, API documentation, technical guides, tech-radar and more. |
| [Booz Allen Hamilton](https://www.boozallen.com/) | [Jason Miller](https://github.com/JasonMiller-BAH) | Developer portal for a full-stack software development ecosystem that accelerates consistent and repeatable Modern Software Development practices for internal innovation and investments. |
| [Netflix](https://www.netflix.com/) | [bleathem](https://github.com/bleathem) | Our Backstage implementation will be the front door to a unified experience connecting our internal platform products across important workflows with integrated knowledge and support. |
| [b.well](https://www.icanbwell.com/) | [Jacob Rosales](https://github.com/jrosales) | Foundation for our engineering portal and cloud insights. |
| [PagerDuty](https://www.pagerduty.com/) | [Mark Shaw](https://github.com/markshawtoronto) | Developer portal, initially focused on software templates and tech-docs. |
| [MoonShiner](https://moonshiner.at) | [Fabian Hippmann](https://github.com/FabianHippmann) | Developer portal - helps us keep track of our customer projects, onboard new developers & improve our development process 🌕🚀🧑‍🚀 |
| [FundApps](https://www.fundapps.co/) | [Elliot Greenwood](https://github.com/egnwd) | Developer Portal - A place for us to keep track of our projects and documentation for all services and processes |
| [DAZN](https://dazn.com/) | [Lou Bichard](https://twitter.com/loujaybee), [Marco Crivellaro](https://github.com/crivetechie), [Alex Hollerith](mailto:alex.hollerith@dazn.com) | Ingesting all of DAZN's repos for the catalog, migrating our internal platform apps (pull request boards, release information, inner source marketplace etc) to Backstage plugins (where applicable). |
| [HelloFresh](https://www.hellofresh.de/) | [@iammuho](https://github.com/iammuho), [@ElenaForester](https://github.com/ElenaForester), [@diegomarangoni](https://github.com/diegomarangoni) | Our developer portal at HelloFresh - Spread across an organisation of 500+ engineers globally. |
| [FactSet](https://www.factset.com/) | [@kuangp](https://github.com/kuangp) | Developer portal to provide discoverability to all internal components, APIs, documentation, and scaffold templates with integrations to our internal infrastructure tools. |
| [Workrise](https://www.workrise.com/) | [Michael Rode](https://github.com/michaelrode) | Developer portal, main gateway to our infrastructure, documentation and internal tooling. |
| [RedVentures](https://www.redventures.com/) | [Chris Diaz](https://github.com/codingdiaz) | Developer portal that brings everything an engineer needs to provide value into a single pane of glass. |
| [MavTek](https://www.mavtek.com/) | [@fgascon](https://github.com/fgascon) | Developer portal focused on standardizing practices, centralizing documentation and streamlining developer practices. |
| [QuintoAndar](https://www.quintoandar.com.br/) | [@quintoandar](https://github.com/quintoandar) | Developer portal, services catalog and centralization of service metrics. |
| [empathy.co](https://empathy.co/) | [@guillermotti](https://github.com/guillermotti) | Developer portal for tech docs, service catalog, plugin discovery and much more. |
| [creditas.com](https://creditas.com/) | [@aureliosaraiva](https://github.com/aureliosaraiva) [@Creditas](https://github.com/creditas) | Centralization of all services, standards, documentation, etc. We started the deployment process. |
| [Prisjakt](https://www.prisjakt.nu) / [PriceSpy](https://pricespy.co.uk) | [@kennylindahl](https://github.com/kennylindahl) | Internal developer portal - Documentation, scaffolding, software catalog, TechRadar, Gitlab org data integration |
| [Powerspike](https://powerspike.tv/) | [@trelore](https://github.com/trelore) | Developer portal for documentation of core libraries and repositories. |
| [2U](https://2u.com) | [Andrew Thal](https://github.com/athal7) | Development team home-base, promoting service discoverability, resource dependencies, and tech radar |
| [Taxfix](https://taxfix.de/) | [Sami Ur Rehman](https://github.com/samiurrehman92) | Developer's portal with software catalog at it's core. Hosts API Specs, Tech Docs, Tech Radar and some custom plugins. |
| [Busuu](https://busuu.com/) | [Adam Tester](https://github.com/adamtester) | Developer portal with service catalog, API docs, Event docs, service templating, and cost insights. |
| [Loadsmart](https://loadsmart.com/) | [Loadsmart](https://github.com/loadsmart) | Improve services visibility and operations for service owners and developers. |
| [Monzo](https://monzo.com/) | [@WillSewell](https://github.com/WillSewell), [@joechrisellis](https://github.com/joechrisellis) | Developer portal showing metadata and docs for over 2000 microservices. We have built a number of plugins such as a UI for our system to measure [software excellence](https://monzo.com/blog/2021/09/15/how-we-measure-software-excellence), and a UI to show deployment and config change events. |
| [Vaimo](https://www.vaimo.com) | [@vaimo-magnus](https://github.com/vaimo-magnus) | Developer Portal for our developers at Vaimo, currently docs and self-service towards our internal PaaS based on k8s. Plans to extend the catalog into Projects, Environments etc |
| [Wayfair](https://www.wayfair.com) | [@fransan](https://github.com/fransan), [@errskipower](https://github.com/errskipower), [@hrrs](https://github.com/hrrs) | Developer portal for service catalog, technical documentation, and APIs. |
| [CircleHD](https://www.circlehd.com) | [@circlehddev](https://github.com/circlehddev) | Developer Portal for internal dev team across the globe |
| [CastDesk](https://castdesk.com) | [@circlehddev](https://github.com/circlehddev) | Developer Portal for internal dev team across the globe |
| [Santagostino](https://santagostino.it) | [@santagostino](https://github.com/santagostino) | Developer portal, gateway to our infrastructure, documentation, service catalog and internal tooling. |
| [Peak](https://peak.ai) | [Luke Beamish](https://github.com/lukebeamish-peak) | Developer portal for all internal engineers to access documentation and tooling. |
| Organization | Contact | Description of Use |
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Spotify](https://www.spotify.com) | [@leemills83](https://github.com/leemills83) | Main interface towards all of Spotify's infrastructure and technical documentation. |
| [bol.com](https://www.bol.com) | [@sagacity](https://github.com/sagacity) | Initial work being done to unify platform tooling. |
| [DFDS](https://www.dfds.com) | [@carlsendk](https://github.com/carlsendk) | V2 self-service platform. |
| [Roadie](https://roadie.io) | [@dtuite](https://github.com/dtuite) | Hosted, managed Backstage with easy set-up |
| [Roku](https://www.roku.com) | [@timurista](https://github.com/timurista) | Initial work on Cloud engineering service platform. |
| [SDA SE](https://sda.se) | [@Fox32](https://github.com/Fox32) | Central place for developing and sharing services in our insurance ecosystem. |
| [H-E-B](https://www.heb.com) | [@german-j-rodriguez](https://github.com/german-j-rodriguez) | Initial work on Engineering Portal service platform. |
| [American Airlines](https://www.aa.com) | [@paulpach](https://github.com/paulpach) | Central place for developers to develop and maintain applications |
| [Kiwi.com](https://kiwi.com) | [@aexvir](https://github.com/aexvir) | Replacing the frontend of [The Zoo](https://github.com/kiwicom/the-zoo), their service registry. |
| [Voi](https://www.voiscooters.com/) | [@K-Phoen](https://github.com/K-Phoen) | Developer portal, main gateway to our infrastructure, documentation and internal tooling. |
| [Talkdesk](https://www.talkdesk.com) | [@jaime-talkdesk](https://github.com/jaime-talkdesk) | Initial work for Engineering Portal and Self Provisioning to R&D |
| [Wealthsimple](https://www.wealthsimple.com) | [@andrewthauer](https://github.com/andrewthauer) | Developer portal, service catalog, documentation and tooling |
| [Grab](https://www.grab.com) | [@althafh](https://github.com/althafh) | Initial work as a unified interface for all of Grab's internal tooling |
| [Telenor Sweden](https://www.telenor.se) | [@O5ten](https://github.com/O5ten) | Building a developer portal for scaffolding projects towards our unified build environment and microservice stacks |
| [Fiverr](https://www.fiverr.com) | [@nirga](https://github.com/nirga) | Unifying separate tools that developers are using today (i.e. monitoring, dead letter queues management, etc.) into a single platform. |
| [Zalando SE](https://www.zalando.de) | [@leviferreira](https://github.com/leviferreira) | Building V2 of the Internal Development Portal. |
| [LegalZoom](https://legalzoom.com) | [@backjo](https://github.com/backjo) | Developer portal - hub for all engineering projects and metadata. |
| [Expedia Group](https://www.expediagroup.com) | [Mike Turner](mailto:miturner@expediagroup.com), [Sneha Kumar](mailto:snkumar@expediagroup.com), [@guillermomanzo](https://github.com/guillermomanzo), [Erik Lindgren](https://github.com/lindgren) | EG Common Developer Toolkit |
| [Paddle.com](https://paddle.com) | [Ioannis Georgoulas](https://github.com/geototti21) | Developer portal (Tech Docs, Service Catalog, Internal Tooling), we use vanilla Backstage FE and custom BE implementation in Go |
| [Acast.com](https://acast.com) | [Olle Lundberg](https://github.com/lndbrg) | Developer portal with tech docs, service catalog and a bunch of other internal tooling |
| [Lunar](https://lunar.app) | [Jacob Valdemar](https://github.com/JacobValdemar) | Internal developer portal for service overview and insights, API documentation, technical guides, onboarding guides and RFC's. |
| [Trendyol](https://trendyol.com) | [Gamze Senturk](https://github.com/gmzsenturk), [Mert Can Bilgic](https://github.com/mertcb) | The Developer Portal has been called `Pandora`. Provides an overview of Trendyol tech ecosystem. TechDocs, Catalog, Custom Plugins and Theme. |
| [Peloton](https://www.onepeloton.com/) | [Jim Haughwout](https://github.com/JimHaughwout) | Creating our first developer portal and tech-docs. Exploring Service Catalog, Tech Insights and Cost Insights as well. |
| [TELUS](https://telus.com) | [Seb Barre](https://github.com/sbarre) | The Go-to place to find answers about development and delivery at TELUS. |
| [Brex](https://www.brex.com/) | [Vamsi Chitters](https://github.com/vamsikc) | A centralized UI to understand how a service fits in the whole Brex architecture and manage a teams engineering dependencies. |
| [Oriflame](https://www.oriflame.com/) | [Oriflame](https://github.com/oriflame) | Internal developer portal for services, single page apps and packages overview, API documentation, technical guides, tech-radar and more. |
| [Booz Allen Hamilton](https://www.boozallen.com/) | [Jason Miller](https://github.com/JasonMiller-BAH) | Developer portal for a full-stack software development ecosystem that accelerates consistent and repeatable Modern Software Development practices for internal innovation and investments. |
| [Netflix](https://www.netflix.com/) | [bleathem](https://github.com/bleathem) | Our Backstage implementation will be the front door to a unified experience connecting our internal platform products across important workflows with integrated knowledge and support. |
| [b.well](https://www.icanbwell.com/) | [Jacob Rosales](https://github.com/jrosales) | Foundation for our engineering portal and cloud insights. |
| [PagerDuty](https://www.pagerduty.com/) | [Mark Shaw](https://github.com/markshawtoronto) | Developer portal, initially focused on software templates and tech-docs. |
| [MoonShiner](https://moonshiner.at) | [Fabian Hippmann](https://github.com/FabianHippmann) | Developer portal - helps us keep track of our customer projects, onboard new developers & improve our development process 🌕🚀🧑‍🚀 |
| [FundApps](https://www.fundapps.co/) | [Elliot Greenwood](https://github.com/egnwd) | Developer Portal - A place for us to keep track of our projects and documentation for all services and processes |
| [DAZN](https://dazn.com/) | [Lou Bichard](https://twitter.com/loujaybee), [Marco Crivellaro](https://github.com/crivetechie), [Alex Hollerith](mailto:alex.hollerith@dazn.com) | Ingesting all of DAZN's repos for the catalog, migrating our internal platform apps (pull request boards, release information, inner source marketplace etc) to Backstage plugins (where applicable). |
| [HelloFresh](https://www.hellofresh.de/) | [@iammuho](https://github.com/iammuho), [@ElenaForester](https://github.com/ElenaForester), [@diegomarangoni](https://github.com/diegomarangoni) | Our developer portal at HelloFresh - Spread across an organisation of 500+ engineers globally. |
| [FactSet](https://www.factset.com/) | [@kuangp](https://github.com/kuangp) | Developer portal to provide discoverability to all internal components, APIs, documentation, and scaffold templates with integrations to our internal infrastructure tools. |
| [Workrise](https://www.workrise.com/) | [Michael Rode](https://github.com/michaelrode) | Developer portal, main gateway to our infrastructure, documentation and internal tooling. |
| [RedVentures](https://www.redventures.com/) | [Chris Diaz](https://github.com/codingdiaz) | Developer portal that brings everything an engineer needs to provide value into a single pane of glass. |
| [MavTek](https://www.mavtek.com/) | [@fgascon](https://github.com/fgascon) | Developer portal focused on standardizing practices, centralizing documentation and streamlining developer practices. |
| [QuintoAndar](https://www.quintoandar.com.br/) | [@quintoandar](https://github.com/quintoandar) | Developer portal, services catalog and centralization of service metrics. |
| [empathy.co](https://empathy.co/) | [@guillermotti](https://github.com/guillermotti) | Developer portal for tech docs, service catalog, plugin discovery and much more. |
| [creditas.com](https://creditas.com/) | [@aureliosaraiva](https://github.com/aureliosaraiva) [@Creditas](https://github.com/creditas) | Centralization of all services, standards, documentation, etc. We started the deployment process. |
| [Prisjakt](https://www.prisjakt.nu) / [PriceSpy](https://pricespy.co.uk) | [@kennylindahl](https://github.com/kennylindahl) | Internal developer portal - Documentation, scaffolding, software catalog, TechRadar, Gitlab org data integration |
| [Powerspike](https://powerspike.tv/) | [@trelore](https://github.com/trelore) | Developer portal for documentation of core libraries and repositories. |
| [2U](https://2u.com) | [Andrew Thal](https://github.com/athal7) | Development team home-base, promoting service discoverability, resource dependencies, and tech radar |
| [Taxfix](https://taxfix.de/) | [Sami Ur Rehman](https://github.com/samiurrehman92) | Developer's portal with software catalog at it's core. Hosts API Specs, Tech Docs, Tech Radar and some custom plugins. |
| [Busuu](https://busuu.com/) | [Adam Tester](https://github.com/adamtester) | Developer portal with service catalog, API docs, Event docs, service templating, and cost insights. |
| [Loadsmart](https://loadsmart.com/) | [Loadsmart](https://github.com/loadsmart) | Improve services visibility and operations for service owners and developers. |
| [Monzo](https://monzo.com/) | [@WillSewell](https://github.com/WillSewell), [@joechrisellis](https://github.com/joechrisellis) | Developer portal showing metadata and docs for over 2000 microservices. We have built a number of plugins such as a UI for our system to measure [software excellence](https://monzo.com/blog/2021/09/15/how-we-measure-software-excellence), and a UI to show deployment and config change events. |
| [Vaimo](https://www.vaimo.com) | [@vaimo-magnus](https://github.com/vaimo-magnus) | Developer Portal for our developers at Vaimo, currently docs and self-service towards our internal PaaS based on k8s. Plans to extend the catalog into Projects, Environments etc |
| [Wayfair](https://www.wayfair.com) | [@fransan](https://github.com/fransan), [@errskipower](https://github.com/errskipower), [@hrrs](https://github.com/hrrs) | Developer portal for service catalog, technical documentation, and APIs. |
| [CircleHD](https://www.circlehd.com) | [@circlehddev](https://github.com/circlehddev) | Developer Portal for internal dev team across the globe |
| [CastDesk](https://castdesk.com) | [@circlehddev](https://github.com/circlehddev) | Developer Portal for internal dev team across the globe |
| [Santagostino](https://santagostino.it) | [@santagostino](https://github.com/santagostino) | Developer portal, gateway to our infrastructure, documentation, service catalog and internal tooling. |
| [Peak](https://peak.ai) | [Luke Beamish](https://github.com/lukebeamish-peak) | Developer portal for all internal engineers to access documentation and tooling. |
| [Gelato](https://gelato.com/) | [Dmitry Makarenko](https://github.com/dmitry-makarenko-gelato) | Developer portal: documentation, service templates, org structure, service catalog, plugins for integration with internal and third-party systems🚀. |
| [GoCardless](https://gocardless.com/) | [James Turley](https://github.com/tragiclifestories) | Developer portal: documentation, service templates, org structure, service catalog, plugins for integration with internal systems. |
| [Box](https://www.box.com) | [@kielosz](https://github.com/kielosz), [@jluk-box](https://github.com/jluk-box), [@ptychu](https://github.com/ptychu), [@alexrybch](https://github.com/alexrybch), [@szubster](https://github.com/szubster) | Developer portal for service catalog, integration with internal systems, new service onboarding. |
| [Bazaarvoice](https://www.bazaarvoice.com) | [@niallmccullagh](https://github.com/niallmccullagh) | Developer portal for service catalog and scaffolds, publishing Github docs and API documentation, visualising our internal tech radar and our product engineering org structure. |
| [Krateo PlatformOps](https://www.krateo.io) | [@projectkerberus](https://github.com/projectkerberus) | A multi-cloud control plane to create, manage and deploy any kind of resource easily and centrally via a Developer Portal that centralizes via a self-service catalog the templating and ownership of services, the available documentation, the overview of the components that compose an entire domain and all the data of the service lifecycle. |
+4 -3
View File
@@ -129,9 +129,10 @@ 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, 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
4. Explain your changes in the generated changeset. See [examples of well written changesets](https://backstage.io/docs/getting-started/contributors#writing-changesets).
5. Add generated changeset to Git
6. Push the commit with your changeset to the branch associated with your PR
7. Accept our gratitude for making the release process easier on the maintainers
For more information, checkout [adding a changeset](https://github.com/atlassian/changesets/blob/master/docs/adding-a-changeset.md) documentation in the changesets repository.
+14
View File
@@ -292,6 +292,15 @@ scaffolder:
visibility: public # or or 'private'
auth:
### Add auth.keyStore.provider to more granularly control how to store JWK data when running
# the auth-backend.
#
# keyStore:
# provider: firestore
# firestore:
# projectId: my-project
# path: my-sessions
environment: development
### Providing an auth.session.secret will enable session support in the auth-backend
# session:
@@ -364,6 +373,11 @@ auth:
development:
clientId: ${AUTH_BITBUCKET_CLIENT_ID}
clientSecret: ${AUTH_BITBUCKET_CLIENT_SECRET}
atlassian:
development:
clientId: ${AUTH_ATLASSIAN_CLIENT_ID}
clientSecret: ${AUTH_ATLASSIAN_CLIENT_SECRET}
scopes: ${AUTH_ATLASSIAN_SCOPES}
costInsights:
engineerCost: 200000
products:
@@ -47,5 +47,5 @@ sentry:
organization: {{ .Values.appConfig.sentry.organization | quote }}
techdocs:
generators:
techdocs: 'local'
generator:
runIn: 'local'
@@ -32,7 +32,7 @@ spec:
ports:
- containerPort: {{ .Values.frontend.containerPort }}
resources:
{{- toYaml .Values.backend.resources | nindent 12 }}
{{- toYaml .Values.frontend.resources | nindent 12 }}
envFrom:
- configMapRef:
name: {{ include "backstage.fullname" . }}-app-env
+52 -24
View File
@@ -100,17 +100,16 @@ const app = createApp({
### Backend
When using ALB auth it is not possible to leverage the built-in auth config discovery mechanism implemented in the app created by default; bespoke logic needs to be implemented.
When using ALB auth you can configure it as described [here](https://backstage.io/docs/auth/identity-resolver).
- replace the content of `packages/backend/plugin/auth.ts` with the below
- replace the content of `packages/backend/plugin/auth.ts` with the below and tweak it according to your needs.
```ts
import {
createRouter,
AuthResponse,
AuthProviderFactoryOptions,
defaultAuthProviderFactories,
createAwsAlbProvider,
} from '@backstage/plugin-auth-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
export default async function createPlugin({
@@ -118,30 +117,59 @@ export default async function createPlugin({
database,
config,
discovery,
}: PluginEnvironment) {
const identityResolver = (payload: any): Promise<AuthResponse<any>> => {
return Promise.resolve({
providerInfo: {},
profile: {
email: payload.email,
displayName: payload.name,
picture: payload.picture,
},
backstageIdentity: {
id: payload.email,
},
});
};
const providerFactories = {
awsalb: (options: AuthProviderFactoryOptions) =>
defaultAuthProviderFactories.awsalb({ ...options, identityResolver }),
};
}: PluginEnvironment): Promise<Router> {
return await createRouter({
logger,
config,
database,
discovery,
providerFactories,
providerFactories: {
awsalb: createAwsAlbProvider({
authHandler: async ({ fullProfile }) => {
let email: string | undefined = undefined;
if (fullProfile.emails && fullProfile.emails.length > 0) {
const [firstEmail] = fullProfile.emails;
email = firstEmail.value;
}
let picture: string | undefined = undefined;
if (fullProfile.photos && fullProfile.photos.length > 0) {
const [firstPhoto] = fullProfile.photos;
picture = firstPhoto.value;
}
const displayName: string | undefined =
fullProfile.displayName ?? fullProfile.username ?? fullProfile.id;
return {
profile: {
email,
picture,
displayName,
},
};
},
signIn: {
resolver: async ({ profile: { email } }, ctx) => {
const [id] = email?.split('@') ?? '';
// Fetch from an external system that returns entity claims like:
// ['user:default/breanna.davison', ...]
const ent = [`user:default/${id}`];
// Resolve group membership from the Backstage catalog
const fullEnt =
await ctx.catalogIdentityClient.resolveCatalogMembership({
entityRefs: [id].concat(ent),
logger: ctx.logger,
});
const token = await ctx.tokenIssuer.issueToken({
claims: { sub: id, ent: fullEnt },
});
return { id, token };
},
},
}),
},
});
}
```
Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

+64
View File
@@ -0,0 +1,64 @@
---
id: provider
title: Atlassian Authentication Provider
sidebar_label: Atlassian
description: Adding Atlassian as an authentication provider in Backstage
---
The Backstage `core-plugin-api` package comes with an Atlassian authentication
provider that can authenticate users using Atlassian products. This auth
**only** provides scopes for the following APIs:
- Confluence API
- User REST API
- Jira platform REST API
- Jira Service Desk API
- Personal data reporting API
- User identity API
## Create an OAuth 2.0 (3LO) app in the Atlassian developer console
To add Atlassian authentication, you must create an OAuth 2.0 (3LO) app.
Go to `https://developer.atlassian.com/console/myapps/`.
Click on the drop down `Create`, and choose `OAuth 2.0 integration`.
Name your integration and click on the `Create` button.
Settings for local development:
- Callback URL: `http://localhost:7000/api/auth/atlassian`
- Use rotating refresh tokens
- For permissions, you **must** enable `View user profile` for the currently
logged-in user, under `User identity API`
## Configuration
The provider configuration can then be added to your `app-config.yaml` under the
root `auth` configuration:
```yaml
auth:
environment: development
providers:
atlassian:
development:
clientId: ${AUTH_ATLASSIAN_CLIENT_ID}
clientSecret: ${AUTH_ATLASSIAN_CLIENT_SECRET}
scopes: ${AUTH_ATLASSIAN_SCOPES}
```
The Atlassian provider is a structure with three configuration keys:
- `clientId`: The Key you generated in the developer console.
- `clientSecret`: The Secret tied to the generated Key.
- `scopes`: List of scopes the app has permissions for, separated by spaces.
**NOTE:** the scopes `offline_access` and `read:me` are provided by default.
## Adding the provider to the Backstage frontend
To add the provider to the frontend, add the `atlassianAuthApi` reference and
`SignInPage` component as shown in
[Adding the provider to the sign-in page](../index.md#adding-the-provider-to-the-sign-in-page).
+1 -1
View File
@@ -76,7 +76,7 @@ CMD ["node", "packages/backend", "--config", "app-config.yaml"]
For more details on how the `backend:bundle` command and the `skeleton.tar.gz`
file works, see the
[`backend:bundle` command docs](../cli/commands.md#backendbundle).
[`backend:bundle` command docs](../local-dev/cli-commands.md#backendbundle).
The `Dockerfile` is located at `packages/backend/Dockerfile`, but needs to be
executed with the root of the repo as the build context, in order to get access
+19
View File
@@ -29,6 +29,7 @@ kubernetes:
serviceAccountToken: ${K8S_MINIKUBE_TOKEN}
dashboardUrl: http://127.0.0.1:64713 # url copied from running the command: minikube service kubernetes-dashboard -n kubernetes-dashboard
dashboardApp: standard
caData: ${K8S_CONFIG_CA_DATA}
- url: http://127.0.0.2:9999
name: aws-cluster-1
authProvider: 'aws'
@@ -135,6 +136,24 @@ See also
https://github.com/backstage/backstage/tree/master/plugins/kubernetes/src/utils/clusterLinks/formatters
for real examples.
##### `clusters.\*.caData` (optional)
PEM-encoded certificate authority certificates.
This values could be obtained via inspecting the Kubernetes config file (usually
at `~/.kube/config`) under `clusters.cluster.certificate-authority-data`. For
GKE, execute the following command to obtain the value
```
gcloud container clusters describe <YOUR_CLUSTER_NAME> \
--zone=<YOUR_COMPUTE_ZONE> \
--format="value(masterAuth.clusterCaCertificate)"
```
See also
https://cloud.google.com/kubernetes-engine/docs/how-to/api-server-authentication#environments-without-gcloud
for complete docs about GKE without `gcloud`.
#### `gke`
This cluster locator is designed to work with Kubernetes clusters running in
+6 -2
View File
@@ -59,14 +59,18 @@ add the following:
```typescript
// In packages/backend/src/plugins/kubernetes.ts
import { createRouter } from '@backstage/plugin-kubernetes-backend';
import { KubernetesBuilder } from '@backstage/plugin-kubernetes-backend';
import { PluginEnvironment } from '../types';
export default async function createPlugin({
logger,
config,
}: PluginEnvironment) {
return await createRouter({ logger, config });
const { router } = await KubernetesBuilder.createBuilder({
logger,
config,
}).build();
return router;
}
```
+14 -10
View File
@@ -102,20 +102,24 @@ more to come...
See [Backstage Search Architecture](architecture.md) to get an overview of how
the search engines are used.
| Search Engine | Support Status |
| ------------- | -------------- |
| Basic (lunr) | ✅ |
| ElasticSearch | Not yet ❌ |
| Search Engines | Support Status |
| -------------------------------------------------- | -------------- |
| [Lunr](./search-engines.md#lunr) | ✅ |
| [ElasticSearch](./search-engines.md#elasticsearch) | |
| [Postgres](./search-engines.md#postgres) | ✅ |
[Reach out to us](#feedback) if you want to chat about support for more search
engines.
[Reach out to us](#get-involved) if you want to chat about support for more
search engines.
## Plugins Integrated with Search
| Plugin | Support Status |
| -------- | -------------- |
| Catalog | ✅ |
| TechDocs | Not yet ❌ |
| Plugin | Support Status |
| -------------------------------------------------------------- | -------------- |
| Catalog | ✅ |
| [TechDocs](./how-to-guides.md#how-to-index-techdocs-documents) | ✅ |
[Reach out to us](#get-involved) if you want to chat about support for more
plugins integrated to search.
## Tech Stack
+98
View File
@@ -0,0 +1,98 @@
---
id: how-to-guides
title: Search "HOW TO" guides
sidebar_label: "HOW TO" guides
description: Search "HOW TO" guides
---
## How to implement your own Search API
The Search plugin provides implementation of one primary API by default: the
[SearchApi](https://github.com/backstage/backstage/blob/db2666b980853c281b8fe77905d7639c5d255f13/plugins/search/src/apis.ts#L35),
which is responsible for talking to the search-backend to query search results.
There may be occasions where you need to implement this API yourself, to
customize it to your own needs - for example if you have your own search backend
that you want to talk to. The purpose of this guide is to walk you through how
to do that in two steps.
1. Implement the `SearchApi`
[interface](https://github.com/backstage/backstage/blob/db2666b980853c281b8fe77905d7639c5d255f13/plugins/search/src/apis.ts#L31)
according to your needs.
```typescript
export class SearchClient implements SearchApi {
// your implementation
}
```
2. Override the API ref `searchApiRef` with your new implemented API in the
`App.tsx` using `ApiFactories`.
[Read more about App APIs](https://backstage.io/docs/api/utility-apis#app-apis).
```typescript
const app = createApp({
apis: [
// SearchApi
createApiFactory({
api: searchApiRef,
deps: { discovery: discoveryApiRef },
factory({ discovery }) {
return new SearchClient({ discoveryApi: discovery });
},
}),
],
});
```
## How to index TechDocs documents
The TechDocs plugin has supported integrations to Search, meaning that it
provides a default collator ready to be used.
The purpose of this guide is to walk you through how to register the
[DefaultTechDocsCollator](https://github.com/backstage/backstage/blob/master/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.ts)
in your App, so that you can get TechDocs documents indexed.
If you have been through the
[Getting Started with Search guide](https://backstage.io/docs/features/search/getting-started),
you should have the `packages/backend/src/plugins/search.ts` file available. If
so, you can go ahead and follow this guide - if not, start by going through the
getting started guide.
1. Import the DefaultTechDocsCollator from `@backstage/plugin-techdocs-backend`.
```typescript
import { DefaultTechDocsCollator } from '@backstage/plugin-techdocs-backend';
```
2. Register the DefaultTechDocsCollator with the IndexBuilder.
```typescript
indexBuilder.addCollator({
defaultRefreshIntervalSeconds: 600,
collator: DefaultTechDocsCollator.fromConfig(config, {
discovery,
logger,
}),
});
```
You should now have your TechDocs documents indexed to your search engine of
choice!
If you want your users to be able to filter down to the techdocs type when
searching, you can update your `SearchPage.tsx` file in
`packages/app/src/components/search` by adding `techdocs` to the list of values
of the `SearchType` component.
```tsx
<Paper className={classes.filters}>
<SearchType
values={['techdocs', 'software-catalog']}
name="type"
defaultValue="software-catalog"
/>
...
</Paper>
```
@@ -620,9 +620,6 @@ The following describes the following entity kind:
| `apiVersion` | `backstage.io/v1beta2` |
| `kind` | `Template` |
If you're looking for docs on `v1alpha1` you can find them
[here](../software-templates/legacy.md)
A template definition describes both the parameters that are rendered in the
frontend part of the scaffolding wizard, and the steps that are executed when
scaffolding that component.
@@ -429,3 +429,101 @@ from one environment to the other, do rollbacks, see their relative performance
metrics, and similar. This coherency and collection of tooling in one place is
where something like Backstage can offer the most value and effectiveness of
use. Splitting your entities apart into small islands makes this harder.
## Implementing custom model extensions
This section walks you through the steps involved extending the catalog model
with a new Entity type.
### Creating a custom entity definition
The first step of introducing a custom entity is to define what shape and schema
it has. We do this both using a TypeScript type, along with a JSONSchema schema.
Most of the time you will want to have at least the TypeScript type of your
extension available in both frontend and backend code, which means you likely
want to have an isomorphic package that houses these types. Within the Backstage
main repo the package naming pattern of `<plugin>-common` is used for isomorphic
packages, and you may choose to adopt this pattern as well.
There's at this point no existing templates for generating isomorphic plugins
using the `@backstage/cli`. Perhaps the simplest wat to get started right now is
to copy the contents of one of the existing packages in the main repository,
such as `plugins/scaffolder-common`, and rename the folder and file contents to
the desired name. This example uses _foobar_ as the plugin name so the plugin
will be named _foobar-common_.
Once you have a common package in place you can start adding your own entity
definitions. For the exact details on how to do that we defer to getting
inspired by the existing
[scaffolder-common](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-common/src/index.ts)
package. But in short you will need to declare a TypeScript type and a
JSONSchema for the new entity kind.
### Building a custom processor for the entity
The next step is to create a custom processor for your new entity kind. This
will be used within the catalog to make sure that it's able to ingest and
validate entities of our new kind. Just like with the definition package, you
can find inspiration in for example the existing
[ScaffolderEntitiesProcessor](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend/src/processor/ScaffolderEntitiesProcessor.ts).
We also provide a high-level example of what a catalog process for a custom
entity might look like:
```ts
import { entityKindSchemaValidator } from '@backstage/catalog-model';
export class FoobarEntitiesProcessor implements CatalogProcessor {
// You often end up wanting to support multiple versions of your kind as you
// iterate on the definition, so we keep each version inside this array.
private readonly validators = [
// This is where we use the JSONSchema that we export from our isomorphic package
entityKindSchemaValidator(foobarEntityV1alpha1Schema),
];
// validateEntityKind is responsible for signaling to the catalog processing engine
// that this entity is valid and should therefore be submitted for further processing.
async validateEntityKind(entity: Entity): Promise<boolean> {
for (const validator of this.validators) {
if (validator(entity)) {
return true;
}
}
return false;
}
async postProcessEntity(
entity: Entity,
_location: LocationSpec,
emit: CatalogProcessorEmit,
): Promise<Entity> {
if (
entity.apiVersion === 'example.com/v1alpha1' &&
entity.kind === 'Foobar'
) {
const foobarEntity = entity as FoobarEntityV1alpha1;
// Here we can modify the entity or emit results related to the entity
// Typically you will want to emit any relations associated with the entity here
emit(results.relation({ ... }))
}
return entity;
}
}
```
Once the processor is created it can be wired up to the catalog via the
`CatalogBuilder` in `packages/backend/src/plugins/catalog.ts`:
```diff
+ import { FoobarEntitiesProcessor implements CatalogProcessor {
} from '@internal/plugin-foobar-backend';
// ...
const builder = await CatalogBuilder.create(env);
+ builder.addProcessor(new FoobarEntitiesProcessor());
const { processingEngine, router } = await builder.build();
```
-117
View File
@@ -1,117 +0,0 @@
---
id: template-legacy
title: Writing Templates (Legacy)
# prettier-ignore
description: Old documentation describing the backstage.io/v1alpha1 format of the Template Schema
---
## Kind: Template
Describes the following entity kind:
| Field | Value |
| ------------ | ----------------------- |
| `apiVersion` | `backstage.io/v1alpha1` |
| `kind` | `Template` |
A Template describes a skeleton for use with the Scaffolder. It is used for
describing what templating library is supported, and also for documenting the
variables that the template requires using
[JSON Forms Schema](https://jsonforms.io/).
Descriptor files for this kind may look as follows.
```yaml
apiVersion: backstage.io/v1alpha1
kind: Template
metadata:
name: react-ssr-template
title: React SSR Template
description:
Next.js application skeleton for creating isomorphic web applications.
tags:
- recommended
- react
spec:
owner: web@example.com
templater: cookiecutter
type: website
path: '.'
schema:
required:
- component_id
- description
properties:
component_id:
title: Name
type: string
description: Unique name of the component
description:
title: Description
type: string
description: Description of the component
```
In addition to the [common envelope metadata](#common-to-all-kinds-the-metadata)
shape, this kind has the following structure.
### `apiVersion` and `kind` [required]
Exactly equal to `backstage.io/v1alpha1` and `Template`, respectively.
### `metadata.title` [required]
The nice display name for the template as a string, e.g. `React SSR Template`.
This field is required as is used to reference the template to the user instead
of the `metadata.name` field.
### `metadata.tags` [optional]
A list of strings that can be associated with the template, e.g.
`['recommended', 'react']`.
This list will also be used in the frontend to display to the user so you can
potentially search and group templates by these tags.
### `spec.type` [optional]
The type of component as a string, e.g. `website`. This field is optional but
recommended.
The software catalog accepts any type value, but an organization should take
great care to establish a proper taxonomy for these. Tools including Backstage
itself may read this field and behave differently depending on its value. For
example, a website type component may present tooling in the Backstage interface
that is specific to just websites.
The current set of well-known and common values for this field is:
- `service` - a backend service, typically exposing an API
- `website` - a website
- `library` - a software library, such as an npm module or a Java library
### `spec.templater` [required]
The templating library that is supported by the template skeleton as a string,
e.g `cookiecutter`.
Different skeletons will use different templating syntax, so it's common that
the template will need to be run with a particular piece of software.
This key will be used to identify the correct templater which is registered into
the `TemplatersBuilder`.
The values which are available by default are:
- `cookiecutter` - [cookiecutter](https://github.com/cookiecutter/cookiecutter).
### `spec.path` [optional]
The string location where the templater should be run if it is not on the same
level as the `template.yaml` definition, e.g. `./cookiecutter/skeleton`.
This will set the `cwd` when running the templater to the folder path that you
specify relative to the `template.yaml` definition.
This is also particularly useful when you have multiple template definitions in
the same repository but only a single `template.yaml` registered in backstage.
@@ -1,333 +0,0 @@
---
id: migrating-from-v1alpha1-to-v1beta2
title: Migrating to v1beta2 templates
# prettier-ignore
description: How to move your old templates from v1alpha1 to the more declarative v1beta2
---
# What's new?
Previously, the scaffolder was very restricted in what you could do when
creating new software components from templates. There were three scaffolding
steps which was pretty hard to extend and add new functionality to, difficult to
re-use logic between templates. There used to be a fixed pipeline of
`preparers`, `templaters`, and `publishers`, which were defined by the backend
and needed to be run for each template. This is now changed, to give the
template total control over what should be executed as part of the templating
run. This makes templates a little more declarative as you can now register
different `actions` or `functions` with the `scaffolder-backend` which you then
can decide how, and in what order, to run using the template definition YAML
file.
We've also made some improvements, and added some helpers to work with
cookiecutter. The skeleton for a template can now be stored in a different place
to where your entity definition is: previously you needed to have your
`template.yaml` next to the skeleton source (`{{cookiecutter.component_id}}`
directory), but now that's not the case. Part of the changes with the `v1beta2`
syntax is that you can grab your template source from any repository, and re-use
them between templates.
We've also renamed the `schema` property to `parameters` as this makes more
sense when using them as parameters to the actions or steps that you've setup
for your templates. There's the added benefit that you can now assign an array
to the `parameters` property, which will then give you multiple steps in the UI,
so you can split apart your input parameters and group them as needed rather
than having one long list of input fields.
## The `parameters` property
The `schema` key has now been renamed to `parameters` with a few more features.
You can pass an array now to break apart the input form into different steps in
the UI. You can also specify `ui:schema` fields that are passed along to
[`react-jsonschema-form`](https://rjsf-team.github.io/react-jsonschema-form/)
inline with the JSON schema.
```yaml
spec:
parameters:
- title: Fill in some steps
required:
- name
properties:
name:
title: Name
type: string
description: Unique name of the component
ui:autofocus: true
ui:options:
rows: 5
```
## The `steps` property
`v1beta2` template syntax introduces the new `steps` property, which is an array
of `actions` that the scaffolder will run in combination with the user input
that is declared in the `schema`. Actions look like the following:
```yaml
spec:
steps:
- id: publish # a unique id for the step, can be anything you like
name: Publish # a user friendly name for the step, this is what is shown in the frontend
action: publish:github # the action ID that has been registered with the scaffolder-backend
input: # parameters that are passed as input to the action handler function
allowedHosts: ['github.com']
description: 'This is {{ parameters.name }}' # handlebars templating is supported with the values from the parameters section in the same file.
repoUrl: '{{ parameters.repoUrl }}'
```
# Migrating a `v1alpha1` template
## The template definition (.yaml)
### `parameters`
Because of the changes to invert the control to the `template.yaml` definition
for running the workflow, we need to adjust the `schema` property and we also
now need to define what the template is actually going to do as part of the
template run.
A simple migration would move the following yaml:
```yaml
apiVersion: backstage.io/v1alpha1
kind: Template
metadata:
name: react-ssr-template
title: React SSR Template
description: Create a website powered with Next.js
tags:
- recommended
- react
spec:
owner: web@example.com
templater: cookiecutter
type: website
path: '.'
schema:
required:
- component_id
- description
properties:
component_id:
title: Name
type: string
description: Unique name of the component
description:
title: Description
type: string
description: Help others understand what this website is for.
```
To something that looks like the following:
```yaml
apiVersion: backstage.io/v1beta2
kind: Template
metadata:
name: react-ssr-template
title: React SSR Template
description: Create a website powered with Next.js
tags:
- recommended
- react
spec:
owner: web@example.com
type: website
parameters:
- title: Add some input
required:
- component_id
- description
properties:
component_id:
title: Name
type: string
description: Unique name of the component
description:
title: Description
type: string
description: Help others understand what this website is for.
- title: Some more additional info that was previously provided automatically
required:
- owner
- repoUrl
properties:
owner:
title: Owner
type: string
description: Owner of the component
ui:field: OwnerPicker
ui:options:
allowedKinds:
- Group
- title: Choose a location
repoUrl:
title: Repository Location
type: string
ui:field: RepoUrlPicker
ui:options:
allowedHosts:
- github.com
```
There are a few things to note here. On the `alpha` version, the second step of
the template flow in the frontend was provided by Backstage for free, so we used
to collect the user input for the `owner` field and the `repositoryUrl` that you
were going to publish to. Now because `actions` can have any workflow they like,
it doesn't make sense to still provide these fields for every scaffolding
workflow, as you might not need these anymore. That's why we now manually add
those fields back into the template parameters that are shown to the user:
```yaml
- title: Some more additional info that was previously provided automatically
required:
- owner
- repoUrl
properties:
owner:
title: Owner
type: string
description: Owner of the component
ui:field: OwnerPicker
ui:options:
allowedKinds:
- Group
- title: Choose a location
repoUrl:
title: Repository Location
type: string
ui:field: RepoUrlPicker
ui:options:
allowedHosts:
- github.com
```
Maybe you also don't need to publish to `github.com`, you should replace this
with your VCS provider URL that is listed in your `integrations` config instead.
### `steps`
So now we should have all the required information that we need from the user in
a much more extensible way. We now need to tell the scaffolder what to do with
these parameters and what to do with the user input.
We've made templating using `cookiecutter` a little simpler. You don't need to
store the `cookiecutter` skeleton in the same directory as the `template.yaml`
definition, it can live wherever you like - maybe a shared repository somewhere
so you can re-use the skeletons but apply different actions for different
templates depending on your use case.
We also no longer need to have a directory called
`{{cookiecutter.component_id}}`. This is because now we can't ensure that
`component_id` will be a parameter that is provided from the frontend, this
could break `cookiecutter`. If your directory structure used to look like this:
```
my-awesome-template
-> {{cookiecutter.component_id}}
-> file.txt
-> some_more_files.ts
-> hooks
-> post_gen_project.sh
-> template.yaml
```
We now recommend that you move to the following structure:
```
my-awesome-template
-> skeleton
-> file.txt
-> some_more_files.ts
-> template.yaml
```
This migration renames the skeleton folder to something more semantic, and also
drops support for `cookiecutter` hooks. We've dropped support for `cookiecutter`
hooks for now, as hopefully everything that is stored in these hooks can be
moved to `actions` instead, and for security reasons, it's more secure to run
trusted code that you ship with Backstage as an action rather than some script
that can be pulled in from anywhere which doesn't get vetted first. It's a
pretty big security risk that those scripts will be run on Backstage instances
inside your infrastructure, especially `.sh` files.
If you really need hooks and can't find a suitable solution by using actions
please reach out to us through a ticket and we'll see what we can do to assist
:)
You'll notice that we removed the `templater` property from the `spec`
definition in the template `yaml`, so there's no way to define that this is a
`cookiecutter` `templater`.
We've created a built-in action that you can use which will when run, go grab a
directory from anywhere and run `cookiecutter` on top of it, and then extract
the contents into the working directory for the scaffolder.
Adding the `steps` for a simple template should look something like the
following:
```yaml
spec:
steps:
# this action will go use cookiecutter to template some files into the working directory
- id: template # an ID for the templating step
name: Create skeleton # A user friendly name for the action
action: fetch:cookiecutter
input:
url: ./skeleton # this is the directory for your skeleton files.
# If it's located next to the `template.yaml` then you can use a relative path,
# otherwise you can use absolute URLs that point at the VCS: https://github.com/backstage/backstage/tree/master/some_folder_somewhere
values:
# for each value that you need to pass to cookiecutter, they should be listed here and set in this values object.
# You can use the handlebars templating syntax to pull them from the input parameters listed in the same file
name: '{{ parameters.name }}'
owner: '{{ parameters.owner }}'
destination: '{{ parseRepoUrl parameters.repoUrl }}'
# this action is for publishing the working directory to the VCS
- id: publish
name: Publish
action: publish:github
input:
allowedHosts: ['github.com']
description: 'This is {{ parameters.name }}'
repoUrl: '{{ parameters.repoUrl }}'
# this action will then register the created component in Backstage
- id: register
name: Register
action: catalog:register
input:
repoContentsUrl: '{{ steps.publish.output.repoContentsUrl }}'
catalogInfoPath: '/catalog-info.yaml'
```
### `output`
Steps can output values, and so can the template itself. This is good for
returning values to the frontend, so we can make the buttons like
`Go to catalog` and `Go to repo` work correctly. You can add the following to
your `template.yaml` to make sure you return the right values from the steps:
```yaml
spec:
output:
remoteUrl: '{{ steps.publish.output.remoteUrl }}'
entityRef: '{{ steps.register.output.entityRef }}'
```
Or you can return a `links` array with text and a URL explicitly:
```yaml
spec:
output:
links:
- url: '{{steps.publish.output.remoteUrl}}'
title: 'Go to Repo'
```
## Questions?
If you have any questions or feedback, please reach out to us on GitHub or
Discord and we will do our best to help!
@@ -0,0 +1,156 @@
---
id: migrating-from-v1beta2-to-v1beta3
title: Migrating to v1beta3 templates
# prettier-ignore
description: How to migrate your existing templates to beta3 syntax
---
# What's new?
Well then, here we are! 🚀
Backstage has had many forms of templating languages throughout different
plugins and different systems. We've had `cookiecutter` syntax in templates, and
we also had `handlebars` templating in the `kind: Template`. Then we wanted to
remove the additional dependency on `cookiecutter` for Software Templates out of
the box, so we introduced `nunjucks` as an alternative in `fetch:template`
action which is based on the `jinja2` syntax so they're pretty similar. In an
effort to reduce confusion and unify on to one templating language, we're
officially deprecating support for `handlebars` templating in the
`kind: Template` entities with `apiVersion` `scaffolder.backstage.io/v1beta3`
and moving to using `nunjucks` instead.
This provides us a lot of built in `filters` (`handlebars` helpers), that as
Template authors will give you much more flexibility out of the box, and also
open up sharing of filters in the Entity and the actual `skeleton` too, and
removing the slight differences between the two languages.
We've also removed a lot of the built in helpers that we shipped with
`handlebars`, as they're now supported as first class citizens by either
`nunjucks` or the new `scaffolder` when using `scaffolder.backstage.io/v1beta3`
`apiVersion`
The migration path is pretty simple, and we've removed some of the pain points
from writing the `handlebars` templates too. Let's go through what's new and how
to upgrade.
## `backstage.io/v1beta2` -> `scaffolder.backstage.io/v1beta3`
The most important change is that you'll need to switch over the `apiVersion` in
your templates to the new one.
```diff
kind: Template
- apiVersion: backstage.io/v1beta2
+ apiVersion: scaffolder.backstage.io/v1beta3
```
## `${{ }}` instead of `"{{ }}"`
One really big readability issue and cause for confusion was the fact that with
`handlebars` and `yaml` you always had to wrap your templating strings in quotes
in `yaml` so that it didn't try to parse it as a `json` object and fail. This
was pretty annoying, as it also meant that all things look like strings. Now
that's no longer the case, you can now remove the `""` and take advantage of
writing nice `yaml` files that just work.
```diff
spec:
steps:
input:
allowedHosts: ['github.com']
- description: 'This is {{ parameters.name }}'
+ description: This is ${{ parameters.name }}
- repoUrl: '{{ parameters.repoUrl }}'
+ repoUrl: ${{ parameters.repoUrl }}
```
## No more `eq` or `not` helpers
These helpers are no longer needed with the more expressive `api` that
`nunjucks` provides. You can simply use the built-in `nunjucks` and `jinja2`
style operators.
```diff
spec:
steps:
input:
- if: '{{ eq parameters.value "backstage" }}'
+ if: ${{ parameters.value === "backstage" }}
...
```
And then for the `not`
```diff
spec:
steps:
input:
- if: '{{ not parameters.value "backstage" }}'
+ if: ${{ parameters.value !== "backstage" }}
...
```
Much better right? ✨
## No more `json` helper
This helper is no longer needed, as we've added support for complex values and
supporting the additional primitive values now rather than everything being a
`string`. This means that now that you can pass around `parameters` and it
should all work as expected and keep the type that has been declared in the
input schema.
```diff
spec:
parameters:
test:
type: number
name: Test Number
address:
type: object
required:
- line1
properties:
line1:🙏
type: string
name: Line 1
line2:
type: string
name: Line 2
steps:
- id: test step
action: run:something
input:
- address: '{{ json parameters.address }}'
+ address: ${{ parameters.address }}
- number: '{{ parameters.number }}'
+ number: ${{ parameters.number }} # this will now make sure that the type of number is a number 🙏
```
## `parseRepoUrl` is now a `filter`
All calls to `parseRepoUrl` are now a `jinja2` `filter`, which means you'll need
to update the syntax.
```diff
spec:
steps:
input:
- repoUrl: '{{ parseRepoUrl parameters.repoUrl }}'
+ repoUrl: ${{ parameters.repoUrl | parseRepoUrl }}
...
```
Now we have complex value support here too, expect that this `filter` will go
away in future versions and the `RepoUrlPicker` will return an object so
`parameters.repoUrl` will already be a
`{ host: string; owner: string; repo: string }` 🚀
### Summary
Of course, we're always available on [discord](https://discord.gg/MUpMjP2) if
you're stuck or something's not working as expected. You can also
[raise an issue](https://github.com/backstage/backstage/issues/new/choose) with
feedback or bugs!
+8
View File
@@ -63,6 +63,10 @@ techdocs:
# (Required) Cloud Storage Bucket Name
bucketName: 'techdocs-storage'
# (Optional) Location in storage bucket to save files
# If not set, the default location will be the root of the storage bucket
bucketRootPath: '/'
# (Optional) An API key is required to write to a storage bucket.
# If missing, GOOGLE_APPLICATION_CREDENTIALS environment variable will be used.
# https://cloud.google.com/docs/authentication/production
@@ -75,6 +79,10 @@ techdocs:
# (Required) AWS S3 Bucket Name
bucketName: 'techdocs-storage'
# (Optional) Location in storage bucket to save files
# If not set, the default location will be the root of the storage bucket
bucketRootPath: '/'
# (Optional) An API key is required to write to a storage bucket.
# If not set, environment variables or aws config file will be used to authenticate.
# https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/loading-node-credentials-environment.html
@@ -5,11 +5,12 @@ sidebar_label: Creating and Publishing Documentation
description: Guidance on how to create and publish documentation
---
This section will guide you through:
This section will guide you through how to:
- [Create a basic documentation setup](#create-a-basic-documentation-setup)
- [Use any software template](#use-any-software-template)
- [Use the documentation template](#use-the-documentation-template)
- [Manually add documentation setup to already existing repository](#manually-add-documentation-setup-to-already-existing-repository)
- [Enable documentation for an already existing entity](#enable-documentation-for-an-already-existing-entity)
- [Writing and previewing your documentation](#writing-and-previewing-your-documentation)
## Prerequisites
@@ -21,29 +22,47 @@ This section will guide you through:
If you have an existing repository that you'd like to add documentation to, skip
to the
[Manually add documentation setup](#manually-add-documentation-setup-to-already-existing-repository)
section below. Otherwise, continue reading to start a documentation repo from
scratch.
[Enable documentation for an already existing entity setup](#enable-documentation-for-an-already-existing-entity)
section below. Otherwise, continue reading to create a new software entity
including documentation from scratch.
### Use any software template
TechDocs is built on top of the
[docs like code approach](https://www.docslikecode.com/about/). This, in short,
means that you should keep documentation close to the code.
Your Backstage app has a set of software templates added by default. All of
these software templates include everything you need to get your TechDocs site
up and running and to start writing your documentation.
If you have created software templates that do not include documentation by
default, we highly recommend you to set that up. Follow our how-to guide
[How to add documentation setup to your software templates](./how-to-guides.md#how-to-add-the-documentation-setup-to-your-software-templates)
to get started.
### Use the documentation template
Your working Backstage instance should by default have a documentation template
added. If not, copy the catalog locations from the
There could be _some_ situations where you don't want to keep your docs close to
your code, but still want to publish documentation - for example, an onboarding
tutorial. For this use case, we have put together a documentation template. Your
Backstage instance should by default have a documentation template added. If
not, copy the catalog locations from the
[create-app template](https://github.com/backstage/backstage/blob/master/packages/create-app/templates/default-app/app-config.yaml.hbs)
to add the documentation template. The template creates a component with only
TechDocs configuration and default markdown files as below mentioned in manual
documentation setup, and is otherwise empty.
to add the documentation template. The template creates a component with
**only** TechDocs configuration and default markdown files, and is otherwise
empty.
![Documentation Template](../../assets/techdocs/documentation-template.png)
Create an entity from the documentation template and you will get the needed
setup for free.
### Manually add documentation setup to already existing repository
### Enable documentation for an already existing entity
Prerequisites:
- An existing component
- An existing entity
[registered in backstage](../software-catalog/index.md#adding-components-to-the-catalog)
(e.g. via a `catalog-info.yaml` file).
@@ -72,11 +91,11 @@ metadata:
The
[`backstage.io/techdocs-ref` annotation](../software-catalog/well-known-annotations.md#backstageiotechdocs-ref)
is used by TechDocs to download the documentation source files for generating an
Entity's TechDocs site.
entity's TechDocs site.
Create a `/docs` folder in the root of the project with at least an `index.md`
file. _(If you add more markdown files, make sure to update the nav in the
mkdocs.yml file to get a proper navigation for your documentation.)_
Create a `/docs` folder in the root of your repository with at least an
`index.md` file in it. _(If you add more markdown files, make sure to update the
nav in the mkdocs.yml file to get a proper navigation for your documentation.)_
> Note - Although `docs` is a popular directory name for storing documentation,
> it can be renamed to something else and can be configured by `mkdocs.yml`. See
@@ -95,9 +114,10 @@ updated documentation next time you run Backstage!
## Writing and previewing your documentation
Using the `techdocs-cli` you can preview your docs inside a local Backstage
instance and get live reload on changes. This is useful when you want to preview
your documentation while writing.
Using the [techdocs-cli](https://github.com/backstage/techdocs-cli) you can
preview your docs inside a local Backstage instance and get live reload on
changes. This is useful when you want to preview your documentation while
writing.
To do this you can run:
+2 -2
View File
@@ -215,10 +215,10 @@ techdocs:
publisher:
type: 'local'
generator:
techdocs: local
runIn: local
```
Setting `generators.techdocs` to `local` means you will have to make sure your
Setting `generator.runIn` to `local` means you will have to make sure your
environment is compatible with techdocs.
You will have to install the `mkdocs` and `mkdocs-techdocs-core` package from
+74 -1
View File
@@ -110,7 +110,8 @@ TechDocs uses a composability pattern similar to the Search and Catalog plugins
in Backstage. While a default table experience, similar to the one provided by
the Catalog plugin, is made available for ease-of-use, it's possible for you to
provide a completely custom experience, tailored to the needs of your
organization.
organization. For example, TechDocs comes with an alternative grid based layout
(`<EntityListDocsGrid>`).
This is done in your `app` package. By default, you might see something like
this in your `App.tsx`:
@@ -348,3 +349,75 @@ const app = createApp({
],
});
```
## How to add the documentation setup to your software templates
[Software Templates](https://backstage.io/docs/features/software-templates/software-templates-index)
in Backstage is a tool that can help your users to create new components out of
already configured templates. It comes with a set of default templates to use,
but you can also
[add your own templates](https://backstage.io/docs/features/software-templates/adding-templates).
If you have your own templates set up, we highly recommend that you include the
required setup for TechDocs in those templates. When creating a new component,
your users will then get a TechDocs site up and running automatically, ready for
them to start writing technical documentation.
The purpose of this how-to guide is to walk you through how to add the required
configuration and some default markdown files to your new template. You can use
the
[react-ssr-template](https://github.com/backstage/software-templates/tree/main/scaffolder-templates/react-ssr-template)
as a reference when walking through the steps.
Prerequisites:
- An existing software template including a `template.yaml` together with a
skeleton folder including at least a `catalog-info.yaml`.
1. Update your component's entity description by adding the following lines to
the `catalog-info.yaml` in your skeleton folder.
```yaml
annotations:
backstage.io/techdocs-ref: dir:.
```
The
[`backstage.io/techdocs-ref` annotation](../software-catalog/well-known-annotations.md#backstageiotechdocs-ref)
is used by TechDocs to download the documentation source files for generating an
entity's TechDocs site.
2. Create an `mkdocs.yml` file in the root of your skeleton folder with the
following content:
```yaml
site_name: ${{values.component_id}}
site_description: ${{values.description}}
nav:
- Introduction: index.md
plugins:
- techdocs-core
```
3. Create a `/docs` folder in the skeleton folder with at least an `index.md`
file in it.
The `docs/index.md` can for example have the following content:
```md
# ${{ values.component_id }}
${{ values.description }}
## Getting started
Start writing your documentation by adding more markdown (.md) files to this
folder (/docs) or replace the content in this file.
```
> Note: The values of `site_name`, `component_id` and `site_description` depends
> on how you have configured your `template.yaml`
Done! You now have support for TechDocs in your own software template!
+90 -1
View File
@@ -96,7 +96,7 @@ yarn start # Start serving the example app, use --check to include type checks a
yarn storybook # Start local storybook, useful for working on components in @backstage/core-components
yarn workspace @backstage/plugin-welcome start # Serve welcome plugin only, also supports --check
yarn workspace @backstage/plugin-api-docs start # Serve api-docs plugin only, also supports --check
yarn tsc # Run typecheck, use --watch for watch mode
yarn tsc:full # Run full type checking, for example without skipLibCheck, use in CI
@@ -139,3 +139,92 @@ default app configs.
You can learn more about the local configuration in
[Static Configuration in Backstage](../conf/) section.
## Writing changesets
Changesets are an important part of the development process. They are used to
generate Changelog entries for all changes to the project. Ultimately they are
read by the end users to learn about important changes and fixes to the project.
Some of these fixes might require manual intervention from users so it's
important to write changesets that users understand and can take action on.
Here are some important do's and don'ts when writing changesets:
### Changeset should give a clear description to what has changed
#### Bad
```
---
'@backstage/catalog': patch
---
Fixed table layout
```
#### Good
```
---
'@backstage/catalog': patch
---
Fixed bug in EntityTable component where table layout did not readjust properly below 1080x768 pixels.
```
### Breaking changes not caught by the type checker should be clearly marked with bold **BREAKING** text
#### Bad
```
---
'@backstage/catalog': minor
---
getEntity is now a function that returns a Promise.
```
#### Good
```
---
'@backstage/catalog': minor
---
**BREAKING** The getEntity function now returns a Promise and **must** be awaited from now on.
```
### Changes to code should include a diff of the files that need updating
#### Bad
```
---
'@backstage/catalog': patch
---
**BREAKING** The catalogEngine now requires a flux capacitor to be passed.
```
#### Good
---
'@backstage/catalog': patch
---
**BREAKING** The catalog createRouter now requires that a `FluxCapacitor` is
passed to the router.
These changes are **required** to `packages/backend/src/plugins/catalog.ts`
```diff
+ import { FluxCapacitor } from '@backstage/time';
+ const fluxCapacitor = new FluxCapacitor();
return await createRouter({
entitiesCatalog,
locationAnalyzer,
locationService,
+ fluxCapacitor,
logger: env.logger,
config: env.config,
});
```
-53
View File
@@ -132,56 +132,3 @@ Now you're free to hack away on your own Backstage installation!
As you get more experienced with the app, in future you can run just the
frontend with `yarn start` in one window, and the backend with
`yarn start-backend` in a different window.
## Linking in local Backstage packages
It can often be useful to try out changes to the packages in the main Backstage
repo within your own app. For example if you want to make modifications to
`@backstage/core-plugin-api` and try them out in your app.
To link in external packages, add them to your `package.json` and `lerna.json`
workspace paths. These can be either relative or absolute paths with or without
globs. For example:
```json
"packages": [
"packages/*",
"plugins/*",
"../backstage/packages/core-plugin-api", // New path added to work on @backstage/core-plugin-api
],
```
Then reinstall packages to make yarn set up symlinks:
```bash
yarn install
```
With this in place you can now modify the `@backstage/core-plugin-api` package
within the main repo, and have those changes be reflected and tested in your
app. Simply run your app using `yarn dev` (or `yarn start` for just frontend) as
normal.
Note that for backend packages you need to make sure that linked packages are
not dependencies of any non-linked package. If you for example want to work on
`@backstage/backend-common`, you need to also link in other backend plugins and
packages that depend on `@backstage/backend-common`, or temporarily disable
those plugins in your backend. This is because the transformation of backend
module tree stops whenever a non-local package is encountered, and from that
point node will `require` packages directly for that entire module subtree.
Type checking can also have issues when linking in external packages, since the
linked in packages will use the types in the external project and dependency
version mismatches between the two projects may cause errors. To fix any of
those errors you need to sync versions of the dependencies in the two projects.
A simple way to do this can be to copy over `yarn.lock` from the external
project and run `yarn install`, although this is quite intrusive and can cause
other issues in existing projects, so use this method with care. It can often be
best to simply ignore the type errors, as app serving will work just fine
anyway.
Another issue with type checking is that the incremental type cache doesn't
invalidate correctly for the linked in packages, causing type checking to not
reflect changes made to types. You can work around this by either setting
`compilerOptions.incremental = false` in `tsconfig.json`, or by deleting the
types cache folder `dist-types` before running `yarn tsc`.
+81 -31
View File
@@ -4,49 +4,99 @@ title: Getting Started
description: Documentation on How to get started with Backstage
---
There are two different ways to get started with Backstage:
For most Backstage installations, installing the standalone app will bring you
the best and most streamlined experience. In this guide you will:
- **Recommended:** Create a standalone app
- **Contributors:** Clone the Backstage repository
- Deploy Backstage Standalone with npm packages
- Run Backstage Standalone with a SQLite in-memory database and demo content
Creating a standalone app makes it simpler to customize the application for your
needs and stay up to date with the project. You will depend on `@backstage`
packages from npm, making your app much smaller. This is the recommended
approach for most installations.
This guide assumes a basic understanding of working on a Linux based operating
system using tools like apt-get, npm, yarn, curl. Docker knowledge is also
helpful for making the best use of your Backstage installation.
If you want to contribute plugins or to the project in general, it's easier to
fork and clone the repository. The `@backstage` packages will be included in the
clone. That will let you stay up to date with the latest changes, and give you
an easier path to make Pull Requests.
If you are planning to contribute plugins or the project in general, we advise
you to use the
[Getting Started for Contributors](https://backstage.io/docs/getting-started/running-backstage-locally)
guide to do a repository-based installation.
### Prerequisites
- Access to a Linux-based operating system, such as Linux, MacOS or
[Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/)
- An account with elevated rights
- `curl` or `wget` installed
- Node.js Active LTS Release installed (currently v14) using one of these
methods:
- Using `nvm` (recommended)
- [Installing nvm](https://github.com/nvm-sh/nvm#install--update-script)
- [Install and change Node version with nvm](https://nodejs.org/en/download/package-manager/#nvm)
- [Binary Download](https://nodejs.org/en/download/)
- [Package manager](https://nodejs.org/en/download/package-manager/)
- [Using NodeSource packages](https://github.com/nodesource/distributions/blob/master/README.md)
- `yarn` [Installation](https://classic.yarnpkg.com/en/docs/install)
- `docker` [installation](https://docs.docker.com/engine/install/)
- `git` [installation](https://github.com/git-guides/install-git)
- If the system is not directly accessible over your network, the following
ports need to be opened: 3000, 7000
### Create your Backstage App
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) 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:
To install the Backstage Standalone app, we make use of `npx`, a tool to run
Node executables straight from the registry. Running the command below will
install Backstage. The wizard will create a subdirectory inside your current
working directory.
```bash
npx @backstage/create-app
```
You will be taken through a wizard to create your app. You can read more about
this process in [Create an app](./create-an-app.md).
The wizard will ask you
### Contributing to Backstage
- The name of the app, which will also be the name of the directory
- The database type to use for the backend. For this guide, you'll be using the
SQLite option.
If you intend to make changes to the core project's packages, certain plugins,
or project documentation, then you can fork and clone
[https://github.com/backstage/backstage](https://github.com/backstage/backstage).
<p align='center'>
<img src='../assets/getting-started/wizard.png' alt='Screenshot of the wizard asking for a name for the app, and a selection menu for the database.'>
</p>
This will let you run the latest code off of the `master` branch, fix bugs or
contribute new features, run test suites, etc.
### Run the Backstage app
You can read more in our
[CONTRIBUTING](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md)
guide, which can help you get setup with a Backstage development environment.
When the installation is complete you can go to the application directory and
start the app. The `yarn dev` command will run both the frontend and backend as
separate processes (named `[0]` and `[1]`) in the same window.
```bash
cd my-backstage-app
yarn dev
```
<p align='center'>
<img src='../assets/getting-started/startup.png' alt='Screenshot of the command output, with the message web pack compiled successfully.'>
</p>
It might take a little while, but as soon as the message
`[0] webpack compiled successfully` appears, you can open a browser and directly
navigate to your freshly installed Backstage portal at `http://localhost:3000`.
You can start exploring the demo immediately.
<p align='center'>
<img src='../assets/getting-started/portal.png' alt='Screenshot of the Backstage portal.'>
</p>
Congratulations! That should be it. Let us know how it went:
[on discord](https://discord.gg/EBHEGzX), file issues for any
[feature](https://github.com/backstage/backstage/issues/new?labels=help+wanted&template=feature_template.md)
or
[plugin suggestions](https://github.com/backstage/backstage/issues/new?labels=plugin&template=plugin_template.md&title=%5BPlugin%5D+THE+PLUGIN+NAME),
or
[bugs](https://github.com/backstage/backstage/issues/new?labels=bug&template=bug_template.md)
you have, and feel free to
[contribute](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md)!
The most common next steps are to configure Backstage, add a plugin and moving
to a more persistent database:
- [Setting up Authentication](https://backstage.io/docs/auth/)
- [Switching from SQLite to PostgresQL](https://backstage.io/docs/tutorials/switching-sqlite-postgres)
- [Adding a plugin](https://backstage.io/docs/getting-started/configure-app-with-plugins)
+1 -1
View File
@@ -7,7 +7,7 @@ description: Importing users and groups from a Microsoft Azure Active Directory
---
The Backstage catalog can be set up to ingest organizational data - users and
teams - directly from an tenant in Microsoft Azure Active Directory via the
teams - directly from a tenant in Microsoft Azure Active Directory via the
Microsoft Graph API.
More details on this are available in the
@@ -1,23 +0,0 @@
---
id: installation
title: Google Analytics Installation
sidebar_label: Installation
# prettier-ignore
description: Adding Google Analytics to Your App
---
There is a basic
[Google Analytics](https://marketingplatform.google.com/about/analytics/)
integration built into Backstage. You can enable it by adding the following to
your app configuration:
```yaml
app:
googleAnalyticsTrackingId: UA-000000-0
```
Replace the tracking ID with the one generated for you after signing up for the
Google Analytics service.
The default behavior is only to send a pageview hit. To record more, review the
[Google Analytics developer documentation](https://developers.google.com/analytics/devguides/collection/gtagjs).
@@ -1,6 +1,6 @@
---
id: commands
title: Commands
id: cli-commands
title: CLI Commands
description: Descriptions of all commands available in the CLI.
---
@@ -1,6 +1,6 @@
---
id: index
title: Overview
id: cli-overview
title: CLI Overview
description: Overview of the Backstage CLI
---
@@ -20,7 +20,7 @@ Under the hood the CLI uses [Webpack](https://webpack.js.org/) for bundling,
linting. It also includes custom tooling for working within Backstage apps, for
example for keeping the app up to date and verifying static configuration.
For a full list of CLI commands, see the [commands](./commands.md) page.
For a full list of CLI commands, see the [commands](./cli-commands.md) page.
## Introduction
+56
View File
@@ -0,0 +1,56 @@
---
id: linking-local-packages
title: Linking in Local Packages
description: How to link in other local packages into your Backstage monorepo
---
It can often be useful to try out changes to the packages in the main Backstage
repo within your own app. For example if you want to make modifications to
`@backstage/core-plugin-api` and try them out in your app.
To link in external packages, add them to your `package.json` and `lerna.json`
workspace paths. These can be either relative or absolute paths with or without
globs. For example:
```json
"packages": [
"packages/*",
"plugins/*",
"../backstage/packages/core-plugin-api", // New path added to work on @backstage/core-plugin-api
],
```
Then reinstall packages to make yarn set up symlinks:
```bash
yarn install
```
With this in place you can now modify the `@backstage/core-plugin-api` package
within the main repo, and have those changes be reflected and tested in your
app. Simply run your app using `yarn dev` (or `yarn start` for just frontend) as
normal.
Note that for backend packages you need to make sure that linked packages are
not dependencies of any non-linked package. If you for example want to work on
`@backstage/backend-common`, you need to also link in other backend plugins and
packages that depend on `@backstage/backend-common`, or temporarily disable
those plugins in your backend. This is because the transformation of backend
module tree stops whenever a non-local package is encountered, and from that
point node will `require` packages directly for that entire module subtree.
Type checking can also have issues when linking in external packages, since the
linked in packages will use the types in the external project and dependency
version mismatches between the two projects may cause errors. To fix any of
those errors you need to sync versions of the dependencies in the two projects.
A simple way to do this can be to copy over `yarn.lock` from the external
project and run `yarn install`, although this is quite intrusive and can cause
other issues in existing projects, so use this method with care. It can often be
best to simply ignore the type errors, as app serving will work just fine
anyway.
Another issue with type checking is that the incremental type cache doesn't
invalidate correctly for the linked in packages, causing type checking to not
reflect changes made to types. You can work around this by either setting
`compilerOptions.incremental = false` in `tsconfig.json`, or by deleting the
types cache folder `dist-types` before running `yarn tsc`.
+298
View File
@@ -0,0 +1,298 @@
---
id: analytics
title: Plugin Analytics
description: Measuring usage of your Backstage instance.
---
Setting up, maintaining, and iterating on an instance of Backstage can be a
large investment. To help measure return on this investment, Backstage comes
with an event-based Analytics API that grants app integrators the flexibility to
collect and analyze Backstage usage in the analytics tool of their choice, while
providing plugin developers a standard interface for instrumenting key user
interactions.
## Concepts
- **Events** consist of, at a minimum, an `action` (like `click`) and a
`subject` (like `thing that was clicked on`).
- **Attributes** represent additional dimensional data (in the form of key/value
pairs) that may be provided on an event-by-event basis. To continue the above
example, the URL a user clicked to might look like `{ "to": "/a/page" }`.
- **Context** represents the broader context in which an event took place. By
default, information like `pluginId`, `extension`, and `routeRef` are
provided.
This composition of events aims to allow analysis at different levels of detail,
enabling very granular questions (like "what is the most clicked on thing on a
particular route") as well as very high-level questions (like "what is the most
used plugin in my Backstage instance") to be answered.
## Supported Analytics Tools
While all that's needed to consume and forward these events to an analytics tool
is a concrete implementation of [AnalyticsApi][analytics-api-type], common
integrations are packaged and provided as plugins. Find your analytics tool of
choice below.
| Analytics Tool | Support Status |
| ---------------------- | -------------- |
| [Google Analytics][ga] | Yes ✅ |
To suggest an integration, please [open an issue][add-tool] for the analytics
tool your organization uses. Or jump to [Writing Integrations][int-howto] to
learn how to contribute the integration yourself!
[ga]:
https://github.com/backstage/backstage/blob/master/plugins/analytics-module-ga/README.md
[add-tool]:
https://github.com/backstage/backstage/issues/new?assignees=&labels=plugin&template=plugin_template.md&title=%5BAnalytics+Module%5D+THE+ANALYTICS+TOOL+TO+INTEGRATE
[int-howto]: #writing-integrations
[analytics-api-type]:
https://backstage.io/docs/reference/core-plugin-api.analyticsapi
## Key Events
The following table summarizes events that, depending on the plugins you have
installed, may be captured.
| Action | Provided By | Subject |
| ---------- | -------------- | ----------------------------------------- |
| `navigate` | Backstage Core | The URL of the page that was navigated to |
| `click` | Backstage Core | The text of the link that was clicked on |
If there is an event you'd like to see captured, please [open an
issue][add-event] describing the event you want to see and the questions it
would help you answer. Or jump to [Capturing Events][event-howto] to learn how
to contribute the instrumentation yourself!
_OSS plugin maintainers: feel free to document your events in the table above._
[add-event]:
https://github.com/backstage/backstage/issues/new?assignees=&labels=enhancement&template=feature_template.md&title=[Analytics%20Event]:%20THE+EVENT+TO+CAPTURE
[event-howto]: #capturing-events
## Writing Integrations
Analytics event forwarding is implemented as a Backstage utility API. Just as
you might provide a custom API implementation for errors or SCM Authentication,
you can provide one for analytics.
The provided API need only provide a single method `captureEvent`, which takes
an `AnalyticsEvent` object.
```ts
import {
analyticsApiRef,
AnalyticsEvent,
AnyApiFactory,
createApiFactory,
} from '@backstage/core-plugin-api';
export const apis: AnyApiFactory[] = [
createApiFactory(analyticsApiRef, {
captureEvent: (event: AnalyticsEvent) => {
window._AcmeAnalyticsQ.push(event);
},
}),
];
```
In reality, you would likely want to encapsulate instantiation logic and pull
some details from configuration. A more complete example might look like:
```ts
import {
AnalyticsApi,
analyticsApiRef,
AnalyticsEvent,
AnyApiFactory,
configApiRef,
createApiFactory,
} from '@backstage/core-plugin-api';
import { AcmeAnalytics } from 'acme-analytics';
class AcmeAnalytics implements AnalyticsApi {
private constructor(accountId: number) {
AcmeAnalytics.init(accountId);
}
static fromConfig(config) {
const accountId = config.getString('app.analytics.acme.id');
return new AcmeAnalytics(accountId);
}
captureEvent(event: AnalyticsEvent) {
const { action, ...rest } = event;
AcmeAnalytics.send(action, rest);
}
}
export const apis: AnyApiFactory[] = [
createApiFactory({
api: analyticsApiRef,
deps: { configApi: configApiRef },
factory: ({ configApi }) => AcmeAnalytics.fromConfig(configApi),
}),
];
```
If you are integrating with an analytics service (as opposed to an internal
tool), consider contributing your API implementation as a plugin!
By convention, such packages should be named
`@backstage/analytics-module-[name]`, and any configuration should be keyed
under `app.analytics.[name]`.
## Capturing Events
To instrument an event in a component, start by retrieving an analytics tracker
using the `useAnalytics()` hook provided by `@backstage/core-plugin-api`. The
tracker includes a `captureEvent` method which takes an `action` and a `subject`
as arguments.
```ts
import { useAnalytics } from '@backstage/core-plugin-api';
const analytics = useAnalytics();
analytics.captureEvent('deploy', serviceName);
```
### Providing Extra Attributes
Additional dimensional `attributes` as well as a numeric `value` can be provided
on a third `options` argument if/when relevant for the event:
```ts
analytics.captureEvent('merge', pullRequestName, {
value: pullRequestAgeInMinutes,
attributes: {
org,
repo,
},
});
```
In the above example, an event resembling the following object would be
captured:
```json
{
"action": "merge",
"subject": "Name of Pull Request",
"value": 60,
"attributes": {
"org": "some-org",
"repo": "some-repo"
}
}
```
### Providing Context for Events
The `attributes` option is good for capturing details available to you within
the component that you're instrumenting. For capturing metadata only available
further up the react tree, or to help app integrators aggregate distinct events
by some common value, use an `<AnalyticsContext>`.
```tsx
import { AnalyticsContext, useAnalytics } from '@backstage/core-plugin-api';
const MyComponent = ({ value }) => {
const analytics = useAnalytics();
const handleClick = () => analytics.captureEvent('check', value);
return <SomeThing value={value} onClick={handleClick} />;
};
const MyWrapper = () => {
return (
<AnalyticsContext attributes={{ segment: 'xyz' }}>
<MyComponent value={'Some Value'} />
</AnalyticsContext>
);
};
```
In the above example, clicking on `<SomeThing />` would result in an analytics
event resembling:
```json
{
"action": "check",
"subject": "Some Value",
"context": {
"segment": "xyz"
}
}
```
Note that, for brevity in the example above, the context keys provided by
Backstage core (`pluginId`, `extension`, and `routeRef`) have been omitted. In
reality, those details would be included alongside any additional context
provided by you.
Analytics contexts can be nested; their values are merged down the react tree,
allowing keys to be overwritten.
### Event Naming Considerations
An event is split into its constituent parts to enable analysis at various
levels of granularity. In order to maintain this flexibility at analysis-time,
it's important to keep each of these levels of detail disaggregated.
- Avoid providing an overly specific `action`. For example, instead of
`filterEntityTable`, consider just using `filter` as the action, and allowing
`EntityTable` to be specified as part of the event's `context` (most likely
automatically as part of the `extension` in which the `filter` event was
captured).
- On the flip side, when adding `attributes` to an event, look at existing
events and see if the data you are capturing matches the intention, type, or
even the content of _their_ `attributes`. For instance, it may be common for
events that involve the Catalog to add details like entity `name`, `kind`,
and/or `namespace` as `attributes`. Using the same keys in your event will
ensure that events instrumented across plugins can easily be aggregated.
### Unit Testing Event Capture
The `@backstage/test-utils` package includes a `MockAnalyticsApi` implementation
that you can use in your unit tests to spy on and make assertions about any
analytics events captured.
Use it like this:
```tsx
import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { analyticsApiRef } from '@backstage/core-plugin-api';
import { MockAnalyticsApi, wrapInTestApp } from '@backstage/test-utils';
import { render, fireEvent, waitFor } from '@testing-library/react';
describe('SomeComponent', () => {
it('should capture event on click', () => {
// Use the Mock Analytics API to spy on event captures.
const apiSpy = new MockAnalyticsApi();
// Render the component being tested
const { getByText } = render(
wrapInTestApp(
<ApiProvider apis={ApiRegistry.from([[analyticsApiRef, apiSpy]])}>
<SomeComponentUnderTest />
</ApiProvider>,
),
);
// Fire the event that triggers event capture.
fireEvent.click(getByText('some component text'));
// Assert that the event was captured with the expected data.
await waitFor(() => {
expect(apiSpy.getEvents()[0]).toMatchObject({
action: 'expected action',
subject: 'expected subject',
attributes: {
foo: 'bar',
},
});
});
});
});
```
+2 -1
View File
@@ -10,7 +10,8 @@ A Backstage Plugin adds functionality to Backstage.
To create a new plugin, make sure you've run `yarn install` and installed
dependencies, then run the following on your command line (a shortcut to
invoking the [`backstage-cli create-plugin`](../cli/commands.md#create-plugin))
invoking the
[`backstage-cli create-plugin`](../local-dev/cli-commands.md#create-plugin))
from the root of your project.
```bash
+3 -3
View File
@@ -36,7 +36,7 @@ that we provide. This gives us a way to automate some of the work required to
create a GitHub app.
You can read more about the
[`backstage-cli create-github-app` method](../cli/commands.md#create-github-app).
[`backstage-cli create-github-app` method](../local-dev/cli-commands.md#create-github-app).
Once you've gone through the CLI command, it should produce a YAML file in the
root of the project which you can then use as an `include` in your
@@ -60,7 +60,7 @@ The YAML file must include the following information. Please note that the
indentation for the `privateKey` is required.
```yaml
appId: 1
appId: app id
clientId: client id
clientSecret: client secret
webhookSecret: webhook secret
@@ -95,7 +95,7 @@ If you want to limit the GitHub app installations visible to backstage you may
optionally include the `allowedInstallationOwners` option.
```yaml
appId: 1
appId: app id
allowedInstallationOwners: ['GlobexCorp']
clientId: client id
clientSecret: client secret
-5
View File
@@ -8,11 +8,6 @@ description: Adding Observability to Your Plugin
This article briefly describes the observability options that are available to a
Backstage integrator.
## Google Analytics
See how to install Google Analytics in your app
[here](../integrations/google-analytics/installation.md)
## Datadog RUM Events
See how to install Datadog Events in your app
@@ -0,0 +1,9 @@
---
title: 'Analytics Module: Google Analytics'
author: Spotify
authorUrl: https://github.com/spotify
category: Analytics
description: Track usage of your Backstage instance using Google Analytics.
documentation: https://github.com/backstage/backstage/blob/master/plugins/analytics-module-ga/README.md
iconUrl: img/ga-icon.png
npmPackageName: '@backstage/plugin-analytics-module-ga'
+1 -1
View File
@@ -1,7 +1,7 @@
---
title: GKE Usage
author: BESTSELLER
authorUrl: bestsellerit.com
authorUrl: https://bestsellerit.com
category: Discovery
description: This plugin will show you the cost and resource usage of your application within Google Kubernetes Engine (GKE).
documentation: https://github.com/BESTSELLER/backstage-plugin-gkeusage/blob/master/README.md
+13
View File
@@ -0,0 +1,13 @@
---
title: Grafana
author: K-Phoen
authorUrl: https://github.com/K-Phoen
category: Monitoring
description: Associate alerts and dashboards to components.
documentation: https://github.com/K-Phoen/backstage-plugin-grafana/
iconUrl: https://avatars.githubusercontent.com/u/7195757?s=200&v=4
npmPackageName: '@k-phoen/backstage-plugin-grafana'
tags:
- dashboards
- monitoring
- alerting
+1 -1
View File
@@ -1,7 +1,7 @@
---
title: Harbor
author: BESTSELLER
authorUrl: bestsellerit.com
authorUrl: https://bestsellerit.com
category: Discovery
description: This plugin will show you information about Docker images within the Harbor cloud native registry.
documentation: https://github.com/BESTSELLER/backstage-plugin-harbor/blob/master/README.md
+14 -9
View File
@@ -29,7 +29,14 @@
"getting-started/contributors",
"getting-started/project-structure"
],
"CLI": ["cli/index", "cli/commands"],
"Local Development": [
{
"type": "subcategory",
"label": "CLI",
"ids": ["local-dev/cli-overview", "local-dev/cli-commands"]
},
"local-dev/linking-local-packages"
],
"Core Features": [
{
"type": "subcategory",
@@ -71,8 +78,7 @@
"features/software-templates/builtin-actions",
"features/software-templates/writing-custom-actions",
"features/software-templates/writing-custom-field-extensions",
"features/software-templates/template-legacy",
"features/software-templates/migrating-from-v1alpha1-to-v1beta2"
"features/software-templates/migrating-from-v1beta2-to-v1beta3"
]
},
{
@@ -83,7 +89,8 @@
"features/search/getting-started",
"features/search/concepts",
"features/search/architecture",
"features/search/search-engines"
"features/search/search-engines",
"features/search/how-to-guides"
]
},
{
@@ -146,11 +153,6 @@
"label": "GitLab",
"ids": ["integrations/gitlab/locations"]
},
{
"type": "subcategory",
"label": "Google Analytics",
"ids": ["integrations/google-analytics/installation"]
},
{
"type": "subcategory",
"label": "Google GCS",
@@ -170,6 +172,7 @@
"plugins/structure-of-a-plugin",
"plugins/integrating-plugin-into-software-catalog",
"plugins/composability",
"plugins/analytics",
{
"type": "subcategory",
"label": "Backends and APIs",
@@ -210,6 +213,8 @@
"label": "Included providers",
"ids": [
"auth/auth0/provider",
"auth/atlassian/provider",
"auth/bitbucket/provider",
"auth/microsoft/provider",
"auth/github/provider",
"auth/gitlab/provider",
+4
View File
@@ -1217,3 +1217,7 @@ code {
.medium-zoom-image {
z-index: 10000;
}
h3.collapsible span.arrow {
margin-right: 4px;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

+7 -5
View File
@@ -27,9 +27,11 @@ nav:
- Key Concepts: 'getting-started/concepts.md'
- Contributors: 'getting-started/contributors.md'
- Project Structure: 'getting-started/project-structure.md'
- CLI:
- Overview: 'cli/index.md'
- Commands: 'cli/commands.md'
- Local Development:
- CLI:
- Overview: 'local-dev/cli-overview.md'
- Commands: 'local-dev/cli-commands.md'
- Linking in Local Packages: 'local-dev/linking-local-packages.md'
- Core Features:
- Software Catalog:
- Overview: 'features/software-catalog/index.md'
@@ -66,6 +68,7 @@ nav:
- Concepts: 'features/search/concepts.md'
- Search Architecture: 'features/search/architecture.md'
- Search Engines: 'features/search/search-engines.md'
- HOW TO guides: 'features/search/how-to-guides.md'
- TechDocs:
- Overview: 'features/techdocs/README.md'
- Getting Started: 'features/techdocs/getting-started.md'
@@ -97,8 +100,6 @@ nav:
- Org Data: 'integrations/github/org.md'
- GitLab:
- Locations: 'integrations/gitlab/locations.md'
- Google Analytics:
- Installation: 'integrations/google-analytics/installation.md'
- Google GCS:
- Locations: 'integrations/google-cloud-storage/locations.md'
- LDAP:
@@ -112,6 +113,7 @@ nav:
- Plugin Development: 'plugins/plugin-development.md'
- Integrate into the Software Catalog: 'plugins/integrating-plugin-into-software-catalog.md'
- Composability System: 'plugins/composability.md'
- Plugin Analytics: 'plugins/analytics.md'
- Backends and APIs:
- Proxying: 'plugins/proxying.md'
- Backend plugin: 'plugins/backend-plugin.md'
-7
View File
@@ -61,7 +61,6 @@
"devDependencies": {
"@types/webpack": "^5.28.0",
"@changesets/cli": "^2.14.0",
"@octokit/openapi-types": "^2.2.0",
"@spotify/prettier-config": "^11.0.0",
"command-exists": "^1.2.9",
"concurrently": "^6.0.0",
@@ -71,7 +70,6 @@
"lerna": "^4.0.0",
"lint-staged": "^11.1.2",
"prettier": "^2.2.1",
"recursive-readdir": "^2.2.2",
"shx": "^0.3.2",
"yarn-lock-check": "^1.0.5"
},
@@ -87,10 +85,5 @@
"*.md": [
"node ./scripts/check-docs-quality"
]
},
"jest": {
"transformModules": [
"@asyncapi/react-component"
]
}
}
+62
View File
@@ -1,5 +1,67 @@
# example-app
## 0.2.51
### Patch Changes
- Updated dependencies
- @backstage/core-components@0.7.1
- @backstage/plugin-techdocs@0.12.3
- @backstage/plugin-sentry@0.3.26
- @backstage/plugin-user-settings@0.3.10
- @backstage/plugin-catalog-graph@0.2.1
- @backstage/plugin-jenkins@0.5.11
- @backstage/core-app-api@0.1.18
- @backstage/core-plugin-api@0.1.11
- @backstage/cli@0.8.0
- @backstage/plugin-catalog@0.7.2
- @backstage/plugin-catalog-import@0.7.3
- @backstage/plugin-catalog-react@0.6.1
- @backstage/catalog-model@0.9.5
## 0.2.50
### Patch Changes
- Updated dependencies
- @backstage/plugin-catalog-react@0.6.0
- @backstage/plugin-catalog@0.7.1
- @backstage/plugin-api-docs@0.6.12
- @backstage/plugin-scaffolder@0.11.8
- @backstage/core-app-api@0.1.17
- @backstage/core-components@0.7.0
- @backstage/theme@0.2.11
- @backstage/plugin-graphiql@0.2.20
- @backstage/cli@0.7.16
- @backstage/plugin-home@0.4.4
- @backstage/plugin-catalog-graph@0.2.0
- @backstage/plugin-search@0.4.15
- @backstage/plugin-techdocs@0.12.2
- @backstage/plugin-kubernetes@0.4.17
- @backstage/plugin-azure-devops@0.1.1
- @backstage/plugin-badges@0.2.13
- @backstage/plugin-catalog-import@0.7.2
- @backstage/plugin-circleci@0.2.27
- @backstage/plugin-cloudbuild@0.2.27
- @backstage/plugin-code-coverage@0.1.15
- @backstage/plugin-explore@0.3.20
- @backstage/plugin-github-actions@0.4.22
- @backstage/plugin-jenkins@0.5.10
- @backstage/plugin-kafka@0.2.19
- @backstage/plugin-lighthouse@0.2.29
- @backstage/plugin-org@0.3.27
- @backstage/plugin-pagerduty@0.3.17
- @backstage/plugin-rollbar@0.3.18
- @backstage/plugin-sentry@0.3.25
- @backstage/plugin-todo@0.1.14
- @backstage/integration-react@0.1.12
- @backstage/plugin-cost-insights@0.11.10
- @backstage/plugin-gcp-projects@0.3.8
- @backstage/plugin-newrelic@0.3.8
- @backstage/plugin-shortcuts@0.1.12
- @backstage/plugin-tech-radar@0.4.11
- @backstage/plugin-user-settings@0.3.9
## 0.2.49
### Patch Changes
+41 -40
View File
@@ -1,48 +1,49 @@
{
"name": "example-app",
"version": "0.2.49",
"version": "0.2.51",
"private": true,
"bundled": true,
"dependencies": {
"@backstage/catalog-model": "^0.9.4",
"@backstage/cli": "^0.7.15",
"@backstage/core-app-api": "^0.1.16",
"@backstage/core-components": "^0.6.1",
"@backstage/core-plugin-api": "^0.1.10",
"@backstage/integration-react": "^0.1.11",
"@backstage/plugin-api-docs": "^0.6.11",
"@backstage/plugin-badges": "^0.2.12",
"@backstage/plugin-catalog": "^0.7.0",
"@backstage/plugin-catalog-graph": "^0.1.3",
"@backstage/plugin-catalog-import": "^0.7.1",
"@backstage/plugin-catalog-react": "^0.5.2",
"@backstage/plugin-circleci": "^0.2.26",
"@backstage/plugin-cloudbuild": "^0.2.26",
"@backstage/plugin-code-coverage": "^0.1.14",
"@backstage/plugin-cost-insights": "^0.11.9",
"@backstage/plugin-explore": "^0.3.19",
"@backstage/plugin-gcp-projects": "^0.3.7",
"@backstage/plugin-github-actions": "^0.4.21",
"@backstage/plugin-graphiql": "^0.2.19",
"@backstage/plugin-home": "^0.4.3",
"@backstage/plugin-jenkins": "^0.5.9",
"@backstage/plugin-kafka": "^0.2.18",
"@backstage/plugin-kubernetes": "^0.4.16",
"@backstage/plugin-lighthouse": "^0.2.28",
"@backstage/plugin-newrelic": "^0.3.7",
"@backstage/plugin-org": "^0.3.26",
"@backstage/plugin-pagerduty": "0.3.16",
"@backstage/plugin-rollbar": "^0.3.17",
"@backstage/plugin-scaffolder": "^0.11.7",
"@backstage/plugin-search": "^0.4.14",
"@backstage/plugin-sentry": "^0.3.24",
"@backstage/plugin-shortcuts": "^0.1.11",
"@backstage/plugin-tech-radar": "^0.4.10",
"@backstage/plugin-techdocs": "^0.12.1",
"@backstage/plugin-todo": "^0.1.13",
"@backstage/plugin-user-settings": "^0.3.8",
"@backstage/catalog-model": "^0.9.5",
"@backstage/cli": "^0.8.0",
"@backstage/core-app-api": "^0.1.18",
"@backstage/core-components": "^0.7.1",
"@backstage/core-plugin-api": "^0.1.11",
"@backstage/integration-react": "^0.1.12",
"@backstage/plugin-api-docs": "^0.6.12",
"@backstage/plugin-azure-devops": "^0.1.1",
"@backstage/plugin-badges": "^0.2.13",
"@backstage/plugin-catalog": "^0.7.2",
"@backstage/plugin-catalog-graph": "^0.2.1",
"@backstage/plugin-catalog-import": "^0.7.3",
"@backstage/plugin-catalog-react": "^0.6.1",
"@backstage/plugin-circleci": "^0.2.27",
"@backstage/plugin-cloudbuild": "^0.2.27",
"@backstage/plugin-code-coverage": "^0.1.15",
"@backstage/plugin-cost-insights": "^0.11.10",
"@backstage/plugin-explore": "^0.3.20",
"@backstage/plugin-gcp-projects": "^0.3.8",
"@backstage/plugin-github-actions": "^0.4.22",
"@backstage/plugin-graphiql": "^0.2.20",
"@backstage/plugin-home": "^0.4.4",
"@backstage/plugin-jenkins": "^0.5.11",
"@backstage/plugin-kafka": "^0.2.19",
"@backstage/plugin-kubernetes": "^0.4.17",
"@backstage/plugin-lighthouse": "^0.2.29",
"@backstage/plugin-newrelic": "^0.3.8",
"@backstage/plugin-org": "^0.3.27",
"@backstage/plugin-pagerduty": "0.3.17",
"@backstage/plugin-rollbar": "^0.3.18",
"@backstage/plugin-scaffolder": "^0.11.8",
"@backstage/plugin-search": "^0.4.15",
"@backstage/plugin-sentry": "^0.3.26",
"@backstage/plugin-shortcuts": "^0.1.12",
"@backstage/plugin-tech-radar": "^0.4.11",
"@backstage/plugin-techdocs": "^0.12.3",
"@backstage/plugin-todo": "^0.1.14",
"@backstage/plugin-user-settings": "^0.3.10",
"@backstage/search-common": "^0.2.0",
"@backstage/theme": "^0.2.10",
"@backstage/theme": "^0.2.11",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.57",
@@ -62,7 +63,7 @@
"zen-observable": "^0.8.15"
},
"devDependencies": {
"@backstage/test-utils": "^0.1.18",
"@backstage/test-utils": "^0.1.19",
"@rjsf/core": "^3.0.0",
"@testing-library/cypress": "^7.0.1",
"@testing-library/jest-dom": "^5.10.1",
+1 -1
View File
@@ -83,7 +83,7 @@
window,
document,
'script',
'https://www.datadoghq-browser-agent.com/datadog-rum.js',
'https://www.datadoghq-browser-agent.com/datadog-rum-v3.js',
'DD_RUM',
);
DD_RUM.onReady(function () {
@@ -14,13 +14,17 @@
* limitations under the License.
*/
import React from 'react';
import { EntityLayout } from '@backstage/plugin-catalog';
import { EntityProvider } from '@backstage/plugin-catalog-react';
import { renderInTestApp } from '@backstage/test-utils';
import { cicdContent } from './EntityPage';
import { githubActionsApiRef } from '@backstage/plugin-github-actions';
import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { EntityLayout } from '@backstage/plugin-catalog';
import {
DefaultStarredEntitiesApi,
EntityProvider,
starredEntitiesApiRef,
} from '@backstage/plugin-catalog-react';
import { githubActionsApiRef } from '@backstage/plugin-github-actions';
import { MockStorageApi, renderInTestApp } from '@backstage/test-utils';
import React from 'react';
import { cicdContent } from './EntityPage';
describe('EntityPage Test', () => {
const entity = {
@@ -48,7 +52,10 @@ describe('EntityPage Test', () => {
downloadJobLogsForWorkflowRun: jest.fn(),
} as jest.Mocked<typeof githubActionsApiRef.T>;
const apis = ApiRegistry.with(githubActionsApiRef, mockedApi);
const apis = ApiRegistry.with(githubActionsApiRef, mockedApi).with(
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({ storageApi: MockStorageApi.create() }),
);
describe('cicdContent', () => {
it('Should render GitHub Actions View', async () => {
@@ -33,6 +33,10 @@ import {
EntityProvidedApisCard,
EntityProvidingComponentsCard,
} from '@backstage/plugin-api-docs';
import {
EntityAzurePipelinesContent,
isAzureDevOpsAvailable,
} from '@backstage/plugin-azure-devops';
import { EntityBadgesDialog } from '@backstage/plugin-badges';
import {
EntityAboutCard,
@@ -183,6 +187,10 @@ export const cicdContent = (
<EntityGithubActionsContent />
</EntitySwitch.Case>
<EntitySwitch.Case if={isAzureDevOpsAvailable}>
<EntityAzurePipelinesContent defaultLimit={25} />
</EntitySwitch.Case>
<EntitySwitch.Case>
<EmptyState
title="No CI/CD available for this entity"
+27 -10
View File
@@ -14,26 +14,43 @@
* limitations under the License.
*/
import React from 'react';
import Grid from '@material-ui/core/Grid';
import {
HomePageRandomJoke,
ComponentAccordion,
ComponentTabs,
ComponentTab,
WelcomeTitle,
HeaderWorldClock,
ClockConfig,
} from '@backstage/plugin-home';
import {
Content,
Header,
Page,
HomepageTimer,
} from '@backstage/core-components';
import { Content, Header, Page } from '@backstage/core-components';
import { HomePageSearchBar } from '@backstage/plugin-search';
import Grid from '@material-ui/core/Grid';
import React from 'react';
const clockConfigs: ClockConfig[] = [
{
label: 'NYC',
timeZone: 'America/New_York',
},
{
label: 'UTC',
timeZone: 'UTC',
},
{
label: 'STO',
timeZone: 'Europe/Stockholm',
},
{
label: 'TYO',
timeZone: 'Asia/Tokyo',
},
];
export const HomePage = () => (
<Page themeId="home">
<Header title="Home">
<HomepageTimer />
<Header title={<WelcomeTitle />} pageTitleOverride="Home">
<HeaderWorldClock clockConfigs={clockConfigs} />
</Header>
<Content>
<Grid container spacing={3}>
+10
View File
@@ -1,5 +1,15 @@
# @backstage/backend-common
## 0.9.7
### Patch Changes
- be59619212: Add "rate limit exceeded" to error from GithubUrlReader if that is the cause of a read failure
- 36e67d2f24: Internal updates to apply more strict checks to throw errors.
- Updated dependencies
- @backstage/config-loader@0.7.0
- @backstage/errors@0.1.3
## 0.9.6
### Patch Changes
+1 -1
View File
@@ -18,7 +18,7 @@ import { GithubCredentialsProvider } from '@backstage/integration';
import { GitHubIntegration } from '@backstage/integration';
import { GitLabIntegration } from '@backstage/integration';
import { isChildPath } from '@backstage/cli-common';
import { JsonValue } from '@backstage/config';
import { JsonValue } from '@backstage/types';
import { Knex } from 'knex';
import { Logger as Logger_2 } from 'winston';
import { MergeResult } from 'isomorphic-git';
+5 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-common",
"description": "Common functionality library for Backstage backends",
"version": "0.9.6",
"version": "0.9.7",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -31,9 +31,10 @@
"dependencies": {
"@backstage/cli-common": "^0.1.4",
"@backstage/config": "^0.1.10",
"@backstage/config-loader": "^0.6.10",
"@backstage/errors": "^0.1.2",
"@backstage/config-loader": "^0.7.0",
"@backstage/errors": "^0.1.3",
"@backstage/integration": "^0.6.7",
"@backstage/types": "^0.1.1",
"@google-cloud/storage": "^5.8.0",
"@octokit/rest": "^18.5.3",
"@types/cors": "^2.8.6",
@@ -77,7 +78,7 @@
}
},
"devDependencies": {
"@backstage/cli": "^0.7.15",
"@backstage/cli": "^0.8.0",
"@backstage/test-utils": "^0.1.18",
"@types/archiver": "^5.1.0",
"@types/compression": "^1.7.0",
+1 -1
View File
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { JsonValue } from '@backstage/config';
import { JsonValue } from '@backstage/types';
import { createHash } from 'crypto';
import Keyv from 'keyv';
+2 -1
View File
@@ -18,7 +18,8 @@ import { resolve as resolvePath } from 'path';
import parseArgs from 'minimist';
import { Logger } from 'winston';
import { findPaths } from '@backstage/cli-common';
import { Config, ConfigReader, JsonValue } from '@backstage/config';
import { Config, ConfigReader } from '@backstage/config';
import { JsonValue } from '@backstage/types';
import { loadConfig } from '@backstage/config-loader';
export class ObservableConfigProxy implements Config {
@@ -15,7 +15,8 @@
*/
import { Knex } from 'knex';
import { omit } from 'lodash';
import { Config, ConfigReader, JsonObject } from '@backstage/config';
import { Config, ConfigReader } from '@backstage/config';
import { JsonObject } from '@backstage/types';
import {
createDatabaseClient,
ensureDatabaseExists,
@@ -14,7 +14,8 @@
* limitations under the License.
*/
import { Config, JsonObject } from '@backstage/config';
import { Config } from '@backstage/config';
import { JsonObject } from '@backstage/types';
import { InputError } from '@backstage/errors';
import knexFactory, { Knex } from 'knex';
import { mergeDatabaseConfig } from './config';
@@ -17,6 +17,7 @@
import knexFactory, { Knex } from 'knex';
import { Config } from '@backstage/config';
import { ForwardedError } from '@backstage/errors';
import { mergeDatabaseConfig } from '../config';
import { DatabaseConnector } from '../types';
import defaultNameOverride from './defaultNameOverride';
@@ -94,8 +95,7 @@ function requirePgConnectionString() {
try {
return require('pg-connection-string').parse;
} catch (e) {
const message = `Postgres: Install 'pg-connection-string'`;
throw new Error(`${message}\n${e.message}`);
throw new ForwardedError("Postgres: Install 'pg-connection-string'", e);
}
}
@@ -13,7 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ConfigReader, JsonObject } from '@backstage/config';
import { ConfigReader } from '@backstage/config';
import { JsonObject } from '@backstage/types';
import { getVoidLogger } from '../logging';
import { DefaultReadTreeResponseFactory } from './tree';
import { AwsS3UrlReader } from './AwsS3UrlReader';
@@ -135,13 +137,7 @@ describe('AwsS3UrlReader', () => {
'getObject',
Buffer.from(
require('fs').readFileSync(
path.resolve(
'src',
'reading',
'__fixtures__',
'awsS3',
'awsS3-mock-object.yaml',
),
path.resolve(__dirname, '__fixtures__/awsS3/awsS3-mock-object.yaml'),
),
),
);
@@ -173,7 +169,7 @@ describe('AwsS3UrlReader', () => {
),
).rejects.toThrow(
Error(
`Could not retrieve file from S3: not a valid AWS S3 URL: https://test-bucket.s3.us-east-2.NOTamazonaws.com/file.yaml`,
`Could not retrieve file from S3; caused by Error: not a valid AWS S3 URL: https://test-bucket.s3.us-east-2.NOTamazonaws.com/file.yaml`,
),
);
});
@@ -187,13 +183,7 @@ describe('AwsS3UrlReader', () => {
'getObject',
Buffer.from(
require('fs').readFileSync(
path.resolve(
'src',
'reading',
'__fixtures__',
'awsS3',
'awsS3-mock-object.yaml',
),
path.resolve(__dirname, '__fixtures__/awsS3/awsS3-mock-object.yaml'),
),
),
);
@@ -228,7 +218,7 @@ describe('AwsS3UrlReader', () => {
),
).rejects.toThrow(
Error(
`Could not retrieve file from S3: not a valid AWS S3 URL: https://test-bucket.s3.us-east-2.NOTamazonaws.com/file.yaml`,
`Could not retrieve file from S3; caused by Error: not a valid AWS S3 URL: https://test-bucket.s3.us-east-2.NOTamazonaws.com/file.yaml`,
),
);
});
@@ -249,13 +239,7 @@ describe('AwsS3UrlReader', () => {
'getObject',
Buffer.from(
require('fs').readFileSync(
path.resolve(
'src',
'reading',
'__fixtures__',
'awsS3',
'awsS3-mock-object.yaml',
),
path.resolve(__dirname, '__fixtures__/awsS3/awsS3-mock-object.yaml'),
),
),
);
@@ -27,6 +27,7 @@ import {
} from './types';
import getRawBody from 'raw-body';
import { AwsS3Integration, ScmIntegrations } from '@backstage/integration';
import { ForwardedError } from '@backstage/errors';
import { ListObjectsV2Output, ObjectList } from 'aws-sdk/clients/s3';
const parseURL = (
@@ -162,7 +163,7 @@ export class AwsS3UrlReader implements UrlReader {
etag: etag,
};
} catch (e) {
throw new Error(`Could not retrieve file from S3: ${e.message}`);
throw new ForwardedError('Could not retrieve file from S3', e);
}
}
@@ -203,7 +204,7 @@ export class AwsS3UrlReader implements UrlReader {
return await this.deps.treeResponseFactory.fromReadableArray(responses);
} catch (e) {
throw new Error(`Could not retrieve file tree from S3: ${e.message}`);
throw new ForwardedError('Could not retrieve file tree from S3', e);
}
}
@@ -152,7 +152,7 @@ describe('AzureUrlReader', () => {
describe('readTree', () => {
const repoBuffer = fs.readFileSync(
path.resolve('src', 'reading', '__fixtures__', 'mock-main.zip'),
path.resolve(__dirname, '__fixtures__/mock-main.zip'),
);
const processor = new AzureUrlReader(
@@ -264,7 +264,7 @@ describe('AzureUrlReader', () => {
describe('search', () => {
const repoBuffer = fs.readFileSync(
path.resolve('src', 'reading', '__fixtures__', 'mock-main.zip'),
path.resolve(__dirname, '__fixtures__/mock-main.zip'),
);
const processor = new AzureUrlReader(
@@ -104,20 +104,13 @@ describe('BitbucketUrlReader', () => {
describe('readTree', () => {
const repoBuffer = fs.readFileSync(
path.resolve(
'src',
'reading',
'__fixtures__',
'bitbucket-repo-with-commit-hash.tar.gz',
__dirname,
'__fixtures__/bitbucket-repo-with-commit-hash.tar.gz',
),
);
const privateBitbucketRepoBuffer = fs.readFileSync(
path.resolve(
'src',
'reading',
'__fixtures__',
'bitbucket-server-repo.tar.gz',
),
path.resolve(__dirname, '__fixtures__/bitbucket-server-repo.tar.gz'),
);
beforeEach(() => {
@@ -298,10 +291,8 @@ describe('BitbucketUrlReader', () => {
describe('search hosted', () => {
const repoBuffer = fs.readFileSync(
path.resolve(
'src',
'reading',
'__fixtures__',
'bitbucket-repo-with-commit-hash.tar.gz',
__dirname,
'__fixtures__/bitbucket-repo-with-commit-hash.tar.gz',
),
);
@@ -386,12 +377,7 @@ describe('BitbucketUrlReader', () => {
describe('search private', () => {
const privateBitbucketRepoBuffer = fs.readFileSync(
path.resolve(
'src',
'reading',
'__fixtures__',
'bitbucket-server-repo.tar.gz',
),
path.resolve(__dirname, '__fixtures__/bitbucket-server-repo.tar.gz'),
);
beforeEach(() => {
@@ -221,6 +221,32 @@ describe('GithubUrlReader', () => {
).rejects.toThrow(NotModifiedError);
});
it('should throw Error with ratelimit exceeded if GitHub responds with 403 and rate limit is exceeded', async () => {
expect.assertions(1);
worker.use(
rest.get(
'https://ghe.github.com/api/v3/repos/backstage/mock/tree/contents/',
(_req, res, ctx) => {
return res(
ctx.status(403),
ctx.set('X-RateLimit-Remaining', '0'),
ctx.body(
'{"message": "API rate limit exceeded for xxx.xxx.xxx.xxx..."}',
),
);
},
),
);
await expect(
gheProcessor.readUrl(
'https://github.com/backstage/mock/tree/blob/main',
{ etag: 'foo' },
),
).rejects.toThrow(/rate limit exceeded/);
});
it('should return etag from the response', async () => {
(mockCredentialsProvider.getCredentials as jest.Mock).mockResolvedValue({
headers: {
@@ -254,12 +280,7 @@ describe('GithubUrlReader', () => {
describe('readTree', () => {
const repoBuffer = fs.readFileSync(
path.resolve(
'src',
'reading',
'__fixtures__',
'backstage-mock-etag123.tar.gz',
),
path.resolve(__dirname, '__fixtures__/backstage-mock-etag123.tar.gz'),
);
const reposGithubApiResponse = {
@@ -540,12 +561,7 @@ describe('GithubUrlReader', () => {
describe('search', () => {
const repoBuffer = fs.readFileSync(
path.resolve(
'src',
'reading',
'__fixtures__',
'backstage-mock-etag123.tar.gz',
),
path.resolve(__dirname, '__fixtures__/backstage-mock-etag123.tar.gz'),
);
const githubTreeContents: GhTreeResponse['tree'] = [
@@ -126,10 +126,21 @@ export class GithubUrlReader implements UrlReader {
};
}
const message = `${url} could not be read as ${ghUrl}, ${response.status} ${response.statusText}`;
let message = `${url} could not be read as ${ghUrl}, ${response.status} ${response.statusText}`;
if (response.status === 404) {
throw new NotFoundError(message);
}
// GitHub returns a 403 response with a couple of headers indicating rate
// limit status. See more in the GitHub docs:
// https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting
if (
response.status === 403 &&
response.headers.get('X-RateLimit-Remaining') === '0'
) {
message += ' (rate limit exceeded)';
}
throw new Error(message);
}
@@ -223,7 +223,7 @@ describe('GitlabUrlReader', () => {
describe('readTree', () => {
const archiveBuffer = fs.readFileSync(
path.resolve('src', 'reading', '__fixtures__', 'gitlab-archive.tar.gz'),
path.resolve(__dirname, '__fixtures__/gitlab-archive.tar.gz'),
);
const projectGitlabApiResponse = {
@@ -495,7 +495,7 @@ describe('GitlabUrlReader', () => {
describe('search', () => {
const archiveBuffer = fs.readFileSync(
path.resolve('src', 'reading', '__fixtures__', 'gitlab-archive.tar.gz'),
path.resolve(__dirname, '__fixtures__/gitlab-archive.tar.gz'),
);
const projectGitlabApiResponse = {
@@ -14,7 +14,8 @@
* limitations under the License.
*/
import { ConfigReader, JsonObject } from '@backstage/config';
import { ConfigReader } from '@backstage/config';
import { JsonObject } from '@backstage/types';
import { getVoidLogger } from '../logging';
import { DefaultReadTreeResponseFactory } from './tree';
import { GoogleGcsUrlReader } from './GoogleGcsUrlReader';
@@ -15,6 +15,7 @@
*/
import { ConfigReader } from '@backstage/config';
import { isError } from '@backstage/errors';
import { getVoidLogger } from '../logging';
import { UrlReaders } from './UrlReaders';
@@ -71,7 +72,10 @@ function withRetries(count: number, fn: () => Promise<void>) {
error = err;
}
}
if (!error.message.match(/rate limit|Too Many Requests/)) {
if (
isError(error) &&
!error.message.match(/rate limit|Too Many Requests/)
) {
throw error;
} else {
console.warn('Request was rate limited', error);
@@ -16,6 +16,7 @@
import Docker from 'dockerode';
import fs from 'fs-extra';
import { ForwardedError } from '@backstage/errors';
import { PassThrough } from 'stream';
import { ContainerRunner, RunContainerOptions } from './ContainerRunner';
@@ -45,8 +46,9 @@ export class DockerContainerRunner implements ContainerRunner {
try {
await this.dockerClient.ping();
} catch (e) {
throw new Error(
`This operation requires Docker. Docker does not appear to be available. Docker.ping() failed with: ${e.message}`,
throw new ForwardedError(
'This operation requires Docker. Docker does not appear to be available. Docker.ping() failed with',
e,
);
}
+8
View File
@@ -1,5 +1,13 @@
# @backstage/backend-test-utils
## 0.1.8
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.9.7
- @backstage/cli@0.8.0
## 0.1.7
### Patch Changes
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-test-utils",
"description": "Test helpers library for Backstage backends",
"version": "0.1.7",
"version": "0.1.8",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -30,8 +30,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.9.2",
"@backstage/cli": "^0.7.11",
"@backstage/backend-common": "^0.9.7",
"@backstage/cli": "^0.8.0",
"@backstage/config": "^0.1.9",
"knex": "^0.95.1",
"mysql2": "^2.2.5",
@@ -41,7 +41,7 @@
"uuid": "^8.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.7.11",
"@backstage/cli": "^0.8.0",
"jest": "^26.0.1"
},
"files": [
+14
View File
@@ -1,5 +1,19 @@
# example-backend
## 0.2.50
### Patch Changes
- Updated dependencies
- @backstage/plugin-auth-backend@0.4.4
- @backstage/integration@0.6.8
- @backstage/plugin-scaffolder-backend@0.15.8
- @backstage/plugin-catalog-backend@0.17.0
- @backstage/plugin-azure-devops-backend@0.1.2
- @backstage/plugin-code-coverage-backend@0.1.13
- @backstage/plugin-kubernetes-backend@0.3.17
- example-app@0.2.50
## 0.2.49
### Patch Changes
+14 -14
View File
@@ -1,6 +1,6 @@
{
"name": "example-backend",
"version": "0.2.49",
"version": "0.2.50",
"main": "dist/index.cjs.js",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -24,36 +24,36 @@
"migrate:create": "knex migrate:make -x ts"
},
"dependencies": {
"@backstage/backend-common": "^0.9.6",
"@backstage/backend-common": "^0.9.7",
"@backstage/catalog-client": "^0.5.0",
"@backstage/catalog-model": "^0.9.4",
"@backstage/catalog-model": "^0.9.5",
"@backstage/config": "^0.1.10",
"@backstage/integration": "^0.6.7",
"@backstage/plugin-app-backend": "^0.3.16",
"@backstage/plugin-auth-backend": "^0.4.3",
"@backstage/plugin-azure-devops-backend": "^0.1.1",
"@backstage/integration": "^0.6.8",
"@backstage/plugin-app-backend": "^0.3.17",
"@backstage/plugin-auth-backend": "^0.4.5",
"@backstage/plugin-azure-devops-backend": "^0.1.3",
"@backstage/plugin-badges-backend": "^0.1.11",
"@backstage/plugin-catalog-backend": "^0.16.0",
"@backstage/plugin-code-coverage-backend": "^0.1.12",
"@backstage/plugin-catalog-backend": "^0.17.1",
"@backstage/plugin-code-coverage-backend": "^0.1.14",
"@backstage/plugin-graphql-backend": "^0.1.9",
"@backstage/plugin-jenkins-backend": "^0.1.6",
"@backstage/plugin-kubernetes-backend": "^0.3.16",
"@backstage/plugin-kubernetes-backend": "^0.3.18",
"@backstage/plugin-kafka-backend": "^0.2.10",
"@backstage/plugin-proxy-backend": "^0.2.13",
"@backstage/plugin-rollbar-backend": "^0.1.15",
"@backstage/plugin-scaffolder-backend": "^0.15.7",
"@backstage/plugin-scaffolder-backend": "^0.15.10",
"@backstage/plugin-scaffolder-backend-module-rails": "^0.1.5",
"@backstage/plugin-search-backend": "^0.2.6",
"@backstage/plugin-search-backend-node": "^0.4.2",
"@backstage/plugin-search-backend-module-elasticsearch": "^0.0.4",
"@backstage/plugin-search-backend-module-pg": "^0.2.1",
"@backstage/plugin-techdocs-backend": "^0.10.4",
"@backstage/plugin-techdocs-backend": "^0.10.5",
"@backstage/plugin-todo-backend": "^0.1.13",
"@gitbeaker/node": "^30.2.0",
"@octokit/rest": "^18.5.3",
"azure-devops-node-api": "^11.0.1",
"dockerode": "^3.2.1",
"example-app": "^0.2.49",
"example-app": "^0.2.51",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
"express-prom-bundle": "^6.3.6",
@@ -65,7 +65,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/cli": "^0.7.15",
"@backstage/cli": "^0.8.0",
"@types/dockerode": "^3.2.1",
"@types/express": "^4.17.6",
"@types/express-serve-static-core": "^4.17.5"
+1 -1
View File
@@ -38,7 +38,7 @@ import { Config } from '@backstage/config';
import healthcheck from './plugins/healthcheck';
import { metricsInit, metricsHandler } from './metrics';
import auth from './plugins/auth';
import azureDevOps from './plugins/azuredevops';
import azureDevOps from './plugins/azure-devops';
import catalog from './plugins/catalog';
import codeCoverage from './plugins/codecoverage';
import kubernetes from './plugins/kubernetes';

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