Merge branch 'backstage:master' into master
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-github-actions': patch
|
||||
---
|
||||
|
||||
Show empty state only when workflow API call has completed
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-azure-devops': patch
|
||||
'@backstage/plugin-azure-devops-common': patch
|
||||
---
|
||||
|
||||
feat: Created pull request card component and initial pull request dashboard page.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/integration': patch
|
||||
---
|
||||
|
||||
Narrow the types returned by the request option functions, to only the specifics that they actually do return. The reason for this change is that a full `RequestInit` is unfortunate to return because it's different between `cross-fetch` and `node-fetch`.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
---
|
||||
|
||||
Removed unused scaffolder visibility configuration; this has been moved to publish actions. Deprecated scaffolder provider configuration keys; these should use the integrations configuration instead.
|
||||
@@ -1,51 +0,0 @@
|
||||
---
|
||||
'@backstage/create-app': patch
|
||||
---
|
||||
|
||||
Incorporate usage of the tokenManager into the backend created using `create-app`.
|
||||
|
||||
In existing backends, update the `PluginEnvironment` to include a `tokenManager`:
|
||||
|
||||
```diff
|
||||
// packages/backend/src/types.ts
|
||||
|
||||
...
|
||||
import {
|
||||
...
|
||||
+ TokenManager,
|
||||
} from '@backstage/backend-common';
|
||||
|
||||
export type PluginEnvironment = {
|
||||
...
|
||||
+ tokenManager: TokenManager;
|
||||
};
|
||||
```
|
||||
|
||||
Then, create a `ServerTokenManager`. This can either be a `noop` that requires no secret and validates all requests by default, or one that uses a secret from your `app-config.yaml` to generate and validate tokens.
|
||||
|
||||
```diff
|
||||
// packages/backend/src/index.ts
|
||||
|
||||
...
|
||||
import {
|
||||
...
|
||||
+ ServerTokenManager,
|
||||
} from '@backstage/backend-common';
|
||||
...
|
||||
|
||||
function makeCreateEnv(config: Config) {
|
||||
...
|
||||
// CHOOSE ONE
|
||||
// TokenManager not requiring a secret
|
||||
+ const tokenManager = ServerTokenManager.noop();
|
||||
// OR TokenManager requiring a secret
|
||||
+ const tokenManager = ServerTokenManager.fromConfig(config);
|
||||
|
||||
...
|
||||
return (plugin: string): PluginEnvironment => {
|
||||
...
|
||||
- return { logger, cache, database, config, reader, discovery };
|
||||
+ return { logger, cache, database, config, reader, discovery, tokenManager };
|
||||
};
|
||||
}
|
||||
```
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-kubernetes-backend': patch
|
||||
---
|
||||
|
||||
Added apiVersionOverrides config to allow for specifying api versions to use for kubernetes objects
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
'@backstage/config-loader': patch
|
||||
'@backstage/plugin-auth-backend': patch
|
||||
'@backstage/plugin-badges-backend': patch
|
||||
'@backstage/plugin-bitrise': patch
|
||||
'@backstage/plugin-catalog-backend': patch
|
||||
'@backstage/plugin-catalog-backend-module-msgraph': patch
|
||||
'@backstage/plugin-code-coverage-backend': patch
|
||||
'@backstage/plugin-fossa': patch
|
||||
'@backstage/plugin-jenkins-backend': patch
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch
|
||||
'@backstage/plugin-sonarqube': patch
|
||||
'@backstage/plugin-tech-insights-backend': patch
|
||||
'@backstage/plugin-techdocs-backend': patch
|
||||
'@backstage/plugin-todo-backend': patch
|
||||
---
|
||||
|
||||
Align on usage of `cross-fetch` vs `node-fetch` in frontend vs backend packages, and remove some unnecessary imports of either one of them
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-user-settings': patch
|
||||
---
|
||||
|
||||
The theme switcher now renders the title of themes instead of their variant
|
||||
@@ -1,28 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-backend': minor
|
||||
---
|
||||
|
||||
**BREAKING** `DefaultTechDocsCollator` has a new required option `tokenManager`. See the create-app changelog for how to create a `tokenManager` and add it to the `PluginEnvironment`. It can then be passed to the collator in `createPlugin`:
|
||||
|
||||
```diff
|
||||
// packages/backend/src/plugins/search.ts
|
||||
|
||||
...
|
||||
export default async function createPlugin({
|
||||
...
|
||||
+ tokenManager,
|
||||
}: PluginEnvironment) {
|
||||
...
|
||||
|
||||
indexBuilder.addCollator({
|
||||
defaultRefreshIntervalSeconds: 600,
|
||||
collator: DefaultTechDocsCollator.fromConfig(config, {
|
||||
discovery,
|
||||
logger,
|
||||
+ tokenManager,
|
||||
}),
|
||||
});
|
||||
|
||||
...
|
||||
}
|
||||
```
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-permission-node': minor
|
||||
'@backstage/plugin-permission-backend': patch
|
||||
---
|
||||
|
||||
Rename and adjust permission policy return type to reduce nesting
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/backend-common': patch
|
||||
---
|
||||
|
||||
Create a `TokenManager` interface and `ServerTokenManager` implementation to generate and validate server tokens for authenticated backend-to-backend API requests.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-kubernetes-backend': patch
|
||||
---
|
||||
|
||||
Query CronJobs from Kubernetes with apiGroup BatchV1beta1
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/cli': minor
|
||||
---
|
||||
|
||||
Remove the `backend:build-image` command from the CLI and added more deprecation warnings to other deprecated fields like `--lax` and `remove-plugin`
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-circleci': patch
|
||||
---
|
||||
|
||||
Fixed a bug in the `CircleCI` plugin where restarting builds was hard-coded to GitHub rather than introspecting the entity source location.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
'@techdocs/cli': patch
|
||||
---
|
||||
|
||||
Bump react-dev-utils to v12
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
build(dependencies): bump `style-loader` from 1.2.1 to 3.3.1
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/core-plugin-api': patch
|
||||
---
|
||||
|
||||
Tweaked the logged deprecation warning for `createRouteRef` to hopefully make it more clear.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-search': patch
|
||||
---
|
||||
|
||||
Add optional icon and secondaryAction properties for DefaultResultListItem component
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-search': patch
|
||||
---
|
||||
|
||||
Add a new optional clearButton property to the SearchBar component. The default value for this new property is true.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
'@backstage/backend-common': patch
|
||||
'@backstage/plugin-catalog-graphql': patch
|
||||
---
|
||||
|
||||
Move to using node-fetch internally instead of cross-fetch
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-auth-backend': patch
|
||||
---
|
||||
|
||||
Expose catalog lib in plugin-auth-backend, i.e `CatalogIdentityClient` class is exposed now.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/core-app-api': patch
|
||||
---
|
||||
|
||||
Fixed a bug where `useRouteRef` would fail in situations where relative navigation was needed and the app was is mounted on a sub-path. This would typically show up as a failure to navigate to a tab on an entity page.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
---
|
||||
|
||||
Add options to spawn in runCommand helper
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-azure-devops': patch
|
||||
'@backstage/plugin-azure-devops-backend': patch
|
||||
---
|
||||
|
||||
**Backend**
|
||||
|
||||
- Created new `/dashboard-pull-requests/:projectName` endpoint
|
||||
- Created new `/all-teams` endpoint
|
||||
- Implemented pull request policy evaluation conversion
|
||||
|
||||
**Frontend**
|
||||
|
||||
- Refactored `PullRequestsPage` and added new properties for `projectName` and `pollingInterval`
|
||||
- Fixed spacing issue between repo link and creation date in `PullRequestCard`
|
||||
- Added missing condition to `PullRequestCardPolicy` for `RequiredReviewers`
|
||||
- Updated `useDashboardPullRequests` hook to implement long polling for pull requests
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
'@backstage/plugin-apache-airflow': minor
|
||||
---
|
||||
|
||||
Introduces a new plugin for the Apache Airflow workflow management platform.
|
||||
This implementation has been tested with the Apache Airflow v2 API,
|
||||
authenticating with basic authentication through the Backstage proxy plugin.
|
||||
|
||||
Supported functionality includes:
|
||||
|
||||
- Information card of version information of the Airflow instance
|
||||
- Information card of instance health for the meta-database and scheduler
|
||||
- Table of DAGs with meta information and status, along with a link to view
|
||||
details in the Airflow UI
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-kubernetes': patch
|
||||
---
|
||||
|
||||
Added accordions to display information on Jobs and CronJobs in the kubernetes plugin. Updated the PodsTable with fewer default columns and the ability to pass in additional ones depending on the use case.
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
---
|
||||
|
||||
Add group filtering to the scaffolder page so that individuals can surface specific templates to end users ahead of others, or group templates together. This can be accomplished by passing in a `groups` prop to the `ScaffolderPage`
|
||||
|
||||
```
|
||||
<ScaffolderPage
|
||||
groups={[
|
||||
{
|
||||
title: "Recommended",
|
||||
filter: entity =>
|
||||
entity?.metadata?.tags?.includes('recommended') ?? false,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
```
|
||||
@@ -1,27 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend': minor
|
||||
---
|
||||
|
||||
**BREAKING** `DefaultCatalogCollator` has a new required option `tokenManager`. See the create-app changelog for how to create a `tokenManager` and add it to the `PluginEnvironment`. It can then be passed to the collator in `createPlugin`:
|
||||
|
||||
```diff
|
||||
// packages/backend/src/plugins/search.ts
|
||||
|
||||
...
|
||||
export default async function createPlugin({
|
||||
...
|
||||
+ tokenManager,
|
||||
}: PluginEnvironment) {
|
||||
...
|
||||
|
||||
indexBuilder.addCollator({
|
||||
defaultRefreshIntervalSeconds: 600,
|
||||
collator: DefaultCatalogCollator.fromConfig(config, {
|
||||
discovery,
|
||||
+ tokenManager,
|
||||
}),
|
||||
});
|
||||
|
||||
...
|
||||
}
|
||||
```
|
||||
@@ -23,10 +23,13 @@
|
||||
/plugins/azure-devops @backstage/reviewers @marleypowell @awanlin
|
||||
/plugins/azure-devops-backend @backstage/reviewers @marleypowell @awanlin
|
||||
/plugins/azure-devops-common @backstage/reviewers @marleypowell @awanlin
|
||||
/plugins/jenkins @backstage/reviewers @timja
|
||||
/plugins/jenkins-backend @backstage/reviewers @timja
|
||||
/plugins/kafka @backstage/reviewers @nirga
|
||||
/plugins/kafka-backend @backstage/reviewers @nirga
|
||||
/plugins/scaffolder-backend-module-yeoman @backstage/reviewers @pawelmitka
|
||||
/plugins/scaffolder-backend-module-rails @backstage/reviewers @angeliski
|
||||
/plugins/git-release-manager @backstage/reviewers @erikengervall
|
||||
/tech-insights-backend @backstage/reviewers @xantier @iain-b
|
||||
/tech-insights-backend-module-jsonfc @backstage/reviewers @xantier @iain-b
|
||||
/tech-insights-tech-insights-common @backstage/reviewers @xantier @iain-b
|
||||
|
||||
+4
-2
@@ -5,7 +5,7 @@
|
||||
| [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. |
|
||||
| [SDA SE](https://sda.se) | [@dschwank](https://github.com/dschwank), [@iammnils](https://github.com/iammnils) | 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. |
|
||||
@@ -72,4 +72,6 @@
|
||||
| [Globo](https://globo.com) | [Carlos Gusmão](https://github.com/caeugusmao), [Guilherme Vierno](https://github.com/vierno), [Denis Aoki](https://github.com/dnsaoki2), [Maycon Dionisio](https://github.com/MayconDionisio), | Reduce the friction of accessing the information engineers need about Globo's digital services through a coherent and centralized experience. |
|
||||
| [QBE](https://www.qbe.com/) | [Daniel Steel](https://github.com/danielsteelqbe), [Pete Jespers](https://github.com/petejespersqbe) | Developer portal allowing our global teams to explore and create applications, documentation and cloud infrastructure easily and quickly 🚀 |
|
||||
| [LogMeIn](https://www.logmein.com) | [Lorenzo Orsatti](https://github.com/lorsatti) | Improve onboarding experience of new developers. Discover faster and painlessly developer documentation, API definitions and team information. Provide useful dev metrics in a central place. Provide easy-to-use templates for new services. |
|
||||
| [Telstra](https://www.telstra.com.au) | [@kiranpatel11](https://github.com/kiranpatel11), [JasonC](https://github.com/JasonC17) | Primary usage: software catalog and templates<br/> Emerging usage : TechDocs, Explore Ecosystem, TechRadar, etc |
|
||||
| [Telstra](https://www.telstra.com.au) | [@kiranpatel11](https://github.com/kiranpatel11), [JasonC](https://github.com/JasonC17) | Primary usage: software catalog and templates<br/> Emerging usage : TechDocs, Explore Ecosystem, TechRadar, etc |
|
||||
| [Mosaico](https://www.mosaico.com.br/) | [Wédney Yuri](https://github.com/wedneyyuri),[@tino.milton](https://github.com/miltonjacomini) | A centralized service catalog of our documentation for our service engineers. |
|
||||
| [Mox Bank](https://www.mox.com/) | [Nick Laqua](https://github.com/nick-laqua-dragon), [Gauthier Roebroeck](https://github.com/gauthier-roebroeck-mox) | "Single pane of glass" developer portal for providing a best-in-class developer experience to our product teams and making Mox the best tech environment in Hongkong 🥰🚀 |
|
||||
|
||||
@@ -97,6 +97,11 @@ proxy:
|
||||
headers:
|
||||
Authorization: ${ILERT_AUTH_HEADER}
|
||||
|
||||
'/airflow':
|
||||
target: https://your.airflow.instance.com/api/v1
|
||||
headers:
|
||||
Authorization: ${AIRFLOW_BASIC_AUTH_HEADER}
|
||||
|
||||
organization:
|
||||
name: My Company
|
||||
|
||||
@@ -437,3 +442,6 @@ azureDevOps:
|
||||
host: dev.azure.com
|
||||
token: my-token
|
||||
organization: my-company
|
||||
|
||||
apacheAirflow:
|
||||
baseUrl: https://your.airflow.instance.com
|
||||
|
||||
+26
-78
@@ -13,9 +13,9 @@
|
||||
figures "^1.7.0"
|
||||
|
||||
"@cypress/request@^2.88.5":
|
||||
version "2.88.5"
|
||||
resolved "https://registry.npmjs.org/@cypress/request/-/request-2.88.5.tgz#8d7ecd17b53a849cfd5ab06d5abe7d84976375d7"
|
||||
integrity sha512-TzEC1XMi1hJkywWpRfD2clreTa/Z+lOrXDCxxBTBPEcY5azdPi56A6Xw+O4tWJnaJH3iIE7G5aDXZC6JgRZLcA==
|
||||
version "2.88.10"
|
||||
resolved "https://registry.npmjs.org/@cypress/request/-/request-2.88.10.tgz#b66d76b07f860d3a4b8d7a0604d020c662752cce"
|
||||
integrity sha512-Zp7F+R93N0yZyG34GutyTNr+okam7s/Fzc1+i3kcqOP8vk6OuajuE9qZJ6Rs+10/1JFtXFYMdyarnU1rZuJesg==
|
||||
dependencies:
|
||||
aws-sign2 "~0.7.0"
|
||||
aws4 "^1.8.0"
|
||||
@@ -24,19 +24,17 @@
|
||||
extend "~3.0.2"
|
||||
forever-agent "~0.6.1"
|
||||
form-data "~2.3.2"
|
||||
har-validator "~5.1.3"
|
||||
http-signature "~1.2.0"
|
||||
http-signature "~1.3.6"
|
||||
is-typedarray "~1.0.0"
|
||||
isstream "~0.1.2"
|
||||
json-stringify-safe "~5.0.1"
|
||||
mime-types "~2.1.19"
|
||||
oauth-sign "~0.9.0"
|
||||
performance-now "^2.1.0"
|
||||
qs "~6.5.2"
|
||||
safe-buffer "^5.1.2"
|
||||
tough-cookie "~2.5.0"
|
||||
tunnel-agent "^0.6.0"
|
||||
uuid "^3.3.2"
|
||||
uuid "^8.3.2"
|
||||
|
||||
"@cypress/xvfb@^1.2.4":
|
||||
version "1.2.4"
|
||||
@@ -68,16 +66,6 @@
|
||||
resolved "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47"
|
||||
integrity sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==
|
||||
|
||||
ajv@^6.12.3:
|
||||
version "6.12.6"
|
||||
resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
|
||||
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.1"
|
||||
fast-json-stable-stringify "^2.0.0"
|
||||
json-schema-traverse "^0.4.1"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
ansi-escapes@^3.0.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b"
|
||||
@@ -539,16 +527,6 @@ extsprintf@^1.2.0:
|
||||
resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
|
||||
integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
|
||||
|
||||
fast-deep-equal@^3.1.1:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||
|
||||
fast-json-stable-stringify@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
|
||||
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
|
||||
|
||||
fd-slicer@~1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
|
||||
@@ -645,19 +623,6 @@ graceful-fs@^4.1.6, graceful-fs@^4.2.0:
|
||||
resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.5.tgz#bc18864a6c9fc7b303f2e2abdb9155ad178fbe29"
|
||||
integrity sha512-kBBSQbz2K0Nyn+31j/w36fUfxkBW9/gfwRWdUY1ULReH3iokVJgddZAFcD1D0xlgTmFxJCbUkUclAlc6/IDJkw==
|
||||
|
||||
har-schema@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
|
||||
integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
|
||||
|
||||
har-validator@~5.1.3:
|
||||
version "5.1.5"
|
||||
resolved "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd"
|
||||
integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==
|
||||
dependencies:
|
||||
ajv "^6.12.3"
|
||||
har-schema "^2.0.0"
|
||||
|
||||
has-ansi@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
|
||||
@@ -675,14 +640,14 @@ has-flag@^4.0.0:
|
||||
resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
|
||||
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
|
||||
|
||||
http-signature@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
|
||||
integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
|
||||
http-signature@~1.3.6:
|
||||
version "1.3.6"
|
||||
resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz#cb6fbfdf86d1c974f343be94e87f7fc128662cf9"
|
||||
integrity sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
jsprim "^1.2.2"
|
||||
sshpk "^1.7.0"
|
||||
jsprim "^2.0.2"
|
||||
sshpk "^1.14.1"
|
||||
|
||||
human-signals@^1.1.1:
|
||||
version "1.1.1"
|
||||
@@ -796,15 +761,10 @@ jsbn@~0.1.0:
|
||||
resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
|
||||
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
|
||||
|
||||
json-schema-traverse@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
||||
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
|
||||
|
||||
json-schema@0.2.3:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
|
||||
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
|
||||
json-schema@0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
|
||||
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
|
||||
|
||||
json-stringify-safe@~5.0.1:
|
||||
version "5.0.1"
|
||||
@@ -820,14 +780,14 @@ jsonfile@^6.0.1:
|
||||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
jsprim@^1.2.2:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
|
||||
integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
|
||||
jsprim@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz#77ca23dbcd4135cd364800d22ff82c2185803d4d"
|
||||
integrity sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==
|
||||
dependencies:
|
||||
assert-plus "1.0.0"
|
||||
extsprintf "1.3.0"
|
||||
json-schema "0.2.3"
|
||||
json-schema "0.4.0"
|
||||
verror "1.10.0"
|
||||
|
||||
lazy-ass@^1.6.0:
|
||||
@@ -985,11 +945,6 @@ number-is-nan@^1.0.0:
|
||||
resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
|
||||
integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
|
||||
|
||||
oauth-sign@~0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
|
||||
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
|
||||
|
||||
object-assign@^4.1.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
@@ -1084,7 +1039,7 @@ punycode@1.3.2:
|
||||
resolved "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
|
||||
integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=
|
||||
|
||||
punycode@^2.1.0, punycode@^2.1.1:
|
||||
punycode@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
||||
@@ -1191,7 +1146,7 @@ slice-ansi@0.0.4:
|
||||
resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
|
||||
integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=
|
||||
|
||||
sshpk@^1.7.0:
|
||||
sshpk@^1.14.1:
|
||||
version "1.16.1"
|
||||
resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877"
|
||||
integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==
|
||||
@@ -1353,13 +1308,6 @@ untildify@^4.0.0:
|
||||
resolved "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b"
|
||||
integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==
|
||||
|
||||
uri-js@^4.2.2:
|
||||
version "4.4.1"
|
||||
resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
|
||||
integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
|
||||
dependencies:
|
||||
punycode "^2.1.0"
|
||||
|
||||
url@^0.11.0:
|
||||
version "0.11.0"
|
||||
resolved "https://registry.npmjs.org/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
|
||||
@@ -1373,10 +1321,10 @@ util-deprecate@~1.0.1:
|
||||
resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
|
||||
|
||||
uuid@^3.3.2:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
|
||||
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
|
||||
uuid@^8.3.2:
|
||||
version "8.3.2"
|
||||
resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
|
||||
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
|
||||
|
||||
verror@1.10.0:
|
||||
version "1.10.0"
|
||||
|
||||
@@ -291,7 +291,7 @@ The figure below shows the relationship between
|
||||
<span style="color: #b85450">fooApiRef</span>.
|
||||
|
||||
<div style="text-align:center">
|
||||
<img src="../assets/utility-apis-fig1.svg" alt="Figure showing the relationship between utility APIs, the apps that provide them, and the plugins that consume them">
|
||||
<img src="../assets/utility-apis-fig1.svg" alt="Figure showing the relationship between utility APIs, the apps that provide them, and the plugins that consume them" />
|
||||
</div>
|
||||
|
||||
The current method for connecting Utility API providers and consumers is via the
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 64 KiB |
@@ -26,6 +26,7 @@ kubernetes:
|
||||
name: minikube
|
||||
authProvider: 'serviceAccount'
|
||||
skipTLSVerify: false
|
||||
skipMetricsLookup: true
|
||||
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
|
||||
@@ -37,6 +38,7 @@ kubernetes:
|
||||
projectId: 'gke-clusters'
|
||||
region: 'europe-west1'
|
||||
skipTLSVerify: true
|
||||
skipMetricsLookup: true
|
||||
```
|
||||
|
||||
### `serviceLocatorMethod`
|
||||
@@ -86,8 +88,13 @@ cluster. Valid values are:
|
||||
|
||||
##### `clusters.\*.skipTLSVerify`
|
||||
|
||||
This determines whether or not the Kubernetes client verifies the TLS
|
||||
certificate presented by the API server. Defaults to `false`.
|
||||
This determines whether the Kubernetes client verifies the TLS certificate
|
||||
presented by the API server. Defaults to `false`.
|
||||
|
||||
##### `clusters.\*.skipMetricsLookup`
|
||||
|
||||
This determines whether the Kubernetes client looks up resource metrics
|
||||
CPU/Memory for pods returned by the API server. Defaults to `false`.
|
||||
|
||||
##### `clusters.\*.serviceAccountToken` (optional)
|
||||
|
||||
@@ -188,8 +195,13 @@ regions.
|
||||
|
||||
##### `skipTLSVerify`
|
||||
|
||||
This determines whether or not the Kubernetes client verifies the TLS
|
||||
certificate presented by the API server. Defaults to `false`.
|
||||
This determines whether the Kubernetes client verifies the TLS certificate
|
||||
presented by the API server. Defaults to `false`.
|
||||
|
||||
##### `skipMetricsLookup`
|
||||
|
||||
This determines whether the Kubernetes client looks up resource metrics
|
||||
CPU/Memory for pods returned by the API server. Defaults to `false`.
|
||||
|
||||
### `customResources` (optional)
|
||||
|
||||
|
||||
@@ -114,13 +114,15 @@ const routes = (
|
||||
In `Root.tsx`, add the `SidebarSearchModal` component:
|
||||
|
||||
```bash
|
||||
import { SidebarSearchModal } from '@backstage/plugin-search';
|
||||
import { SidebarSearchModal, SearchContextProvider } from '@backstage/plugin-search';
|
||||
|
||||
export const Root = ({ children }: PropsWithChildren<{}>) => (
|
||||
<SidebarPage>
|
||||
<Sidebar>
|
||||
<SidebarLogo />
|
||||
<SidebarSearchModal />
|
||||
<SearchContextProvider>
|
||||
<SidebarSearchModal />
|
||||
</SearchContextProvider>
|
||||
<SidebarDivider />
|
||||
...
|
||||
```
|
||||
|
||||
@@ -11,13 +11,13 @@ would be good to also have some files in there that can be templated in.
|
||||
A simple `template.yaml` definition might look something like this:
|
||||
|
||||
```yaml
|
||||
apiVersion: backstage.io/v1beta2
|
||||
apiVersion: scaffolder.backstage.io/v1beta3
|
||||
kind: Template
|
||||
# some metadata about the template itself
|
||||
metadata:
|
||||
name: v1beta2-demo
|
||||
name: v1beta3-demo
|
||||
title: Test Action template
|
||||
description: scaffolder v1beta2 template demo
|
||||
description: scaffolder v1beta3 template demo
|
||||
spec:
|
||||
owner: backstage/techdocs-core
|
||||
type: service
|
||||
@@ -55,7 +55,7 @@ spec:
|
||||
input:
|
||||
url: ./template
|
||||
values:
|
||||
name: '{{ parameters.name }}'
|
||||
name: ${{ parameters.name }}
|
||||
|
||||
- id: fetch-docs
|
||||
name: Fetch Docs
|
||||
@@ -69,14 +69,14 @@ spec:
|
||||
action: publish:github
|
||||
input:
|
||||
allowedHosts: ['github.com']
|
||||
description: 'This is {{ parameters.name }}'
|
||||
repoUrl: '{{ parameters.repoUrl }}'
|
||||
description: This is ${{ parameters.name }}
|
||||
repoUrl: ${{ parameters.repoUrl }}
|
||||
|
||||
- id: register
|
||||
name: Register
|
||||
action: catalog:register
|
||||
input:
|
||||
repoContentsUrl: '{{ steps.publish.output.repoContentsUrl }}'
|
||||
repoContentsUrl: ${{ steps.publish.output.repoContentsUrl }}
|
||||
catalogInfoPath: '/catalog-info.yaml'
|
||||
```
|
||||
|
||||
|
||||
@@ -18,17 +18,31 @@ The next step is to add
|
||||
[add templates](http://backstage.io/docs/features/software-templates/adding-templates)
|
||||
to your Backstage app.
|
||||
|
||||
### GitHub
|
||||
### Publishing defaults
|
||||
|
||||
For GitHub, you can configure who can see the new repositories that are created
|
||||
by specifying `visibility` option. Valid options are `public`, `private` and
|
||||
`internal`. The `internal` option is for GitHub Enterprise clients, which means
|
||||
public within the enterprise.
|
||||
Software templates can define _publish_ actions, such as `publish:github`, to
|
||||
create new repositories or submit pull / merge requests to existing
|
||||
repositories. You can configure the author and commit message through the
|
||||
`scaffolder` configuration in `app-config.yaml`:
|
||||
|
||||
```yaml
|
||||
scaffolder:
|
||||
github:
|
||||
visibility: public # or 'internal' or 'private'
|
||||
defaultAuthor:
|
||||
name: M.C. Hammer # Defaults to `Scaffolder`
|
||||
email: hammer@donthurtem.com # Defaults to `scaffolder@backstage.io`
|
||||
defaultCommitMessage: "U can't touch this" # Defaults to 'Initial commit'
|
||||
```
|
||||
|
||||
To configure who can see the new repositories created from software templates,
|
||||
add the `repoVisibility` key within a software template:
|
||||
|
||||
```yaml
|
||||
- id: publish
|
||||
name: Publish
|
||||
action: publish:github
|
||||
input:
|
||||
repoUrl: '{{ parameters.repoUrl }}'
|
||||
repoVisibility: public # or 'internal' or 'private'
|
||||
```
|
||||
|
||||
### Disabling Docker in Docker situation (Optional)
|
||||
|
||||
@@ -12,7 +12,7 @@ code, template in some variables, and then publish the template to some
|
||||
locations like GitHub or GitLab.
|
||||
|
||||
<video width="100%" height="100%" controls>
|
||||
<source src="https://backstage.io/blog/assets/2020-08-05/feature.mp4" type="video/mp4">
|
||||
<source src="https://backstage.io/blog/assets/2020-08-05/feature.mp4" type="video/mp4" />
|
||||
</video>
|
||||
|
||||
### Getting Started
|
||||
|
||||
@@ -6,21 +6,21 @@ description: Details around creating your own custom Software Templates
|
||||
|
||||
Templates are stored in the **Software Catalog** under a kind `Template`. You
|
||||
can create your own templates with a small `yaml` definition which describes the
|
||||
template and it's metadata, along with some input variables that your template
|
||||
template and its metadata, along with some input variables that your template
|
||||
will need, and then a list of actions which are then executed by the scaffolding
|
||||
service.
|
||||
|
||||
Let's take a look at a simple example:
|
||||
|
||||
```yaml
|
||||
# Notice the v1beta2 version
|
||||
apiVersion: backstage.io/v1beta2
|
||||
# Notice the v1beta3 version
|
||||
apiVersion: scaffolder.backstage.io/v1beta3
|
||||
kind: Template
|
||||
# some metadata about the template itself
|
||||
metadata:
|
||||
name: v1beta2-demo
|
||||
name: v1beta3-demo
|
||||
title: Test Action template
|
||||
description: scaffolder v1beta2 template demo
|
||||
description: scaffolder v1beta3 template demo
|
||||
spec:
|
||||
owner: backstage/techdocs-core
|
||||
type: service
|
||||
@@ -66,8 +66,8 @@ spec:
|
||||
input:
|
||||
url: ./template
|
||||
values:
|
||||
name: '{{ parameters.name }}'
|
||||
owner: '{{ parameters.owner }}'
|
||||
name: ${{ parameters.name }}
|
||||
owner: ${{ parameters.owner }}
|
||||
|
||||
- id: fetch-docs
|
||||
name: Fetch Docs
|
||||
@@ -81,20 +81,20 @@ spec:
|
||||
action: publish:github
|
||||
input:
|
||||
allowedHosts: ['github.com']
|
||||
description: 'This is {{ parameters.name }}'
|
||||
repoUrl: '{{ parameters.repoUrl }}'
|
||||
description: This is ${{ parameters.name }}
|
||||
repoUrl: ${{ parameters.repoUrl }}
|
||||
|
||||
- id: register
|
||||
name: Register
|
||||
action: catalog:register
|
||||
input:
|
||||
repoContentsUrl: '{{ steps.publish.output.repoContentsUrl }}'
|
||||
repoContentsUrl: ${{ steps.publish.output.repoContentsUrl }}
|
||||
catalogInfoPath: '/catalog-info.yaml'
|
||||
|
||||
# some outputs which are saved along with the job for use in the frontend
|
||||
output:
|
||||
remoteUrl: '{{ steps.publish.output.remoteUrl }}'
|
||||
entityRef: '{{ steps.register.output.entityRef }}'
|
||||
remoteUrl: ${{ steps.publish.output.remoteUrl }}
|
||||
entityRef: ${{ steps.register.output.entityRef }}
|
||||
```
|
||||
|
||||
Let's dive in and pick apart what each of these sections do and what they are.
|
||||
@@ -183,12 +183,12 @@ this:
|
||||
It would look something like the following in a template:
|
||||
|
||||
```yaml
|
||||
apiVersion: backstage.io/v1beta2
|
||||
apiVersion: scaffolder.backstage.io/v1beta3
|
||||
kind: Template
|
||||
metadata:
|
||||
name: v1beta2-demo
|
||||
name: v1beta3-demo
|
||||
title: Test Action template
|
||||
description: scaffolder v1beta2 template demo
|
||||
description: scaffolder v1beta3 template demo
|
||||
spec:
|
||||
owner: backstage/techdocs-core
|
||||
type: service
|
||||
@@ -315,12 +315,12 @@ template. These follow the same standard format:
|
||||
```yaml
|
||||
- id: fetch-base # A unique id for the step
|
||||
name: Fetch Base # A title displayed in the frontend
|
||||
if: '{{ parameters.name }}' # Optional condition, skip the step if not truthy
|
||||
if: ${{ parameters.name }} # Optional condition, skip the step if not truthy
|
||||
action: fetch:template # An action to call
|
||||
input: # Input that is passed as arguments to the action handler
|
||||
url: ./template
|
||||
values:
|
||||
name: '{{ parameters.name }}'
|
||||
name: ${{ parameters.name }}
|
||||
```
|
||||
|
||||
By default we ship some [built in actions](./builtin-actions.md) that you can
|
||||
@@ -338,22 +338,19 @@ The main two that are used are the following:
|
||||
|
||||
```yaml
|
||||
output:
|
||||
remoteUrl: '{{ steps.publish.output.remoteUrl }}' # link to the remote repository
|
||||
entityRef: '{{ steps.register.output.entityRef }}' # link to the entity that has been ingested to the catalog
|
||||
remoteUrl: ${{ steps.publish.output.remoteUrl }} # link to the remote repository
|
||||
entityRef: ${{ steps.register.output.entityRef }} # link to the entity that has been ingested to the catalog
|
||||
```
|
||||
|
||||
### The templating syntax
|
||||
|
||||
You might have noticed variables wrapped in `{{ }}` in the examples. These are
|
||||
`handlebars` template strings for linking and gluing the different parts of the
|
||||
template together. All the form inputs from the `parameters` section will be
|
||||
available by using this template syntax (for example,
|
||||
`{{ parameters.firstName }}` inserts the value of `firstName` from the
|
||||
parameters). This is great for passing the values from the form into different
|
||||
steps and reusing these input variables. To pass arrays or objects use the
|
||||
`json` custom [helper](https://handlebarsjs.com/guide/expressions.html#helpers).
|
||||
For example, `{{ json parameters.nicknames }}` will insert the result of calling
|
||||
`JSON.stringify` on the value of the `nicknames` parameter.
|
||||
You might have noticed variables wrapped in `${{ }}` in the examples. These are
|
||||
template strings for linking and gluing the different parts of the template
|
||||
together. All the form inputs from the `parameters` section will be available by
|
||||
using this template syntax (for example, `${{ parameters.firstName }}` inserts
|
||||
the value of `firstName` from the parameters). This is great for passing the
|
||||
values from the form into different steps and reusing these input variables.
|
||||
These template strings preserve the type of the parameter.
|
||||
|
||||
As you can see above in the `Outputs` section, `actions` and `steps` can also
|
||||
output things. You can grab that output using `steps.$stepId.output.$property`.
|
||||
|
||||
@@ -40,7 +40,7 @@ storage system (e.g. AWS S3, GCS or Azure Blob Storage). Read more in
|
||||
|
||||
## Recommended deployment
|
||||
|
||||
This is how we recommend deploying TechDocs in production environment.
|
||||
This is how we recommend deploying TechDocs in a production environment.
|
||||
|
||||
<img data-zoomable src="../../assets/techdocs/architecture-recommended.drawio.svg" alt="TechDocs Architecture diagram" />
|
||||
|
||||
@@ -58,12 +58,12 @@ Similar to how it is done in the Basic setup, the TechDocs Reader requests
|
||||
your configured storage solution for the necessary files and returns them to
|
||||
TechDocs Reader.
|
||||
|
||||
Note about caching: We have noticed internally that some storage providers can
|
||||
be quite slow, which is why we are recommending a cache that sits between the
|
||||
TechDocs Reader and the Storage.
|
||||
|
||||
_Feel free to suggest better ideas to us in #docs-like-code channel in Discord
|
||||
or via a GitHub issue._
|
||||
Depending on your chosen cloud storage provider and its real-world proximity to
|
||||
your backend server, there may be a comparably high amount of latency when
|
||||
loading TechDocs sites using this deployment approach. If you encounter this,
|
||||
you can optionally configure the `techdocs-backend` to cache responses in a
|
||||
cache store
|
||||
[supported by Backstage](../../overview/architecture-overview.md#cache).
|
||||
|
||||
### Security consideration
|
||||
|
||||
|
||||
@@ -135,6 +135,22 @@ techdocs:
|
||||
# the old, case-sensitive entity triplet behavior.
|
||||
legacyUseCaseSensitiveTripletPaths: false
|
||||
|
||||
# techdocs.cache is optional, and is only recommended when you've configured
|
||||
# an external techdocs.publisher.type above. Also requires backend.cache to
|
||||
# be configured with a valid cache store.
|
||||
cache:
|
||||
# Represents the number of milliseconds a statically built asset should
|
||||
# stay cached. Cache invalidation is handled automatically by the frontend,
|
||||
# which compares the build times in cached metadata vs. canonical storage,
|
||||
# allowing long TTLs (e.g. 1 month/year)
|
||||
ttl: 3600000
|
||||
|
||||
# (Optional) The time (in milliseconds) that the TechDocs backend will wait
|
||||
# for a cache service to respond before continuing on as though the cached
|
||||
# object was not found (e.g. when the cache sercice is unavailable). The
|
||||
# default value is 1000
|
||||
readTimeout: 500
|
||||
|
||||
# (Optional and Legacy) TechDocs makes API calls to techdocs-backend using this URL. e.g. get docs of an entity, get metadata, etc.
|
||||
# You don't have to specify this anymore.
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ This will create a new Backstage App inside the current folder. The name of the
|
||||
app-folder is the name that was provided when prompted.
|
||||
|
||||
<p align='center'>
|
||||
<img src='../assets/getting-started/create-app_output.png' width='600' alt='create app'>
|
||||
<img src='../assets/getting-started/create-app_output.png' width='600' alt='create app' />
|
||||
</p>
|
||||
|
||||
Inside that directory, it will generate all the files and folder structure
|
||||
|
||||
@@ -58,7 +58,7 @@ The wizard will ask you
|
||||
SQLite option.
|
||||
|
||||
<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.'>
|
||||
<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>
|
||||
|
||||
### Run the Backstage app
|
||||
@@ -73,7 +73,7 @@ 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.'>
|
||||
<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
|
||||
@@ -84,7 +84,7 @@ database will be cleared when you restart the app, so you'll most likely want to
|
||||
carry on with the database steps.
|
||||
|
||||
<p align='center'>
|
||||
<img src='../assets/getting-started/portal.png' alt='Screenshot of the Backstage portal.'>
|
||||
<img src='../assets/getting-started/portal.png' alt='Screenshot of the Backstage portal.'/>
|
||||
</p>
|
||||
|
||||
The most common next steps are to move to a persistent database, configure
|
||||
|
||||
@@ -165,6 +165,7 @@ common example being the `migrations` directory.
|
||||
Usage: backstage-cli backend:build [options]
|
||||
|
||||
Options:
|
||||
--minify Minify the generated code
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
@@ -371,6 +372,7 @@ the monorepo.
|
||||
Usage: backstage-cli plugin:build [options]
|
||||
|
||||
Options:
|
||||
--minify Minify the generated code
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ authorURL: https://twitter.com/stalund
|
||||
**TL;DR** Today we are announcing a new Backstage feature: Software Templates. Simplify setup, standardize tooling, and deploy with the click of a button. Using automated templates, your engineers can spin up a new microservice, website, or other software component with your organization’s best practices built-in, right from the start.
|
||||
|
||||
<video width="100%" height="100%" controls>
|
||||
<source src="/blog/assets/2020-08-05/feature.mp4" type="video/mp4">
|
||||
<source src="/blog/assets/2020-08-05/feature.mp4" type="video/mp4" />
|
||||
</video>
|
||||
|
||||
<!--truncate-->
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"@spotify/prettier-config": "^12.0.0",
|
||||
"docusaurus": "^2.0.0-alpha.70",
|
||||
"js-yaml": "^4.1.0",
|
||||
"prettier": "^2.5.0",
|
||||
"prettier": "^2.5.1",
|
||||
"yarn-lock-check": "^1.0.5"
|
||||
},
|
||||
"prettier": "@spotify/prettier-config"
|
||||
|
||||
+4
-4
@@ -5190,10 +5190,10 @@ prepend-http@^2.0.0:
|
||||
resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
|
||||
integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
|
||||
|
||||
prettier@^2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.npmjs.org/prettier/-/prettier-2.5.0.tgz#a6370e2d4594e093270419d9cc47f7670488f893"
|
||||
integrity sha512-FM/zAKgWTxj40rH03VxzIPdXmj39SwSjwG0heUcNFwI+EMZJnY93yAiKXM3dObIKAM5TA88werc8T/EwhB45eg==
|
||||
prettier@^2.5.1:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a"
|
||||
integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==
|
||||
|
||||
prismjs@^1.22.0:
|
||||
version "1.25.0"
|
||||
|
||||
+2
-1
@@ -63,7 +63,8 @@
|
||||
"devDependencies": {
|
||||
"@changesets/cli": "^2.14.0",
|
||||
"@octokit/rest": "^18.12.0",
|
||||
"@spotify/prettier-config": "^11.0.0",
|
||||
"@spotify/prettier-config": "^12.0.0",
|
||||
"@types/node": "^14.14.32",
|
||||
"@types/webpack": "^5.28.0",
|
||||
"command-exists": "^1.2.9",
|
||||
"cross-env": "^7.0.0",
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# @backstage/app-defaults
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- cd450844f6: Moved React dependencies to `peerDependencies` and allow both React v16 and v17 to be used.
|
||||
- Updated dependencies
|
||||
- @backstage/core-components@0.8.0
|
||||
- @backstage/core-plugin-api@0.3.0
|
||||
- @backstage/core-app-api@0.2.0
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/app-defaults",
|
||||
"description": "Provides the default wiring of a Backstage App",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
@@ -29,23 +29,25 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/core-components": "^0.7.4",
|
||||
"@backstage/core-app-api": "^0.1.21",
|
||||
"@backstage/core-plugin-api": "^0.2.0",
|
||||
"@backstage/theme": "^0.2.13",
|
||||
"@backstage/core-components": "^0.8.0",
|
||||
"@backstage/core-app-api": "^0.2.0",
|
||||
"@backstage/core-plugin-api": "^0.3.0",
|
||||
"@backstage/theme": "^0.2.14",
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"react": "^16.12.0",
|
||||
"react-router-dom": "6.0.0-beta.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.9.0",
|
||||
"@backstage/test-utils": "^0.1.22",
|
||||
"@backstage/cli": "^0.10.1",
|
||||
"@backstage/test-utils": "^0.1.24",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@types/jest": "^26.0.7",
|
||||
"@types/node": "^14.14.32",
|
||||
"@types/react": "*"
|
||||
"@types/react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
|
||||
@@ -1,5 +1,70 @@
|
||||
# example-app
|
||||
|
||||
## 0.2.56
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/core-components@0.8.0
|
||||
- @backstage/core-plugin-api@0.3.0
|
||||
- @backstage/plugin-cloudbuild@0.2.29
|
||||
- @backstage/plugin-catalog@0.7.4
|
||||
- @backstage/core-app-api@0.2.0
|
||||
- @backstage/plugin-scaffolder@0.11.14
|
||||
- @backstage/plugin-kubernetes@0.5.0
|
||||
- @backstage/app-defaults@0.1.2
|
||||
- @backstage/integration-react@0.1.15
|
||||
- @backstage/plugin-api-docs@0.6.18
|
||||
- @backstage/plugin-azure-devops@0.1.6
|
||||
- @backstage/plugin-badges@0.2.16
|
||||
- @backstage/plugin-catalog-graph@0.2.3
|
||||
- @backstage/plugin-catalog-import@0.7.5
|
||||
- @backstage/plugin-catalog-react@0.6.5
|
||||
- @backstage/plugin-circleci@0.2.31
|
||||
- @backstage/plugin-code-coverage@0.1.19
|
||||
- @backstage/plugin-cost-insights@0.11.13
|
||||
- @backstage/plugin-explore@0.3.22
|
||||
- @backstage/plugin-gcp-projects@0.3.10
|
||||
- @backstage/plugin-github-actions@0.4.26
|
||||
- @backstage/plugin-graphiql@0.2.24
|
||||
- @backstage/plugin-home@0.4.7
|
||||
- @backstage/plugin-jenkins@0.5.14
|
||||
- @backstage/plugin-kafka@0.2.22
|
||||
- @backstage/plugin-lighthouse@0.2.31
|
||||
- @backstage/plugin-newrelic@0.3.10
|
||||
- @backstage/plugin-org@0.3.30
|
||||
- @backstage/plugin-pagerduty@0.3.19
|
||||
- @backstage/plugin-rollbar@0.3.20
|
||||
- @backstage/plugin-search@0.5.1
|
||||
- @backstage/plugin-sentry@0.3.30
|
||||
- @backstage/plugin-shortcuts@0.1.15
|
||||
- @backstage/plugin-tech-insights@0.1.1
|
||||
- @backstage/plugin-tech-radar@0.4.13
|
||||
- @backstage/plugin-techdocs@0.12.9
|
||||
- @backstage/plugin-todo@0.1.16
|
||||
- @backstage/plugin-user-settings@0.3.13
|
||||
- @backstage/cli@0.10.1
|
||||
|
||||
## 0.2.55
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-azure-devops@0.1.5
|
||||
- @backstage/core-components@0.7.6
|
||||
- @backstage/theme@0.2.14
|
||||
- @backstage/plugin-user-settings@0.3.12
|
||||
- @backstage/plugin-api-docs@0.6.16
|
||||
- @backstage/cli@0.10.0
|
||||
- @backstage/plugin-circleci@0.2.30
|
||||
- @backstage/core-plugin-api@0.2.2
|
||||
- @backstage/plugin-search@0.5.0
|
||||
- @backstage/plugin-tech-insights@0.1.0
|
||||
- @backstage/core-app-api@0.1.24
|
||||
- @backstage/plugin-kubernetes@0.4.22
|
||||
- @backstage/plugin-scaffolder@0.11.13
|
||||
- @backstage/plugin-techdocs@0.12.8
|
||||
|
||||
## 0.2.53
|
||||
|
||||
### Patch Changes
|
||||
|
||||
+45
-44
@@ -1,62 +1,63 @@
|
||||
{
|
||||
"name": "example-app",
|
||||
"version": "0.2.53",
|
||||
"version": "0.2.56",
|
||||
"private": true,
|
||||
"bundled": true,
|
||||
"dependencies": {
|
||||
"@backstage/app-defaults": "^0.1.1",
|
||||
"@backstage/app-defaults": "^0.1.2",
|
||||
"@backstage/catalog-model": "^0.9.7",
|
||||
"@backstage/cli": "^0.9.0",
|
||||
"@backstage/core-app-api": "^0.1.21",
|
||||
"@backstage/core-components": "^0.7.4",
|
||||
"@backstage/core-plugin-api": "^0.2.0",
|
||||
"@backstage/integration-react": "^0.1.14",
|
||||
"@backstage/plugin-api-docs": "^0.6.14",
|
||||
"@backstage/plugin-azure-devops": "^0.1.4",
|
||||
"@backstage/plugin-badges": "^0.2.14",
|
||||
"@backstage/plugin-catalog": "^0.7.3",
|
||||
"@backstage/plugin-catalog-graph": "^0.2.2",
|
||||
"@backstage/plugin-catalog-import": "^0.7.4",
|
||||
"@backstage/plugin-catalog-react": "^0.6.4",
|
||||
"@backstage/plugin-circleci": "^0.2.29",
|
||||
"@backstage/plugin-cloudbuild": "^0.2.28",
|
||||
"@backstage/plugin-code-coverage": "^0.1.18",
|
||||
"@backstage/plugin-cost-insights": "^0.11.11",
|
||||
"@backstage/plugin-explore": "^0.3.21",
|
||||
"@backstage/plugin-gcp-projects": "^0.3.9",
|
||||
"@backstage/plugin-github-actions": "^0.4.24",
|
||||
"@backstage/plugin-graphiql": "^0.2.21",
|
||||
"@backstage/plugin-home": "^0.4.6",
|
||||
"@backstage/plugin-jenkins": "^0.5.12",
|
||||
"@backstage/plugin-kafka": "^0.2.21",
|
||||
"@backstage/plugin-kubernetes": "^0.4.20",
|
||||
"@backstage/plugin-lighthouse": "^0.2.30",
|
||||
"@backstage/plugin-newrelic": "^0.3.9",
|
||||
"@backstage/plugin-org": "^0.3.28",
|
||||
"@backstage/plugin-pagerduty": "0.3.18",
|
||||
"@backstage/plugin-rollbar": "^0.3.19",
|
||||
"@backstage/plugin-scaffolder": "^0.11.11",
|
||||
"@backstage/plugin-search": "^0.4.18",
|
||||
"@backstage/plugin-sentry": "^0.3.29",
|
||||
"@backstage/plugin-shortcuts": "^0.1.14",
|
||||
"@backstage/plugin-tech-radar": "^0.4.12",
|
||||
"@backstage/plugin-techdocs": "^0.12.6",
|
||||
"@backstage/plugin-todo": "^0.1.15",
|
||||
"@backstage/plugin-user-settings": "^0.3.11",
|
||||
"@backstage/cli": "^0.10.1",
|
||||
"@backstage/core-app-api": "^0.2.0",
|
||||
"@backstage/core-components": "^0.8.0",
|
||||
"@backstage/core-plugin-api": "^0.3.0",
|
||||
"@backstage/integration-react": "^0.1.15",
|
||||
"@backstage/plugin-api-docs": "^0.6.18",
|
||||
"@backstage/plugin-azure-devops": "^0.1.6",
|
||||
"@backstage/plugin-apache-airflow": "^0.0.0",
|
||||
"@backstage/plugin-badges": "^0.2.16",
|
||||
"@backstage/plugin-catalog": "^0.7.4",
|
||||
"@backstage/plugin-catalog-graph": "^0.2.3",
|
||||
"@backstage/plugin-catalog-import": "^0.7.5",
|
||||
"@backstage/plugin-catalog-react": "^0.6.5",
|
||||
"@backstage/plugin-circleci": "^0.2.31",
|
||||
"@backstage/plugin-cloudbuild": "^0.2.29",
|
||||
"@backstage/plugin-code-coverage": "^0.1.19",
|
||||
"@backstage/plugin-cost-insights": "^0.11.13",
|
||||
"@backstage/plugin-explore": "^0.3.22",
|
||||
"@backstage/plugin-gcp-projects": "^0.3.10",
|
||||
"@backstage/plugin-github-actions": "^0.4.26",
|
||||
"@backstage/plugin-graphiql": "^0.2.24",
|
||||
"@backstage/plugin-home": "^0.4.7",
|
||||
"@backstage/plugin-jenkins": "^0.5.14",
|
||||
"@backstage/plugin-kafka": "^0.2.22",
|
||||
"@backstage/plugin-kubernetes": "^0.5.0",
|
||||
"@backstage/plugin-lighthouse": "^0.2.31",
|
||||
"@backstage/plugin-newrelic": "^0.3.10",
|
||||
"@backstage/plugin-org": "^0.3.30",
|
||||
"@backstage/plugin-pagerduty": "0.3.19",
|
||||
"@backstage/plugin-rollbar": "^0.3.20",
|
||||
"@backstage/plugin-scaffolder": "^0.11.14",
|
||||
"@backstage/plugin-search": "^0.5.1",
|
||||
"@backstage/plugin-sentry": "^0.3.30",
|
||||
"@backstage/plugin-shortcuts": "^0.1.15",
|
||||
"@backstage/plugin-tech-radar": "^0.4.13",
|
||||
"@backstage/plugin-techdocs": "^0.12.9",
|
||||
"@backstage/plugin-todo": "^0.1.16",
|
||||
"@backstage/plugin-user-settings": "^0.3.13",
|
||||
"@backstage/search-common": "^0.2.0",
|
||||
"@backstage/theme": "^0.2.11",
|
||||
"@backstage/plugin-tech-insights": "^0.1.1",
|
||||
"@backstage/theme": "^0.2.14",
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "4.0.0-alpha.57",
|
||||
"@octokit/rest": "^18.5.3",
|
||||
"@roadiehq/backstage-plugin-buildkite": "^1.0.8",
|
||||
"@roadiehq/backstage-plugin-github-insights": "^1.1.23",
|
||||
"@roadiehq/backstage-plugin-github-pull-requests": "^1.0.13",
|
||||
"@roadiehq/backstage-plugin-travis-ci": "^1.0.11",
|
||||
"history": "^5.0.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^16.12.0",
|
||||
"react-dom": "^16.12.0",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-hot-loader": "^4.12.21",
|
||||
"react-router": "6.0.0-beta.0",
|
||||
"react-router-dom": "6.0.0-beta.0",
|
||||
@@ -64,7 +65,7 @@
|
||||
"zen-observable": "^0.8.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/test-utils": "^0.1.22",
|
||||
"@backstage/test-utils": "^0.1.24",
|
||||
"@rjsf/core": "^3.2.1",
|
||||
"@testing-library/cypress": "^8.0.2",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
|
||||
@@ -87,6 +87,7 @@ import { providers } from './identityProviders';
|
||||
import * as plugins from './plugins';
|
||||
|
||||
import { techDocsPage } from './components/techdocs/TechDocsPage';
|
||||
import { ApacheAirflowPage } from '@backstage/plugin-apache-airflow';
|
||||
|
||||
const app = createApp({
|
||||
apis,
|
||||
@@ -218,6 +219,7 @@ const routes = (
|
||||
/>
|
||||
<Route path="/settings" element={<UserSettingsPage />} />
|
||||
<Route path="/azure-pull-requests" element={<AzurePullRequestsPage />} />
|
||||
<Route path="/apache-airflow" element={<ApacheAirflowPage />} />
|
||||
</FlatRoutes>
|
||||
);
|
||||
|
||||
|
||||
@@ -29,7 +29,10 @@ import LogoIcon from './LogoIcon';
|
||||
import { NavLink } from 'react-router-dom';
|
||||
import { GraphiQLIcon } from '@backstage/plugin-graphiql';
|
||||
import { Settings as SidebarSettings } from '@backstage/plugin-user-settings';
|
||||
import { SidebarSearchModal } from '@backstage/plugin-search';
|
||||
import {
|
||||
SidebarSearchModal,
|
||||
SearchContextProvider,
|
||||
} from '@backstage/plugin-search';
|
||||
import { Shortcuts } from '@backstage/plugin-shortcuts';
|
||||
import {
|
||||
Sidebar,
|
||||
@@ -80,7 +83,9 @@ export const Root = ({ children }: PropsWithChildren<{}>) => (
|
||||
<SidebarPage>
|
||||
<Sidebar>
|
||||
<SidebarLogo />
|
||||
<SidebarSearchModal />
|
||||
<SearchContextProvider>
|
||||
<SidebarSearchModal />
|
||||
</SearchContextProvider>
|
||||
<SidebarDivider />
|
||||
{/* Global nav, not org-specific */}
|
||||
<SidebarItem icon={HomeIcon} to="catalog" text="Home" />
|
||||
|
||||
@@ -106,10 +106,7 @@ import { EntityTechdocsContent } from '@backstage/plugin-techdocs';
|
||||
import { EntityTodoContent } from '@backstage/plugin-todo';
|
||||
import { Button, Grid } from '@material-ui/core';
|
||||
import BadgeIcon from '@material-ui/icons/CallToAction';
|
||||
import {
|
||||
EntityBuildkiteContent,
|
||||
isBuildkiteAvailable,
|
||||
} from '@roadiehq/backstage-plugin-buildkite';
|
||||
|
||||
import {
|
||||
EntityGithubInsightsContent,
|
||||
EntityGithubInsightsLanguagesCard,
|
||||
@@ -168,10 +165,6 @@ export const cicdContent = (
|
||||
<EntityJenkinsContent />
|
||||
</EntitySwitch.Case>
|
||||
|
||||
<EntitySwitch.Case if={isBuildkiteAvailable}>
|
||||
<EntityBuildkiteContent />
|
||||
</EntitySwitch.Case>
|
||||
|
||||
<EntitySwitch.Case if={isCircleCIAvailable}>
|
||||
<EntityCircleCIContent />
|
||||
</EntitySwitch.Case>
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
# @backstage/backend-common
|
||||
|
||||
## 0.9.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- dcd1a0c3f4: Minor improvement to the API reports, by not unpacking arguments directly
|
||||
- 5a008576c4: Add possibility to use custom error handler
|
||||
- 98a9c35f0c: Add options argument to support additional database migrations configuration
|
||||
- 6298de32dd: Add knexConfig config section
|
||||
|
||||
## 0.9.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 905dd952ac: Create a `TokenManager` interface and `ServerTokenManager` implementation to generate and validate server tokens for authenticated backend-to-backend API requests.
|
||||
- 6b500622d5: Move to using node-fetch internally instead of cross-fetch
|
||||
- 54989b671d: Fixed a potential crash in the log redaction code
|
||||
- Updated dependencies
|
||||
- @backstage/integration@0.6.10
|
||||
- @backstage/config-loader@0.8.1
|
||||
|
||||
## 0.9.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -175,23 +175,22 @@ export function createStatusCheckRouter(options: {
|
||||
// @public (undocumented)
|
||||
export class DatabaseManager {
|
||||
forPlugin(pluginId: string): PluginDatabaseManager;
|
||||
static fromConfig(config: Config): DatabaseManager;
|
||||
static fromConfig(
|
||||
config: Config,
|
||||
options?: DatabaseManagerOptions,
|
||||
): DatabaseManager;
|
||||
}
|
||||
|
||||
// @public
|
||||
export type DatabaseManagerOptions = {
|
||||
migrations?: PluginDatabaseManager['migrations'];
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export class DockerContainerRunner implements ContainerRunner {
|
||||
constructor({ dockerClient }: { dockerClient: Docker });
|
||||
constructor(options: { dockerClient: Docker });
|
||||
// (undocumented)
|
||||
runContainer({
|
||||
imageName,
|
||||
command,
|
||||
args,
|
||||
logStream,
|
||||
mountDirs,
|
||||
workingDir,
|
||||
envVars,
|
||||
pullImage,
|
||||
}: RunContainerOptions): Promise<void>;
|
||||
runContainer(options: RunContainerOptions): Promise<void>;
|
||||
}
|
||||
|
||||
// @public
|
||||
@@ -227,34 +226,17 @@ export function getVoidLogger(): winston.Logger;
|
||||
// @public (undocumented)
|
||||
export class Git {
|
||||
// (undocumented)
|
||||
add({ dir, filepath }: { dir: string; filepath: string }): Promise<void>;
|
||||
add(options: { dir: string; filepath: string }): Promise<void>;
|
||||
// (undocumented)
|
||||
addRemote({
|
||||
dir,
|
||||
url,
|
||||
remote,
|
||||
}: {
|
||||
addRemote(options: {
|
||||
dir: string;
|
||||
remote: string;
|
||||
url: string;
|
||||
}): Promise<void>;
|
||||
// (undocumented)
|
||||
clone({
|
||||
url,
|
||||
dir,
|
||||
ref,
|
||||
}: {
|
||||
url: string;
|
||||
dir: string;
|
||||
ref?: string;
|
||||
}): Promise<void>;
|
||||
clone(options: { url: string; dir: string; ref?: string }): Promise<void>;
|
||||
// (undocumented)
|
||||
commit({
|
||||
dir,
|
||||
message,
|
||||
author,
|
||||
committer,
|
||||
}: {
|
||||
commit(options: {
|
||||
dir: string;
|
||||
message: string;
|
||||
author: {
|
||||
@@ -267,41 +249,22 @@ export class Git {
|
||||
};
|
||||
}): Promise<string>;
|
||||
// (undocumented)
|
||||
currentBranch({
|
||||
dir,
|
||||
fullName,
|
||||
}: {
|
||||
currentBranch(options: {
|
||||
dir: string;
|
||||
fullName?: boolean;
|
||||
}): Promise<string | undefined>;
|
||||
// (undocumented)
|
||||
fetch({ dir, remote }: { dir: string; remote?: string }): Promise<void>;
|
||||
fetch(options: { dir: string; remote?: string }): Promise<void>;
|
||||
// (undocumented)
|
||||
static fromAuth: ({
|
||||
username,
|
||||
password,
|
||||
logger,
|
||||
}: {
|
||||
username?: string | undefined;
|
||||
password?: string | undefined;
|
||||
logger?: Logger_2 | undefined;
|
||||
static fromAuth: (options: {
|
||||
username?: string;
|
||||
password?: string;
|
||||
logger?: Logger_2;
|
||||
}) => Git;
|
||||
// (undocumented)
|
||||
init({
|
||||
dir,
|
||||
defaultBranch,
|
||||
}: {
|
||||
dir: string;
|
||||
defaultBranch?: string;
|
||||
}): Promise<void>;
|
||||
init(options: { dir: string; defaultBranch?: string }): Promise<void>;
|
||||
// (undocumented)
|
||||
merge({
|
||||
dir,
|
||||
theirs,
|
||||
ours,
|
||||
author,
|
||||
committer,
|
||||
}: {
|
||||
merge(options: {
|
||||
dir: string;
|
||||
theirs: string;
|
||||
ours?: string;
|
||||
@@ -315,17 +278,11 @@ export class Git {
|
||||
};
|
||||
}): Promise<MergeResult>;
|
||||
// (undocumented)
|
||||
push({ dir, remote }: { dir: string; remote: string }): Promise<PushResult>;
|
||||
push(options: { dir: string; remote: string }): Promise<PushResult>;
|
||||
// (undocumented)
|
||||
readCommit({
|
||||
dir,
|
||||
sha,
|
||||
}: {
|
||||
dir: string;
|
||||
sha: string;
|
||||
}): Promise<ReadCommitResult>;
|
||||
readCommit(options: { dir: string; sha: string }): Promise<ReadCommitResult>;
|
||||
// (undocumented)
|
||||
resolveRef({ dir, ref }: { dir: string; ref: string }): Promise<string>;
|
||||
resolveRef(options: { dir: string; ref: string }): Promise<string>;
|
||||
}
|
||||
|
||||
// @public
|
||||
@@ -395,6 +352,9 @@ export type PluginCacheManager = {
|
||||
// @public
|
||||
export interface PluginDatabaseManager {
|
||||
getClient(): Promise<Knex>;
|
||||
migrations?: {
|
||||
skip?: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
// @public
|
||||
@@ -561,6 +521,8 @@ export type ServiceBuilder = {
|
||||
setRequestLoggingHandler(
|
||||
requestLoggingHandler: RequestLoggingHandlerFactory,
|
||||
): ServiceBuilder;
|
||||
setErrorHandler(errorHandler: ErrorRequestHandler): ServiceBuilder;
|
||||
disableDefaultErrorHandler(): ServiceBuilder;
|
||||
start(): Promise<Server>;
|
||||
};
|
||||
|
||||
@@ -623,8 +585,8 @@ export type UrlReaderPredicateTuple = {
|
||||
|
||||
// @public
|
||||
export class UrlReaders {
|
||||
static create({ logger, config, factories }: UrlReadersOptions): UrlReader;
|
||||
static default({ logger, config, factories }: UrlReadersOptions): UrlReader;
|
||||
static create(options: UrlReadersOptions): UrlReader;
|
||||
static default(options: UrlReadersOptions): UrlReader;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
@@ -642,4 +604,8 @@ export function useHotCleanup(
|
||||
|
||||
// @public
|
||||
export function useHotMemoize<T>(_module: NodeModule, valueFactory: () => T): T;
|
||||
|
||||
// Warnings were encountered during analysis:
|
||||
//
|
||||
// src/database/types.d.ts:23:12 - (tsdoc-undefined-tag) The TSDoc tag "@default" is not defined in this configuration
|
||||
```
|
||||
|
||||
Vendored
+14
@@ -96,6 +96,12 @@ export interface Config {
|
||||
* @default database
|
||||
*/
|
||||
pluginDivisionMode?: 'database' | 'schema';
|
||||
/**
|
||||
* Arbitrary config object to pass to knex when initializing
|
||||
* (https://knexjs.org/#Installation-client). Most notable is the debug
|
||||
* and asyncStackTraces booleans
|
||||
*/
|
||||
knexConfig?: object;
|
||||
/** Plugin specific database configuration and client override */
|
||||
plugin?: {
|
||||
[pluginId: string]: {
|
||||
@@ -111,6 +117,14 @@ export interface Config {
|
||||
* Defaults to base config if unspecified.
|
||||
*/
|
||||
ensureExists?: boolean;
|
||||
/**
|
||||
* Arbitrary config object to pass to knex when initializing
|
||||
* (https://knexjs.org/#Installation-client). Most notable is the
|
||||
* debug and asyncStackTraces booleans.
|
||||
*
|
||||
* This is merged recursively into the base knexConfig
|
||||
*/
|
||||
knexConfig?: object;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/backend-common",
|
||||
"description": "Common functionality library for Backstage backends",
|
||||
"version": "0.9.11",
|
||||
"version": "0.9.13",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"private": false,
|
||||
@@ -31,9 +31,9 @@
|
||||
"dependencies": {
|
||||
"@backstage/cli-common": "^0.1.6",
|
||||
"@backstage/config": "^0.1.11",
|
||||
"@backstage/config-loader": "^0.8.0",
|
||||
"@backstage/config-loader": "^0.8.1",
|
||||
"@backstage/errors": "^0.1.5",
|
||||
"@backstage/integration": "^0.6.9",
|
||||
"@backstage/integration": "^0.6.10",
|
||||
"@backstage/types": "^0.1.1",
|
||||
"@google-cloud/storage": "^5.8.0",
|
||||
"@lerna/project": "^4.0.0",
|
||||
@@ -81,8 +81,8 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.9.1",
|
||||
"@backstage/test-utils": "^0.1.23",
|
||||
"@backstage/cli": "^0.10.1",
|
||||
"@backstage/test-utils": "^0.1.24",
|
||||
"@types/archiver": "^5.1.0",
|
||||
"@types/compression": "^1.7.0",
|
||||
"@types/concat-stream": "^1.6.0",
|
||||
|
||||
@@ -36,25 +36,45 @@ describe('DatabaseManager', () => {
|
||||
afterEach(() => jest.resetAllMocks());
|
||||
|
||||
describe('DatabaseManager.fromConfig', () => {
|
||||
it('accesses the backend.database key', () => {
|
||||
const config = new ConfigReader({
|
||||
backend: {
|
||||
database: {
|
||||
client: 'pg',
|
||||
connection: {
|
||||
host: 'localhost',
|
||||
user: 'foo',
|
||||
password: 'bar',
|
||||
database: 'foodb',
|
||||
},
|
||||
const backendConfig = {
|
||||
backend: {
|
||||
database: {
|
||||
client: 'pg',
|
||||
connection: {
|
||||
host: 'localhost',
|
||||
user: 'foo',
|
||||
password: 'bar',
|
||||
database: 'foodb',
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
it('accesses the backend.database key', () => {
|
||||
const config = new ConfigReader(backendConfig);
|
||||
const getConfigSpy = jest.spyOn(config, 'getConfig');
|
||||
DatabaseManager.fromConfig(config);
|
||||
|
||||
expect(getConfigSpy).toHaveBeenCalledWith('backend.database');
|
||||
});
|
||||
|
||||
it('handles default options', () => {
|
||||
const config = new ConfigReader(backendConfig);
|
||||
const database = DatabaseManager.fromConfig(config);
|
||||
const client = database.forPlugin('test');
|
||||
|
||||
expect(client.migrations?.skip).toBe(false);
|
||||
});
|
||||
|
||||
it('handles migrations options', () => {
|
||||
const config = new ConfigReader(backendConfig);
|
||||
const database = DatabaseManager.fromConfig(config, {
|
||||
migrations: { skip: true },
|
||||
});
|
||||
const client = database.forPlugin('test');
|
||||
|
||||
expect(client.migrations?.skip).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('DatabaseManager.forPlugin', () => {
|
||||
@@ -505,5 +525,42 @@ describe('DatabaseManager', () => {
|
||||
'database_name_overriden',
|
||||
);
|
||||
});
|
||||
|
||||
it('fetches and merges additional knex config', async () => {
|
||||
const testManager = DatabaseManager.fromConfig(
|
||||
new ConfigReader({
|
||||
backend: {
|
||||
database: {
|
||||
client: 'pg',
|
||||
connection: {
|
||||
host: 'localhost',
|
||||
database: 'foodb',
|
||||
},
|
||||
knexConfig: {
|
||||
something: false,
|
||||
},
|
||||
plugin: {
|
||||
testdbname: {
|
||||
knexConfig: {
|
||||
debug: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
await testManager.forPlugin('testdbname').getClient();
|
||||
|
||||
const mockCalls = mocked(createDatabaseClient).mock.calls.splice(-1);
|
||||
const [baseConfig] = mockCalls[0];
|
||||
|
||||
expect(baseConfig.data).toEqual(
|
||||
expect.objectContaining({
|
||||
debug: true,
|
||||
something: false,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,20 +14,20 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Knex } from 'knex';
|
||||
import { omit } from 'lodash';
|
||||
import { Config, ConfigReader } from '@backstage/config';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { Knex } from 'knex';
|
||||
import { merge, omit } from 'lodash';
|
||||
import { mergeDatabaseConfig } from './config';
|
||||
import {
|
||||
createNameOverride,
|
||||
ensureDatabaseExists,
|
||||
normalizeConnection,
|
||||
createSchemaOverride,
|
||||
ensureSchemaExists,
|
||||
createDatabaseClient,
|
||||
createNameOverride,
|
||||
createSchemaOverride,
|
||||
ensureDatabaseExists,
|
||||
ensureSchemaExists,
|
||||
normalizeConnection,
|
||||
} from './connection';
|
||||
import { PluginDatabaseManager } from './types';
|
||||
import { mergeDatabaseConfig } from './config';
|
||||
|
||||
/**
|
||||
* Provides a config lookup path for a plugin's config block.
|
||||
@@ -36,6 +36,15 @@ function pluginPath(pluginId: string): string {
|
||||
return `plugin.${pluginId}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration options object.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type DatabaseManagerOptions = {
|
||||
migrations?: PluginDatabaseManager['migrations'];
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export class DatabaseManager {
|
||||
/**
|
||||
@@ -47,19 +56,25 @@ export class DatabaseManager {
|
||||
* names if config is not provided.
|
||||
*
|
||||
* @param config - The loaded application configuration.
|
||||
* @param options - An optional configuration object.
|
||||
*/
|
||||
static fromConfig(config: Config): DatabaseManager {
|
||||
static fromConfig(
|
||||
config: Config,
|
||||
options?: DatabaseManagerOptions,
|
||||
): DatabaseManager {
|
||||
const databaseConfig = config.getConfig('backend.database');
|
||||
|
||||
return new DatabaseManager(
|
||||
databaseConfig,
|
||||
databaseConfig.getOptionalString('prefix'),
|
||||
options,
|
||||
);
|
||||
}
|
||||
|
||||
private constructor(
|
||||
private readonly config: Config,
|
||||
private readonly prefix: string = 'backstage_plugin_',
|
||||
private readonly options?: DatabaseManagerOptions,
|
||||
) {}
|
||||
|
||||
/**
|
||||
@@ -76,6 +91,10 @@ export class DatabaseManager {
|
||||
getClient(): Promise<Knex> {
|
||||
return _this.getDatabase(pluginId);
|
||||
},
|
||||
migrations: {
|
||||
skip: false,
|
||||
..._this.options?.migrations,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -138,6 +157,24 @@ export class DatabaseManager {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the knexConfig which should be used for a given plugin.
|
||||
*
|
||||
* @param pluginId Plugin to get the knexConfig for
|
||||
* @returns the merged kexConfig value or undefined if it isn't specified
|
||||
*/
|
||||
private getAdditionalKnexConfig(pluginId: string): JsonObject | undefined {
|
||||
const pluginConfig = this.config
|
||||
.getOptionalConfig(`${pluginPath(pluginId)}.knexConfig`)
|
||||
?.get<JsonObject>();
|
||||
|
||||
const baseConfig = this.config
|
||||
.getOptionalConfig('knexConfig')
|
||||
?.get<JsonObject>();
|
||||
|
||||
return merge(baseConfig, pluginConfig);
|
||||
}
|
||||
|
||||
private getEnsureExistsConfig(pluginId: string): boolean {
|
||||
const baseConfig = this.config.getOptionalBoolean('ensureExists') ?? true;
|
||||
return (
|
||||
@@ -200,6 +237,7 @@ export class DatabaseManager {
|
||||
const { client } = this.getClientType(pluginId);
|
||||
|
||||
return {
|
||||
...this.getAdditionalKnexConfig(pluginId),
|
||||
client,
|
||||
connection: this.getConnectionConfig(pluginId),
|
||||
};
|
||||
|
||||
@@ -30,6 +30,18 @@ export interface PluginDatabaseManager {
|
||||
* stores so that plugins are discouraged from database integration.
|
||||
*/
|
||||
getClient(): Promise<Knex>;
|
||||
|
||||
/**
|
||||
* This property is used to control the behavior of database migrations.
|
||||
*/
|
||||
migrations?: {
|
||||
/**
|
||||
* skip database migrations. Useful if connecting to a read-only database.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
skip?: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -54,10 +54,13 @@ export function setRootLoggerRedactionList(redactionList: string[]) {
|
||||
* and replaces them with the corresponding identifier.
|
||||
*/
|
||||
function redactLogLine(info: winston.Logform.TransformableInfo) {
|
||||
// TODO(hhogg): The logger is created before the config is loaded,
|
||||
// because the logger is needed in the config loader. There is a risk of
|
||||
// a secret being logged out during the config loading stage.
|
||||
if (redactionRegExp) {
|
||||
// TODO(hhogg): The logger is created before the config is loaded, because the
|
||||
// logger is needed in the config loader. There is a risk of a secret being
|
||||
// logged out during the config loading stage.
|
||||
// TODO(freben): Added a check that info.message actually was a string,
|
||||
// because it turned out that this was not necessarily guaranteed.
|
||||
// https://github.com/backstage/backstage/issues/8306
|
||||
if (redactionRegExp && typeof info.message === 'string') {
|
||||
info.message = info.message.replace(redactionRegExp, '[REDACTED]');
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,8 @@ export class UrlReaders {
|
||||
/**
|
||||
* Creates a UrlReader without any known types.
|
||||
*/
|
||||
static create({ logger, config, factories }: UrlReadersOptions): UrlReader {
|
||||
static create(options: UrlReadersOptions): UrlReader {
|
||||
const { logger, config, factories } = options;
|
||||
const mux = new UrlReaderPredicateMux(logger);
|
||||
const treeResponseFactory = DefaultReadTreeResponseFactory.create({
|
||||
config,
|
||||
@@ -68,7 +69,8 @@ export class UrlReaders {
|
||||
*
|
||||
* Any additional factories passed will be loaded before the default ones.
|
||||
*/
|
||||
static default({ logger, config, factories = [] }: UrlReadersOptions) {
|
||||
static default(options: UrlReadersOptions) {
|
||||
const { logger, config, factories = [] } = options;
|
||||
return UrlReaders.create({
|
||||
logger,
|
||||
config,
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import git, {
|
||||
ProgressCallback,
|
||||
MergeResult,
|
||||
@@ -42,44 +43,32 @@ export class Git {
|
||||
},
|
||||
) {}
|
||||
|
||||
async add({
|
||||
dir,
|
||||
filepath,
|
||||
}: {
|
||||
dir: string;
|
||||
filepath: string;
|
||||
}): Promise<void> {
|
||||
async add(options: { dir: string; filepath: string }): Promise<void> {
|
||||
const { dir, filepath } = options;
|
||||
this.config.logger?.info(`Adding file {dir=${dir},filepath=${filepath}}`);
|
||||
|
||||
return git.add({ fs, dir, filepath });
|
||||
}
|
||||
|
||||
async addRemote({
|
||||
dir,
|
||||
url,
|
||||
remote,
|
||||
}: {
|
||||
async addRemote(options: {
|
||||
dir: string;
|
||||
remote: string;
|
||||
url: string;
|
||||
}): Promise<void> {
|
||||
const { dir, url, remote } = options;
|
||||
this.config.logger?.info(
|
||||
`Creating new remote {dir=${dir},remote=${remote},url=${url}}`,
|
||||
);
|
||||
return git.addRemote({ fs, dir, remote, url });
|
||||
}
|
||||
|
||||
async commit({
|
||||
dir,
|
||||
message,
|
||||
author,
|
||||
committer,
|
||||
}: {
|
||||
async commit(options: {
|
||||
dir: string;
|
||||
message: string;
|
||||
author: { name: string; email: string };
|
||||
committer: { name: string; email: string };
|
||||
}): Promise<string> {
|
||||
const { dir, message, author, committer } = options;
|
||||
this.config.logger?.info(
|
||||
`Committing file to repo {dir=${dir},message=${message}}`,
|
||||
);
|
||||
@@ -87,15 +76,12 @@ export class Git {
|
||||
return git.commit({ fs, dir, message, author, committer });
|
||||
}
|
||||
|
||||
async clone({
|
||||
url,
|
||||
dir,
|
||||
ref,
|
||||
}: {
|
||||
async clone(options: {
|
||||
url: string;
|
||||
dir: string;
|
||||
ref?: string;
|
||||
}): Promise<void> {
|
||||
const { url, dir, ref } = options;
|
||||
this.config.logger?.info(`Cloning repo {dir=${dir},url=${url}}`);
|
||||
return git.clone({
|
||||
fs,
|
||||
@@ -114,51 +100,35 @@ export class Git {
|
||||
}
|
||||
|
||||
// https://isomorphic-git.org/docs/en/currentBranch
|
||||
async currentBranch({
|
||||
dir,
|
||||
fullName,
|
||||
}: {
|
||||
async currentBranch(options: {
|
||||
dir: string;
|
||||
fullName?: boolean;
|
||||
}): Promise<string | undefined> {
|
||||
const fullname = fullName ?? false;
|
||||
return git.currentBranch({ fs, dir, fullname }) as Promise<
|
||||
const { dir, fullName = false } = options;
|
||||
return git.currentBranch({ fs, dir, fullname: fullName }) as Promise<
|
||||
string | undefined
|
||||
>;
|
||||
}
|
||||
|
||||
// https://isomorphic-git.org/docs/en/fetch
|
||||
async fetch({
|
||||
dir,
|
||||
remote,
|
||||
}: {
|
||||
dir: string;
|
||||
remote?: string;
|
||||
}): Promise<void> {
|
||||
const remoteValue = remote ?? 'origin';
|
||||
async fetch(options: { dir: string; remote?: string }): Promise<void> {
|
||||
const { dir, remote = 'origin' } = options;
|
||||
this.config.logger?.info(
|
||||
`Fetching remote=${remoteValue} for repository {dir=${dir}}`,
|
||||
`Fetching remote=${remote} for repository {dir=${dir}}`,
|
||||
);
|
||||
await git.fetch({
|
||||
fs,
|
||||
http,
|
||||
dir,
|
||||
remote: remoteValue,
|
||||
remote,
|
||||
onProgress: this.onProgressHandler(),
|
||||
headers: {
|
||||
'user-agent': 'git/@isomorphic-git',
|
||||
},
|
||||
headers: { 'user-agent': 'git/@isomorphic-git' },
|
||||
onAuth: this.onAuth,
|
||||
});
|
||||
}
|
||||
|
||||
async init({
|
||||
dir,
|
||||
defaultBranch = 'master',
|
||||
}: {
|
||||
dir: string;
|
||||
defaultBranch?: string;
|
||||
}): Promise<void> {
|
||||
async init(options: { dir: string; defaultBranch?: string }): Promise<void> {
|
||||
const { dir, defaultBranch = 'master' } = options;
|
||||
this.config.logger?.info(`Init git repository {dir=${dir}}`);
|
||||
|
||||
return git.init({
|
||||
@@ -169,19 +139,14 @@ export class Git {
|
||||
}
|
||||
|
||||
// https://isomorphic-git.org/docs/en/merge
|
||||
async merge({
|
||||
dir,
|
||||
theirs,
|
||||
ours,
|
||||
author,
|
||||
committer,
|
||||
}: {
|
||||
async merge(options: {
|
||||
dir: string;
|
||||
theirs: string;
|
||||
ours?: string;
|
||||
author: { name: string; email: string };
|
||||
committer: { name: string; email: string };
|
||||
}): Promise<MergeResult> {
|
||||
const { dir, theirs, ours, author, committer } = options;
|
||||
this.config.logger?.info(
|
||||
`Merging branch '${theirs}' into '${ours}' for repository {dir=${dir}}`,
|
||||
);
|
||||
@@ -197,7 +162,8 @@ export class Git {
|
||||
});
|
||||
}
|
||||
|
||||
async push({ dir, remote }: { dir: string; remote: string }) {
|
||||
async push(options: { dir: string; remote: string }) {
|
||||
const { dir, remote } = options;
|
||||
this.config.logger?.info(
|
||||
`Pushing directory to remote {dir=${dir},remote=${remote}}`,
|
||||
);
|
||||
@@ -215,24 +181,17 @@ export class Git {
|
||||
}
|
||||
|
||||
// https://isomorphic-git.org/docs/en/readCommit
|
||||
async readCommit({
|
||||
dir,
|
||||
sha,
|
||||
}: {
|
||||
async readCommit(options: {
|
||||
dir: string;
|
||||
sha: string;
|
||||
}): Promise<ReadCommitResult> {
|
||||
const { dir, sha } = options;
|
||||
return git.readCommit({ fs, dir, oid: sha });
|
||||
}
|
||||
|
||||
// https://isomorphic-git.org/docs/en/resolveRef
|
||||
async resolveRef({
|
||||
dir,
|
||||
ref,
|
||||
}: {
|
||||
dir: string;
|
||||
ref: string;
|
||||
}): Promise<string> {
|
||||
async resolveRef(options: { dir: string; ref: string }): Promise<string> {
|
||||
const { dir, ref } = options;
|
||||
return git.resolveRef({ fs, dir, ref });
|
||||
}
|
||||
|
||||
@@ -256,13 +215,12 @@ export class Git {
|
||||
};
|
||||
};
|
||||
|
||||
static fromAuth = ({
|
||||
username,
|
||||
password,
|
||||
logger,
|
||||
}: {
|
||||
static fromAuth = (options: {
|
||||
username?: string;
|
||||
password?: string;
|
||||
logger?: Logger;
|
||||
}) => new Git({ username, password, logger });
|
||||
}) => {
|
||||
const { username, password, logger } = options;
|
||||
return new Git({ username, password, logger });
|
||||
};
|
||||
}
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { applyCspDirectives } from './ServiceBuilderImpl';
|
||||
import { NextFunction, Request, Response } from 'express';
|
||||
import { applyCspDirectives, ServiceBuilderImpl } from './ServiceBuilderImpl';
|
||||
|
||||
describe('ServiceBuilderImpl', () => {
|
||||
describe('applyCspDirectives', () => {
|
||||
@@ -33,4 +34,27 @@ describe('ServiceBuilderImpl', () => {
|
||||
expect(result!['upgrade-insecure-requests']).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('setCustomErrorHandler', () => {
|
||||
it('check if custom error handler is undefined', () => {
|
||||
const serviceBuilder = new ServiceBuilderImpl(module);
|
||||
const serviceBuilderProto = Object.getPrototypeOf(serviceBuilder);
|
||||
expect(serviceBuilderProto.errorHandler).toBeUndefined();
|
||||
});
|
||||
|
||||
it('adds custom error handler', () => {
|
||||
const serviceBuilder = new ServiceBuilderImpl(module);
|
||||
const serviceBuilderProto = Object.getPrototypeOf(serviceBuilder);
|
||||
const customErrorHandler = (
|
||||
error: Error,
|
||||
_req: Request,
|
||||
_res: Response,
|
||||
next: NextFunction,
|
||||
) => {
|
||||
next(error);
|
||||
};
|
||||
serviceBuilderProto.setErrorHandler(customErrorHandler);
|
||||
expect(serviceBuilderProto.errorHandler).toEqual(customErrorHandler);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import { Config } from '@backstage/config';
|
||||
import compression from 'compression';
|
||||
import cors from 'cors';
|
||||
import express, { Router } from 'express';
|
||||
import express, { Router, ErrorRequestHandler } from 'express';
|
||||
import helmet from 'helmet';
|
||||
import * as http from 'http';
|
||||
import stoppable from 'stoppable';
|
||||
@@ -25,7 +25,7 @@ import { Logger } from 'winston';
|
||||
import { useHotCleanup } from '../../hot';
|
||||
import { getRootLogger } from '../../logging';
|
||||
import {
|
||||
errorHandler,
|
||||
errorHandler as defaultErrorHandler,
|
||||
notFoundHandler,
|
||||
requestLoggingHandler as defaultRequestLoggingHandler,
|
||||
} from '../../middleware';
|
||||
@@ -66,6 +66,8 @@ export class ServiceBuilderImpl implements ServiceBuilder {
|
||||
private httpsSettings: HttpsSettings | undefined;
|
||||
private routers: [string, Router][];
|
||||
private requestLoggingHandler: RequestLoggingHandlerFactory | undefined;
|
||||
private errorHandler: ErrorRequestHandler | undefined;
|
||||
private useDefaultErrorHandler: boolean;
|
||||
// Reference to the module where builder is created - needed for hot module
|
||||
// reloading
|
||||
private module: NodeModule;
|
||||
@@ -73,6 +75,7 @@ export class ServiceBuilderImpl implements ServiceBuilder {
|
||||
constructor(moduleRef: NodeModule) {
|
||||
this.routers = [];
|
||||
this.module = moduleRef;
|
||||
this.useDefaultErrorHandler = true;
|
||||
}
|
||||
|
||||
loadConfig(config: Config): ServiceBuilder {
|
||||
@@ -152,6 +155,16 @@ export class ServiceBuilderImpl implements ServiceBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
setErrorHandler(errorHandler: ErrorRequestHandler) {
|
||||
this.errorHandler = errorHandler;
|
||||
return this;
|
||||
}
|
||||
|
||||
disableDefaultErrorHandler() {
|
||||
this.useDefaultErrorHandler = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
async start(): Promise<http.Server> {
|
||||
const app = express();
|
||||
const { port, host, logger, corsOptions, httpsSettings, helmetOptions } =
|
||||
@@ -169,7 +182,14 @@ export class ServiceBuilderImpl implements ServiceBuilder {
|
||||
app.use(root, route);
|
||||
}
|
||||
app.use(notFoundHandler());
|
||||
app.use(errorHandler());
|
||||
|
||||
if (this.errorHandler) {
|
||||
app.use(this.errorHandler);
|
||||
}
|
||||
|
||||
if (this.useDefaultErrorHandler) {
|
||||
app.use(defaultErrorHandler());
|
||||
}
|
||||
|
||||
const server: http.Server = httpsSettings
|
||||
? await createHttpsServer(app, httpsSettings, logger)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import { Config } from '@backstage/config';
|
||||
import cors from 'cors';
|
||||
import { Router, RequestHandler } from 'express';
|
||||
import { Router, RequestHandler, ErrorRequestHandler } from 'express';
|
||||
import { Server } from 'http';
|
||||
import { Logger } from 'winston';
|
||||
|
||||
@@ -98,6 +98,21 @@ export type ServiceBuilder = {
|
||||
requestLoggingHandler: RequestLoggingHandlerFactory,
|
||||
): ServiceBuilder;
|
||||
|
||||
/**
|
||||
* Sets an additional errorHandler to run before the defaultErrorHandler.
|
||||
*
|
||||
* For execution of only the custom error handler make sure to also invoke disableDefaultErrorHandler()
|
||||
* otherwise the defaultErrorHandler is executed at the end of the error middleware chain.
|
||||
*
|
||||
* @param errorHandler - an error handler
|
||||
*/
|
||||
setErrorHandler(errorHandler: ErrorRequestHandler): ServiceBuilder;
|
||||
|
||||
/**
|
||||
* Disables the default error handler
|
||||
*/
|
||||
disableDefaultErrorHandler(): ServiceBuilder;
|
||||
|
||||
/**
|
||||
* Starts the server using the given settings.
|
||||
*/
|
||||
|
||||
@@ -28,20 +28,22 @@ export type UserOptions = {
|
||||
export class DockerContainerRunner implements ContainerRunner {
|
||||
private readonly dockerClient: Docker;
|
||||
|
||||
constructor({ dockerClient }: { dockerClient: Docker }) {
|
||||
this.dockerClient = dockerClient;
|
||||
constructor(options: { dockerClient: Docker }) {
|
||||
this.dockerClient = options.dockerClient;
|
||||
}
|
||||
|
||||
async runContainer({
|
||||
imageName,
|
||||
command,
|
||||
args,
|
||||
logStream = new PassThrough(),
|
||||
mountDirs = {},
|
||||
workingDir,
|
||||
envVars = {},
|
||||
pullImage = true,
|
||||
}: RunContainerOptions) {
|
||||
async runContainer(options: RunContainerOptions) {
|
||||
const {
|
||||
imageName,
|
||||
command,
|
||||
args,
|
||||
logStream = new PassThrough(),
|
||||
mountDirs = {},
|
||||
workingDir,
|
||||
envVars = {},
|
||||
pullImage = true,
|
||||
} = options;
|
||||
|
||||
// Show a better error message when Docker is unavailable.
|
||||
try {
|
||||
await this.dockerClient.ping();
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.9.10",
|
||||
"@backstage/backend-common": "^0.9.12",
|
||||
"@backstage/config": "^0.1.11",
|
||||
"@backstage/errors": "^0.1.4",
|
||||
"@backstage/types": "^0.1.1",
|
||||
@@ -43,8 +43,8 @@
|
||||
"zod": "^3.9.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/backend-test-utils": "^0.1.9",
|
||||
"@backstage/cli": "^0.9.0",
|
||||
"@backstage/backend-test-utils": "^0.1.10",
|
||||
"@backstage/cli": "^0.10.0",
|
||||
"jest": "^26.0.1",
|
||||
"wait-for-expect": "^3.0.2"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# @backstage/backend-test-utils
|
||||
|
||||
## 0.1.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.9.12
|
||||
- @backstage/cli@0.10.0
|
||||
|
||||
## 0.1.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/backend-test-utils",
|
||||
"description": "Test helpers library for Backstage backends",
|
||||
"version": "0.1.9",
|
||||
"version": "0.1.10",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"private": false,
|
||||
@@ -30,8 +30,8 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.9.10",
|
||||
"@backstage/cli": "^0.9.0",
|
||||
"@backstage/backend-common": "^0.9.12",
|
||||
"@backstage/cli": "^0.10.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.9.0",
|
||||
"@backstage/cli": "^0.10.0",
|
||||
"jest": "^26.0.1"
|
||||
},
|
||||
"files": [
|
||||
|
||||
@@ -1,5 +1,46 @@
|
||||
# example-backend
|
||||
|
||||
## 0.2.56
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-auth-backend@0.5.0
|
||||
- @backstage/plugin-scaffolder-backend@0.15.16
|
||||
- @backstage/plugin-kubernetes-backend@0.4.0
|
||||
- @backstage/backend-common@0.9.13
|
||||
- @backstage/plugin-catalog-backend@0.19.1
|
||||
- @backstage/plugin-search-backend@0.2.8
|
||||
- @backstage/plugin-search-backend-module-elasticsearch@0.0.6
|
||||
- @backstage/plugin-search-backend-module-pg@0.2.2
|
||||
- @backstage/plugin-techdocs-backend@0.12.0
|
||||
- @backstage/plugin-todo-backend@0.1.15
|
||||
- @backstage/plugin-scaffolder-backend-module-rails@0.2.0
|
||||
- @backstage/plugin-azure-devops-backend@0.2.4
|
||||
- example-app@0.2.56
|
||||
|
||||
## 0.2.55
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/integration@0.6.10
|
||||
- @backstage/plugin-scaffolder-backend@0.15.15
|
||||
- @backstage/plugin-auth-backend@0.4.10
|
||||
- @backstage/plugin-kubernetes-backend@0.3.20
|
||||
- @backstage/plugin-badges-backend@0.1.13
|
||||
- @backstage/plugin-catalog-backend@0.19.0
|
||||
- @backstage/plugin-code-coverage-backend@0.1.16
|
||||
- @backstage/plugin-jenkins-backend@0.1.9
|
||||
- @backstage/plugin-tech-insights-backend@0.1.3
|
||||
- @backstage/plugin-techdocs-backend@0.11.0
|
||||
- @backstage/plugin-todo-backend@0.1.14
|
||||
- @backstage/backend-common@0.9.12
|
||||
- @backstage/plugin-azure-devops-backend@0.2.3
|
||||
- @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.2
|
||||
- @backstage/plugin-tech-insights-node@0.1.1
|
||||
- example-app@0.2.55
|
||||
|
||||
## 0.2.54
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "example-backend",
|
||||
"version": "0.2.54",
|
||||
"version": "0.2.56",
|
||||
"main": "dist/index.cjs.js",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -24,39 +24,39 @@
|
||||
"migrate:create": "knex migrate:make -x ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.9.11",
|
||||
"@backstage/backend-common": "^0.9.13",
|
||||
"@backstage/catalog-client": "^0.5.2",
|
||||
"@backstage/catalog-model": "^0.9.7",
|
||||
"@backstage/config": "^0.1.10",
|
||||
"@backstage/integration": "^0.6.8",
|
||||
"@backstage/integration": "^0.6.10",
|
||||
"@backstage/plugin-app-backend": "^0.3.19",
|
||||
"@backstage/plugin-auth-backend": "^0.4.9",
|
||||
"@backstage/plugin-azure-devops-backend": "^0.2.2",
|
||||
"@backstage/plugin-badges-backend": "^0.1.12",
|
||||
"@backstage/plugin-catalog-backend": "^0.18.0",
|
||||
"@backstage/plugin-code-coverage-backend": "^0.1.15",
|
||||
"@backstage/plugin-auth-backend": "^0.5.0",
|
||||
"@backstage/plugin-azure-devops-backend": "^0.2.4",
|
||||
"@backstage/plugin-badges-backend": "^0.1.13",
|
||||
"@backstage/plugin-catalog-backend": "^0.19.1",
|
||||
"@backstage/plugin-code-coverage-backend": "^0.1.16",
|
||||
"@backstage/plugin-graphql-backend": "^0.1.9",
|
||||
"@backstage/plugin-jenkins-backend": "^0.1.8",
|
||||
"@backstage/plugin-kubernetes-backend": "^0.3.19",
|
||||
"@backstage/plugin-jenkins-backend": "^0.1.9",
|
||||
"@backstage/plugin-kubernetes-backend": "^0.4.0",
|
||||
"@backstage/plugin-kafka-backend": "^0.2.12",
|
||||
"@backstage/plugin-proxy-backend": "^0.2.14",
|
||||
"@backstage/plugin-rollbar-backend": "^0.1.16",
|
||||
"@backstage/plugin-scaffolder-backend": "^0.15.14",
|
||||
"@backstage/plugin-scaffolder-backend-module-rails": "^0.1.7",
|
||||
"@backstage/plugin-search-backend": "^0.2.7",
|
||||
"@backstage/plugin-scaffolder-backend": "^0.15.16",
|
||||
"@backstage/plugin-scaffolder-backend-module-rails": "^0.2.0",
|
||||
"@backstage/plugin-search-backend": "^0.2.8",
|
||||
"@backstage/plugin-search-backend-node": "^0.4.2",
|
||||
"@backstage/plugin-search-backend-module-elasticsearch": "^0.0.5",
|
||||
"@backstage/plugin-search-backend-module-pg": "^0.2.1",
|
||||
"@backstage/plugin-techdocs-backend": "^0.10.9",
|
||||
"@backstage/plugin-tech-insights-backend": "^0.1.2",
|
||||
"@backstage/plugin-tech-insights-node": "^0.1.0",
|
||||
"@backstage/plugin-tech-insights-backend-module-jsonfc": "^0.1.1",
|
||||
"@backstage/plugin-todo-backend": "^0.1.13",
|
||||
"@backstage/plugin-search-backend-module-elasticsearch": "^0.0.6",
|
||||
"@backstage/plugin-search-backend-module-pg": "^0.2.2",
|
||||
"@backstage/plugin-techdocs-backend": "^0.12.0",
|
||||
"@backstage/plugin-tech-insights-backend": "^0.1.3",
|
||||
"@backstage/plugin-tech-insights-node": "^0.1.1",
|
||||
"@backstage/plugin-tech-insights-backend-module-jsonfc": "^0.1.2",
|
||||
"@backstage/plugin-todo-backend": "^0.1.15",
|
||||
"@gitbeaker/node": "^34.6.0",
|
||||
"@octokit/rest": "^18.5.3",
|
||||
"azure-devops-node-api": "^11.0.1",
|
||||
"dockerode": "^3.3.1",
|
||||
"example-app": "^0.2.53",
|
||||
"example-app": "^0.2.56",
|
||||
"express": "^4.17.1",
|
||||
"express-promise-router": "^4.1.0",
|
||||
"express-prom-bundle": "^6.3.6",
|
||||
@@ -68,7 +68,7 @@
|
||||
"winston": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.9.1",
|
||||
"@backstage/cli": "^0.10.1",
|
||||
"@types/dockerode": "^3.3.0",
|
||||
"@types/express": "^4.17.6",
|
||||
"@types/express-serve-static-core": "^4.17.5"
|
||||
|
||||
@@ -29,6 +29,7 @@ export default async function createPlugin({
|
||||
config,
|
||||
discovery,
|
||||
reader,
|
||||
cache,
|
||||
}: PluginEnvironment): Promise<Router> {
|
||||
// Preparers are responsible for fetching source files for documentation.
|
||||
const preparers = await Preparers.fromConfig(config, {
|
||||
@@ -64,5 +65,6 @@ export default async function createPlugin({
|
||||
logger,
|
||||
config,
|
||||
discovery,
|
||||
cache,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
"cross-fetch": "^3.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.9.0",
|
||||
"@backstage/cli": "^0.10.0",
|
||||
"@types/jest": "^26.0.7",
|
||||
"msw": "^0.35.0"
|
||||
},
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"yup": "^0.32.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.9.0",
|
||||
"@backstage/cli": "^0.10.0",
|
||||
"@types/jest": "^26.0.7",
|
||||
"@types/lodash": "^4.14.151",
|
||||
"yaml": "^1.9.2"
|
||||
|
||||
@@ -1,5 +1,31 @@
|
||||
# @backstage/cli
|
||||
|
||||
## 0.10.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 0ebb05eee2: Add cli option to minify the generated code of a plugin or backend package
|
||||
|
||||
```
|
||||
backstage-cli plugin:build --minify
|
||||
backstage-cli backend:build --minify
|
||||
```
|
||||
|
||||
- cd450844f6: Updated the frontend plugin template to put React dependencies in `peerDependencies` by default, as well as allowing both React v16 and v17. This change can be applied to existing plugins by running `yarn backstage-cli plugin:diff` within the plugin package directory.
|
||||
|
||||
## 0.10.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- ea99ef5198: Remove the `backend:build-image` command from the CLI and added more deprecation warnings to other deprecated fields like `--lax` and `remove-plugin`
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- e7230ef814: Bump react-dev-utils to v12
|
||||
- 416b68675d: build(dependencies): bump `style-loader` from 1.2.1 to 3.3.1
|
||||
- Updated dependencies
|
||||
- @backstage/config-loader@0.8.1
|
||||
|
||||
## 0.9.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
+15
-16
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/cli",
|
||||
"description": "CLI for developing Backstage plugins and apps",
|
||||
"version": "0.9.1",
|
||||
"version": "0.10.1",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
@@ -30,7 +30,7 @@
|
||||
"dependencies": {
|
||||
"@backstage/cli-common": "^0.1.6",
|
||||
"@backstage/config": "^0.1.11",
|
||||
"@backstage/config-loader": "^0.8.0",
|
||||
"@backstage/config-loader": "^0.8.1",
|
||||
"@backstage/errors": "^0.1.5",
|
||||
"@backstage/types": "^0.1.1",
|
||||
"@hot-loader/react-dom": "^16.13.0",
|
||||
@@ -38,9 +38,9 @@
|
||||
"@lerna/project": "^4.0.0",
|
||||
"@octokit/request": "^5.4.12",
|
||||
"@rollup/plugin-commonjs": "^21.0.1",
|
||||
"@rollup/plugin-json": "^4.0.2",
|
||||
"@rollup/plugin-json": "^4.1.0",
|
||||
"@rollup/plugin-node-resolve": "^13.0.0",
|
||||
"@rollup/plugin-yaml": "^3.0.0",
|
||||
"@rollup/plugin-yaml": "^3.1.0",
|
||||
"@spotify/eslint-config-base": "^12.0.0",
|
||||
"@spotify/eslint-config-react": "^12.0.0",
|
||||
"@spotify/eslint-config-typescript": "^12.0.0",
|
||||
@@ -62,7 +62,7 @@
|
||||
"css-loader": "^5.2.6",
|
||||
"dashify": "^2.0.0",
|
||||
"diff": "^5.0.0",
|
||||
"esbuild": "^0.8.56",
|
||||
"esbuild": "^0.14.1",
|
||||
"eslint": "^7.30.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-formatter-friendly": "^7.0.0",
|
||||
@@ -89,14 +89,13 @@
|
||||
"ora": "^5.3.0",
|
||||
"postcss": "^8.1.0",
|
||||
"process": "^0.11.10",
|
||||
"react": "^16.0.0",
|
||||
"react-dev-utils": "^12.0.0-next.47",
|
||||
"react-hot-loader": "^4.12.21",
|
||||
"recursive-readdir": "^2.2.2",
|
||||
"replace-in-file": "^6.0.0",
|
||||
"rollup": "2.44.x",
|
||||
"rollup-plugin-dts": "^3.0.1",
|
||||
"rollup-plugin-esbuild": "2.6.x",
|
||||
"rollup": "^2.60.2",
|
||||
"rollup-plugin-dts": "^4.0.1",
|
||||
"rollup-plugin-esbuild": "^4.7.2",
|
||||
"rollup-plugin-peer-deps-external": "^2.2.2",
|
||||
"rollup-plugin-postcss": "^4.0.0",
|
||||
"rollup-pluginutils": "^2.8.2",
|
||||
@@ -117,14 +116,14 @@
|
||||
"yn": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/backend-common": "^0.9.11",
|
||||
"@backstage/backend-common": "^0.9.13",
|
||||
"@backstage/config": "^0.1.11",
|
||||
"@backstage/core-components": "^0.7.5",
|
||||
"@backstage/core-plugin-api": "^0.2.1",
|
||||
"@backstage/core-app-api": "^0.1.23",
|
||||
"@backstage/dev-utils": "^0.2.13",
|
||||
"@backstage/test-utils": "^0.1.23",
|
||||
"@backstage/theme": "^0.2.13",
|
||||
"@backstage/core-components": "^0.8.0",
|
||||
"@backstage/core-plugin-api": "^0.3.0",
|
||||
"@backstage/core-app-api": "^0.2.0",
|
||||
"@backstage/dev-utils": "^0.2.14",
|
||||
"@backstage/test-utils": "^0.1.24",
|
||||
"@backstage/theme": "^0.2.14",
|
||||
"@types/diff": "^5.0.0",
|
||||
"@types/express": "^4.17.6",
|
||||
"@types/fs-extra": "^9.0.1",
|
||||
|
||||
@@ -14,10 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Command } from 'commander';
|
||||
import { buildPackage, Output } from '../../lib/builder';
|
||||
|
||||
export default async () => {
|
||||
export default async (cmd: Command) => {
|
||||
await buildPackage({
|
||||
outputs: new Set([Output.cjs, Output.types]),
|
||||
minify: cmd.minify,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -47,6 +47,7 @@ export function registerCommands(program: CommanderStatic) {
|
||||
program
|
||||
.command('backend:build')
|
||||
.description('Build a backend plugin')
|
||||
.option('--minify', 'Minify the generated code')
|
||||
.action(lazy(() => import('./backend/build').then(m => m.default)));
|
||||
|
||||
program
|
||||
@@ -116,6 +117,7 @@ export function registerCommands(program: CommanderStatic) {
|
||||
program
|
||||
.command('plugin:build')
|
||||
.description('Build a plugin')
|
||||
.option('--minify', 'Minify the generated code')
|
||||
.action(lazy(() => import('./plugin/build').then(m => m.default)));
|
||||
|
||||
program
|
||||
|
||||
@@ -14,10 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Command } from 'commander';
|
||||
import { buildPackage, Output } from '../../lib/builder';
|
||||
|
||||
export default async () => {
|
||||
export default async (cmd: Command) => {
|
||||
await buildPackage({
|
||||
outputs: new Set([Output.esm, Output.types]),
|
||||
minify: cmd.minify,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -100,6 +100,7 @@ export const makeConfigs = async (
|
||||
}),
|
||||
esbuild({
|
||||
target: 'es2019',
|
||||
minify: options.minify,
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
@@ -22,4 +22,5 @@ export enum Output {
|
||||
|
||||
export type BuildOptions = {
|
||||
outputs: Set<Output>;
|
||||
minify?: boolean;
|
||||
};
|
||||
|
||||
@@ -75,7 +75,9 @@ class PackageJsonHandler {
|
||||
await this.syncScripts();
|
||||
await this.syncPublishConfig();
|
||||
await this.syncDependencies('dependencies');
|
||||
await this.syncDependencies('peerDependencies', true);
|
||||
await this.syncDependencies('devDependencies');
|
||||
await this.syncReactDeps();
|
||||
}
|
||||
|
||||
// Make sure a field inside package.json is in sync. This mutates the targetObj and writes package.json on change.
|
||||
@@ -207,12 +209,12 @@ class PackageJsonHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private async syncDependencies(fieldName: string) {
|
||||
private async syncDependencies(fieldName: string, required: boolean = false) {
|
||||
const pkgDeps = this.pkg[fieldName];
|
||||
const targetDeps = (this.targetPkg[fieldName] =
|
||||
this.targetPkg[fieldName] || {});
|
||||
|
||||
if (!pkgDeps) {
|
||||
if (!pkgDeps && !required) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -231,10 +233,26 @@ class PackageJsonHandler {
|
||||
continue;
|
||||
}
|
||||
|
||||
await this.syncField(key, pkgDeps, targetDeps, fieldName, true, true);
|
||||
await this.syncField(
|
||||
key,
|
||||
pkgDeps,
|
||||
targetDeps,
|
||||
fieldName,
|
||||
true,
|
||||
!required,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async syncReactDeps() {
|
||||
const targetDeps = (this.targetPkg.dependencies =
|
||||
this.targetPkg.dependencies || {});
|
||||
|
||||
// Remove these from from deps since they're now in peerDeps
|
||||
await this.syncField('react', {}, targetDeps, 'dependencies');
|
||||
await this.syncField('react-dom', {}, targetDeps, 'dependencies');
|
||||
}
|
||||
|
||||
private async write() {
|
||||
await this.writeFunc(`${JSON.stringify(this.targetPkg, null, 2)}\n`);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ export const version = findVersion();
|
||||
export const isDev = fs.pathExistsSync(paths.resolveOwn('src'));
|
||||
|
||||
export function createPackageVersionProvider(lockfile?: Lockfile) {
|
||||
return (name: string, versionHint?: string) => {
|
||||
return (name: string, versionHint?: string): string => {
|
||||
const packageVersion = packageVersions[name];
|
||||
const targetVersion = versionHint || packageVersion;
|
||||
if (!targetVersion) {
|
||||
@@ -94,6 +94,6 @@ export function createPackageVersionProvider(lockfile?: Lockfile) {
|
||||
if (semver.parse(versionHint)?.prerelease.length) {
|
||||
return versionHint!;
|
||||
}
|
||||
return `^${versionHint}`;
|
||||
return versionHint?.match(/^[\d\.]+$/) ? `^${versionHint}` : versionHint!;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -32,10 +32,11 @@
|
||||
"@material-ui/core": "{{versionQuery '@material-ui/core' '4.12.2'}}",
|
||||
"@material-ui/icons": "{{versionQuery '@material-ui/icons' '4.9.1'}}",
|
||||
"@material-ui/lab": "{{versionQuery '@material-ui/lab' '4.0.0-alpha.57'}}",
|
||||
"react": "{{versionQuery 'react' '16.13.1'}}",
|
||||
"react-dom": "{{versionQuery 'react-dom' '16.13.1'}}",
|
||||
"react-use": "{{versionQuery 'react-use' '17.2.4'}}"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "{{versionQuery 'react' '^16.13.1 || ^17.0.0'}}"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "{{versionQuery '@backstage/cli'}}",
|
||||
"@backstage/core-app-api": "{{versionQuery '@backstage/core-app-api'}}",
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# @backstage/codemods
|
||||
|
||||
## 0.1.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/core-components@0.8.0
|
||||
- @backstage/core-plugin-api@0.3.0
|
||||
- @backstage/core-app-api@0.2.0
|
||||
|
||||
## 0.1.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/core-components@0.7.6
|
||||
- @backstage/core-plugin-api@0.2.2
|
||||
- @backstage/core-app-api@0.1.24
|
||||
|
||||
## 0.1.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/codemods",
|
||||
"description": "A collection of codemods for Backstage projects",
|
||||
"version": "0.1.23",
|
||||
"version": "0.1.25",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @backstage/config-loader
|
||||
|
||||
## 0.8.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- b055a6addc: Align on usage of `cross-fetch` vs `node-fetch` in frontend vs backend packages, and remove some unnecessary imports of either one of them
|
||||
- 4bea7b81d3: Uses key visibility as fallback in non-object arrays
|
||||
|
||||
## 0.8.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/config-loader",
|
||||
"description": "Config loading functionality used by Backstage backend, and CLI",
|
||||
"version": "0.8.0",
|
||||
"version": "0.8.1",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
|
||||
@@ -20,6 +20,7 @@ import { filterByVisibility, filterErrorsByVisibility } from './filtering';
|
||||
|
||||
const data = {
|
||||
arr: ['f', 'b', 's'],
|
||||
arrU: ['f', 'b', 't'],
|
||||
objArr: [
|
||||
{ f: 1, b: 2, s: 3 },
|
||||
{ f: 4, b: 5, s: 6 },
|
||||
@@ -40,6 +41,8 @@ const data = {
|
||||
|
||||
const visibility = new Map<string, ConfigVisibility>(
|
||||
Object.entries({
|
||||
'/arrU': 'frontend',
|
||||
'/arrU/2': 'backend',
|
||||
'/arr/0': 'frontend',
|
||||
'/arr/1': 'backend',
|
||||
'/arr/2': 'secret',
|
||||
@@ -71,6 +74,9 @@ describe('filterByVisibility', () => {
|
||||
'arr[0]',
|
||||
'arr[1]',
|
||||
'arr[2]',
|
||||
'arrU[0]',
|
||||
'arrU[1]',
|
||||
'arrU[2]',
|
||||
'objArr[0].f',
|
||||
'objArr[0].b',
|
||||
'objArr[0].s',
|
||||
@@ -97,10 +103,12 @@ describe('filterByVisibility', () => {
|
||||
obj: { f: 'a' },
|
||||
arrF: [],
|
||||
objF: {},
|
||||
arrU: ['f', 'b'],
|
||||
},
|
||||
filteredKeys: [
|
||||
'arr[1]',
|
||||
'arr[2]',
|
||||
'arrU[2]',
|
||||
'objArr[0].b',
|
||||
'objArr[0].s',
|
||||
'objArr[1].b',
|
||||
@@ -120,6 +128,7 @@ describe('filterByVisibility', () => {
|
||||
{
|
||||
data: {
|
||||
arr: ['b'],
|
||||
arrU: ['t'],
|
||||
objArr: [{ b: 2 }, { b: 5 }],
|
||||
obj: { b: {} },
|
||||
arrF: [{ never: 'here' }],
|
||||
@@ -132,6 +141,8 @@ describe('filterByVisibility', () => {
|
||||
filteredKeys: [
|
||||
'arr[0]',
|
||||
'arr[2]',
|
||||
'arrU[0]',
|
||||
'arrU[1]',
|
||||
'objArr[0].f',
|
||||
'objArr[0].s',
|
||||
'objArr[1].f',
|
||||
@@ -154,6 +165,9 @@ describe('filterByVisibility', () => {
|
||||
filteredKeys: [
|
||||
'arr[0]',
|
||||
'arr[1]',
|
||||
'arrU[0]',
|
||||
'arrU[1]',
|
||||
'arrU[2]',
|
||||
'objArr[0].f',
|
||||
'objArr[0].b',
|
||||
'objArr[1].f',
|
||||
|
||||
@@ -61,11 +61,17 @@ export function filterByVisibility(
|
||||
const arr = new Array<JsonValue>();
|
||||
|
||||
for (const [index, value] of jsonVal.entries()) {
|
||||
const out = transform(
|
||||
value,
|
||||
let path = visibilityPath;
|
||||
const hasVisibilityInIndex = visibilityByDataPath.get(
|
||||
`${visibilityPath}/${index}`,
|
||||
`${filterPath}[${index}]`,
|
||||
);
|
||||
|
||||
if (hasVisibilityInIndex || typeof value === 'object') {
|
||||
path = `${visibilityPath}/${index}`;
|
||||
}
|
||||
|
||||
const out = transform(value, path, `${filterPath}[${index}]`);
|
||||
|
||||
if (out !== undefined) {
|
||||
arr.push(out);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,61 @@
|
||||
# @backstage/core-app-api
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- a036b65c2f: **BREAKING CHANGE**
|
||||
|
||||
The app `SignInPage` component has been updated to switch out the `onResult` callback for a new `onSignInSuccess` callback. This is an immediate breaking change without any deprecation period, as it was deemed to be the way of making this change that had the lowest impact.
|
||||
|
||||
The new `onSignInSuccess` callback directly accepts an implementation of an `IdentityApi`, rather than a `SignInResult`. The `SignInPage` from `@backstage/core-component` has been updated to fit this new API, and as long as you pass on `props` directly you should not see any breakage.
|
||||
|
||||
However, if you implement your own custom `SignInPage`, then this will be a breaking change and you need to migrate over to using the new callback. While doing so you can take advantage of the `UserIdentity.fromLegacy` helper from `@backstage/core-components` to make the migration simpler by still using the `SignInResult` type. This helper is also deprecated though and is only provided for immediate migration. Long-term it will be necessary to build the `IdentityApi` using for example `UserIdentity.create` instead.
|
||||
|
||||
The following is an example of how you can migrate existing usage immediately using `UserIdentity.fromLegacy`:
|
||||
|
||||
```ts
|
||||
onResult(signInResult);
|
||||
// becomes
|
||||
onSignInSuccess(UserIdentity.fromLegacy(signInResult));
|
||||
```
|
||||
|
||||
The following is an example of how implement the new `onSignInSuccess` callback of the `SignInPage` using `UserIdentity.create`:
|
||||
|
||||
```ts
|
||||
const identityResponse = await authApi.getBackstageIdentity();
|
||||
// Profile is optional and will be removed, but allows the
|
||||
// synchronous getProfile method of the IdentityApi to be used.
|
||||
const profile = await authApi.getProfile();
|
||||
onSignInSuccess(
|
||||
UserIdentity.create({
|
||||
identity: identityResponse.identity,
|
||||
authApi,
|
||||
profile,
|
||||
}),
|
||||
);
|
||||
```
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- cd450844f6: Moved React dependencies to `peerDependencies` and allow both React v16 and v17 to be used.
|
||||
- dcd1a0c3f4: Minor improvement to the API reports, by not unpacking arguments directly
|
||||
- Updated dependencies
|
||||
- @backstage/core-components@0.8.0
|
||||
- @backstage/core-plugin-api@0.3.0
|
||||
- @backstage/app-defaults@0.1.2
|
||||
- @backstage/version-bridge@0.1.1
|
||||
|
||||
## 0.1.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 0e7f256034: Fixed a bug where `useRouteRef` would fail in situations where relative navigation was needed and the app was is mounted on a sub-path. This would typically show up as a failure to navigate to a tab on an entity page.
|
||||
- Updated dependencies
|
||||
- @backstage/core-components@0.7.6
|
||||
- @backstage/theme@0.2.14
|
||||
- @backstage/core-plugin-api@0.2.2
|
||||
|
||||
## 0.1.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -39,6 +39,7 @@ import { FeatureFlagsSaveOptions } from '@backstage/core-plugin-api';
|
||||
import { gitlabAuthApiRef } from '@backstage/core-plugin-api';
|
||||
import { googleAuthApiRef } from '@backstage/core-plugin-api';
|
||||
import { IconComponent } from '@backstage/core-plugin-api';
|
||||
import { IdentityApi } from '@backstage/core-plugin-api';
|
||||
import { microsoftAuthApiRef } from '@backstage/core-plugin-api';
|
||||
import { OAuthApi } from '@backstage/core-plugin-api';
|
||||
import { OAuthRequestApi } from '@backstage/core-plugin-api';
|
||||
@@ -250,24 +251,13 @@ export class AppThemeSelector implements AppThemeApi {
|
||||
// @public
|
||||
export class AtlassianAuth {
|
||||
// (undocumented)
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment,
|
||||
provider,
|
||||
oauthRequestApi,
|
||||
}: OAuthApiCreateOptions): typeof atlassianAuthApiRef.T;
|
||||
static create(options: OAuthApiCreateOptions): typeof atlassianAuthApiRef.T;
|
||||
}
|
||||
|
||||
// @public
|
||||
export class Auth0Auth {
|
||||
// (undocumented)
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment,
|
||||
provider,
|
||||
oauthRequestApi,
|
||||
defaultScopes,
|
||||
}: OAuthApiCreateOptions): typeof auth0AuthApiRef.T;
|
||||
static create(options: OAuthApiCreateOptions): typeof auth0AuthApiRef.T;
|
||||
}
|
||||
|
||||
// @public
|
||||
@@ -303,13 +293,7 @@ export type BackstagePluginWithAnyOutput = Omit<
|
||||
// @public
|
||||
export class BitbucketAuth {
|
||||
// (undocumented)
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment,
|
||||
provider,
|
||||
oauthRequestApi,
|
||||
defaultScopes,
|
||||
}: OAuthApiCreateOptions): typeof bitbucketAuthApiRef.T;
|
||||
static create(options: OAuthApiCreateOptions): typeof bitbucketAuthApiRef.T;
|
||||
}
|
||||
|
||||
// @public
|
||||
@@ -402,13 +386,7 @@ export class GithubAuth implements OAuthApi, SessionApi {
|
||||
// @deprecated
|
||||
constructor(sessionManager: SessionManager<GithubSession>);
|
||||
// (undocumented)
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment,
|
||||
provider,
|
||||
oauthRequestApi,
|
||||
defaultScopes,
|
||||
}: OAuthApiCreateOptions): GithubAuth;
|
||||
static create(options: OAuthApiCreateOptions): GithubAuth;
|
||||
// (undocumented)
|
||||
getAccessToken(scope?: string, options?: AuthRequestOptions): Promise<string>;
|
||||
// (undocumented)
|
||||
@@ -441,25 +419,13 @@ export type GithubSession = {
|
||||
// @public
|
||||
export class GitlabAuth {
|
||||
// (undocumented)
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment,
|
||||
provider,
|
||||
oauthRequestApi,
|
||||
defaultScopes,
|
||||
}: OAuthApiCreateOptions): typeof gitlabAuthApiRef.T;
|
||||
static create(options: OAuthApiCreateOptions): typeof gitlabAuthApiRef.T;
|
||||
}
|
||||
|
||||
// @public
|
||||
export class GoogleAuth {
|
||||
// (undocumented)
|
||||
static create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
environment,
|
||||
provider,
|
||||
defaultScopes,
|
||||
}: OAuthApiCreateOptions): typeof googleAuthApiRef.T;
|
||||
static create(options: OAuthApiCreateOptions): typeof googleAuthApiRef.T;
|
||||
}
|
||||
|
||||
// @public
|
||||
@@ -477,13 +443,7 @@ export class LocalStorageFeatureFlags implements FeatureFlagsApi {
|
||||
// @public
|
||||
export class MicrosoftAuth {
|
||||
// (undocumented)
|
||||
static create({
|
||||
environment,
|
||||
provider,
|
||||
oauthRequestApi,
|
||||
discoveryApi,
|
||||
defaultScopes,
|
||||
}: OAuthApiCreateOptions): typeof microsoftAuthApiRef.T;
|
||||
static create(options: OAuthApiCreateOptions): typeof microsoftAuthApiRef.T;
|
||||
}
|
||||
|
||||
// @public
|
||||
@@ -507,14 +467,7 @@ export class OAuth2
|
||||
scopeTransform: (scopes: string[]) => string[];
|
||||
});
|
||||
// (undocumented)
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment,
|
||||
provider,
|
||||
oauthRequestApi,
|
||||
defaultScopes,
|
||||
scopeTransform,
|
||||
}: OAuth2CreateOptions): OAuth2;
|
||||
static create(options: OAuth2CreateOptions): OAuth2;
|
||||
// (undocumented)
|
||||
getAccessToken(
|
||||
scope?: string | string[],
|
||||
@@ -570,24 +523,15 @@ export class OAuthRequestManager implements OAuthRequestApi {
|
||||
// @public
|
||||
export class OktaAuth {
|
||||
// (undocumented)
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment,
|
||||
provider,
|
||||
oauthRequestApi,
|
||||
defaultScopes,
|
||||
}: OAuthApiCreateOptions): typeof oktaAuthApiRef.T;
|
||||
static create(options: OAuthApiCreateOptions): typeof oktaAuthApiRef.T;
|
||||
}
|
||||
|
||||
// @public
|
||||
export class OneLoginAuth {
|
||||
// (undocumented)
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment,
|
||||
provider,
|
||||
oauthRequestApi,
|
||||
}: OneLoginAuthCreateOptions): typeof oneloginAuthApiRef.T;
|
||||
static create(
|
||||
options: OneLoginAuthCreateOptions,
|
||||
): typeof oneloginAuthApiRef.T;
|
||||
}
|
||||
|
||||
// @public
|
||||
@@ -607,11 +551,7 @@ export class SamlAuth
|
||||
// @deprecated
|
||||
constructor(sessionManager: SessionManager<SamlSession>);
|
||||
// (undocumented)
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment,
|
||||
provider,
|
||||
}: AuthApiCreateOptions): SamlAuth;
|
||||
static create(options: AuthApiCreateOptions): SamlAuth;
|
||||
// (undocumented)
|
||||
getBackstageIdentity(
|
||||
options?: AuthRequestOptions,
|
||||
@@ -635,10 +575,10 @@ export type SamlSession = {
|
||||
|
||||
// @public
|
||||
export type SignInPageProps = {
|
||||
onResult(result: SignInResult): void;
|
||||
onSignInSuccess(identityApi: IdentityApi): void;
|
||||
};
|
||||
|
||||
// @public
|
||||
// @public @deprecated
|
||||
export type SignInResult = {
|
||||
userId: string;
|
||||
profile: ProfileInfo;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/core-app-api",
|
||||
"description": "Core app API used by Backstage apps",
|
||||
"version": "0.1.23",
|
||||
"version": "0.2.0",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
@@ -29,26 +29,28 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/app-defaults": "^0.1.1",
|
||||
"@backstage/core-components": "^0.7.5",
|
||||
"@backstage/app-defaults": "^0.1.2",
|
||||
"@backstage/core-components": "^0.8.0",
|
||||
"@backstage/config": "^0.1.11",
|
||||
"@backstage/core-plugin-api": "^0.2.1",
|
||||
"@backstage/theme": "^0.2.13",
|
||||
"@backstage/core-plugin-api": "^0.3.0",
|
||||
"@backstage/theme": "^0.2.14",
|
||||
"@backstage/types": "^0.1.1",
|
||||
"@backstage/version-bridge": "^0.1.0",
|
||||
"@backstage/version-bridge": "^0.1.1",
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@types/react": "*",
|
||||
"@types/prop-types": "^15.7.3",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^16.12.0",
|
||||
"react-router-dom": "6.0.0-beta.0",
|
||||
"react-use": "^17.2.4",
|
||||
"zen-observable": "^0.8.15"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.13.1 || ^17.0.0",
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.9.1",
|
||||
"@backstage/test-utils": "^0.1.23",
|
||||
"@backstage/cli": "^0.10.1",
|
||||
"@backstage/test-utils": "^0.1.24",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@testing-library/react-hooks": "^7.0.2",
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
IdentityApi,
|
||||
ProfileInfo,
|
||||
BackstageUserIdentity,
|
||||
} from '@backstage/core-plugin-api';
|
||||
|
||||
function mkError(thing: string) {
|
||||
return new Error(
|
||||
`Tried to access IdentityApi ${thing} before app was loaded`,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of the connection between the App-wide IdentityApi
|
||||
* and sign-in page.
|
||||
*/
|
||||
export class AppIdentityProxy implements IdentityApi {
|
||||
private target?: IdentityApi;
|
||||
|
||||
// This is called by the app manager once the sign-in page provides us with an implementation
|
||||
setTarget(identityApi: IdentityApi) {
|
||||
this.target = identityApi;
|
||||
}
|
||||
|
||||
getUserId(): string {
|
||||
if (!this.target) {
|
||||
throw mkError('getUserId');
|
||||
}
|
||||
return this.target.getUserId();
|
||||
}
|
||||
|
||||
getProfile(): ProfileInfo {
|
||||
if (!this.target) {
|
||||
throw mkError('getProfile');
|
||||
}
|
||||
return this.target.getProfile();
|
||||
}
|
||||
|
||||
async getProfileInfo(): Promise<ProfileInfo> {
|
||||
if (!this.target) {
|
||||
throw mkError('getProfileInfo');
|
||||
}
|
||||
return this.target.getProfileInfo();
|
||||
}
|
||||
|
||||
async getBackstageIdentity(): Promise<BackstageUserIdentity> {
|
||||
if (!this.target) {
|
||||
throw mkError('getBackstageIdentity');
|
||||
}
|
||||
return this.target.getBackstageIdentity();
|
||||
}
|
||||
|
||||
async getCredentials(): Promise<{ token?: string | undefined }> {
|
||||
if (!this.target) {
|
||||
throw mkError('getCredentials');
|
||||
}
|
||||
return this.target.getCredentials();
|
||||
}
|
||||
|
||||
async getIdToken(): Promise<string | undefined> {
|
||||
if (!this.target) {
|
||||
throw mkError('getIdToken');
|
||||
}
|
||||
return this.target.getIdToken();
|
||||
}
|
||||
|
||||
async signOut(): Promise<void> {
|
||||
if (!this.target) {
|
||||
throw mkError('signOut');
|
||||
}
|
||||
await this.target.signOut();
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
@@ -30,12 +30,14 @@ const DEFAULT_PROVIDER = {
|
||||
* @public
|
||||
*/
|
||||
export default class AtlassianAuth {
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
}: OAuthApiCreateOptions): typeof atlassianAuthApiRef.T {
|
||||
static create(options: OAuthApiCreateOptions): typeof atlassianAuthApiRef.T {
|
||||
const {
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
} = options;
|
||||
|
||||
return OAuth2.create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
|
||||
@@ -30,13 +30,15 @@ const DEFAULT_PROVIDER = {
|
||||
* @public
|
||||
*/
|
||||
export default class Auth0Auth {
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
defaultScopes = ['openid', `email`, `profile`],
|
||||
}: OAuthApiCreateOptions): typeof auth0AuthApiRef.T {
|
||||
static create(options: OAuthApiCreateOptions): typeof auth0AuthApiRef.T {
|
||||
const {
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
defaultScopes = ['openid', `email`, `profile`],
|
||||
} = options;
|
||||
|
||||
return OAuth2.create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user