Merge backstage/master

Signed-off-by: Kai Szybiak <kaiszybiak@gmail.com>
This commit is contained in:
Kai Szybiak
2021-12-06 12:08:54 +01:00
825 changed files with 30493 additions and 4159 deletions
+2 -2
View File
@@ -23,13 +23,13 @@ const {
async function getDependencyReleaseLine(changesets, dependenciesUpdated) {
if (dependenciesUpdated.length === 0) return '';
const updatedDepenenciesList = dependenciesUpdated.map(
const updatedDependenciesList = dependenciesUpdated.map(
dependency => ` - ${dependency.name}@${dependency.newVersion}`,
);
// Return one `Updated dependencies` bullet instead of repeating for each changeset; this
// sacrifices the commit shas for brevity.
return ['- Updated dependencies', ...updatedDepenenciesList].join('\n');
return ['- Updated dependencies', ...updatedDependenciesList].join('\n');
}
module.exports = {
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/core-components': patch
'@backstage/create-app': patch
'@backstage/plugin-catalog': patch
---
Addressed some peer dependency warnings
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder': patch
---
Can specify allowedOwners to the RepoUrlPicker picker in a template definition
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend': patch
---
Bump esbuild to ^0.14.1
+14
View File
@@ -0,0 +1,14 @@
---
'@backstage/plugin-kubernetes': minor
'@backstage/plugin-kubernetes-backend': minor
'@backstage/plugin-kubernetes-common': minor
---
Add pod metrics lookup and display in pod table.
## Backwards incompatible changes
If your Kubernetes distribution does not have the [metrics server](https://github.com/kubernetes-sigs/metrics-server) installed,
you will need to set the `skipMetricsLookup` config flag to `false`.
See the [configuration docs](https://backstage.io/docs/features/kubernetes/configuration) for more details.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend': patch
---
Reject catalog entities that have duplicate fields that vary only in casing.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder': patch
---
Fix bug with setting owner in RepoUrlPicker causing validation failure
+10
View File
@@ -0,0 +1,10 @@
---
'@backstage/cli': patch
---
Add cli option to minify the generated code of a plugin or backend package
```
backstage-cli plugin:build --minify
backstage-cli backend:build --minify
```
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-search': patch
---
Export SearchApi interface from plugin
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-analytics-module-ga': patch
---
Support self hosted analytics.js script via `scriptSrc` config option
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-common': patch
---
Add knexConfig config section
@@ -0,0 +1,7 @@
---
'@backstage/techdocs-common': minor
'@backstage/plugin-techdocs-backend': minor
---
Added the ability for the TechDocs Backend to (optionally) leverage a cache
store to improve performance when reading files from a cloud storage provider.
+42
View File
@@ -0,0 +1,42 @@
---
'@backstage/create-app': patch
---
TechDocs Backend may now (optionally) leverage a cache store to improve
performance when reading content from a cloud storage provider.
To apply this change to an existing app, pass the cache manager from the plugin
environment to the `createRouter` function in your backend:
```diff
// packages/backend/src/plugins/techdocs.ts
export default async function createPlugin({
logger,
config,
discovery,
reader,
+ cache,
}: PluginEnvironment): Promise<Router> {
// ...
return await createRouter({
preparers,
generators,
publisher,
logger,
config,
discovery,
+ cache,
});
```
If your `PluginEnvironment` does not include a cache manager, be sure you've
applied [the cache management change][cm-change] to your backend as well.
[Additional configuration][td-rec-arch] is required if you wish to enable
caching in TechDocs.
[cm-change]: https://github.com/backstage/backstage/blob/master/packages/create-app/CHANGELOG.md#patch-changes-6
[td-rec-arch]: https://backstage.io/docs/features/techdocs/architecture#recommended-deployment
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-xcmetrics': patch
---
Handle a case where XCode data from backend (before 0.0.8) could be missing
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-bazaar-backend': patch
---
Handle migration error when old data is present in the database
+16
View File
@@ -8,6 +8,8 @@
/docs/features/techdocs @backstage/techdocs-core
/docs/features/search @backstage/techdocs-core
/docs/assets/search @backstage/techdocs-core
/plugins/allure @backstage/reviewers @deepak-bhardwaj-ps
/plugins/circleci @backstage/reviewers @adamdmharvey
/plugins/code-coverage @backstage/reviewers @alde @nissayeva
/plugins/code-coverage-backend @backstage/reviewers @alde @nissayeva
/plugins/cost-insights @backstage/silver-lining
@@ -18,6 +20,20 @@
/plugins/techdocs-backend @backstage/techdocs-core
/plugins/ilert @backstage/reviewers @yacut
/plugins/home @backstage/techdocs-core
/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
/tech-insights-tech-insights-node @backstage/reviewers @xantier @iain-b
/packages/embedded-techdocs-app @backstage/techdocs-core
/packages/search-common @backstage/techdocs-core
/packages/techdocs-cli @backstage/techdocs-core
-21
View File
@@ -1,21 +0,0 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- pinned
- security
- plugin
- help wanted
- good first issue
- rfc
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false
+1
View File
@@ -189,6 +189,7 @@ oidc
Okta
onboarding
Onboarding
OpenShift
orgs
pagerduty
pageview
@@ -6,6 +6,8 @@ on:
jobs:
sync:
if: github.repository == 'backstage/backstage' # prevent running on forks
runs-on: ubuntu-latest
strategy:
+30
View File
@@ -0,0 +1,30 @@
name: 'Stale workflow'
on:
workflow_dispatch:
schedule:
- cron: '*/10 * * * *' # run every 10 minutes as it also removes labels.
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@main
id: stale
with:
stale-issue-message: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
days-before-issue-stale: 60
days-before-issue-close: 7
exempt-issue-labels: 'pinned,security,plugin,help wanted,good first issue,rfc'
stale-issue-label: stale
stale-pr-message: >
This PR has been automatically marked as stale because it has not had
recent activity from the author. It will be closed if no further activity occurs.
If you are the author and the PR has been closed, feel free to re-open the PR and continue the contribution!
days-before-pr-stale: 7
days-before-pr-close: 3
exempt-pr-labels: reviewer-approved,awaiting-review
stale-pr-label: stale
operations-per-run: 100
+2 -2
View File
@@ -1,7 +1,7 @@
services:
backstage:
image: tugboatqa/node:lts
expose: 7000
expose: 7007
default: true
commands:
init:
@@ -14,4 +14,4 @@ services:
- yarn workspace example-app build
start:
# wget the endpoint. Will retry every 2 seconds. 30 retries = 1m for service to come up. Plenty.
- wget -O /dev/null -o /dev/null --tries=30 --timeout=5 --retry-connrefused http://localhost:7000
- wget -O /dev/null -o /dev/null --tries=30 --timeout=5 --retry-connrefused http://localhost:7007
+8 -2
View File
@@ -66,6 +66,12 @@
| [Palo Alto Networks](https://www.paloaltonetworks.com) | [Jeremy Guarini](https://github.com/jeremyguarini), [Brian Lomeland](https://github.com/bbbmmmlll), [Palo Alto Networks](https://github.com/PaloAltoNetworks) | Developer portal, service catalog, documentation and tooling |
| [Signal Iduna Group](https://www.signal-iduna.de/) | [Jonas Thomsen](https://github.com/JoThomsen) | Developer Portal, documentation, monitoring, service catalog for our insurance ecosystem |
| [Tradeshift](https://www.tradeshift.com/) | [Soren Mathiasen](https://github.com/sorenmat) | Developer Portal: documentation, monitoring, service templates, service catalog for our micro services |
| [Unity](https://unity.com) | [Ted Cordery](https://github.com/TeddyBallGame) | A centralized service catalog with documentation for our service engineers. |
| [PicPay](https://www.picpay.com) | [Luis Baroni](https://github.com/lcsbaroni), [Renata Poluceno](https://github.com/renatapoluceno), [PicPay](https://github.com/picpay) | Developer portal for building services throught templates, service catalog with ownership of services, documentation and metrics providing autonomy and visibility for all. |
| [Unity](https://unity.com) | [Ted Cordery](https://github.com/TeddyBallGame) | A centralized service catalog with documentation for our service engineers. |
| [PicPay](https://www.picpay.com) | [Luis Baroni](https://github.com/lcsbaroni), [Renata Poluceno](https://github.com/renatapoluceno), [PicPay](https://github.com/picpay) | Developer portal for building services throught templates, service catalog with ownership of services, documentation and metrics providing autonomy and visibility for all. |
| [Epic Games](https://www.epicgames.com) | [Brian Jung](https://github.com/brian-at-epic), [Jeff Goldian](https://github.com/jeffgoldian-Epic) | Developer Portal: Service Catalog, Documentation, Software Templates and more making our internal teams' lives easier! |
| [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 |
| [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 🥰🚀 |
+3 -1
View File
@@ -122,7 +122,9 @@ We use [changesets](https://github.com/atlassian/changesets) to help us prepare
Any time a patch, minor, or major change aligning to [Semantic Versioning](https://semver.org) is made to any published package in `packages/` or `plugins/`, a changeset should be used. It helps to align your change to the [Backstage stability index](https://backstage.io/docs/overview/stability-index) for the package you are changing, for example, when to provide additional clarity on deprecation or impacting changes which will then be included into CHANGELOGs.
In general, changesets are not needed for the documentation, build utilities, contributed samples in `contrib/`, or the [example `packages/app`](packages/app).
In general, changesets are only needed for changes to packages within `packages/` or `plugins/` directories, and only for the packages that are not marked as `private`. Changesets are also not needed for changes that do not affect the published version of each package, for example changes to tests or in-line source code comments.
Changesets **are** needed for new packages, as that is what triggers the package to be part of the next release.
### How to create a changeset
+7 -20
View File
@@ -23,9 +23,14 @@ app:
title: '#backstage'
backend:
baseUrl: http://localhost:7000
# Used for enabling authentication, secret is shared by all backend plugins
# See backend-to-backend-auth.md in the docs for information on the format
# auth:
# keys:
# - secret: ${BACKEND_SECRET}
baseUrl: http://localhost:7007
listen:
port: 7000
port: 7007
database:
client: sqlite3
connection: ':memory:'
@@ -272,24 +277,6 @@ scaffolder:
# email: scaffolder@backstage.io
# Use to customize the default commit message when new components are created
# defaultCommitMessage: 'Initial commit'
github:
token: ${GITHUB_TOKEN}
visibility: public # or 'internal' or 'private'
gitlab:
api:
baseUrl: https://gitlab.com
token: ${GITLAB_TOKEN}
visibility: public # or 'internal' or 'private'
azure:
baseUrl: https://dev.azure.com/{your-organization}
api:
token: ${AZURE_TOKEN}
bitbucket:
api:
host: https://bitbucket.org
username: ${BITBUCKET_USERNAME}
token: ${BITBUCKET_TOKEN}
visibility: public # or or 'private'
auth:
### Add auth.keyStore.provider to more granularly control how to store JWK data when running
@@ -1,7 +1,7 @@
backend:
lighthouseHostname: {{ include "lighthouse.serviceName" . | quote }}
listen:
port: {{ .Values.appConfig.backend.listen.port | default 7000 }}
port: {{ .Values.appConfig.backend.listen.port | default 7007 }}
database:
client: {{ .Values.appConfig.backend.database.client | quote }}
connection:
@@ -1,7 +1,13 @@
{{- $frontendUrl := urlParse .Values.appConfig.app.baseUrl}}
{{- $backendUrl := urlParse .Values.appConfig.backend.baseUrl}}
{{- $lighthouseUrl := urlParse .Values.appConfig.lighthouse.baseUrl}}
{{/* Determine the api type for the ingress */}}
{{- if lt .Capabilities.KubeVersion.Minor "19" }}
apiVersion: networking.k8s.io/v1beta1
{{- else if ge .Capabilities.KubeVersion.Minor "19" }}
apiVersion: networking.k8s.io/v1
{{- end }}
kind: Ingress
metadata:
name: {{ include "backstage.fullname" . }}-ingress
+2 -2
View File
@@ -26,7 +26,7 @@ backend:
repository: martinaif/backstage-k8s-demo-backend
tag: 20210423T1550
pullPolicy: IfNotPresent
containerPort: 7000
containerPort: 7007
serviceType: ClusterIP
postgresCertMountEnabled: true
resources:
@@ -96,7 +96,7 @@ appConfig:
backend:
baseUrl: https://demo.example.com
listen:
port: 7000
port: 7007
cors:
origin: https://demo.example.com
database:
+5 -5
View File
@@ -9,8 +9,8 @@ docker_name_prefix := backstage-make
# to the host computer
frontend_port := 3000
frontend_host_port := 3000
backend_port := 7000
backend_host_port := 7000
backend_port := 7007
backend_host_port := 7007
# path to this "makefile"
my_dir_path = $(dir $(CURDIR)/$(firstword $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
@@ -191,10 +191,10 @@ test: check-tests
check: check-code check-docs check-type-dependencies check-styles
# run development instance
# BUG: the frontend seems to run on "$(backend_port)" (7000 default).
# BUG: the frontend seems to run on "$(backend_port)" (7007 default).
# The documentation states "This is going to start two things,
# the frontend (:3000) and the backend (:7000)."
# However, the frontend seems to end up running on 7000.
# the frontend (:3000) and the backend (:7007)."
# However, the frontend seems to end up running on 7007.
.PHONY: dev
dev: build
@docker run --rm -it \
@@ -22,6 +22,6 @@ spec:
image: spotify/backstage-backend:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 7000
- containerPort: 7007
name: backend
protocol: TCP
@@ -63,7 +63,7 @@ backend:
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 7000
port: 7007
ingress:
enabled: false
annotations:
@@ -30,6 +30,6 @@ spec:
component: backend
ports:
- name: backend
port: 7000
port: 7007
protocol: TCP
targetPort: backend
+1 -1
View File
@@ -1,5 +1,5 @@
{
"baseUrl": "http://localhost:7000",
"baseUrl": "http://localhost:7007",
"integrationFolder": "./src/integration",
"supportFile": "./src/support",
"fixturesFolder": "./src/fixtures",
+26 -78
View File
@@ -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"
+7
View File
@@ -54,3 +54,10 @@ const darkTheme = {
),
};
```
Note that the existing `AppTheme` type still requires the `theme` property to be
set since it's the type that's consumed in the `AppThemeApi`, and it would be a
breaking change to make `theme` optional. This means that if you currently
construct the themes that you pass on to `createApp` using `AppTheme` as an
intermediate type, you will need to work around this in some way, for example by
passing the themes to `createApp` more directly.
+1 -1
View File
@@ -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
@@ -1,6 +1,6 @@
---
id: adrs-adr012
title: ADR000: Use Luxon.toLocaleString and date/time presets
title: ADR012: Use Luxon.toLocaleString and date/time presets
description: Architecture Decision Record (ADR) for using Luxon's toLocaleString method and date/time presets for displaying dates and times
---
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 64 KiB

+1 -1
View File
@@ -229,7 +229,7 @@ name.
### Test the new provider
You can `curl -i localhost:7000/api/auth/providerA/start` and which should
You can `curl -i localhost:7007/api/auth/providerA/start` and which should
provide a `302` redirect with a `Location` header. Paste the url from that
header into a web browser and you should be able to trigger the authorization
flow.
+1 -1
View File
@@ -28,7 +28,7 @@ Name your integration and click on the `Create` button.
Settings for local development:
- Callback URL: `http://localhost:7000/api/auth/atlassian`
- Callback URL: `http://localhost:7007/api/auth/atlassian`
- Use rotating refresh tokens
- For permissions, you **must** enable `View user profile` for the currently
logged-in user, under `User identity API`
+1 -1
View File
@@ -17,7 +17,7 @@ provider that can authenticate users using OAuth.
- Application type: Single Page Web Application
4. Click on the Settings tab
5. Add under `Application URIs` > `Allowed Callback URLs`:
`http://localhost:7000/api/auth/auth0/handler/frame`
`http://localhost:7007/api/auth/auth0/handler/frame`
6. Click `Save Changes`
## Configuration
+1 -1
View File
@@ -20,7 +20,7 @@ Click Add Consumer.
Settings for local development:
- Application name: Backstage (or your custom app name)
- Callback URL: `http://localhost:7000/api/auth/bitbucket`
- Callback URL: `http://localhost:7007/api/auth/bitbucket`
- Other are optional
- (IMPORTANT) **Permissions: Account - Read, Workspace membership - Read**
+1 -1
View File
@@ -24,7 +24,7 @@ Settings for local development:
- Application name: Backstage (or your custom app name)
- Homepage URL: `http://localhost:3000`
- Authorization callback URL: `http://localhost:7000/api/auth/github`
- Authorization callback URL: `http://localhost:7007/api/auth/github`
## Configuration
+1 -1
View File
@@ -17,7 +17,7 @@ should point to your Backstage backend auth handler.
Settings for local development:
- Name: Backstage (or your custom app name)
- Redirect URI: `http://localhost:7000/api/auth/gitlab/handler/frame`
- Redirect URI: `http://localhost:7007/api/auth/gitlab/handler/frame`
- Scopes: read_user
## Configuration
+1 -1
View File
@@ -26,7 +26,7 @@ To support Google authentication, you must create OAuth credentials:
- `Name`: Backstage (or your custom app name)
- `Authorized JavaScript origins`: http://localhost:3000
- `Authorized Redirect URIs`:
http://localhost:7000/api/auth/google/handler/frame
http://localhost:7007/api/auth/google/handler/frame
7. Click Create
## Configuration
+2
View File
@@ -16,8 +16,10 @@ Backstage identity information in your app or plugins.
Backstage comes with many common authentication providers in the core library:
- [Atlassian](atlassian/provider.md)
- [Auth0](auth0/provider.md)
- [Azure](microsoft/provider.md)
- [Bitbucket](bitbucket/provider.md)
- [GitHub](github/provider.md)
- [GitLab](gitlab/provider.md)
- [Google](google/provider.md)
+1 -1
View File
@@ -21,7 +21,7 @@ To support Azure authentication, you must create an App Registration:
4. Register an application
- Name: Backstage (or your custom app name)
- Redirect URI: Web >
`http://localhost:7000/api/auth/microsoft/handler/frame`
`http://localhost:7007/api/auth/microsoft/handler/frame`
5. Navigate to **Certificates & secrets > New client secret** to create a secret
## Configuration
+2 -2
View File
@@ -22,8 +22,8 @@ To add Okta authentication, you must create an Application from Okta:
- `App integration name`: `Backstage` (or your custom app name)
- `Grant type`: `Authorization Code` & `Refresh Token`
- `Sign-in redirect URIs`:
`http://localhost:7000/api/auth/okta/handler/frame`
- `Sign-out redirect URIs`: `http://localhost:7000`
`http://localhost:7007/api/auth/okta/handler/frame`
- `Sign-out redirect URIs`: `http://localhost:7007`
- `Controlled access`: (select as appropriate)
- Click Save
+1 -1
View File
@@ -18,7 +18,7 @@ To support OneLogin authentication, you must create an Application:
3. Click Save
4. Go to the Configuration tab for the Application and set:
- `Login Url`: `http://localhost:3000`
- `Redirect URIs`: `http://localhost:7000/api/auth/onelogin/handler/frame`
- `Redirect URIs`: `http://localhost:7007/api/auth/onelogin/handler/frame`
5. Click Save
6. Go to the SSO tab for the Application and set:
- `Token Endpoint` > `Authentication Method`: `POST`
+2 -2
View File
@@ -16,8 +16,8 @@ app:
baseUrl: http://localhost:3000
backend:
listen: 0.0.0.0:7000
baseUrl: http://localhost:7000
listen: 0.0.0.0:7007
baseUrl: http://localhost:7007
organization:
name: CNCF
+7 -7
View File
@@ -7,9 +7,9 @@ description: How to build a Backstage Docker image for deployment
This section describes how to build a Backstage App into a deployable Docker
image. It is split into three sections, first covering the host build approach,
which is recommended due its speed and more efficient and often simpler caching.
The second section covers a full multi-stage Docker build, and the last section
covers how to deploy the frontend and backend as separate images.
which is recommended due to its speed and more efficient and often simpler
caching. The second section covers a full multi-stage Docker build, and the last
section covers how to deploy the frontend and backend as separate images.
Something that goes for all of these docker deployment strategies is that they
are stateless, so for a production deployment you will want to set up and
@@ -105,11 +105,11 @@ docker image build . -f packages/backend/Dockerfile --tag backstage
To try out the image locally you can run the following:
```sh
docker run -it -p 7000:7000 backstage
docker run -it -p 7007:7007 backstage
```
You should then start to get logs in your terminal, and then you can open your
browser at `http://localhost:7000`
browser at `http://localhost:7007`
## Multi-stage Build
@@ -208,11 +208,11 @@ docker image build -t backstage .
To try out the image locally you can run the following:
```sh
docker run -it -p 7000:7000 backstage
docker run -it -p 7007:7007 backstage
```
You should then start to get logs in your terminal, and then you can open your
browser at `http://localhost:7000`
browser at `http://localhost:7007`
## Separate Frontend
+7 -7
View File
@@ -351,7 +351,7 @@ spec:
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 7000
containerPort: 7007
envFrom:
- secretRef:
name: postgres-secrets
@@ -361,11 +361,11 @@ spec:
# https://backstage.io/docs/plugins/observability#health-checks
# readinessProbe:
# httpGet:
# port: 7000
# port: 7007
# path: /healthcheck
# livenessProbe:
# httpGet:
# port: 7000
# port: 7007
# path: /healthcheck
```
@@ -449,7 +449,7 @@ spec:
```
The `selector` here is telling the Service which pods to target, and the port
mapping translates normal HTTP port 80 to the backend http port (7000) on the
mapping translates normal HTTP port 80 to the backend http port (7007) on the
pod.
Apply this Service to the Kubernetes cluster:
@@ -464,10 +464,10 @@ reveal**_, you can forward a local port to the service:
```shell
$ sudo kubectl port-forward --namespace=backstage svc/backstage 80:80
Forwarding from 127.0.0.1:80 -> 7000
Forwarding from 127.0.0.1:80 -> 7007
```
This shows port 7000 since `port-forward` doesn't _really_ support services, so
This shows port 7007 since `port-forward` doesn't _really_ support services, so
it cheats by looking up the first pod for a service and connecting to the mapped
pod port.
@@ -486,7 +486,7 @@ organization:
backend:
baseUrl: http://localhost
listen:
port: 7000
port: 7007
cors:
origin: http://localhost
```
+36 -4
View File
@@ -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)
@@ -219,6 +231,26 @@ The custom resource's apiVersion.
The plural representing the custom resource.
### `apiVersionOverrides` (optional)
Overrides for the API versions used to make requests for the corresponding
objects. If using a legacy Kubernetes version, you may use this config to
override the default API versions to ones that are supported by your cluster.
Example:
```yaml
---
kubernetes:
apiVersionOverrides:
cronjobs: 'v1beta1'
```
For more information on which API versions are supported by your cluster, please
view the Kubernetes API docs for your Kubernetes version (e.g.
[API Groups for v1.22](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#-strong-api-groups-strong-)
)
### Role Based Access Control
The current RBAC permissions required are read-only cluster wide, for the
+17 -5
View File
@@ -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 />
...
```
@@ -154,13 +156,17 @@ import { DefaultCatalogCollator } from '@backstage/plugin-catalog-backend';
export default async function createPlugin({
logger,
discovery,
tokenManager,
}: PluginEnvironment) {
const searchEngine = new LunrSearchEngine({ logger });
const indexBuilder = new IndexBuilder({ logger, searchEngine });
indexBuilder.addCollator({
defaultRefreshIntervalSeconds: 600,
collator: new DefaultCatalogCollator({ discovery }),
collator: new DefaultCatalogCollator({
discovery,
tokenManager,
}),
});
const { scheduler } = await indexBuilder.build();
@@ -285,7 +291,10 @@ const indexBuilder = new IndexBuilder({ logger, searchEngine });
indexBuilder.addCollator({
defaultRefreshIntervalSeconds: 600,
collator: new DefaultCatalogCollator({ discovery }),
collator: new DefaultCatalogCollator({
discovery,
tokenManager,
}),
});
indexBuilder.addCollator({
@@ -303,6 +312,9 @@ its `defaultRefreshIntervalSeconds` value, like this:
```typescript {3}
indexBuilder.addCollator({
defaultRefreshIntervalSeconds: 600,
collator: new DefaultCatalogCollator({ discovery }),
collator: new DefaultCatalogCollator({
discovery,
tokenManager,
}),
});
```
+2 -1
View File
@@ -2,7 +2,7 @@
id: how-to-guides
title: Search "HOW TO" guides
sidebar_label: "HOW TO" guides
description: Search "HOW TO" guides
description: Search "HOW TO" guides
---
## How to implement your own Search API
@@ -74,6 +74,7 @@ indexBuilder.addCollator({
collator: DefaultTechDocsCollator.fromConfig(config, {
discovery,
logger,
tokenManager,
}),
});
```
+3 -3
View File
@@ -4,9 +4,9 @@ title: Search Engines
description: Choosing and configuring your search engine for Backstage
---
Backstage supports 2 search engines by default, an in-memory engine called Lunr
and ElasticSearch. You can configure your own search engines by implementing the
provided interface as mentioned in the
Backstage supports 3 search engines by default, an in-memory engine called Lunr,
ElasticSearch and Postgres. You can configure your own search engines by
implementing the provided interface as mentioned in the
[search backend documentation.](./getting-started.md#Backend)
Provided search engine implementations have their own way of constructing
@@ -53,3 +53,30 @@ You can do so by including the following lines in the last step of your
RUN apt-get update && apt-get install -y python3 python3-pip
RUN pip3 install cookiecutter
```
### Customizing the ScaffolderPage with Grouping and Filtering
Once you have more than a few software templates you may want to customize your
`ScaffolderPage` by grouping and surfacing certain templates together. You can
accomplish this by creating `groups` and passing them to your `ScaffolderPage`
like below
```
<ScaffolderPage
groups={[
{
title: "Recommended",
filter: entity =>
entity?.metadata?.tags?.includes('recommended') ?? false,
},
]}
/>
```
This code will group all templates with the 'recommended' tag together at the
top of the page above any other templates not filtered by this group or others.
You can also further customize groups by passing in a `titleComponent` instead
of a `title` which will be a component to use as the header instead of just the
default `ContentHeader` with the `title` set as it's value.
![Grouped Templates](../../assets/software-templates/grouped-templates.png)
+1 -1
View File
@@ -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
+7 -7
View File
@@ -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
+18 -2
View File
@@ -135,14 +135,30 @@ 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.
requestUrl: http://localhost:7000/api/techdocs
requestUrl: http://localhost:7007/api/techdocs
# (Optional and Legacy) Just another route in techdocs-backend where TechDocs requests the static files from. This URL uses an HTTP middleware
# to serve files from either a local directory or an External storage provider.
# You don't have to specify this anymore.
storageUrl: http://localhost:7000/api/techdocs/static/docs
storageUrl: http://localhost:7007/api/techdocs/static/docs
```
+1 -1
View File
@@ -43,7 +43,7 @@ the project root. Make sure you have run the above mentioned commands first.
$ yarn dev
```
This is going to start two things, the frontend (:3000) and the backend (:7000).
This is going to start two things, the frontend (:3000) and the backend (:7007).
This should open a local instance of Backstage in your browser, otherwise open
one of the URLs printed in the terminal.
+1 -1
View File
@@ -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
+20 -17
View File
@@ -23,7 +23,7 @@ guide to do a repository-based installation.
- Access to a Linux-based operating system, such as Linux, MacOS or
[Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/)
- An account with elevated rights
- An account with elevated rights to install the dependencies
- `curl` or `wget` installed
- Node.js Active LTS Release installed (currently v14) using one of these
methods:
@@ -36,15 +36,16 @@ guide to do a repository-based installation.
- `yarn` [Installation](https://classic.yarnpkg.com/en/docs/install)
- `docker` [installation](https://docs.docker.com/engine/install/)
- `git` [installation](https://github.com/git-guides/install-git)
- If the system is not directly accessible over your network, the following
ports need to be opened: 3000, 7000
- If the system is not directly accessible over your network the following ports
need to be opened: 3000, 7007. This is quite uncommon, unless when you're
installing in a container, VM or remote system.
### Create your Backstage App
To install the Backstage Standalone app, we make use of `npx`, a tool to run
Node executables straight from the registry. Running the command below will
install Backstage. The wizard will create a subdirectory inside your current
working directory.
Node executables straight from the registry. This tool is part of your Node.js
installation. Running the command below will install Backstage. The wizard will
create a subdirectory inside your current working directory.
```bash
npx @backstage/create-app
@@ -57,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
@@ -72,18 +73,27 @@ 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
`[0] webpack compiled successfully` appears, you can open a browser and directly
navigate to your freshly installed Backstage portal at `http://localhost:3000`.
You can start exploring the demo immediately.
You can start exploring the demo immediately. Please note that the in-memory
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
authentication, and add a plugin:
- [Switching from SQLite to PostgresQL](https://backstage.io/docs/tutorials/switching-sqlite-postgres)
- [Setting up Authentication](https://backstage.io/docs/auth/)
- [Adding a plugin](https://backstage.io/docs/getting-started/configure-app-with-plugins)
Congratulations! That should be it. Let us know how it went:
[on discord](https://discord.gg/EBHEGzX), file issues for any
[feature](https://github.com/backstage/backstage/issues/new?labels=help+wanted&template=feature_template.md)
@@ -93,10 +103,3 @@ or
[bugs](https://github.com/backstage/backstage/issues/new?labels=bug&template=bug_template.md)
you have, and feel free to
[contribute](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md)!
The most common next steps are to configure Backstage, add a plugin and moving
to a more persistent database:
- [Setting up Authentication](https://backstage.io/docs/auth/)
- [Switching from SQLite to PostgresQL](https://backstage.io/docs/tutorials/switching-sqlite-postgres)
- [Adding a plugin](https://backstage.io/docs/getting-started/configure-app-with-plugins)
+1 -5
View File
@@ -166,13 +166,9 @@ are separated out into their own folder, see further down.
plugin and [techdocs-cli](https://github.com/backstage/techdocs-cli).
- [`test-utils/`](https://github.com/backstage/backstage/tree/master/packages/test-utils) -
This package contains more general purpose testing facilities for testing a
This package contains general purpose testing facilities for testing a
Backstage App or its plugins.
- [`test-utils-core/`](https://github.com/backstage/backstage/tree/master/packages/test-utils-core) -
This package contains specific testing facilities used when testing Backstage
core internals.
- [`theme/`](https://github.com/backstage/backstage/tree/master/packages/theme) -
Holds the Backstage Theme.
@@ -70,7 +70,7 @@ cd packages/backend
yarn start
```
That starts up a backend instance on port 7000.
That starts up a backend instance on port 7007.
In the other window, we will then launch the frontend. This command is run from
the project root, not inside the backend directory.
+49
View File
@@ -0,0 +1,49 @@
---
id: discovery
title: Azure DevOps Discovery
sidebar_label: Discovery
# prettier-ignore
description: Automatically discovering catalog entities from repositories in an Azure DevOps organization
---
The Azure DevOps integration has a special discovery processor for discovering
catalog entities within an Azure DevOps. The processor will crawl the Azure
DevOps organization and register entities matching the configured path. This can
be useful as an alternative to static locations or manually adding things to the
catalog.
To use the discovery processor, you'll need a GitHub integration
[set up](locations.md) with a `AZURE_TOKEN`. Then you can add a location target
to the catalog configuration:
```yaml
catalog:
locations:
# Scan all repositories for a catalog-info.yaml in the root of the default branch
- type: azure-discovery
target: https://dev.azure.com/myorg/myproject
# Or use a custom pattern for a subset of all repositories with default repository
- type: azure-discovery
target: https://dev.azure.com/myorg/myproject/_git/service-*
# Or use a custom file format and location
- type: azure-discovery
target: https://dev.azure.com/myorg/myproject/_git/*?path=/src/*/catalog-info.yaml
```
Note the `azure-discovery` type, as this is not a regular `url` processor.
When using a custom pattern, the target is composed of five parts:
- The base instance URL, `https://dev.azure.com` in this case
- The organization name which is required, `myorg` in this case
- The project name which is required, `myproject` in this case
- The repository blob to scan, which accepts \* wildcard tokens and must be
added after `_git/`. This can simply be `*` to scan all repositories in the
project.
- The path within each repository to find the catalog YAML file. This will
usually be `/catalog-info.yaml`, `/src/*/catalog-info.yaml` or a similar
variation for catalog files stored in the root directory of each repository.
_Note:_ the path parameter follows the same rules as the search on Azure DevOps
web interface. For more details visit the
[official search documentation](https://docs.microsoft.com/en-us/azure/devops/project/search/get-started-search?view=azure-devops)
+2
View File
@@ -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
```
+1 -1
View File
@@ -21,7 +21,7 @@ externalDocs:
description: Backstage official documentation
url: https://github.com/backstage/backstage/blob/master/docs/README.md
servers:
- url: http://localhost:7000/api/auth/
- url: http://localhost:7007/api/auth/
tags:
- name: provider
description: List of endpoints per provider
+1 -10
View File
@@ -27,7 +27,7 @@ point building on top of the previous one:
and the new APIs can be used in parallel. This deprecation must have been
released for at least two weeks before the deprecated API is removed in a
minor version bump.
- **3** - The time limit for the deprecation is 3 months instead of two days.
- **3** - The time limit for the deprecation is 3 months instead of two weeks.
TL;DR:
@@ -175,15 +175,6 @@ Utilities for writing tests for Backstage plugins and apps.
Stability: `2`
### `test-utils-core` [GitHub](https://github.com/backstage/backstage/tree/master/packages/test-utils-core/)
Internal testing utilities that are separated out for usage in
@backstage/core-app-api and @backstage/core-plugin-api. All exports are
re-exported by @backstage/test-utils. This package should not be depended on
directly.
Stability: See @backstage/test-utils
### `theme` [GitHub](https://github.com/backstage/backstage/tree/master/packages/theme/)
The core Backstage MUI theme along with customization utilities.
+8 -5
View File
@@ -261,10 +261,13 @@ analytics events captured.
Use it like this:
```tsx
import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { analyticsApiRef } from '@backstage/core-plugin-api';
import { MockAnalyticsApi, wrapInTestApp } from '@backstage/test-utils';
import { render, fireEvent, waitFor } from '@testing-library/react';
import { analyticsApiRef } from '@backstage/core-plugin-api';
import {
MockAnalyticsApi,
TestApiProvider,
wrapInTestApp,
} from '@backstage/test-utils';
describe('SomeComponent', () => {
it('should capture event on click', () => {
@@ -274,9 +277,9 @@ describe('SomeComponent', () => {
// Render the component being tested
const { getByText } = render(
wrapInTestApp(
<ApiProvider apis={ApiRegistry.from([[analyticsApiRef, apiSpy]])}>
<TestApiProvider apis={[[analyticsApiRef, apiSpy]]}>
<SomeComponentUnderTest />
</ApiProvider>,
</TestApiProvider>,
),
);
+3 -3
View File
@@ -44,11 +44,11 @@ cd plugins/carmen-backend
yarn start
```
This will think for a bit, and then say `Listening on :7000`. In a different
This will think for a bit, and then say `Listening on :7007`. In a different
terminal window, now run
```sh
curl localhost:7000/carmen/health
curl localhost:7007/carmen/health
```
This should return `{"status":"ok"}`. Success! Press `Ctrl + c` to kill it
@@ -107,7 +107,7 @@ root), you should be able to fetch data from it.
```sh
# Note the extra /api here
curl localhost:7000/api/carmen/health
curl localhost:7007/api/carmen/health
```
This should return `{"status":"ok"}` like before. Success!
+68
View File
@@ -0,0 +1,68 @@
---
id: backend-to-backend-auth
title: Backend-to-Backend Authentication
description:
Guide for authenticating API requests between Backstage plugin backends
---
This tutorial describes the steps needed to handle _backend-to-backend
authentication_, which allows plugin backends to determine whether a given
request originates from a legitimate Backstage backend by verifying a token
signed with a shared secret. This system has limited use for now, but will be
needed to support the upcoming framework for permissions and authorization (see
[the PRFC on the topic](https://github.com/backstage/backstage/pull/7761) for
more details).
Backends have no concept of a Backstage identity, so instead they use a token
generated using a shared key stored in config. You can generate a unique key for
your app in a terminal, and set the `BACKEND_SECRET` environment variable to the
resulting value.
```bash
node -p 'require("crypto").randomBytes(24).toString("base64")'
```
Requests originating from a backend plugin can be authenticated by decorating
them with a backend token. Backend tokens can be generated using a
`TokenManager`, which can be passed to plugin backends via the
`PluginEnvironment`. The `TokenManager` provided in new Backstage instances
generated by `create-app` is a stub, which returns empty tokens and accepts any
input string as valid. To enable backend-to-backend authentication, you'll need
to instantiate a new one using the secret from your config instead:
```diff
// packages/backend/src/index.ts
function makeCreateEnv(config: Config) {
const root = getRootLogger();
const reader = UrlReaders.default({ logger: root, config });
const discovery = SingleHostDiscovery.fromConfig(config);
root.info(`Created UrlReader ${reader}`);
const cacheManager = CacheManager.fromConfig(config);
const databaseManager = DatabaseManager.fromConfig(config);
- const tokenManager = ServerTokenManager.noop();
+ const tokenManager = ServerTokenManager.fromConfig(config);
```
With this `tokenManager`, you can then generate a server token for requests:
```typescript
const { token } = await this.tokenManager.getToken();
const response = await fetch(pluginBackendApiUrl, {
method: 'GET',
headers: {
...headers,
Authorization: `Bearer ${token}`,
},
});
```
You can use the same `tokenManager` to authenticate tokens supplied on incoming
requests:
```typescript
await tokenManager.authenticate(token); // throws if token is invalid
```
+1 -1
View File
@@ -2,5 +2,5 @@
"packages": ["packages/*", "plugins/*"],
"npmClient": "yarn",
"useWorkspaces": true,
"version": "0.1.0"
"version": "0.0.0"
}
@@ -1,5 +1,5 @@
---
title: Starting Phase 2: The Service Catalog
title: 'Starting Phase 2: The Service Catalog'
author: Stefan Ålund, Spotify
authorURL: http://twitter.com/stalund
authorImageURL: https://pbs.twimg.com/profile_images/121166861/6919c047c0d0edaace78c3009b28e917-user-full-200-130.generated_400x400.jpg
@@ -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 organizations 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-->
@@ -1,5 +1,5 @@
---
title: Announcing TechDocs: Spotifys docs-like-code plugin for Backstage
title: 'Announcing TechDocs: Spotifys docs-like-code plugin for Backstage'
author: Gary Niemen, Spotify
authorURL: https://github.com/garyniemen
---
@@ -1,5 +1,5 @@
---
title: New Cost Insights plugin: The engineers solution to taming cloud costs
title: 'New Cost Insights plugin: The engineers solution to taming cloud costs'
author: Janisa Anandamohan, Spotify
authorURL: https://twitter.com/janisa_a
---
@@ -1,5 +1,5 @@
---
title: New Backstage feature: Kubernetes for Service owners
title: 'New Backstage feature: Kubernetes for Service owners'
author: Matthew Clarke, Spotify
authorURL: https://github.com/mclarke47
---
@@ -1,5 +1,5 @@
---
title: Announcing the Backstage Search platform: a customizable search tool built just for you
title: 'Announcing the Backstage Search platform: a customizable search tool built just for you'
author: Emma Indal, Spotify
authorURL: https://www.linkedin.com/in/emma-indal
---
+1 -1
View File
@@ -19,7 +19,7 @@
"@spotify/prettier-config": "^12.0.0",
"docusaurus": "^2.0.0-alpha.70",
"js-yaml": "^4.1.0",
"prettier": "^2.4.1",
"prettier": "^2.5.1",
"yarn-lock-check": "^1.0.5"
},
"prettier": "@spotify/prettier-config"
+5 -1
View File
@@ -125,7 +125,11 @@
{
"type": "subcategory",
"label": "Azure",
"ids": ["integrations/azure/locations", "integrations/azure/org"]
"ids": [
"integrations/azure/locations",
"integrations/azure/discovery",
"integrations/azure/org"
]
},
{
"type": "subcategory",
+4 -4
View File
@@ -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.4.1:
version "2.4.1"
resolved "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c"
integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==
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"
+1
View File
@@ -88,6 +88,7 @@ nav:
- Discovery: 'integrations/aws-s3/discovery.md'
- Azure:
- Locations: 'integrations/azure/locations.md'
- Discovery: 'integrations/azure/discovery.md'
- Org Data: 'integrations/azure/org.md'
- Bitbucket:
- Locations: 'integrations/bitbucket/locations.md'
+4 -1
View File
@@ -30,6 +30,8 @@
"prettier:check": "prettier --check .",
"lerna": "lerna",
"storybook": "yarn workspace storybook start",
"snyk:test": "npx snyk test --yarn-workspaces --strict-out-of-sync=false",
"snyk:test:package": "yarn snyk:test --include",
"build-storybook": "yarn workspace storybook build-storybook",
"techdocs-cli": "node scripts/techdocs-cli.js",
"techdocs-cli:dev": "cross-env TECHDOCS_CLI_DEV_MODE=true node scripts/techdocs-cli.js",
@@ -61,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",
+5 -5
View File
@@ -29,17 +29,17 @@
"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.7.6",
"@backstage/core-app-api": "^0.1.24",
"@backstage/core-plugin-api": "^0.2.2",
"@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"
},
"devDependencies": {
"@backstage/cli": "^0.9.0",
"@backstage/cli": "^0.10.0",
"@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
+20
View File
@@ -1,5 +1,25 @@
# example-app
## 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
@@ -14,7 +14,7 @@
* limitations under the License.
*/
const API_ENDPOINT = 'http://localhost:7000/api/search/query';
const API_ENDPOINT = 'http://localhost:7007/api/search/query';
describe('SearchPage', () => {
describe('Given a search context with a term, results, and filter values', () => {
+17 -16
View File
@@ -1,24 +1,24 @@
{
"name": "example-app",
"version": "0.2.53",
"version": "0.2.55",
"private": true,
"bundled": true,
"dependencies": {
"@backstage/app-defaults": "^0.1.1",
"@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/cli": "^0.10.0",
"@backstage/core-app-api": "^0.1.24",
"@backstage/core-components": "^0.7.6",
"@backstage/core-plugin-api": "^0.2.2",
"@backstage/integration-react": "^0.1.14",
"@backstage/plugin-api-docs": "^0.6.14",
"@backstage/plugin-azure-devops": "^0.1.4",
"@backstage/plugin-api-docs": "^0.6.16",
"@backstage/plugin-azure-devops": "^0.1.5",
"@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-circleci": "^0.2.30",
"@backstage/plugin-cloudbuild": "^0.2.28",
"@backstage/plugin-code-coverage": "^0.1.18",
"@backstage/plugin-cost-insights": "^0.11.11",
@@ -29,22 +29,23 @@
"@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-kubernetes": "^0.4.22",
"@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-scaffolder": "^0.11.13",
"@backstage/plugin-search": "^0.5.0",
"@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-techdocs": "^0.12.8",
"@backstage/plugin-todo": "^0.1.15",
"@backstage/plugin-user-settings": "^0.3.11",
"@backstage/plugin-user-settings": "^0.3.12",
"@backstage/search-common": "^0.2.0",
"@backstage/theme": "^0.2.11",
"@backstage/plugin-tech-insights": "^0.1.0",
"@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",
@@ -65,8 +66,8 @@
},
"devDependencies": {
"@backstage/test-utils": "^0.1.22",
"@rjsf/core": "^3.0.0",
"@testing-library/cypress": "^7.0.1",
"@rjsf/core": "^3.2.1",
"@testing-library/cypress": "^8.0.2",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
+3 -3
View File
@@ -27,14 +27,14 @@ describe('App', () => {
data: {
app: {
title: 'Test',
support: { url: 'http://localhost:7000/support' },
support: { url: 'http://localhost:7007/support' },
},
backend: { baseUrl: 'http://localhost:7000' },
backend: { baseUrl: 'http://localhost:7007' },
lighthouse: {
baseUrl: 'http://localhost:3003',
},
techdocs: {
storageUrl: 'http://localhost:7000/api/techdocs/static/docs',
storageUrl: 'http://localhost:7007/api/techdocs/static/docs',
},
},
context: 'test',
+16 -1
View File
@@ -34,6 +34,7 @@ import {
SignInPage,
} from '@backstage/core-components';
import { apiDocsPlugin, ApiExplorerPage } from '@backstage/plugin-api-docs';
import { AzurePullRequestsPage } from '@backstage/plugin-azure-devops';
import {
CatalogEntityPage,
CatalogIndexPage,
@@ -175,7 +176,20 @@ const routes = (
>
{techDocsPage}
</Route>
<Route path="/create" element={<ScaffolderPage />}>
<Route
path="/create"
element={
<ScaffolderPage
groups={[
{
title: 'Recommended',
filter: entity =>
entity?.metadata?.tags?.includes('recommended') ?? false,
},
]}
/>
}
>
<ScaffolderFieldExtensions>
<LowerCaseValuePickerFieldExtension />
</ScaffolderFieldExtensions>
@@ -203,6 +217,7 @@ const routes = (
element={<CostInsightsLabelDataflowInstructionsPage />}
/>
<Route path="/settings" element={<UserSettingsPage />} />
<Route path="/azure-pull-requests" element={<AzurePullRequestsPage />} />
</FlatRoutes>
);
+13 -2
View File
@@ -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,
@@ -41,6 +44,7 @@ import {
SidebarSpace,
SidebarScrollWrapper,
} from '@backstage/core-components';
import { AzurePullRequestsIcon } from '@backstage/plugin-azure-devops';
const useSidebarLogoStyles = makeStyles({
root: {
@@ -79,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" />
@@ -94,6 +100,11 @@ export const Root = ({ children }: PropsWithChildren<{}>) => (
<SidebarItem icon={RuleIcon} to="lighthouse" text="Lighthouse" />
<SidebarItem icon={MoneyIcon} to="cost-insights" text="Cost Insights" />
<SidebarItem icon={GraphiQLIcon} to="graphiql" text="GraphiQL" />
<SidebarItem
icon={AzurePullRequestsIcon}
to="azure-pull-requests"
text="Azure PRs"
/>
</SidebarScrollWrapper>
<SidebarDivider />
<Shortcuts />
@@ -14,7 +14,6 @@
* limitations under the License.
*/
import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { EntityLayout } from '@backstage/plugin-catalog';
import {
DefaultStarredEntitiesApi,
@@ -22,7 +21,11 @@ import {
starredEntitiesApiRef,
} from '@backstage/plugin-catalog-react';
import { githubActionsApiRef } from '@backstage/plugin-github-actions';
import { MockStorageApi, renderInTestApp } from '@backstage/test-utils';
import {
MockStorageApi,
renderInTestApp,
TestApiProvider,
} from '@backstage/test-utils';
import React from 'react';
import { cicdContent } from './EntityPage';
@@ -45,22 +48,22 @@ describe('EntityPage Test', () => {
const mockedApi = {
listWorkflowRuns: jest.fn().mockResolvedValue([]),
getWorkflow: jest.fn(),
getWorkflowRun: jest.fn(),
reRunWorkflow: jest.fn(),
listJobsForWorkflowRun: jest.fn(),
downloadJobLogsForWorkflowRun: jest.fn(),
} as jest.Mocked<typeof githubActionsApiRef.T>;
const apis = ApiRegistry.with(githubActionsApiRef, mockedApi).with(
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({ storageApi: MockStorageApi.create() }),
);
};
describe('cicdContent', () => {
it('Should render GitHub Actions View', async () => {
const rendered = await renderInTestApp(
<ApiProvider apis={apis}>
<TestApiProvider
apis={[
[githubActionsApiRef, mockedApi],
[
starredEntitiesApiRef,
new DefaultStarredEntitiesApi({
storageApi: MockStorageApi.create(),
}),
],
]}
>
<EntityProvider entity={entity}>
<EntityLayout>
<EntityLayout.Route path="/ci-cd" title="CI-CD">
@@ -68,7 +71,7 @@ describe('EntityPage Test', () => {
</EntityLayout.Route>
</EntityLayout>
</EntityProvider>
</ApiProvider>,
</TestApiProvider>,
);
expect(rendered.getByText('ExampleComponent')).toBeInTheDocument();
+32
View File
@@ -1,5 +1,37 @@
# @backstage/backend-common
## 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
- bab752e2b3: Change default port of backend from 7000 to 7007.
This is due to the AirPlay Receiver process occupying port 7000 and preventing local Backstage instances on MacOS to start.
You can change the port back to 7000 or any other value by providing an `app-config.yaml` with the following values:
```
backend:
listen: 0.0.0.0:7123
baseUrl: http://localhost:7123
```
More information can be found here: https://backstage.io/docs/conf/writing
- Updated dependencies
- @backstage/errors@0.1.5
## 0.9.10
### Patch Changes
+24
View File
@@ -526,6 +526,20 @@ export type SearchResponseFile = {
content(): Promise<Buffer>;
};
// @public
export class ServerTokenManager implements TokenManager {
// (undocumented)
authenticate(token: string): Promise<void>;
// (undocumented)
static fromConfig(config: Config): ServerTokenManager;
// (undocumented)
getToken(): Promise<{
token: string;
}>;
// (undocumented)
static noop(): TokenManager;
}
// @public (undocumented)
export type ServiceBuilder = {
loadConfig(config: Config): ServiceBuilder;
@@ -583,6 +597,16 @@ export interface StatusCheckHandlerOptions {
statusCheck?: StatusCheck;
}
// @public
export interface TokenManager {
// (undocumented)
authenticate: (token: string) => Promise<void>;
// (undocumented)
getToken: () => Promise<{
token: string;
}>;
}
// @public
export type UrlReader = {
read(url: string): Promise<Buffer>;
+28
View File
@@ -20,6 +20,20 @@ export interface Config {
};
backend: {
/** Backend configuration for when request authentication is enabled */
auth?: {
/** Keys shared by all backends for signing and validating backend tokens. */
keys: {
/**
* Secret for generating tokens. Should be a base64 string, recommended
* length is 24 bytes.
*
* @visibility secret
*/
secret: string;
}[];
};
baseUrl: string; // defined in core, but repeated here without doc
/** Address that the backend should listen to. */
@@ -82,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]: {
@@ -97,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;
};
};
};
+8 -7
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-common",
"description": "Common functionality library for Backstage backends",
"version": "0.9.10",
"version": "0.9.12",
"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/errors": "^0.1.4",
"@backstage/integration": "^0.6.9",
"@backstage/config-loader": "^0.8.1",
"@backstage/errors": "^0.1.5",
"@backstage/integration": "^0.6.10",
"@backstage/types": "^0.1.1",
"@google-cloud/storage": "^5.8.0",
"@lerna/project": "^4.0.0",
@@ -46,7 +46,6 @@
"compression": "^1.7.4",
"concat-stream": "^2.0.0",
"cors": "^2.8.5",
"cross-fetch": "^3.0.6",
"dockerode": "^3.3.1",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
@@ -54,6 +53,7 @@
"git-url-parse": "^11.6.0",
"helmet": "^4.0.0",
"isomorphic-git": "^1.8.0",
"jose": "^1.27.1",
"keyv": "^4.0.3",
"keyv-memcache": "^1.2.5",
"knex": "^0.95.1",
@@ -63,6 +63,7 @@
"minimist": "^1.2.5",
"morgan": "^1.10.0",
"node-abort-controller": "^3.0.1",
"node-fetch": "^2.6.1",
"raw-body": "^2.4.1",
"selfsigned": "^1.10.7",
"stoppable": "^1.1.0",
@@ -80,8 +81,8 @@
}
},
"devDependencies": {
"@backstage/cli": "^0.9.0",
"@backstage/test-utils": "^0.1.22",
"@backstage/cli": "^0.10.0",
"@backstage/test-utils": "^0.1.23",
"@types/archiver": "^5.1.0",
"@types/compression": "^1.7.0",
"@types/concat-stream": "^1.6.0",
@@ -505,5 +505,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.
@@ -138,6 +138,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 +218,7 @@ export class DatabaseManager {
const { client } = this.getClientType(pluginId);
return {
...this.getAdditionalKnexConfig(pluginId),
client,
connection: this.getConnectionConfig(pluginId),
};
@@ -37,7 +37,7 @@ export class SingleHostDiscovery implements PluginEndpointDiscovery {
* for the internal one.
*
* The basePath defaults to `/api`, meaning the default full internal
* path for the `catalog` plugin will be `http://localhost:7000/api/catalog`.
* path for the `catalog` plugin will be `http://localhost:7007/api/catalog`.
*/
static fromConfig(config: Config, options?: { basePath?: string }) {
const basePath = options?.basePath ?? '/api';
+1
View File
@@ -31,4 +31,5 @@ export * from './paths';
export * from './reading';
export * from './scm';
export * from './service';
export * from './tokens';
export * from './util';

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