Merge branch 'master' of github.com:backstage/backstage into RoadieHQ-5identity-api-client-interface
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
---
|
||||
'@backstage/app-defaults': patch
|
||||
'@backstage/core-app-api': patch
|
||||
'@backstage/core-components': patch
|
||||
'@backstage/core-plugin-api': patch
|
||||
'@backstage/dev-utils': patch
|
||||
'@backstage/test-utils': patch
|
||||
'@backstage/plugin-adr': patch
|
||||
'@backstage/plugin-airbrake': patch
|
||||
'@backstage/plugin-allure': patch
|
||||
'@backstage/plugin-api-docs': patch
|
||||
'@backstage/plugin-azure-devops': patch
|
||||
'@backstage/plugin-badges': patch
|
||||
'@backstage/plugin-bazaar': patch
|
||||
'@backstage/plugin-catalog-graph': patch
|
||||
'@backstage/plugin-catalog-import': patch
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
'@backstage/plugin-catalog': patch
|
||||
'@backstage/plugin-circleci': patch
|
||||
'@backstage/plugin-cloudbuild': patch
|
||||
'@backstage/plugin-code-climate': patch
|
||||
'@backstage/plugin-code-coverage': patch
|
||||
'@backstage/plugin-codescene': patch
|
||||
'@backstage/plugin-cost-insights': patch
|
||||
'@backstage/plugin-explore': patch
|
||||
'@backstage/plugin-gcp-projects': patch
|
||||
'@backstage/plugin-git-release-manager': patch
|
||||
'@backstage/plugin-github-actions': patch
|
||||
'@backstage/plugin-gitops-profiles': patch
|
||||
'@backstage/plugin-graphiql': patch
|
||||
'@backstage/plugin-home': patch
|
||||
'@backstage/plugin-jenkins': patch
|
||||
'@backstage/plugin-kafka': patch
|
||||
'@backstage/plugin-kubernetes': patch
|
||||
'@backstage/plugin-lighthouse': patch
|
||||
'@backstage/plugin-org': patch
|
||||
'@backstage/plugin-pagerduty': patch
|
||||
'@backstage/plugin-permission-react': patch
|
||||
'@backstage/plugin-rollbar': patch
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
'@backstage/plugin-search-react': patch
|
||||
'@backstage/plugin-search': patch
|
||||
'@backstage/plugin-sentry': patch
|
||||
'@backstage/plugin-shortcuts': patch
|
||||
'@backstage/plugin-splunk-on-call': patch
|
||||
'@backstage/plugin-tech-insights': patch
|
||||
'@backstage/plugin-techdocs-addons-test-utils': patch
|
||||
'@backstage/plugin-techdocs-react': patch
|
||||
'@backstage/plugin-techdocs': patch
|
||||
'@backstage/plugin-todo': patch
|
||||
'@backstage/plugin-user-settings': patch
|
||||
---
|
||||
|
||||
Updated React Router dependencies to be peer dependencies.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend-module-msgraph': patch
|
||||
---
|
||||
|
||||
Fixed a bug in the `MicrosoftGraphEntityProvider` that ignored the `userExpand` and `groupExpand` configuration parameters
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-auth-node': patch
|
||||
'@backstage/plugin-permission-node': patch
|
||||
---
|
||||
|
||||
Minor update to tests
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/test-utils': minor
|
||||
---
|
||||
|
||||
Elements rendered in a test app are no longer wrapped in a `Routes` and `Route` element, as this is not compatible with React Router v6 stable.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-adr-backend': patch
|
||||
---
|
||||
|
||||
Continue processing subsequent entities when an error occurs in collator
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-stack-overflow-backend': patch
|
||||
---
|
||||
|
||||
Now requests all questions available using pagination. Default max page is set to 100, with a configurable `maxPage` option on the collator.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/backend-common': patch
|
||||
---
|
||||
|
||||
Added a keep-alive refresh loop to the `DatabaseManager`, keeping the connection
|
||||
pool up.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/backend-common': patch
|
||||
---
|
||||
|
||||
The options part of `DatabaseManager.fromConfig` now accepts an optional logger
|
||||
field.
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
'@backstage/plugin-cloudbuild': patch
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
'@backstage/plugin-tech-insights': patch
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
Internal refactor to use more type safe code when dealing with route parameters.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend': minor
|
||||
---
|
||||
|
||||
Allow unknown typed location from being registered via the location service by configuration settings
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/create-app': patch
|
||||
---
|
||||
|
||||
The Backstage packages and plugins have all been updated to support React Router v6 stable. The `create-app` template has not been migrated yet, but if you want to migrate your own app or plugins, check out the [migration guide](https://backstage.io/docs/tutorials/react-router-stable-migration).
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
---
|
||||
|
||||
Fixing bug when the workspace would not be automatically saved when using `allowedOwners`
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend': minor
|
||||
---
|
||||
|
||||
The search index now does retain fields that have a very long value, but in the form of just a null. This makes it possible to at least filter for their existence.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-app-api': minor
|
||||
---
|
||||
|
||||
Updated the routing system to be compatible with React Router v6 stable.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend': minor
|
||||
---
|
||||
|
||||
Added `projectId` for gitlab projects to be displayed in the `gitlab:publish` output
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend': patch
|
||||
---
|
||||
|
||||
Fixes a bug to be able to utilize refresh keys after the entity is loaded from cache
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Added a new `migrate react-router-deps` command to aid in the migration to React Router v6 stable.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-search-backend-node': patch
|
||||
---
|
||||
|
||||
Fixed bug in LunrSearchEngine where stopwords in title is causing in-doc search not working
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
'@backstage/plugin-airbrake-backend': patch
|
||||
'@backstage/plugin-catalog-backend-module-bitbucket-server': patch
|
||||
'@backstage/plugin-dynatrace': patch
|
||||
'@backstage/plugin-periskop-backend': patch
|
||||
'@backstage/plugin-stack-overflow-backend': patch
|
||||
'@backstage/plugin-vault-backend': patch
|
||||
---
|
||||
|
||||
Switched to using node-fetch instead of cross-fetch as is standard for our backend packages
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
---
|
||||
|
||||
Properly handle free-text entity filtering in the case of empty tag arrays
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
'@backstage/plugin-tech-insights': minor
|
||||
---
|
||||
|
||||
Added the possibility to display check results of different types on a single scorecard.
|
||||
|
||||
- **BREAKING** Removed the `getScorecardsDefinition` method from the `TechInsightsApi` interface. Added the `getCheckResultRenderers` method that returns rendering components for given types.
|
||||
- **BREAKING** The `CheckResultRenderer` type now exposes the `component` factory method that creates a React component used to display a result of a provided check result.
|
||||
- The `TechInsightsClient` constructor accepts now the optional `renderers` parameter that can be used to inject a custom renderer.
|
||||
- **BREAKING** The `title` parameter in the `EntityTechInsightsScorecardContent` and `EntityTechInsightsScorecardCard` components is now mandatory.
|
||||
- The `jsonRulesEngineCheckResultRenderer` used to render `json-rules-engine` check results is exported.
|
||||
- The `BooleanCheck` component that can be used to render other check results types is also exported.
|
||||
|
||||
If you were overriding the `getScorecardsDefinition` method to adjust the rendering of check results, you should now provide a custom renderer using `renderers` parameter in the `TechInsightsClient` class.
|
||||
|
||||
See the [README](https://github.com/backstage/backstage/tree/master/plugins/tech-insights/README.md) for more details.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
---
|
||||
|
||||
Applied the fix from version 1.5.1 of this package, which is part of the v1.5.1 release of Backstage.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend-module-ldap': patch
|
||||
---
|
||||
|
||||
Added ae-dir LDAP vendor to correctly extract DN.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
Updated the `TechDocsReaderPage` to be compatible with React Router v6 stable.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
---
|
||||
|
||||
The `RoutedTabs` component has been updated to be compatible with React Router v6 stable.
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@backstage/plugin-permission-react': patch
|
||||
---
|
||||
|
||||
**DEPRECATION**: The `PermissionedRoute` component has been deprecated in favor of the new `RequirePermission` component. This is because the usage pattern of `PermissionedRoute` is not compatible with React Router v6 stable.
|
||||
|
||||
Embed the type from `react-router` instead of exporting it directly.
|
||||
@@ -172,44 +172,87 @@
|
||||
"@backstage/plugin-xcmetrics": "0.2.28"
|
||||
},
|
||||
"changesets": [
|
||||
"afraid-horses-lick",
|
||||
"afraid-radios-boil",
|
||||
"beige-monkeys-add",
|
||||
"beige-pumas-tap",
|
||||
"big-dolls-reflect",
|
||||
"big-teachers-tell",
|
||||
"blue-snakes-compete",
|
||||
"clever-beans-turn",
|
||||
"cold-frogs-kiss",
|
||||
"curly-hounds-wait",
|
||||
"dry-games-end",
|
||||
"eight-spies-protect",
|
||||
"eleven-bees-marry",
|
||||
"famous-hounds-sit",
|
||||
"famous-wombats-happen",
|
||||
"five-carrots-pay",
|
||||
"flat-plums-shout",
|
||||
"flat-walls-kiss",
|
||||
"fresh-rabbits-juggle",
|
||||
"funny-hounds-obey",
|
||||
"funny-years-speak",
|
||||
"gold-hounds-vanish",
|
||||
"good-avocados-grow",
|
||||
"good-papayas-dress",
|
||||
"gorgeous-swans-kiss",
|
||||
"great-cats-sit",
|
||||
"grumpy-kiwis-juggle",
|
||||
"happy-kiwis-look",
|
||||
"heavy-ligers-laugh",
|
||||
"hot-files-begin",
|
||||
"hot-suits-glow",
|
||||
"hungry-dogs-agree",
|
||||
"large-eagles-shop",
|
||||
"large-trainers-float",
|
||||
"lazy-snakes-film",
|
||||
"light-beans-share",
|
||||
"loud-comics-search",
|
||||
"lovely-ants-invite",
|
||||
"lucky-points-wash",
|
||||
"many-rules-raise",
|
||||
"mean-tomatoes-visit",
|
||||
"metal-crabs-wash",
|
||||
"nervous-rivers-sneeze",
|
||||
"old-lemons-switch",
|
||||
"old-tables-joke",
|
||||
"popular-shirts-happen",
|
||||
"red-numbers-suffer",
|
||||
"renovate-16f36a0",
|
||||
"renovate-4f0c2e3",
|
||||
"renovate-58c2860",
|
||||
"renovate-7d3b357",
|
||||
"renovate-c98c336",
|
||||
"renovate-f18a0fc",
|
||||
"rich-cooks-camp",
|
||||
"rich-melons-compete",
|
||||
"rotten-books-crash",
|
||||
"rude-books-rush",
|
||||
"shaggy-chicken-behave",
|
||||
"shaggy-vans-repeat",
|
||||
"sharp-swans-suffer",
|
||||
"shiny-lobsters-fix",
|
||||
"silent-kings-live",
|
||||
"slimy-zebras-reply",
|
||||
"small-lemons-brake",
|
||||
"small-walls-promise",
|
||||
"smooth-yaks-hug",
|
||||
"spicy-cherries-remember",
|
||||
"strong-games-kiss",
|
||||
"strong-planes-return",
|
||||
"sweet-fishes-taste",
|
||||
"tall-trains-remain",
|
||||
"tame-papayas-protect",
|
||||
"techdocs-jeans-wait",
|
||||
"tender-ladybugs-relax",
|
||||
"tiny-oranges-thank",
|
||||
"tough-dolphins-smile",
|
||||
"two-planets-provide",
|
||||
"weak-yaks-learn",
|
||||
"wild-sheep-roll",
|
||||
"witty-cats-wink",
|
||||
"witty-queens-happen",
|
||||
"young-trees-rescue"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
'@backstage/backend-common': patch
|
||||
'@backstage/plugin-app-backend': patch
|
||||
'@backstage/plugin-graphql-backend': patch
|
||||
'@backstage/plugin-kubernetes-backend': patch
|
||||
'@backstage/plugin-vault-backend': patch
|
||||
---
|
||||
|
||||
Updated dependency `helmet` to `^6.0.0`.
|
||||
|
||||
Please note that these policies are no longer applied by default:
|
||||
|
||||
helmet.contentSecurityPolicy no longer sets block-all-mixed-content directive by default
|
||||
helmet.expectCt is no longer set by default. It can, however, be explicitly enabled. It will be removed in Helmet 7.
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
'@backstage/cli': minor
|
||||
---
|
||||
|
||||
Updated dependency `eslint-plugin-jest` to `^27.0.0`.
|
||||
|
||||
Note that this major update to the Jest plugin contains some breaking changes.
|
||||
This means that some of your tests may start seeing some new lint errors. [Read
|
||||
about them
|
||||
here](https://github.com/jest-community/eslint-plugin-jest/blob/main/CHANGELOG.md#2700-2022-08-28).
|
||||
|
||||
These are mostly possible to fix automatically. You can try to run `yarn backstage-cli repo lint --fix` in your repo root to have most or all of them
|
||||
corrected.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-jenkins-backend': patch
|
||||
---
|
||||
|
||||
Updated dependency `jenkins` to `^1.0.0`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Updated dependency `@types/minimatch` to `^5.0.0`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-gcalendar': patch
|
||||
---
|
||||
|
||||
Upgrade `react-query:3` to `@tanstack/react-query:4`
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
'@backstage/create-app': patch
|
||||
---
|
||||
|
||||
The options part of `DatabaseManager.fromConfig` now accepts an optional logger
|
||||
field. You may want to supply that logger in your backend initialization code to
|
||||
ensure that you can get relevant logging data when things happen related to the
|
||||
connection pool.
|
||||
|
||||
In `packages/backend/src/index.ts`:
|
||||
|
||||
```diff
|
||||
function makeCreateEnv(config: Config) {
|
||||
const root = getRootLogger();
|
||||
...
|
||||
- const databaseManager = DatabaseManager.fromConfig(config);
|
||||
+ const databaseManager = DatabaseManager.fromConfig(config, { logger: root });
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-stack-overflow': patch
|
||||
---
|
||||
|
||||
Create a front end API.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend': patch
|
||||
---
|
||||
|
||||
Include entity ref into error message when catalog policies fail
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-tech-insights-backend': patch
|
||||
---
|
||||
|
||||
Changed the description of the `techdocsAnnotationFactName` fact.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend-module-github': patch
|
||||
---
|
||||
|
||||
Added the ability to configure the host for the `GitHubEntityProvider` to use against GitHub Enterprise
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-github-pull-requests-board': patch
|
||||
---
|
||||
|
||||
Add optional `pullRequestLimit` prop to `EntityTeamPullRequestsCard` and `EntityTeamPullRequestsContent` to limit the number of PRs shown per repository. Excluding this prop will default the number of pull requests shown to 10 per repository (the existing functionality).
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-app-api': patch
|
||||
---
|
||||
|
||||
Updated `FlatRoutes` to be compatible with React Router v6 stable.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-stack-overflow': patch
|
||||
---
|
||||
|
||||
Support showing HTML entity references from the API response before rendering the question title to the list component.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-adr': patch
|
||||
---
|
||||
|
||||
Fix parsing of ADR location which includes a trailing slash
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
registry-url: https://registry.npmjs.org/ # Needed for auth
|
||||
|
||||
- name: yarn install
|
||||
uses: backstage/actions/yarn-install@v0.5.3
|
||||
uses: backstage/actions/yarn-install@v0.5.5
|
||||
with:
|
||||
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
|
||||
|
||||
@@ -63,7 +63,7 @@ jobs:
|
||||
registry-url: https://registry.npmjs.org/ # Needed for auth
|
||||
|
||||
- name: yarn install
|
||||
uses: backstage/actions/yarn-install@v0.5.3
|
||||
uses: backstage/actions/yarn-install@v0.5.5
|
||||
with:
|
||||
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
|
||||
|
||||
@@ -181,7 +181,7 @@ jobs:
|
||||
registry-url: https://registry.npmjs.org/ # Needed for auth
|
||||
|
||||
- name: yarn install
|
||||
uses: backstage/actions/yarn-install@v0.5.3
|
||||
uses: backstage/actions/yarn-install@v0.5.5
|
||||
with:
|
||||
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ jobs:
|
||||
cron:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: backstage/actions/cron@v0.5.3
|
||||
- uses: backstage/actions/cron@v0.5.5
|
||||
with:
|
||||
app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }}
|
||||
private-key: ${{ secrets.BACKSTAGE_GOALIE_PRIVATE_KEY }}
|
||||
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
registry-url: https://registry.npmjs.org/ # Needed for auth
|
||||
- name: yarn install
|
||||
uses: backstage/actions/yarn-install@v0.5.3
|
||||
uses: backstage/actions/yarn-install@v0.5.5
|
||||
with:
|
||||
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
registry-url: https://registry.npmjs.org/ # Needed for auth
|
||||
- name: yarn install
|
||||
uses: backstage/actions/yarn-install@v0.5.3
|
||||
uses: backstage/actions/yarn-install@v0.5.5
|
||||
with:
|
||||
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
|
||||
|
||||
@@ -145,7 +145,7 @@ jobs:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
registry-url: https://registry.npmjs.org/ # Needed for auth
|
||||
- name: yarn install
|
||||
uses: backstage/actions/yarn-install@v0.5.3
|
||||
uses: backstage/actions/yarn-install@v0.5.5
|
||||
with:
|
||||
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
|
||||
|
||||
|
||||
@@ -10,4 +10,4 @@ jobs:
|
||||
if: github.repository == 'backstage/backstage'
|
||||
steps:
|
||||
- name: Issue sync
|
||||
uses: backstage/actions/issue-sync@v0.5.3
|
||||
uses: backstage/actions/issue-sync@v0.5.5
|
||||
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
const prNumber = artifact.name.slice('pr_number-'.length)
|
||||
console.log(`::set-output name=pr-number::${prNumber}`);
|
||||
|
||||
- uses: backstage/actions/re-review@v0.5.3
|
||||
- uses: backstage/actions/re-review@v0.5.5
|
||||
with:
|
||||
app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }}
|
||||
private-key: ${{ secrets.BACKSTAGE_GOALIE_PRIVATE_KEY }}
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
if: github.repository == 'backstage/backstage' && ( github.event.pull_request || github.event.issue.pull_request )
|
||||
steps:
|
||||
- name: PR sync
|
||||
uses: backstage/actions/pr-sync@v0.5.3
|
||||
uses: backstage/actions/pr-sync@v0.5.5
|
||||
with:
|
||||
github-token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }}
|
||||
app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }}
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
registry-url: https://registry.npmjs.org/ # Needed for auth
|
||||
- name: yarn install
|
||||
uses: backstage/actions/yarn-install@v0.5.3
|
||||
uses: backstage/actions/yarn-install@v0.5.5
|
||||
with:
|
||||
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
registry-url: https://registry.npmjs.org/ # Needed for auth
|
||||
- name: yarn install
|
||||
uses: backstage/actions/yarn-install@v0.5.3
|
||||
uses: backstage/actions/yarn-install@v0.5.5
|
||||
with:
|
||||
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
registry-url: https://registry.npmjs.org/ # Needed for auth
|
||||
- name: yarn install
|
||||
uses: backstage/actions/yarn-install@v0.5.3
|
||||
uses: backstage/actions/yarn-install@v0.5.5
|
||||
with:
|
||||
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
registry-url: https://registry.npmjs.org/ # Needed for auth
|
||||
- name: yarn install
|
||||
uses: backstage/actions/yarn-install@v0.5.3
|
||||
uses: backstage/actions/yarn-install@v0.5.5
|
||||
with:
|
||||
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
|
||||
- name: storybook yarn install
|
||||
|
||||
+4
-2
@@ -171,7 +171,7 @@ _You can do this by using the [Adopter form](https://form.typeform.com/to/zcOaKi
|
||||
| [AEB](https://www.aeb.com/) | [David Fankhänel](mailto:dfl@aeb.com) | Central developer platform for creating new apps via templates, getting an overview via software catalog, etc |
|
||||
| [SALTO Systems](https://saltosystems.com) | [Ian Cowley](mailto:i.cowley@saltosystems.com) | Currently using Backstage as an internal documentation portal. |
|
||||
| [Lummo](https://lummo.com) | [Anjul Sahu](mailto:anjul@lummo.com) | We are building the internal developer portal using Backstage and bringing up all integrations and service information at one place. |
|
||||
| [Frontside](https://frontside.com) | [Taras Mankovski](mailto:taras@frontside.com) | |
|
||||
| [Frontside](https://frontside.com/backstage) | [Taras Mankovski](mailto:taras@frontside.com) | An active community member and contributor, Frontside offers both custom development as well as enterprise support services to help teams get the most out of Backstage for the long-run. |
|
||||
| [Stepstone](https://www.stepstone.com/en/) | [Neil Kennedy](mailto:neil.kennedy@stepstone.com) | StepStone is using Backstage to solve problems around ownership and visibility of our applications. We have thousands of repos, multiple legacy systems and a growing platform that is hard to maintain. Backstage is forming the centre of our push to embrace the chaos. |
|
||||
| [idwall](https://idwall.co) | [Rodrigo Catão Araujo](mailto:rodrigo@idwall.co) | Developer Portal for internal engineers to access service catalog, documentation, observability, infrastructure and internal tooling. |
|
||||
| [Jaguar Land Rover](https://www.jaguarlandrover.com) | [Josh Walker](mailto:jwalke18@jaguarlandrover.com) | Users can request a Gitlab user, which creates a commit with the Terraform code. |
|
||||
@@ -207,4 +207,6 @@ _You can do this by using the [Adopter form](https://form.typeform.com/to/zcOaKi
|
||||
| [Fanatics](https://www.fanaticsinc.com/) | [Rory Scott](mailto:rscott@fanatics.com) | Internal Portal consolidating documentation, making it easier to manage applications, internal developer community platform, and self-service cloud infrastructure + pipelines. |
|
||||
| [Appfolio](https://appfolio.com) | [Andy Vaughn](mailto:andy.vaughn@appfolio.com) | Internal software catalog, tech radar, documentation portal to disambiguate software and domain ownership, foster exploration of available developer platform services and tools, improve communication, democratize documentation and knowledge sharing, and coordinate the software lifecycle; all in service of a best-in-class developer experience. |
|
||||
| [isaac](https://isaac.com.br/) | [Leonardo Borges](mailto:leonardo.borges@isaac.com.br), [Ordilei Souza](mailto:ordilei.souza@isaac.com.br) | We're using Backstage as our Internal Developer Portal and main microservices catalog for mapping ownership, health and metrics for each one. |
|
||||
| [Paraná Banco](https://site.paranabanco.com.br/) | [Joao Antunes](mailto:joaopma@pbtech.net.br) | Internal software catalog, documentation and ownership, improve communication, democratize documentation and knowledge sharing, and coordinate the software lifecycle; all in service of a best-in-class developer experience. |
|
||||
| [Paraná Banco](https://site.paranabanco.com.br/) | [Joao Antunes](mailto:joaopma@pbtech.net.br) | Internal software catalog, documentation and ownership, improve communication, democratize documentation and knowledge sharing, and coordinate the software lifecycle; all in service of a best-in-class developer experience. |
|
||||
| [Stone](https://stone.com.br/) | [Levy Fialho](mailto:lfialho@stone.com.br) | We're using Backstage as our Credit Team Developer Portal and microservices catalog for mapping ownership. We are also using mkdocs for microservices documentation. |
|
||||
| [REI](https://www.rei.com/) | [Jen Evans](mailto:jenevan@rei.com) | Developer portal focused on an enterprise-wide app catalog to track ownership and surface APIs. |
|
||||
|
||||
+3
-3
@@ -1059,9 +1059,9 @@ type-fest@^0.21.3:
|
||||
integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
|
||||
|
||||
typescript@^4.1.3:
|
||||
version "4.7.4"
|
||||
resolved "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235"
|
||||
integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==
|
||||
version "4.8.2"
|
||||
resolved "https://registry.npmjs.org/typescript/-/typescript-4.8.2.tgz#e3b33d5ccfb5914e4eeab6699cf208adee3fd790"
|
||||
integrity sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==
|
||||
|
||||
universalify@^2.0.0:
|
||||
version "2.0.0"
|
||||
|
||||
@@ -111,5 +111,4 @@ guidelines to get started.
|
||||
|
||||
If you have specific questions about the roadmap, please create an
|
||||
[issue](https://github.com/backstage/backstage/issues/new/choose), ping us on
|
||||
[Discord](https://discord.gg/qxsEfa8Vq8), or [book
|
||||
time](http://calendly.com/spotify-backstage) with the Spotify team.
|
||||
[Discord](https://discord.gg/qxsEfa8Vq8), or [book time](https://info.backstage.spotify.com/office-hours) with the Spotify team.
|
||||
|
||||
+2
-1
@@ -55,6 +55,7 @@ process is used to release an emergency fix as version `6.5.1` in the patch rele
|
||||
of the repo in order to convert your changeset into package version bumps and changelog entries.
|
||||
Commit these changes as a second `"Generated release"` commit.
|
||||
- [ ] Create PR towards the base branch (`patch/v1.18.0`) containing the two commits.
|
||||
- [ ] Add a PR body, it will be used as the release description. Typically something like "This release fixes ...".
|
||||
- [ ] Review/Merge the PR into `patch/v1.18.0`. This will automatically trigger a release.
|
||||
|
||||
- [ ] Look up the new version of our package in the patch PR as well as the new release
|
||||
@@ -65,5 +66,5 @@ process is used to release an emergency fix as version `6.5.1` in the patch rele
|
||||
master branch as well. Create a PR that contains the following:
|
||||
|
||||
- [ ] The fix, which you can likely cherry-pick from your patch branch: `git cherry-pick origin/patch/v1.18.0^`
|
||||
- [ ] An updated `CHANGELOG.md` of all patched packages from the tip of the patch branch, `git checkout origin/patch/v1.18.0 -- {packages,plugins}/*/CHANGELOG.md`.
|
||||
- [ ] An updated `CHANGELOG.md` of all patched packages from the tip of the patch branch, `git checkout origin/patch/v1.18.0 -- {packages,plugins}/*/CHANGELOG.md`. Note that if the patch happens after any next-line releases you'll need to restore those entries in the changelog, placing the patch release entry beneath any next-line release entries.
|
||||
- [ ] A changeset with the message "Applied the fix from version `6.5.1` of this package, which is part of the `v1.18.1` release of Backstage."
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,205 @@
|
||||
---
|
||||
id: react-router-stable-migration
|
||||
title: React Router 6.0 Migration
|
||||
description: Guide for how to migrate from React Router v6 beta to React Router v6 stable
|
||||
---
|
||||
|
||||
Backstage has for a long time been using `react-router` version `6.0.0-beta.0`.
|
||||
We adopted this unstable version because v6 had some new features that fit
|
||||
really well with Backstage, particularly relative routing. Because we jumped on
|
||||
this early and unstable version, we knew that we would at some point need a
|
||||
breaking migration to the stable version of `react-router` v6, which is the
|
||||
point we're at now!
|
||||
|
||||
This migration is required but controlled by each app, meaning that you choose
|
||||
when you want to migrate your app. There will however be some point in the
|
||||
future where we drop support for the beta version of `react-router`, at which
|
||||
time you would be forced to migrate.
|
||||
|
||||
The stable version of React Router v6 brings a number of improvements and bug
|
||||
fixes. Notably, the way that paths are resolved has been improved, which fixes a
|
||||
bug where paths like `/catalog` and `/catalog-import` could get confused.
|
||||
|
||||
## Migration
|
||||
|
||||
### Step 1 - Upgrade to Backstage 1.6
|
||||
|
||||
The first Backstage release to support `react-router` v6 is `1.6`. You should upgrade to this version first before you start migrating. If you are an early bird and want to try out migration before that release, it is also shipped in `1.6.0-next.1`.
|
||||
|
||||
### Step 2 - Move `react-router` to `peerDependencies`
|
||||
|
||||
It's important that only one version of `react-router` is installed in the
|
||||
project at a time. Similar to how the `react` version is handled, all plugins
|
||||
and packages now declare a peer dependency on the React Router dependencies,
|
||||
rather than a direct dependency. The only exception to this is the app package
|
||||
(in `packages/app/package.json`), which has the direct dependencies that end up
|
||||
deciding what version of React Router that you are using in your project.
|
||||
|
||||
Your internal packages might specify a dependency on `react-router` or `react-router-dom` in their `package.json`, and it's important that those are converted to `peerDependencies` so that we can control the version of `react-router` in the app `package.json`.
|
||||
|
||||
You can automate this step by running the following command:
|
||||
|
||||
```bash
|
||||
yarn backstage-cli migrate react-router-deps
|
||||
```
|
||||
|
||||
For those interested in doing this manually, apply the below change to all `package.json` files except the one at `packages/app/package.json` or any other app packages. Skip moving any dependencies that don't already exist, and move both `dependencies` and `devDependencies`.
|
||||
|
||||
```diff
|
||||
dependencies {
|
||||
...
|
||||
- "react-router-dom": "^6.0.0-beta.0",
|
||||
- "react-router": "^6.0.0-beta.0"
|
||||
},
|
||||
peerDependencies: {
|
||||
...
|
||||
+ "react-router-dom": "6.0.0-beta.0 || ^6.3.0",
|
||||
+ "react-router": "6.0.0-beta.0 || ^6.3.0"
|
||||
},
|
||||
```
|
||||
|
||||
### Step 3 - Ensure that your external plugins are updated
|
||||
|
||||
It's important that you also update your external plugins to their latest version as these will have to perform the same `peerDependencies` update.
|
||||
|
||||
During this migration there may be external plugins that need updating. If you encounter any plugins outside of the `@backstage` scope that are incompatible with your installation, make sure to check for an existing issue or raise a new one at the plugin's GitHub repository.
|
||||
|
||||
### Step 4 - Bump the React Router dependencies in your app.
|
||||
|
||||
Now it's time to do the actual migration to the latest version of React Router. At this time of writing that is `6.3.0`, but that is of course a moving target.
|
||||
|
||||
The first step is to modify `packages/app/package.json`:
|
||||
|
||||
```diff
|
||||
- "react-router": "6.0.0-beta.0",
|
||||
- "react-router-dom": "6.0.0-beta.0",
|
||||
+ "react-router": "^6.3.0",
|
||||
+ "react-router-dom": "^6.3.0",
|
||||
```
|
||||
|
||||
In case you happen to have multiple app packages in your project, apply the same change to all those packages.
|
||||
|
||||
Once the change has been made, run `yarn install`, and then `yarn why react-router` to validate the installation. You should see the following line in the log as the only resulting entry:
|
||||
|
||||
```
|
||||
=> Found "react-router@6.3.0"
|
||||
```
|
||||
|
||||
If you see multiple entries, and especially `=> Found "react-router@6.0.0-beta.0"`, then your dependencies have not yet been fully migrated to support React Router v6 stable. Double check the steps above, using the information that the Yarn `why` command logged. Repeat the same process for `yarn why react-router-dom`.
|
||||
|
||||
If you end up being stuck not being able to move your entire project to stable versions cleanly, then you can use Yarn `"resolutions"` overrides in your root `package.json`. Try to avoid this option as it may lead to hidden breakages at runtime, and verify any plugins that needed the override. A better option is likely to hold off migrating for a while until plugins have had time to be updated.
|
||||
|
||||
### Step 5 - Breaking Changes
|
||||
|
||||
For a new app created with `npx @backstage/create-app`, the above steps are all you need to do. If you have created internal plugins and customizations then be sure to review the breaking changes in the [React Router changelog](https://reactrouter.com/docs/en/v6/upgrading/reach#breaking-updates) and validate all parts of your app. We've summarized the most important breaking changes below.
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
See [changelog](https://reactrouter.com/docs/en/v6/upgrading/reach#breaking-updates) for a full list of breaking changes. Below we highlight a couple of the most important ones.
|
||||
|
||||
### Route paths
|
||||
|
||||
`Route` components must always contain a `path` or `index` prop.
|
||||
|
||||
```tsx
|
||||
<Routes>
|
||||
{/* Invalid */}
|
||||
<Route element={<Example />} />
|
||||
|
||||
{/* Valid */}
|
||||
<Route path="/" element={<Example />} />
|
||||
|
||||
{/* Valid but discouraged due to incompatibility with react-router beta */}
|
||||
<Route index element={<Example />} />
|
||||
</Routes>
|
||||
```
|
||||
|
||||
Absolute route paths within each `Routes` element must now match their own location, meaning that the following is invalid:
|
||||
|
||||
```tsx
|
||||
<Routes>
|
||||
<Route path="/foo">
|
||||
<Route path="/bar" /> {/* INVALID, must be "/foo/bar" or "bar" */}
|
||||
</Route>
|
||||
</Routes>
|
||||
```
|
||||
|
||||
### Routes and Route components
|
||||
|
||||
The `Routes` and `Route` component both received a large related breaking changes. It is no longer possible
|
||||
to have anything but `Route` elements and React fragments be a child of a `Routes` element. This means that
|
||||
structures like these:
|
||||
|
||||
```tsx
|
||||
<Routes>
|
||||
<MyComponent path="/foo" />
|
||||
...
|
||||
</Routes>
|
||||
```
|
||||
|
||||
need to be migrated to this:
|
||||
|
||||
```tsx
|
||||
<Routes>
|
||||
<Route path="/foo" element={<MyComponent />} />
|
||||
...
|
||||
</Routes>
|
||||
```
|
||||
|
||||
Somewhat related to the `Routes` change, it is no longer possible to render a
|
||||
`Route` element by itself, outside of a `Routes` wrapper. Previously, rendering
|
||||
such a `Route` element would cause the contents of its `element` prop to be
|
||||
rendered instead, but it will now throw an error.
|
||||
|
||||
### `PermissionedRoute`
|
||||
|
||||
Because of the above change, the `PermissionedRoute` component no longer works in all situations with React Router v6 stable. It has been deprecated in favor of the new `RequirePermission` component, which can be placed anywhere in order to perform a permissions check.
|
||||
|
||||
It's crucial that you update to `RequirePermission` at the same time as you update to React Router v6 stable as the `PermissionedRoute` component will no longer function.
|
||||
|
||||
```diff
|
||||
- <PermissionedRoute
|
||||
- path="/catalog-import"
|
||||
- permission={catalogEntityCreatePermission}
|
||||
- element={<CatalogImportPage />}
|
||||
+ <Route
|
||||
+ path="/catalog-import"
|
||||
+ element={
|
||||
+ <RequirePermission permission={catalogEntityCreatePermission}>
|
||||
+ <CatalogImportPage />
|
||||
+ </RequirePermission>
|
||||
+ }
|
||||
/>
|
||||
```
|
||||
|
||||
### `<Navigate />` component
|
||||
|
||||
When migrating over to React Router v6 stable, you might also see browser console warnings for the `Navigate` component. This will need to be wrapped up in a `Route` component with the `Navigate` component in the `element` prop.
|
||||
|
||||
```diff
|
||||
- <Navigate key="/" to="catalog" />
|
||||
+ <Route path="/" element={<Navigate to="/catalog" />} />
|
||||
```
|
||||
|
||||
### `NavLink`
|
||||
|
||||
The `NavLink` component no longer has the `activeClassName` and `activeStyle` props. Instead, the `className` and `style` props accept a callback that receives a boolean indicating whether the link is active.
|
||||
|
||||
## For Plugin Authors
|
||||
|
||||
There are a few things to keep in mind when migrating a published plugin. You of course need to make sure that dependencies on React Router are moved to `peerDependencies` as described above.
|
||||
In addition, you need to make sure that your plugin truly is compatible with both versions of React Router at runtime. To help you achieve that, you can follow these additional guidelines:
|
||||
|
||||
- Bump the version of `react-router` and `react-router-dom` in your own project to use the stable version. Place them in `devDependencies` if your plugin is a single package project. The stable version is more strict, so this is the better baseline to work from.
|
||||
- Make sure all `Route` elements have a `path` prop. Do not use the new `index` props, as it is not supported by the beta version. Use `path="/"` for the index routes within a `Routes`.
|
||||
- If you are using `NavLink`, use both the new and old APIs simultaneously, and work around any TypeScript errors.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Check the browser console for React Router related error messages.
|
||||
|
||||
Check `yarn.lock` for packages depending on older versions of `react-router`:
|
||||
|
||||
```bash
|
||||
yarn why react-router
|
||||
```
|
||||
@@ -51,4 +51,4 @@ As with most alpha releases, you should expect things to change quite a lot unti
|
||||
|
||||
If you have feedback or questions, please open a [GitHub issue](https://github.com/backstage/backstage/issues), ping us on [Discord chat](https://discord.gg/EBHEGzX) or send us an email at [backstage-interest@spotify.com](mailto:backstage-interest@spotify.com) 🙏
|
||||
|
||||
To get regular product updates and news about the Backstage community, sign up for the [Backstage newsletter](https://mailchi.mp/spotify/backstage-community).
|
||||
To get regular product updates and news about the Backstage community, sign up for the [Backstage newsletter](https://info.backstage.spotify.com/newsletter_subscribe).
|
||||
|
||||
@@ -75,4 +75,4 @@ We have learned that one of the keys to getting these standards adopted is to ke
|
||||
|
||||
If you have feedback or questions, please open a [GitHub issue](https://github.com/backstage/backstage/issues), ping us on [Discord chat](https://discord.gg/EBHEGzX) or send us an email at [backstage-interest@spotify.com](mailto:backstage-interest@spotify.com) 🙏
|
||||
|
||||
To get regular product updates and news about the Backstage community, sign up for the [Backstage newsletter](https://mailchi.mp/spotify/backstage-community).
|
||||
To get regular product updates and news about the Backstage community, sign up for the [Backstage newsletter](https://info.backstage.spotify.com/newsletter_subscribe).
|
||||
|
||||
@@ -18,4 +18,4 @@ The Backstage community is healthy and growing quickly. Over [130 people](https:
|
||||
|
||||
We’re excited to embark on this journey with the CNCF community. There’s so much great tech being built here, and it’s about time we share it to build even greater products, together. Entering into the CNCF Sandbox is just the first step. We are committed to working with the community to bring Backstage through the Incubation step, and finally all the way to becoming a Graduated, top-level project.
|
||||
|
||||
Thanks to everyone for your support so far. We hope you [join us](https://mailchi.mp/spotify/backstage-community) in this next chapter of Backstage's journey. If you have questions or feedback, feel free to [email](mailto:backstage-interest@spotify.com) me directly.
|
||||
Thanks to everyone for your support so far. We hope you [join us](https://info.backstage.spotify.com/newsletter_subscribe) in this next chapter of Backstage's journey. If you have questions or feedback, feel free to [email](mailto:backstage-interest@spotify.com) me directly.
|
||||
|
||||
@@ -49,7 +49,7 @@ We’ve launched a new website at: [backstage.spotify.com](https://backstage.spo
|
||||
|
||||
You’ll find a high-level introduction to the platform, tips and tricks tested by Spotify to accelerate developer effectiveness, and access to a group of partners that have scaled Backstage for numerous adopters. You can also use the site to book product overviews, demos, and technical deep dives with members of the Spotify team.
|
||||
|
||||
We will continue to post important product announcements, technical documentation, feature demos, and community news here on Backstage.io. ([Subscribe to the newsletter](https://mailchi.mp/spotify/backstage-community) to stay up to date.) And both contributors and adopting companies can continue to find around-the-clock/around-the-world technical support on [GitHub](https://github.com/backstage/backstage) and [Discord](https://discord.gg/MUpMjP2).
|
||||
We will continue to post important product announcements, technical documentation, feature demos, and community news here on Backstage.io. ([Subscribe to the newsletter](https://info.backstage.spotify.com/newsletter_subscribe) to stay up to date.) And both contributors and adopting companies can continue to find around-the-clock/around-the-world technical support on [GitHub](https://github.com/backstage/backstage) and [Discord](https://discord.gg/MUpMjP2).
|
||||
|
||||
## Separate community sessions for adopters and contributors
|
||||
|
||||
|
||||
@@ -41,5 +41,5 @@ If you are a Backstage enthusiast, please [join me][news] and the entire Backsta
|
||||
[da]: https://medium.com/dazn-tech/developer-experience-dx-at-dazn-e6de9a0208d2
|
||||
[ex]: https://backstage.spotify.com/blog/community-session/firehydrant-expedia-loblaw/
|
||||
[plugins]: https://backstage.io/plugins
|
||||
[news]: https://mailchi.mp/spotify/backstage-community
|
||||
[news]: https://info.backstage.spotify.com/newsletter_subscribe
|
||||
[gh]: https://github.com/backstage/backstage/blob/master/ADOPTERS.md
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
# prettier-ignore
|
||||
title: Backstage Security Audit & Updates
|
||||
author: Patrik Oldsberg, Spotify
|
||||
authorURL: https://github.com/Rugvip
|
||||
---
|
||||
|
||||
**TL;DR** Backstage’s security posture continues to mature! Today, we’re releasing a report from an independent security audit and the first version of the Backstage Threat Model.
|
||||
|
||||

|
||||
|
||||
As an [Incubating project](https://www.cncf.io/blog/2022/03/15/backstage-project-joins-the-cncf-incubator/) within the [Cloud Native Computing Foundation (CNCF)](https://www.cncf.io/), Backstage was fortunate enough to take advantage of a sponsored security audit. The [Open Source Technology Improvement Fund (OSTIF)](https://ostif.org/) sponsored the audit as part of its ongoing efforts to secure the open source software ecosystem, and the audit itself was performed by [X41 D-Sec](https://x41-dsec.de/). Our goal with the audit was to evaluate and improve Backstage’s security posture, focusing on the core Backstage framework and plugins.
|
||||
|
||||
<!--truncate-->
|
||||
|
||||
## Report Findings and Fixes
|
||||
|
||||
The security audit and improvements concluded earlier this month, on August 18th. The audit **findings** totalled two critical, two high, five medium, and three low severity vulnerabilities, alongside 15 side findings with no direct security impact. As of the [Backstage 1.5 release](https://backstage.io/docs/releases/v1.5.0), eight out of the 12 main findings and many of the side findings are fully remedied. If you are a few versions behind there’s no need to worry though, most fixes were included in the 1.3 release.
|
||||
|
||||
Out of the four findings that have yet to be fixed, three are related to rate limiting or internal DoS concerns. With the introduction of the Backstage Threat Model (more on that below), Backstage’s positioning states that this is outside the scope of the security concerns of Backstage. Rather, we trust internal users of Backstage to not intentionally sabotage the availability of the service. This is not to say that we will never aim to get these findings addressed, but we have pushed them to be potential future improvements as we focus our near-term efforts on improving the product in other ways.
|
||||
|
||||
The last outstanding finding is to build out the capabilities of our service-to-service auth system. This is an area where the audit identified a couple of missing pieces in our early version of the implementation. We have since closed the gap by introducing token expiration, and will continue to work on this as we open up for more complex and hardened deployment patterns through the [evolution of the backend system](https://github.com/backstage/backstage/issues/11611).
|
||||
|
||||
Another important finding was the potential for confusion and user impersonation due to most authentication providers having sign-in enabled by default. This finding reinforced our decision to switch sign-in to being disabled by default for all authentication providers, which was part of the [1.1 release](https://backstage.io/docs/releases/v1.1.0).
|
||||
|
||||
Perhaps the most important outcome of this audit is that it helped us focus our efforts to keep improving the security of Backstage. It identified priority areas in both implementation and documentation for us going forward. One particular area that was pointed out in a finding is the documentation around the security model of Backstage deployment. There have been several efforts to highlight this in documentation, but it is still not clear enough. What we’ve been lacking is documentation that is completely dedicated towards detailing the security concerns of Backstage. That is why in addition to publishing the security audit report, we are also introducing the [Backstage Threat Model](https://backstage.io/docs/overview/threat-model).
|
||||
|
||||
## Introducing the Backstage Threat Model
|
||||
|
||||
The existing Backstage documentation has many security concerns interwoven within its text, but to find them all, you need to spend a lot of time reading. We previously lacked a one-stop-shop for readers that are interested in the security model and concerns of Backstage. So, we are happy to introduce the [Backstage Threat Model](https://backstage.io/docs/overview/threat-model), which closes this gap. The Threat Model outlines key security considerations for operators, developers, and security researchers. It is a living document that will evolve and expand alongside the Backstage project.
|
||||
|
||||
The threat model document covers the trust model and roles involved in a typical Backstage setup, the responsibilities that fall on integrators of Backstage, and common configuration concerns across all Backstage projects. Beyond these three topics, it also dives deeper into a number of core features. The `auth`, `catalog`, `scaffolder`, and `techdocs` plugins are all covered separately with their individual security concerns.
|
||||
|
||||
We’d like to point out a few key parts in case you are in a rush. Be sure to familiarize yourself with the integrator's responsibility to protect the Backstage installation from unauthorized access. If you ingest organizational data into the catalog and use that to sign in users, you’ll also want to check out the first halves of the authentication and catalog sections.
|
||||
|
||||
## Links and References
|
||||
|
||||
- [Full Audit Report](assets/22-08-23/X41-Backstage-Audit-2022.pdf)
|
||||
- [Backstage Security Policy](https://github.com/backstage/backstage/blob/master/SECURITY.md)
|
||||
|
||||
On behalf of the Backstage maintainers and community: thanks to the CNCF, OSTIF, and X41 D-Sec for the opportunity to improve the project.
|
||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
@@ -48,7 +48,7 @@ class Footer extends React.Component {
|
||||
<a href="https://github.com/backstage/community">
|
||||
Community Sessions
|
||||
</a>
|
||||
<a href="https://mailchi.mp/spotify/backstage-community">
|
||||
<a href="https://info.backstage.spotify.com/newsletter_subscribe">
|
||||
Subscribe to our newsletter
|
||||
</a>
|
||||
<a href="https://www.cncf.io/projects/">CNCF Incubation</a>
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import React from 'react';
|
||||
|
||||
export class HubSpotForm extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<>
|
||||
<script src="https://js.hsforms.net/forms/v2.js" />
|
||||
<div
|
||||
className="Sidebar__Container"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
<button class="Sidebar__Button" onclick="toggleFormVisibility()">New Adopters</button>
|
||||
<div id="Sidebar__HubSpotContainer"></div>
|
||||
`,
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="text/javascript"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
if (typeof window !== undefined) {
|
||||
window.hbspt.forms.create({
|
||||
portalId: '21894833',
|
||||
formId: '9a5aa2af-87f3-4a44-819f-88ee243bb61e',
|
||||
target: '#Sidebar__HubSpotContainer',
|
||||
pageId: '79735607665',
|
||||
})
|
||||
}
|
||||
|
||||
function toggleFormVisibility() {
|
||||
var form = document.querySelector('.Sidebar__Container');
|
||||
form.classList.toggle('Sidebar__Container--open');
|
||||
}
|
||||
`,
|
||||
}}
|
||||
></script>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
export function Typeform() {
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
data-tf-sidetab="zcOaKikB"
|
||||
data-tf-width="320"
|
||||
data-tf-height="400"
|
||||
data-tf-custom-icon="https://images.typeform.com/images/769rUZbqPrvq"
|
||||
data-tf-button-color="#5CD6C8"
|
||||
data-tf-button-text="New Adopters"
|
||||
data-tf-iframe-props="title=Public Adopter: Hand Raiser Form"
|
||||
data-tf-medium="snippet"
|
||||
data-tf-hidden="utm_source=.iobanner"
|
||||
style={{ all: 'unset' }}
|
||||
/>
|
||||
<script src="//embed.typeform.com/next/embed.js" />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -76,7 +76,7 @@ const Background = props => {
|
||||
<li>
|
||||
<Block.Paragraph style={{ marginBottom: '0' }}>
|
||||
Subscribe to the{' '}
|
||||
<a href="https://mailchi.mp/spotify/backstage-community">
|
||||
<a href="https://info.backstage.spotify.com/newsletter_subscribe">
|
||||
Community newsletter
|
||||
</a>
|
||||
</Block.Paragraph>
|
||||
@@ -122,7 +122,7 @@ const Background = props => {
|
||||
The official monthly Backstage newsletter. Don't miss the latest
|
||||
news from your favorite project!
|
||||
</Block.Paragraph>
|
||||
<Block.LinkButton href="https://mailchi.mp/spotify/backstage-community">
|
||||
<Block.LinkButton href="https://info.backstage.spotify.com/newsletter_subscribe">
|
||||
Subscribe
|
||||
</Block.LinkButton>
|
||||
</Block.TextBox>
|
||||
|
||||
+528
-510
File diff suppressed because it is too large
Load Diff
@@ -64,7 +64,7 @@ const Background = props => {
|
||||
Good First Issues
|
||||
</a>
|
||||
<br />- Subscribe to the{' '}
|
||||
<a href="https://mailchi.mp/spotify/backstage-community">
|
||||
<a href="https://info.backstage.spotify.com/newsletter_subscribe">
|
||||
Community newsletter
|
||||
</a>
|
||||
<br />- Join the{' '}
|
||||
|
||||
@@ -325,6 +325,7 @@
|
||||
"Tutorials": [
|
||||
"tutorials/journey",
|
||||
"tutorials/quickstart-app-plugin",
|
||||
"tutorials/react-router-stable-migration",
|
||||
"tutorials/package-role-migration",
|
||||
"tutorials/migrating-away-from-core",
|
||||
"tutorials/configuring-plugin-databases",
|
||||
|
||||
@@ -1227,3 +1227,66 @@ code {
|
||||
h3.collapsible span.arrow {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.Sidebar__Container {
|
||||
top: 50%;
|
||||
right: 0;
|
||||
position: fixed;
|
||||
color: rgb(0, 0, 0);
|
||||
transition: transform 250ms ease-in-out, height 250ms ease-in-out;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
transform: translateY(-50%) translateX(500px);
|
||||
}
|
||||
|
||||
.Sidebar__Container--open {
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.Sidebar__Button {
|
||||
transform: rotate(-90deg) translateY(48px);
|
||||
padding: 12px 16px;
|
||||
border-radius: 8px 8px 0 0;
|
||||
background-color: rgb(92, 214, 200);
|
||||
color: rgb(0, 0, 0);
|
||||
outline: 0;
|
||||
border: 0;
|
||||
font-family: Helvetica Neue, sans-serif;
|
||||
max-height: 48px;
|
||||
max-width: 150px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.Sidebar__Button:hover {
|
||||
transform: rotate(-90deg) translateY(48px) scale(1.01);
|
||||
}
|
||||
|
||||
#Sidebar__HubSpotContainer {
|
||||
width: 500px;
|
||||
background-color: white;
|
||||
border-radius: 8px 0 0 8px;
|
||||
padding: 16px;
|
||||
padding-bottom: 0px;
|
||||
z-index: 10001;
|
||||
min-height: 260px;
|
||||
}
|
||||
|
||||
#Sidebar__HubSpotContainer .hs-button {
|
||||
padding: 12px 16px;
|
||||
border-radius: 8px;
|
||||
background-color: rgb(92, 214, 200);
|
||||
color: rgb(0, 0, 0);
|
||||
border: 0;
|
||||
}
|
||||
#Sidebar__HubSpotContainer.submitted-message {
|
||||
min-height: 260px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
#Sidebar__HubSpotContainer.submitted-message p {
|
||||
color: rgb(0, 0, 0);
|
||||
}
|
||||
|
||||
@@ -181,6 +181,7 @@ nav:
|
||||
- Deprecations: 'api/deprecations.md'
|
||||
- Tutorials:
|
||||
- Future developer journey: 'tutorials/journey.md'
|
||||
- React Router 6.0 Migration: 'tutorials/react-router-stable-migration.md'
|
||||
- Package Role Migration: 'tutorials/package-role-migration.md'
|
||||
- Migrating away from @backstage/core: 'tutorials/migrating-away-from-core.md'
|
||||
- Adding Custom Plugin to Existing Monorepo App: 'tutorials/quickstart-app-plugin.md'
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@
|
||||
"@types/react": "^17",
|
||||
"@types/react-dom": "^17"
|
||||
},
|
||||
"version": "1.6.0-next.0",
|
||||
"version": "1.6.0-next.1",
|
||||
"dependencies": {
|
||||
"@manypkg/get-packages": "^1.1.3",
|
||||
"@microsoft/api-documenter": "^7.17.11",
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
# @backstage/app-defaults
|
||||
|
||||
## 1.0.6-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 817f3196f6: Updated React Router dependencies to be peer dependencies.
|
||||
- Updated dependencies
|
||||
- @backstage/core-app-api@1.1.0-next.1
|
||||
- @backstage/core-components@0.11.1-next.1
|
||||
- @backstage/core-plugin-api@1.0.6-next.1
|
||||
- @backstage/plugin-permission-react@0.4.5-next.1
|
||||
|
||||
## 1.0.6-next.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/app-defaults",
|
||||
"description": "Provides the default wiring of a Backstage App",
|
||||
"version": "1.0.6-next.0",
|
||||
"version": "1.0.6-next.1",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
@@ -33,21 +33,21 @@
|
||||
"start": "backstage-cli package start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/core-components": "^0.11.1-next.0",
|
||||
"@backstage/core-app-api": "^1.0.6-next.0",
|
||||
"@backstage/core-plugin-api": "^1.0.6-next.0",
|
||||
"@backstage/plugin-permission-react": "^0.4.5-next.0",
|
||||
"@backstage/core-components": "^0.11.1-next.1",
|
||||
"@backstage/core-app-api": "^1.1.0-next.1",
|
||||
"@backstage/core-plugin-api": "^1.0.6-next.1",
|
||||
"@backstage/plugin-permission-react": "^0.4.5-next.1",
|
||||
"@backstage/theme": "^0.2.16",
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"react-router-dom": "6.0.0-beta.0"
|
||||
"@material-ui/icons": "^4.9.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
"react": "^16.13.1 || ^17.0.0",
|
||||
"react-router-dom": "6.0.0-beta.0 || ^6.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.18.2-next.0",
|
||||
"@backstage/test-utils": "^1.1.4-next.0",
|
||||
"@backstage/cli": "^0.19.0-next.1",
|
||||
"@backstage/test-utils": "^1.2.0-next.1",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^12.1.3",
|
||||
"@types/jest": "^26.0.7",
|
||||
|
||||
@@ -1,5 +1,57 @@
|
||||
# example-app
|
||||
|
||||
## 0.2.75-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/app-defaults@1.0.6-next.1
|
||||
- @backstage/core-app-api@1.1.0-next.1
|
||||
- @backstage/core-components@0.11.1-next.1
|
||||
- @backstage/core-plugin-api@1.0.6-next.1
|
||||
- @backstage/plugin-airbrake@0.3.9-next.1
|
||||
- @backstage/plugin-api-docs@0.8.9-next.1
|
||||
- @backstage/plugin-azure-devops@0.2.0-next.1
|
||||
- @backstage/plugin-badges@0.2.33-next.1
|
||||
- @backstage/plugin-catalog-graph@0.2.21-next.1
|
||||
- @backstage/plugin-catalog-import@0.8.12-next.1
|
||||
- @backstage/plugin-catalog-react@1.1.4-next.1
|
||||
- @backstage/plugin-circleci@0.3.9-next.1
|
||||
- @backstage/plugin-cloudbuild@0.3.9-next.1
|
||||
- @backstage/plugin-code-coverage@0.2.2-next.1
|
||||
- @backstage/plugin-cost-insights@0.11.31-next.1
|
||||
- @backstage/plugin-explore@0.3.40-next.1
|
||||
- @backstage/plugin-gcp-projects@0.3.28-next.1
|
||||
- @backstage/plugin-github-actions@0.5.9-next.1
|
||||
- @backstage/plugin-graphiql@0.2.41-next.1
|
||||
- @backstage/plugin-home@0.4.25-next.1
|
||||
- @backstage/plugin-jenkins@0.7.8-next.1
|
||||
- @backstage/plugin-kafka@0.3.9-next.1
|
||||
- @backstage/plugin-kubernetes@0.7.2-next.1
|
||||
- @backstage/plugin-lighthouse@0.3.9-next.1
|
||||
- @backstage/plugin-org@0.5.9-next.1
|
||||
- @backstage/plugin-pagerduty@0.5.2-next.1
|
||||
- @backstage/plugin-permission-react@0.4.5-next.1
|
||||
- @backstage/plugin-rollbar@0.4.9-next.1
|
||||
- @backstage/plugin-scaffolder@1.6.0-next.1
|
||||
- @backstage/plugin-search-react@1.0.2-next.1
|
||||
- @backstage/plugin-search@1.0.2-next.1
|
||||
- @backstage/plugin-sentry@0.4.2-next.1
|
||||
- @backstage/plugin-shortcuts@0.3.1-next.1
|
||||
- @backstage/plugin-tech-insights@0.3.0-next.1
|
||||
- @backstage/plugin-techdocs-react@1.0.4-next.1
|
||||
- @backstage/plugin-techdocs@1.3.2-next.1
|
||||
- @backstage/plugin-todo@0.2.11-next.1
|
||||
- @backstage/plugin-user-settings@0.4.8-next.1
|
||||
- @backstage/cli@0.19.0-next.1
|
||||
- @backstage/plugin-dynatrace@0.2.0-next.1
|
||||
- @backstage/plugin-apache-airflow@0.2.2-next.1
|
||||
- @backstage/plugin-gcalendar@0.3.5-next.1
|
||||
- @backstage/plugin-newrelic@0.3.27-next.1
|
||||
- @backstage/plugin-newrelic-dashboard@0.2.2-next.1
|
||||
- @backstage/plugin-tech-radar@0.5.16-next.1
|
||||
- @backstage/plugin-stack-overflow@0.1.5-next.1
|
||||
|
||||
## 0.2.75-next.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
+50
-50
@@ -1,65 +1,65 @@
|
||||
{
|
||||
"name": "example-app",
|
||||
"version": "0.2.75-next.0",
|
||||
"version": "0.2.75-next.1",
|
||||
"private": true,
|
||||
"backstage": {
|
||||
"role": "frontend"
|
||||
},
|
||||
"bundled": true,
|
||||
"dependencies": {
|
||||
"@backstage/app-defaults": "^1.0.6-next.0",
|
||||
"@backstage/app-defaults": "^1.0.6-next.1",
|
||||
"@backstage/catalog-model": "^1.1.0",
|
||||
"@backstage/cli": "^0.18.2-next.0",
|
||||
"@backstage/cli": "^0.19.0-next.1",
|
||||
"@backstage/config": "^1.0.1",
|
||||
"@backstage/core-app-api": "^1.0.6-next.0",
|
||||
"@backstage/core-components": "^0.11.1-next.0",
|
||||
"@backstage/core-plugin-api": "^1.0.6-next.0",
|
||||
"@backstage/core-app-api": "^1.1.0-next.1",
|
||||
"@backstage/core-components": "^0.11.1-next.1",
|
||||
"@backstage/core-plugin-api": "^1.0.6-next.1",
|
||||
"@backstage/integration-react": "^1.1.4-next.0",
|
||||
"@backstage/plugin-airbrake": "^0.3.9-next.0",
|
||||
"@backstage/plugin-api-docs": "^0.8.9-next.0",
|
||||
"@backstage/plugin-azure-devops": "^0.2.0-next.0",
|
||||
"@backstage/plugin-apache-airflow": "^0.2.2-next.0",
|
||||
"@backstage/plugin-badges": "^0.2.33-next.0",
|
||||
"@backstage/plugin-airbrake": "^0.3.9-next.1",
|
||||
"@backstage/plugin-api-docs": "^0.8.9-next.1",
|
||||
"@backstage/plugin-azure-devops": "^0.2.0-next.1",
|
||||
"@backstage/plugin-apache-airflow": "^0.2.2-next.1",
|
||||
"@backstage/plugin-badges": "^0.2.33-next.1",
|
||||
"@backstage/plugin-catalog-common": "^1.0.6-next.0",
|
||||
"@backstage/plugin-catalog-graph": "^0.2.21-next.0",
|
||||
"@backstage/plugin-catalog-import": "^0.8.12-next.0",
|
||||
"@backstage/plugin-catalog-react": "^1.1.4-next.0",
|
||||
"@backstage/plugin-circleci": "^0.3.9-next.0",
|
||||
"@backstage/plugin-cloudbuild": "^0.3.9-next.0",
|
||||
"@backstage/plugin-code-coverage": "^0.2.2-next.0",
|
||||
"@backstage/plugin-cost-insights": "^0.11.31-next.0",
|
||||
"@backstage/plugin-dynatrace": "^0.2.0-next.0",
|
||||
"@backstage/plugin-explore": "^0.3.40-next.0",
|
||||
"@backstage/plugin-gcalendar": "^0.3.5-next.0",
|
||||
"@backstage/plugin-gcp-projects": "^0.3.28-next.0",
|
||||
"@backstage/plugin-github-actions": "^0.5.9-next.0",
|
||||
"@backstage/plugin-catalog-graph": "^0.2.21-next.1",
|
||||
"@backstage/plugin-catalog-import": "^0.8.12-next.1",
|
||||
"@backstage/plugin-catalog-react": "^1.1.4-next.1",
|
||||
"@backstage/plugin-circleci": "^0.3.9-next.1",
|
||||
"@backstage/plugin-cloudbuild": "^0.3.9-next.1",
|
||||
"@backstage/plugin-code-coverage": "^0.2.2-next.1",
|
||||
"@backstage/plugin-cost-insights": "^0.11.31-next.1",
|
||||
"@backstage/plugin-dynatrace": "^0.2.0-next.1",
|
||||
"@backstage/plugin-explore": "^0.3.40-next.1",
|
||||
"@backstage/plugin-gcalendar": "^0.3.5-next.1",
|
||||
"@backstage/plugin-gcp-projects": "^0.3.28-next.1",
|
||||
"@backstage/plugin-github-actions": "^0.5.9-next.1",
|
||||
"@backstage/plugin-gocd": "^0.1.15-next.0",
|
||||
"@backstage/plugin-graphiql": "^0.2.41-next.0",
|
||||
"@backstage/plugin-home": "^0.4.25-next.0",
|
||||
"@backstage/plugin-jenkins": "^0.7.8-next.0",
|
||||
"@backstage/plugin-kafka": "^0.3.9-next.0",
|
||||
"@backstage/plugin-kubernetes": "^0.7.2-next.0",
|
||||
"@backstage/plugin-lighthouse": "^0.3.9-next.0",
|
||||
"@backstage/plugin-newrelic": "^0.3.27-next.0",
|
||||
"@backstage/plugin-newrelic-dashboard": "^0.2.2-next.0",
|
||||
"@backstage/plugin-org": "^0.5.9-next.0",
|
||||
"@backstage/plugin-pagerduty": "0.5.2-next.0",
|
||||
"@backstage/plugin-permission-react": "^0.4.5-next.0",
|
||||
"@backstage/plugin-rollbar": "^0.4.9-next.0",
|
||||
"@backstage/plugin-scaffolder": "^1.6.0-next.0",
|
||||
"@backstage/plugin-search": "^1.0.2-next.0",
|
||||
"@backstage/plugin-graphiql": "^0.2.41-next.1",
|
||||
"@backstage/plugin-home": "^0.4.25-next.1",
|
||||
"@backstage/plugin-jenkins": "^0.7.8-next.1",
|
||||
"@backstage/plugin-kafka": "^0.3.9-next.1",
|
||||
"@backstage/plugin-kubernetes": "^0.7.2-next.1",
|
||||
"@backstage/plugin-lighthouse": "^0.3.9-next.1",
|
||||
"@backstage/plugin-newrelic": "^0.3.27-next.1",
|
||||
"@backstage/plugin-newrelic-dashboard": "^0.2.2-next.1",
|
||||
"@backstage/plugin-org": "^0.5.9-next.1",
|
||||
"@backstage/plugin-pagerduty": "0.5.2-next.1",
|
||||
"@backstage/plugin-permission-react": "^0.4.5-next.1",
|
||||
"@backstage/plugin-rollbar": "^0.4.9-next.1",
|
||||
"@backstage/plugin-scaffolder": "^1.6.0-next.1",
|
||||
"@backstage/plugin-search": "^1.0.2-next.1",
|
||||
"@backstage/plugin-search-common": "^1.0.1-next.0",
|
||||
"@backstage/plugin-search-react": "^1.0.2-next.0",
|
||||
"@backstage/plugin-sentry": "^0.4.2-next.0",
|
||||
"@backstage/plugin-shortcuts": "^0.3.1-next.0",
|
||||
"@backstage/plugin-stack-overflow": "^0.1.5-next.0",
|
||||
"@backstage/plugin-tech-insights": "^0.2.5-next.0",
|
||||
"@backstage/plugin-tech-radar": "^0.5.16-next.0",
|
||||
"@backstage/plugin-techdocs": "^1.3.2-next.0",
|
||||
"@backstage/plugin-search-react": "^1.0.2-next.1",
|
||||
"@backstage/plugin-sentry": "^0.4.2-next.1",
|
||||
"@backstage/plugin-shortcuts": "^0.3.1-next.1",
|
||||
"@backstage/plugin-stack-overflow": "^0.1.5-next.1",
|
||||
"@backstage/plugin-tech-insights": "^0.3.0-next.1",
|
||||
"@backstage/plugin-tech-radar": "^0.5.16-next.1",
|
||||
"@backstage/plugin-techdocs": "^1.3.2-next.1",
|
||||
"@backstage/plugin-techdocs-module-addons-contrib": "^1.0.4-next.0",
|
||||
"@backstage/plugin-techdocs-react": "^1.0.4-next.0",
|
||||
"@backstage/plugin-todo": "^0.2.11-next.0",
|
||||
"@backstage/plugin-user-settings": "^0.4.8-next.0",
|
||||
"@backstage/plugin-techdocs-react": "^1.0.4-next.1",
|
||||
"@backstage/plugin-todo": "^0.2.11-next.1",
|
||||
"@backstage/plugin-user-settings": "^0.4.8-next.1",
|
||||
"@backstage/theme": "^0.2.16",
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
@@ -74,13 +74,13 @@
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-router": "6.0.0-beta.0",
|
||||
"react-router-dom": "6.0.0-beta.0",
|
||||
"react-router": "^6.3.0",
|
||||
"react-router-dom": "^6.3.0",
|
||||
"react-use": "^17.2.4",
|
||||
"zen-observable": "^0.8.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/test-utils": "^1.1.4-next.0",
|
||||
"@backstage/test-utils": "^1.2.0-next.1",
|
||||
"@rjsf/core": "^3.2.1",
|
||||
"@testing-library/cypress": "^8.0.2",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
|
||||
@@ -101,7 +101,7 @@ import * as plugins from './plugins';
|
||||
|
||||
import { techDocsPage } from './components/techdocs/TechDocsPage';
|
||||
import { ApacheAirflowPage } from '@backstage/plugin-apache-airflow';
|
||||
import { PermissionedRoute } from '@backstage/plugin-permission-react';
|
||||
import { RequirePermission } from '@backstage/plugin-permission-react';
|
||||
import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common';
|
||||
|
||||
const app = createApp({
|
||||
@@ -157,10 +157,13 @@ const routes = (
|
||||
>
|
||||
{entityPage}
|
||||
</Route>
|
||||
<PermissionedRoute
|
||||
<Route
|
||||
path="/catalog-import"
|
||||
permission={catalogEntityCreatePermission}
|
||||
element={<CatalogImportPage />}
|
||||
element={
|
||||
<RequirePermission permission={catalogEntityCreatePermission}>
|
||||
<CatalogImportPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/catalog-graph"
|
||||
|
||||
@@ -110,6 +110,7 @@ import {
|
||||
} from '@backstage/plugin-rollbar';
|
||||
import { EntitySentryContent } from '@backstage/plugin-sentry';
|
||||
import { EntityTechdocsContent } from '@backstage/plugin-techdocs';
|
||||
import { EntityTechInsightsScorecardCard } from '@backstage/plugin-tech-insights';
|
||||
import { EntityTodoContent } from '@backstage/plugin-todo';
|
||||
import { Button, Grid } from '@material-ui/core';
|
||||
import BadgeIcon from '@material-ui/icons/CallToAction';
|
||||
@@ -445,6 +446,24 @@ const serviceEntityPage = (
|
||||
<EntityGithubInsightsContent />
|
||||
</EntityLayout.Route>
|
||||
|
||||
<EntityLayout.Route path="/tech-insights" title="Scorecards">
|
||||
<Grid container spacing={3} alignItems="stretch">
|
||||
<Grid item xs={12} md={6}>
|
||||
<EntityTechInsightsScorecardCard
|
||||
title="Scorecard 1"
|
||||
description="This is a sample scorecard no. 1"
|
||||
checksId={['titleCheck']}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={6}>
|
||||
<EntityTechInsightsScorecardCard
|
||||
title="Scorecard 2"
|
||||
checksId={['techDocsCheck']}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</EntityLayout.Route>
|
||||
|
||||
<EntityLayout.Route path="/code-coverage" title="Code Coverage">
|
||||
<EntityCodeCoverageContent />
|
||||
</EntityLayout.Route>
|
||||
|
||||
@@ -35,15 +35,15 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-plugin-api": "^0.1.2-next.0",
|
||||
"@backstage/backend-common": "^0.15.1-next.0",
|
||||
"@backstage/backend-common": "^0.15.1-next.1",
|
||||
"@backstage/backend-tasks": "^0.3.5-next.0",
|
||||
"@backstage/plugin-permission-node": "^0.6.5-next.0",
|
||||
"@backstage/plugin-permission-node": "^0.6.5-next.1",
|
||||
"express": "^4.17.1",
|
||||
"express-promise-router": "^4.1.0",
|
||||
"winston": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.18.2-next.0"
|
||||
"@backstage/cli": "^0.19.0-next.1"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# @backstage/backend-common
|
||||
|
||||
## 0.15.1-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- c3c90280be: Added a keep-alive refresh loop to the `DatabaseManager`, keeping the connection
|
||||
pool up.
|
||||
- c3c90280be: The options part of `DatabaseManager.fromConfig` now accepts an optional logger
|
||||
field.
|
||||
- 60b85d8ade: Updated dependency `helmet` to `^6.0.0`.
|
||||
|
||||
Please note that these policies are no longer applied by default:
|
||||
|
||||
helmet.contentSecurityPolicy no longer sets block-all-mixed-content directive by default
|
||||
helmet.expectCt is no longer set by default. It can, however, be explicitly enabled. It will be removed in Helmet 7.
|
||||
|
||||
## 0.15.1-next.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -252,6 +252,7 @@ export class DatabaseManager {
|
||||
// @public
|
||||
export type DatabaseManagerOptions = {
|
||||
migrations?: PluginDatabaseManager['migrations'];
|
||||
logger?: Logger;
|
||||
};
|
||||
|
||||
// @public
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/backend-common",
|
||||
"description": "Common functionality library for Backstage backends",
|
||||
"version": "0.15.1-next.0",
|
||||
"version": "0.15.1-next.1",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"private": false,
|
||||
@@ -60,7 +60,7 @@
|
||||
"express-promise-router": "^4.1.0",
|
||||
"fs-extra": "10.1.0",
|
||||
"git-url-parse": "^12.0.0",
|
||||
"helmet": "^5.0.2",
|
||||
"helmet": "^6.0.0",
|
||||
"isomorphic-git": "^1.8.0",
|
||||
"jose": "^4.6.0",
|
||||
"keyv": "^4.0.3",
|
||||
@@ -91,8 +91,8 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/backend-test-utils": "^0.1.28-next.0",
|
||||
"@backstage/cli": "^0.18.2-next.0",
|
||||
"@backstage/backend-test-utils": "^0.1.28-next.1",
|
||||
"@backstage/cli": "^0.19.0-next.1",
|
||||
"@types/archiver": "^5.1.0",
|
||||
"@types/base64-stream": "^1.0.2",
|
||||
"@types/compression": "^1.7.0",
|
||||
|
||||
+2
-2
@@ -65,7 +65,7 @@ describe('CacheManager', () => {
|
||||
const config = new ConfigReader({ backend: {} });
|
||||
expect(() => {
|
||||
CacheManager.fromConfig(config);
|
||||
}).not.toThrowError();
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('throws on unknown cache store', () => {
|
||||
@@ -74,7 +74,7 @@ describe('CacheManager', () => {
|
||||
});
|
||||
expect(() => {
|
||||
CacheManager.fromConfig(config);
|
||||
}).toThrowError();
|
||||
}).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -37,12 +37,12 @@ describe('AbortContext', () => {
|
||||
|
||||
expect(child.abortSignal.aborted).toBe(false);
|
||||
expect(Math.abs(+child.deadline! - deadline)).toBeLessThan(50);
|
||||
expect(childListener).toBeCalledTimes(0);
|
||||
expect(childListener).toHaveBeenCalledTimes(0);
|
||||
|
||||
jest.advanceTimersByTime(timeout + 1);
|
||||
|
||||
expect(child.abortSignal.aborted).toBe(true);
|
||||
expect(childListener).toBeCalledTimes(1);
|
||||
expect(childListener).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('results in minimum deadline when parent triggers sooner', async () => {
|
||||
@@ -66,15 +66,15 @@ describe('AbortContext', () => {
|
||||
expect(child.abortSignal.aborted).toBe(false);
|
||||
expect(Math.abs(+parent.deadline! - parentDeadline)).toBeLessThan(50);
|
||||
expect(Math.abs(+child.deadline! - childDeadline)).toBeLessThan(50);
|
||||
expect(parentListener).toBeCalledTimes(0);
|
||||
expect(childListener).toBeCalledTimes(0);
|
||||
expect(parentListener).toHaveBeenCalledTimes(0);
|
||||
expect(childListener).toHaveBeenCalledTimes(0);
|
||||
|
||||
jest.advanceTimersByTime(parentTimeout + 1);
|
||||
|
||||
expect(parent.abortSignal.aborted).toBe(true);
|
||||
expect(child.abortSignal.aborted).toBe(true);
|
||||
expect(parentListener).toBeCalledTimes(1);
|
||||
expect(childListener).toBeCalledTimes(1);
|
||||
expect(parentListener).toHaveBeenCalledTimes(1);
|
||||
expect(childListener).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('results in minimum deadline when child triggers sooner', async () => {
|
||||
@@ -98,22 +98,22 @@ describe('AbortContext', () => {
|
||||
expect(child.abortSignal.aborted).toBe(false);
|
||||
expect(Math.abs(+parent.deadline! - parentDeadline)).toBeLessThan(50);
|
||||
expect(Math.abs(+child.deadline! - childDeadline)).toBeLessThan(50);
|
||||
expect(parentListener).toBeCalledTimes(0);
|
||||
expect(childListener).toBeCalledTimes(0);
|
||||
expect(parentListener).toHaveBeenCalledTimes(0);
|
||||
expect(childListener).toHaveBeenCalledTimes(0);
|
||||
|
||||
jest.advanceTimersByTime(childTimeout + 1);
|
||||
|
||||
expect(parent.abortSignal.aborted).toBe(false);
|
||||
expect(child.abortSignal.aborted).toBe(true);
|
||||
expect(parentListener).toBeCalledTimes(0);
|
||||
expect(childListener).toBeCalledTimes(1);
|
||||
expect(parentListener).toHaveBeenCalledTimes(0);
|
||||
expect(childListener).toHaveBeenCalledTimes(1);
|
||||
|
||||
jest.advanceTimersByTime(parentTimeout - childTimeout + 1);
|
||||
|
||||
expect(parent.abortSignal.aborted).toBe(true);
|
||||
expect(child.abortSignal.aborted).toBe(true);
|
||||
expect(parentListener).toBeCalledTimes(1);
|
||||
expect(childListener).toBeCalledTimes(1);
|
||||
expect(parentListener).toHaveBeenCalledTimes(1);
|
||||
expect(childListener).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('child carries over parent signal state if parent was already aborted and had no deadline', async () => {
|
||||
@@ -133,13 +133,13 @@ describe('AbortContext', () => {
|
||||
child.abortSignal.addEventListener('abort', childListener);
|
||||
|
||||
expect(child.abortSignal.aborted).toBe(true);
|
||||
expect(childListener).toBeCalledTimes(0);
|
||||
expect(childListener).toHaveBeenCalledTimes(0);
|
||||
expect(Math.abs(+child.deadline! - childDeadline)).toBeLessThan(50);
|
||||
|
||||
jest.advanceTimersByTime(childTimeout + 1);
|
||||
|
||||
expect(child.abortSignal.aborted).toBe(true);
|
||||
expect(childListener).toBeCalledTimes(0); // still
|
||||
expect(childListener).toHaveBeenCalledTimes(0); // still
|
||||
});
|
||||
|
||||
it('child carries over parent signal state if parent was already aborted and had a deadline', async () => {
|
||||
@@ -175,15 +175,15 @@ describe('AbortContext', () => {
|
||||
|
||||
expect(parent.abortSignal.aborted).toBe(false);
|
||||
expect(child.abortSignal.aborted).toBe(false);
|
||||
expect(parentListener).toBeCalledTimes(0);
|
||||
expect(childListener).toBeCalledTimes(0);
|
||||
expect(parentListener).toHaveBeenCalledTimes(0);
|
||||
expect(childListener).toHaveBeenCalledTimes(0);
|
||||
|
||||
parentController.abort();
|
||||
|
||||
expect(parent.abortSignal.aborted).toBe(true);
|
||||
expect(child.abortSignal.aborted).toBe(true);
|
||||
expect(parentListener).toBeCalledTimes(1);
|
||||
expect(childListener).toBeCalledTimes(1);
|
||||
expect(parentListener).toHaveBeenCalledTimes(1);
|
||||
expect(childListener).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('does not signal parent when child is aborted', async () => {
|
||||
@@ -201,15 +201,15 @@ describe('AbortContext', () => {
|
||||
|
||||
expect(parent.abortSignal.aborted).toBe(false);
|
||||
expect(child.abortSignal.aborted).toBe(false);
|
||||
expect(parentListener).toBeCalledTimes(0);
|
||||
expect(childListener).toBeCalledTimes(0);
|
||||
expect(parentListener).toHaveBeenCalledTimes(0);
|
||||
expect(childListener).toHaveBeenCalledTimes(0);
|
||||
|
||||
childController.abort();
|
||||
|
||||
expect(parent.abortSignal.aborted).toBe(false);
|
||||
expect(child.abortSignal.aborted).toBe(true);
|
||||
expect(parentListener).toBeCalledTimes(0);
|
||||
expect(childListener).toBeCalledTimes(1);
|
||||
expect(parentListener).toHaveBeenCalledTimes(0);
|
||||
expect(childListener).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('child carries over parent signal state if parent was already aborted', async () => {
|
||||
@@ -227,13 +227,13 @@ describe('AbortContext', () => {
|
||||
|
||||
expect(parent.abortSignal.aborted).toBe(true);
|
||||
expect(child.abortSignal.aborted).toBe(true);
|
||||
expect(childListener).toBeCalledTimes(0);
|
||||
expect(childListener).toHaveBeenCalledTimes(0);
|
||||
|
||||
childController.abort();
|
||||
|
||||
expect(parent.abortSignal.aborted).toBe(true);
|
||||
expect(child.abortSignal.aborted).toBe(true);
|
||||
expect(childListener).toBeCalledTimes(0);
|
||||
expect(childListener).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('child carries over given signal state if it was already aborted', async () => {
|
||||
@@ -247,7 +247,7 @@ describe('AbortContext', () => {
|
||||
child.abortSignal.addEventListener('abort', childListener);
|
||||
|
||||
expect(child.abortSignal.aborted).toBe(true);
|
||||
expect(childListener).toBeCalledTimes(0);
|
||||
expect(childListener).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -267,15 +267,15 @@ describe('AbortContext', () => {
|
||||
|
||||
expect(parent.abortSignal.aborted).toBe(false);
|
||||
expect(child.abortSignal.aborted).toBe(false);
|
||||
expect(parentListener).toBeCalledTimes(0);
|
||||
expect(childListener).toBeCalledTimes(0);
|
||||
expect(parentListener).toHaveBeenCalledTimes(0);
|
||||
expect(childListener).toHaveBeenCalledTimes(0);
|
||||
|
||||
parentController.abort();
|
||||
|
||||
expect(parent.abortSignal.aborted).toBe(true);
|
||||
expect(child.abortSignal.aborted).toBe(true);
|
||||
expect(parentListener).toBeCalledTimes(1);
|
||||
expect(childListener).toBeCalledTimes(1);
|
||||
expect(parentListener).toHaveBeenCalledTimes(1);
|
||||
expect(childListener).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('does not signal parent when child is aborted', async () => {
|
||||
@@ -293,15 +293,15 @@ describe('AbortContext', () => {
|
||||
|
||||
expect(parent.abortSignal.aborted).toBe(false);
|
||||
expect(child.abortSignal.aborted).toBe(false);
|
||||
expect(parentListener).toBeCalledTimes(0);
|
||||
expect(childListener).toBeCalledTimes(0);
|
||||
expect(parentListener).toHaveBeenCalledTimes(0);
|
||||
expect(childListener).toHaveBeenCalledTimes(0);
|
||||
|
||||
childController.abort();
|
||||
|
||||
expect(parent.abortSignal.aborted).toBe(false);
|
||||
expect(child.abortSignal.aborted).toBe(true);
|
||||
expect(parentListener).toBeCalledTimes(0);
|
||||
expect(childListener).toBeCalledTimes(1);
|
||||
expect(parentListener).toHaveBeenCalledTimes(0);
|
||||
expect(childListener).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('child carries over parent signal state if parent was already aborted', async () => {
|
||||
@@ -319,13 +319,13 @@ describe('AbortContext', () => {
|
||||
|
||||
expect(parent.abortSignal.aborted).toBe(true);
|
||||
expect(child.abortSignal.aborted).toBe(true);
|
||||
expect(childListener).toBeCalledTimes(0);
|
||||
expect(childListener).toHaveBeenCalledTimes(0);
|
||||
|
||||
childController.abort();
|
||||
|
||||
expect(parent.abortSignal.aborted).toBe(true);
|
||||
expect(child.abortSignal.aborted).toBe(true);
|
||||
expect(childListener).toBeCalledTimes(0);
|
||||
expect(childListener).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('child carries over given signal state if it was already aborted', async () => {
|
||||
@@ -339,7 +339,7 @@ describe('AbortContext', () => {
|
||||
child.abortSignal.addEventListener('abort', childListener);
|
||||
|
||||
expect(child.abortSignal.aborted).toBe(true);
|
||||
expect(childListener).toBeCalledTimes(0);
|
||||
expect(childListener).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -29,6 +29,8 @@ import {
|
||||
} from './connection';
|
||||
import { PluginDatabaseManager } from './types';
|
||||
import path from 'path';
|
||||
import { Logger } from 'winston';
|
||||
import { stringifyError } from '@backstage/errors';
|
||||
|
||||
/**
|
||||
* Provides a config lookup path for a plugin's config block.
|
||||
@@ -44,6 +46,7 @@ function pluginPath(pluginId: string): string {
|
||||
*/
|
||||
export type DatabaseManagerOptions = {
|
||||
migrations?: PluginDatabaseManager['migrations'];
|
||||
logger?: Logger;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -339,6 +342,31 @@ export class DatabaseManager {
|
||||
schemaOverrides,
|
||||
);
|
||||
|
||||
return createDatabaseClient(pluginConfig, databaseClientOverrides);
|
||||
const client = createDatabaseClient(pluginConfig, databaseClientOverrides);
|
||||
this.startKeepaliveLoop(pluginId, client);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
private startKeepaliveLoop(pluginId: string, client: Knex): void {
|
||||
let lastKeepaliveFailed = false;
|
||||
|
||||
setInterval(() => {
|
||||
client.raw('select 1').then(
|
||||
() => {
|
||||
lastKeepaliveFailed = false;
|
||||
},
|
||||
(error: unknown) => {
|
||||
if (!lastKeepaliveFailed) {
|
||||
lastKeepaliveFailed = true;
|
||||
this.options?.logger?.warn(
|
||||
`Database keepalive failed for plugin ${pluginId}, ${stringifyError(
|
||||
error,
|
||||
)}`,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}, 60 * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ describe('database connection', () => {
|
||||
connection: '',
|
||||
}),
|
||||
),
|
||||
).toThrowError();
|
||||
).toThrow();
|
||||
});
|
||||
|
||||
it('throws an error without a connection', () => {
|
||||
@@ -120,7 +120,7 @@ describe('database connection', () => {
|
||||
client: 'pg',
|
||||
}),
|
||||
),
|
||||
).toThrowError();
|
||||
).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -147,7 +147,7 @@ describe('database connection', () => {
|
||||
});
|
||||
|
||||
it('throws an error for unknown connection', () => {
|
||||
expect(() => createNameOverride('unknown', 'testname')).toThrowError();
|
||||
expect(() => createNameOverride('unknown', 'testname')).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -194,7 +194,7 @@ describe('postgres', () => {
|
||||
'postgresql://postgres:pass@localhost:5432/dbname?sslrootcert=/path/to/file',
|
||||
),
|
||||
),
|
||||
).toThrowError(/no such file or directory/);
|
||||
).toThrow(/no such file or directory/);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -551,7 +551,7 @@ describe('GithubUrlReader', () => {
|
||||
credentialsProvider: mockCredentialsProvider,
|
||||
},
|
||||
);
|
||||
}).toThrowError('must configure an explicit apiBaseUrl');
|
||||
}).toThrow('must configure an explicit apiBaseUrl');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ describe('GcsUrlReader', () => {
|
||||
|
||||
it('throws if search url looks truly glob-y', async () => {
|
||||
const glob = 'https://storage.cloud.google.com/bucket/**/path*';
|
||||
await expect(() => reader.search(glob)).rejects.toThrowError(
|
||||
await expect(() => reader.search(glob)).rejects.toThrow(
|
||||
'GcsUrlReader only supports prefix-based searches',
|
||||
);
|
||||
});
|
||||
|
||||
@@ -55,7 +55,7 @@ describe('ReadUrlResponseFactory', () => {
|
||||
it('buffer cannot be called after stream is called', async () => {
|
||||
const response = await ReadUrlResponseFactory.fromReadable(readable);
|
||||
response.stream!();
|
||||
expect(() => response.buffer()).toThrowError(ConflictError);
|
||||
expect(() => response.buffer()).toThrow(ConflictError);
|
||||
});
|
||||
|
||||
it('stream returns expected data', async () => {
|
||||
@@ -68,7 +68,7 @@ describe('ReadUrlResponseFactory', () => {
|
||||
it('stream cannot be called after buffer is called', async () => {
|
||||
const response = await ReadUrlResponseFactory.fromReadable(readable);
|
||||
response.buffer();
|
||||
expect(() => response.stream!()).toThrowError(ConflictError);
|
||||
expect(() => response.stream!()).toThrow(ConflictError);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ describe('UrlReaderPredicateMux', () => {
|
||||
it('throws an error if no predicate matches', async () => {
|
||||
const mux = new UrlReaderPredicateMux(getVoidLogger());
|
||||
|
||||
await expect(mux.readUrl('http://foo/1')).rejects.toThrowError(
|
||||
await expect(mux.readUrl('http://foo/1')).rejects.toThrow(
|
||||
/^Reading from 'http:\/\/foo\/1' is not allowed. You may/,
|
||||
);
|
||||
|
||||
@@ -80,7 +80,7 @@ describe('UrlReaderPredicateMux', () => {
|
||||
|
||||
await expect(mux.readUrl('http://foo/1')).resolves.toBeUndefined();
|
||||
|
||||
await expect(mux.readUrl('http://bar/1')).rejects.toThrowError(
|
||||
await expect(mux.readUrl('http://bar/1')).rejects.toThrow(
|
||||
/^Reading from 'http:\/\/bar\/1' is not allowed. You may/,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -66,9 +66,9 @@ describe('ServerTokenManager', () => {
|
||||
const tokenManager = ServerTokenManager.fromConfig(configWithSecret, {
|
||||
logger,
|
||||
});
|
||||
await expect(
|
||||
tokenManager.authenticate('random-string'),
|
||||
).rejects.toThrowError(/invalid server token/i);
|
||||
await expect(tokenManager.authenticate('random-string')).rejects.toThrow(
|
||||
/invalid server token/i,
|
||||
);
|
||||
});
|
||||
|
||||
it('should validate server tokens created by a different instance using the same secret', async () => {
|
||||
@@ -129,7 +129,7 @@ describe('ServerTokenManager', () => {
|
||||
|
||||
const { token } = await tokenManager1.getToken();
|
||||
|
||||
await expect(tokenManager2.authenticate(token)).rejects.toThrowError(
|
||||
await expect(tokenManager2.authenticate(token)).rejects.toThrow(
|
||||
/invalid server token/i,
|
||||
);
|
||||
});
|
||||
@@ -145,7 +145,7 @@ describe('ServerTokenManager', () => {
|
||||
|
||||
const { token } = await noopTokenManager.getToken();
|
||||
|
||||
await expect(tokenManager.authenticate(token)).rejects.toThrowError(
|
||||
await expect(tokenManager.authenticate(token)).rejects.toThrow(
|
||||
/invalid server token/i,
|
||||
);
|
||||
});
|
||||
@@ -164,7 +164,7 @@ describe('ServerTokenManager', () => {
|
||||
|
||||
const { token } = await tokenManager2.getToken();
|
||||
|
||||
await expect(tokenManager1.authenticate(token)).rejects.toThrowError(
|
||||
await expect(tokenManager1.authenticate(token)).rejects.toThrow(
|
||||
/invalid server token/i,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
"@backstage/backend-plugin-api": "^0.1.2-next.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.18.2-next.0"
|
||||
"@backstage/cli": "^0.19.0-next.1"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# example-backend-next
|
||||
|
||||
## 0.0.3-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-catalog-backend@1.4.0-next.1
|
||||
- @backstage/plugin-scaffolder-backend@1.6.0-next.1
|
||||
|
||||
## 0.0.3-next.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "example-backend-next",
|
||||
"version": "0.0.3-next.0",
|
||||
"version": "0.0.3-next.1",
|
||||
"main": "dist/index.cjs.js",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -26,11 +26,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-defaults": "^0.1.1-next.0",
|
||||
"@backstage/plugin-catalog-backend": "^1.3.2-next.0",
|
||||
"@backstage/plugin-scaffolder-backend": "^1.6.0-next.0"
|
||||
"@backstage/plugin-catalog-backend": "^1.4.0-next.1",
|
||||
"@backstage/plugin-scaffolder-backend": "^1.6.0-next.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.18.2-next.0"
|
||||
"@backstage/cli": "^0.19.0-next.1"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
|
||||
@@ -20,6 +20,6 @@ import { createBackend } from '@backstage/backend-defaults';
|
||||
|
||||
const backend = createBackend();
|
||||
|
||||
backend.add(catalogPlugin({}));
|
||||
backend.add(scaffolderCatalogModule({}));
|
||||
backend.add(catalogPlugin());
|
||||
backend.add(scaffolderCatalogModule());
|
||||
backend.start();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user