Merge branch 'master' into hchb/azgittags
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
---
|
||||
|
||||
Added ARIA landmark <main> to Page component and added ARIA landmark <nav> to DesktopSidebar and Sidebar components
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-common': patch
|
||||
---
|
||||
|
||||
Implemented the `UrlReader.search()` method for Google Cloud Storage. Due to limitations in the underlying storage API, only prefix-based searches are supported right now (for example, `https://storage.cloud.google.com/your-bucket/some-path/*`).
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-auth-backend': patch
|
||||
---
|
||||
|
||||
Fixed a bug that was introduced in `0.13.1-next.0` which caused the `ent` claim of issued tokens to be dropped.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/test-utils': patch
|
||||
---
|
||||
|
||||
Fixed `renderInTestApp` so that it is able to re-render the result without removing the app wrapping.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-api-docs': patch
|
||||
---
|
||||
|
||||
Updated dependency `graphiql` to `^1.8.8`.
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
'@backstage/plugin-tech-insights-backend': minor
|
||||
---
|
||||
|
||||
**BREAKING**: The `buildTechInsightsContext` function now takes an additional
|
||||
field in its options argument: `tokenManager`. This is an instance of
|
||||
`TokenManager`, which can be found in your backend initialization code's
|
||||
`env`.
|
||||
|
||||
```diff
|
||||
const builder = buildTechInsightsContext({
|
||||
logger: env.logger,
|
||||
config: env.config,
|
||||
database: env.database,
|
||||
discovery: env.discovery,
|
||||
scheduler: env.scheduler,
|
||||
+ tokenManager: env.tokenManager,
|
||||
factRetrievers: [ /* ... */ ],
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-tech-insights': patch
|
||||
---
|
||||
|
||||
Add new component `EntityTechInsightsScorecardCard`, which can be used in the overview of the `EntityPage` page or display multiple individual `EntityTechInsightsScorecardCard` in `EntityLayout.Route`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-tech-radar': patch
|
||||
---
|
||||
|
||||
Rename `use` to `adopt`, to reflect Zalando Tech Radar regarding quadrants and add link to Zalando explanation.
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
'@backstage/backend-tasks': patch
|
||||
---
|
||||
|
||||
`TaskScheduleDefinition` has been updated to also accept an options object containing duration information in the form of days, hours, seconds and so on. This allows for scheduling without importing `luxon`.
|
||||
|
||||
```diff
|
||||
-import { Duration } from 'luxon';
|
||||
// omitted other code
|
||||
|
||||
const schedule = env.scheduler.createScheduledTaskRunner({
|
||||
- frequency: Duration.fromObject({ minutes: 10 }),
|
||||
- timeout: Duration.fromObject({ minutes: 15 }),
|
||||
+ frequency: { minutes: 10 },
|
||||
+ timeout: { minutes: 15 },
|
||||
// omitted other code
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
---
|
||||
|
||||
Announce external links to screen readers
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Fixed coverage configuration when using `BACKSTAGE_NEXT_TESTS`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-common': patch
|
||||
---
|
||||
|
||||
Update types to match the new version of `@keyv/redis`
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-tech-insights-node': minor
|
||||
---
|
||||
|
||||
**BREAKING**: The `FactRetrieverContext` type now contains an additional
|
||||
field: `tokenManager`.
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
'@backstage/create-app': patch
|
||||
---
|
||||
|
||||
Simplified the search collator scheduling by removing the need for the `luxon` dependency.
|
||||
|
||||
For existing installations the scheduling can be simplified by removing the `luxon` dependency and using the human friendly duration object instead.
|
||||
Please note that this only applies if luxon is not used elsewhere in your installation.
|
||||
|
||||
`packages/backend/package.json`
|
||||
|
||||
```diff
|
||||
"express": "^4.17.1",
|
||||
"express-promise-router": "^4.1.0",
|
||||
- "luxon": "^2.0.2",
|
||||
```
|
||||
|
||||
`packages/backend/src/plugins/search.ts`
|
||||
|
||||
```diff
|
||||
import { Router } from 'express';
|
||||
-import { Duration } from 'luxon';
|
||||
|
||||
// omitted other code
|
||||
|
||||
const schedule = env.scheduler.createScheduledTaskRunner({
|
||||
- frequency: Duration.fromObject({ minutes: 10 }),
|
||||
- timeout: Duration.fromObject({ minutes: 15 }),
|
||||
+ frequency: { minutes: 10 },
|
||||
+ timeout: { minutes: 15 },
|
||||
// A 3 second delay gives the backend server a chance to initialize before
|
||||
// any collators are executed, which may attempt requests against the API.
|
||||
- initialDelay: Duration.fromObject({ seconds: 3 }),
|
||||
+ initialDelay: { seconds: 3 },
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-rails': minor
|
||||
---
|
||||
|
||||
**BREAKING**: Added a new `allowedImageNames` option, which needs to list any image name for it to be allowed as `imageName` input.
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
'@backstage/create-app': patch
|
||||
---
|
||||
|
||||
Tweaked the `.dockerignore` file so that it's easier to add additional backend packages if desired.
|
||||
|
||||
To apply this change to an existing app, make the following change to `.dockerignore`:
|
||||
|
||||
```diff
|
||||
cypress
|
||||
microsite
|
||||
node_modules
|
||||
-packages
|
||||
-!packages/backend/dist
|
||||
+packages/*/src
|
||||
+packages/*/node_modules
|
||||
plugins
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Extended lint rule to prevents imports of stories or tests from production code.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-tech-insights-backend-module-jsonfc': patch
|
||||
---
|
||||
|
||||
Updated usages of `buildTechInsightsContext` in README.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/test-utils': minor
|
||||
---
|
||||
|
||||
Added the options parameter to `renderWithEffects`, which if forwarded to the `render` function from `@testling-library/react`. Initially only the `wrapper` option is supported.
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend-module-github': patch
|
||||
---
|
||||
|
||||
`GitHubOrgEntityProvider.fromConfig` now supports a `schedule` option like other
|
||||
entity providers, that makes it more convenient to leverage using the common
|
||||
task scheduler.
|
||||
|
||||
If you want to use this in your own project, it is used something like the following:
|
||||
|
||||
```ts
|
||||
// In packages/backend/src/plugins/catalog.ts
|
||||
builder.addEntityProvider(
|
||||
GitHubOrgEntityProvider.fromConfig(env.config, {
|
||||
id: 'production',
|
||||
orgUrl: 'https://github.com/backstage',
|
||||
schedule: env.scheduler.createScheduledTaskRunner({
|
||||
frequency: { cron: '*/30 * * * *' },
|
||||
timeout: { minutes: 10 },
|
||||
}),
|
||||
logger: env.logger,
|
||||
}),
|
||||
);
|
||||
```
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
'@backstage/plugin-auth-backend': patch
|
||||
---
|
||||
|
||||
Updates the OAuth2 Proxy provider to require less infrastructure configuration.
|
||||
|
||||
The auth result object of the OAuth2 Proxy now provides access to the request headers, both through the `headers` object as well as `getHeader` method. The existing logic that parses and extracts the user information from ID tokens is deprecated and will be removed in a future release. See the OAuth2 Proxy provider documentation for more details.
|
||||
|
||||
The OAuth2 Proxy provider now also has a default `authHandler` implementation that reads the display name and email from the incoming request headers.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-user-settings': patch
|
||||
---
|
||||
|
||||
Added alternative text to profile picture
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend-module-gerrit': patch
|
||||
---
|
||||
|
||||
Fix incorrect main path in `publishConfig`
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
---
|
||||
|
||||
Added optional anchorOrigin alignment prop to AlertDisplay
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
---
|
||||
|
||||
Allow validation for custom field extension with type object
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend': patch
|
||||
---
|
||||
|
||||
Minor internal tweak to support TypeScript 4.6
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-rollbar-backend': patch
|
||||
---
|
||||
|
||||
Updated README to include clearer installation instructions on how to install and configure.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/create-app': patch
|
||||
---
|
||||
|
||||
Tweaked template to provide an example and guidance for how to configure sign-in in `packages/backend/src/plugins/auth.ts`. There is no need to add this to existing apps, but for more information about sign-in configuration, see https://backstage.io/docs/auth/identity-resolver.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
---
|
||||
|
||||
Add an aria-label to the support button to improve accessibility for screen readers
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Changed Rollup configuration for TypeScript definition plugin to ignore `css`,
|
||||
`scss`, `sass`, `svg`, `eot`, `woff`, `woff2` and `ttf` files.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog': patch
|
||||
---
|
||||
|
||||
Lighthouse was reporting this button as having invalid aria- values, as the popover doesn't exist until clicked. This adds additional labels to the button to make it valid aria
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
---
|
||||
|
||||
Added menu parent role for menu items accessibility
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-org': patch
|
||||
---
|
||||
|
||||
Fix linking ownership card to catalog owner filter when namespaces are used
|
||||
+49
-1
@@ -144,52 +144,100 @@
|
||||
"@backstage/plugin-user-settings": "0.4.3",
|
||||
"@backstage/plugin-xcmetrics": "0.2.24",
|
||||
"@backstage/plugin-catalog-backend-module-gerrit": "0.0.0",
|
||||
"@backstage/plugin-techdocs-module-addons-contrib": "0.0.0"
|
||||
"@backstage/plugin-techdocs-module-addons-contrib": "0.0.0",
|
||||
"@backstage/plugin-adr": "0.0.0",
|
||||
"@backstage/plugin-adr-backend": "0.0.0",
|
||||
"@backstage/plugin-adr-common": "0.0.0",
|
||||
"@internal/plugin-todo-list": "1.0.0",
|
||||
"@internal/plugin-todo-list-backend": "1.0.0",
|
||||
"@internal/plugin-todo-list-common": "1.0.0",
|
||||
"@backstage/plugin-techdocs-addons-test-utils": "0.0.0"
|
||||
},
|
||||
"changesets": [
|
||||
"afraid-insects-do",
|
||||
"beige-panthers-dream",
|
||||
"brave-starfishes-try",
|
||||
"breezy-days-prove",
|
||||
"bright-panthers-guess",
|
||||
"chatty-forks-bathe",
|
||||
"clever-trains-greet",
|
||||
"cool-mice-sit",
|
||||
"cool-ties-share",
|
||||
"curly-parrots-applaud",
|
||||
"cyan-boxes-double",
|
||||
"dirty-eagles-hunt",
|
||||
"early-crabs-help",
|
||||
"early-lemons-add",
|
||||
"eighty-chicken-retire",
|
||||
"empty-mugs-bow",
|
||||
"empty-poems-lick",
|
||||
"fair-kings-retire",
|
||||
"fair-pigs-mate",
|
||||
"funny-lamps-turn",
|
||||
"fuzzy-seahorses-teach",
|
||||
"giant-cheetahs-thank",
|
||||
"grumpy-panthers-peel",
|
||||
"hip-adults-collect",
|
||||
"hip-monkeys-hide",
|
||||
"honest-kids-live",
|
||||
"hot-peaches-give",
|
||||
"hungry-goats-mate",
|
||||
"kind-cats-clap",
|
||||
"lazy-zebras-pay",
|
||||
"loud-peaches-warn",
|
||||
"lovely-houses-argue",
|
||||
"mean-flowers-change",
|
||||
"mean-owls-share",
|
||||
"mean-seas-burn",
|
||||
"metal-hairs-build",
|
||||
"metal-pants-fly",
|
||||
"moody-laws-boil",
|
||||
"moody-suns-smell",
|
||||
"nasty-humans-give",
|
||||
"nasty-paws-move",
|
||||
"new-beds-argue",
|
||||
"nine-actors-fly",
|
||||
"nine-geese-rest",
|
||||
"odd-apples-smash",
|
||||
"old-bikes-study",
|
||||
"orange-elephants-laugh",
|
||||
"perfect-penguins-rescue",
|
||||
"pink-mayflies-rhyme",
|
||||
"polite-planets-learn",
|
||||
"renovate-05696d1",
|
||||
"renovate-5970cc2",
|
||||
"renovate-b063c4b",
|
||||
"renovate-bf43c44",
|
||||
"renovate-ca619fc",
|
||||
"search-dry-wolves-join",
|
||||
"search-heavy-llamas-worry",
|
||||
"seven-deers-rule",
|
||||
"shiny-students-approve",
|
||||
"short-chicken-act",
|
||||
"short-dodos-sparkle",
|
||||
"short-flies-collect",
|
||||
"silver-readers-deliver",
|
||||
"six-buckets-tap",
|
||||
"sixty-llamas-change",
|
||||
"smart-ghosts-search",
|
||||
"spotty-plums-rule",
|
||||
"stale-pigs-reply",
|
||||
"strong-mangos-sell",
|
||||
"swift-bugs-share",
|
||||
"swift-parrots-hammer",
|
||||
"tall-parents-deny",
|
||||
"tasty-drinks-teach",
|
||||
"techdocs-changeset-not-found",
|
||||
"techdocs-five-hundred-ml",
|
||||
"techdocs-low-calorie-drink",
|
||||
"techdocs-nice-boats-wonder",
|
||||
"techdocs-quick-owls-smile",
|
||||
"techdocs-touch-screen-wipes",
|
||||
"techdocs-vitamin-well-reload",
|
||||
"thick-bees-brush",
|
||||
"tough-forks-carry",
|
||||
"violet-steaks-knock",
|
||||
"wicked-vans-press",
|
||||
"wild-pigs-work",
|
||||
"wise-emus-wait"
|
||||
]
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-api-docs': patch
|
||||
---
|
||||
|
||||
Updated dependency `@asyncapi/react-component` to `1.0.0-next.37`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
---
|
||||
|
||||
Updated dependency `use-immer` to `^0.7.0`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-api-docs': patch
|
||||
---
|
||||
|
||||
Updated dependency `@asyncapi/react-component` to `1.0.0-next.38`.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
Updated dependency `event-source-polyfill` to `1.0.26`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
---
|
||||
|
||||
Updated dependency `@codemirror/legacy-modes` to `^0.20.0`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-graphiql': patch
|
||||
---
|
||||
|
||||
Updated dependency `@types/codemirror` to `^0.0.109`.
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@backstage/plugin-search-backend-node': patch
|
||||
'@backstage/plugin-search-backend-module-elasticsearch': patch
|
||||
'@backstage/plugin-search-backend-module-pg': patch
|
||||
---
|
||||
|
||||
Search Engines will now index documents in batches of 1000 instead of 100 (under the hood). This may result in your Backstage backend consuming slightly more memory during index runs, but should dramatically improve indexing performance for large document sets.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Added the ability to help a user get started with a new organization
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/test-utils': minor
|
||||
---
|
||||
|
||||
Added `createTestAppWrapper`, which returns a component that can be used as the `wrapper` option for `render` or `renderWithEffects`.
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
'@backstage/create-app': patch
|
||||
---
|
||||
|
||||
Removed the database choice from the `create-app` command.
|
||||
|
||||
This reduces the step from development to production by always installing the dependencies and templating the production configuration in `app-config.production.yaml`.
|
||||
|
||||
Added `app-config.local.yaml` to allow for local configuration overrides.
|
||||
To replicate this behavior in an existing installation simply `touch app-config.local.yaml` in the project root and apply your local configuration.
|
||||
|
||||
`better-sqlite3` has been moved to devDependencies, for existing installations using postgres in production and SQLite in development it's recommended to move SQLite into the devDependencies section to avoid unnecessary dependencies during builds.
|
||||
|
||||
in `packages/backend/package.json`
|
||||
|
||||
```diff
|
||||
"dependencies": {
|
||||
...
|
||||
"pg": "^8.3.0",
|
||||
- "better-sqlite3": "^7.5.0",
|
||||
"winston": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
...
|
||||
"@types/luxon": "^2.0.4",
|
||||
+ "better-sqlite3": "^7.5.0"
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
'@backstage/plugin-search-react': minor
|
||||
---
|
||||
|
||||
**BREAKING**: `SearchContextProviderForStorybook` and `SearchApiProviderForStorybook` has been deleted. New mock implementation of the `SearchApi` introduced. If you need to mock the api we recommend you to do the following:
|
||||
|
||||
```tsx
|
||||
import {
|
||||
searchApiRef,
|
||||
MockSearchApi,
|
||||
SearchContextProvider,
|
||||
} from '@backstage/plugin-search-react';
|
||||
import { TestApiProvider } from '@backstage/test-utils';
|
||||
|
||||
<TestApiProvider apis={[[searchApiRef, new MockSearchApi()]]}>
|
||||
<SearchContextProvider>
|
||||
<Component />
|
||||
</SearchContextProvider>
|
||||
</TestApiProvider>;
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@techdocs/cli': patch
|
||||
---
|
||||
|
||||
The TechDocs CLI's embedded app now imports all API refs from the `@backstage/plugin-techdocs-react` package.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-react': patch
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
The `TechDocsStorageApi` and its associated ref are now exported by `@backstage/plugin-techdocs-react`. The API interface, ref, and types are now deprecated in `@backstage/plugin-techdocs` and will be removed in a future release.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-addons-test-utils': minor
|
||||
---
|
||||
|
||||
Introducing a package with utilities to help test TechDocs Addons.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Updated `create-github-app` command to prompt for read or write permissions to simplify setup.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-tasks': patch
|
||||
---
|
||||
|
||||
Correctly set next run time for tasks
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
'@backstage/create-app': patch
|
||||
---
|
||||
|
||||
Bumped the `typescript` version in the template to `~4.6.4`.
|
||||
|
||||
To apply this change to an existing app, make the following change to the root `package.json`:
|
||||
|
||||
```diff
|
||||
dependencies: {
|
||||
...
|
||||
- "typescript": "~4.5.4"
|
||||
+ "typescript": "~4.6.4"
|
||||
},
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
---
|
||||
|
||||
Make Menu item on filters accessible through keyboard
|
||||
+2
-2
@@ -3,6 +3,6 @@ docs
|
||||
cypress
|
||||
microsite
|
||||
node_modules
|
||||
packages
|
||||
!packages/backend/dist
|
||||
packages/*/src
|
||||
packages/*/node_modules
|
||||
plugins
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
# https://help.github.com/articles/about-codeowners/
|
||||
|
||||
* @backstage/reviewers
|
||||
yarn.lock @backstage/reviewers @backstage-service
|
||||
*/yarn.lock @backstage/reviewers @backstage-service
|
||||
/.changeset/cost-insights-* @backstage/reviewers @backstage/silver-lining
|
||||
/.changeset/search-* @backstage/reviewers @backstage/techdocs-core
|
||||
/.changeset/techdocs-* @backstage/reviewers @backstage/techdocs-core
|
||||
|
||||
@@ -8,9 +8,6 @@ airbrake
|
||||
Anddddd
|
||||
Apdex
|
||||
api
|
||||
Api
|
||||
apis
|
||||
args
|
||||
asciidoc
|
||||
async
|
||||
Atlassian
|
||||
@@ -19,7 +16,6 @@ autoscaling
|
||||
Autoscaling
|
||||
autoselect
|
||||
Avro
|
||||
aws
|
||||
backported
|
||||
backporting
|
||||
Bigtable
|
||||
@@ -38,7 +34,6 @@ changesets
|
||||
Changesets
|
||||
chanwit
|
||||
Chanwit
|
||||
ci
|
||||
CI/CD
|
||||
classname
|
||||
cli
|
||||
@@ -127,7 +122,6 @@ hoc
|
||||
horizontalpodautoscalers
|
||||
Hostname
|
||||
hotspots
|
||||
html
|
||||
http
|
||||
https
|
||||
Iain
|
||||
@@ -224,6 +218,8 @@ performant
|
||||
Performant
|
||||
periskop
|
||||
Periskop
|
||||
permissioned
|
||||
permissioning
|
||||
plantuml
|
||||
Platformize
|
||||
Podman
|
||||
@@ -314,8 +310,8 @@ templaters
|
||||
Templaters
|
||||
theia
|
||||
thumbsup
|
||||
toc
|
||||
todo
|
||||
todos
|
||||
tolerations
|
||||
Tolerations
|
||||
toolchain
|
||||
@@ -339,7 +335,6 @@ unregistration
|
||||
untracked
|
||||
upsert
|
||||
upvote
|
||||
url
|
||||
URIs
|
||||
URLs
|
||||
utils
|
||||
@@ -0,0 +1,6 @@
|
||||
StylesPath = .
|
||||
Vocab = Backstage
|
||||
|
||||
[*.md]
|
||||
BasedOnStyles = Vale
|
||||
Vale.Terms = NO
|
||||
@@ -0,0 +1,85 @@
|
||||
name: Automate Merge Renovate PRs
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '*/10 * * * *'
|
||||
|
||||
jobs:
|
||||
diff:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
const owner = "backstage";
|
||||
const repo = "backstage";
|
||||
const query = `{
|
||||
repository(owner: "backstage", name: "backstage") {
|
||||
pullRequests(labels: ["dependencies"], last: 10, states: [OPEN]) {
|
||||
nodes {
|
||||
title
|
||||
author {
|
||||
login
|
||||
}
|
||||
number
|
||||
mergeable
|
||||
files(first: 1) {
|
||||
nodes {
|
||||
path
|
||||
}
|
||||
}
|
||||
changedFiles
|
||||
commits(last: 1) {
|
||||
nodes {
|
||||
commit {
|
||||
statusCheckRollup {
|
||||
state
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
reviewDecision
|
||||
reviews(first: 10) {
|
||||
nodes {
|
||||
author {
|
||||
login
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`;
|
||||
|
||||
const date = new Date();
|
||||
if (date.getDay() === 2) {
|
||||
console.log("Skipping auto merge because Tuesday is release day");
|
||||
return;
|
||||
}
|
||||
|
||||
const r = await github.graphql(query);
|
||||
const mergable = r.repository.pullRequests.nodes.filter(
|
||||
(pr) =>
|
||||
pr.author.login === "renovate" &&
|
||||
pr.mergeable === "MERGEABLE" &&
|
||||
pr.changedFiles === 1 &&
|
||||
pr.files.nodes[0].path.split("/").slice(-1)[0] === "yarn.lock" &&
|
||||
pr.commits.nodes[0].commit.statusCheckRollup.state === "SUCCESS" &&
|
||||
pr.reviewDecision === "APPROVED"
|
||||
);
|
||||
|
||||
if (mergable.length === 0) {
|
||||
console.log("no mergable PRs");
|
||||
return;
|
||||
}
|
||||
|
||||
for (const pr of mergable) {
|
||||
console.log(`Merging #${pr.number} - ${pr.title}`);
|
||||
await github.rest.pulls.merge({
|
||||
owner,
|
||||
repo,
|
||||
pull_number: pr.number,
|
||||
});
|
||||
await new Promise((r) => setTimeout(r, 2000));
|
||||
}
|
||||
@@ -75,7 +75,7 @@ jobs:
|
||||
# Cache every node_modules folder inside the monorepo
|
||||
- name: cache all node_modules
|
||||
id: cache-modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
# We use both yarn.lock and package.json as cache keys to ensure that
|
||||
@@ -91,7 +91,7 @@ jobs:
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
|
||||
- name: cache global yarn cache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
if: steps.cache-modules.outputs.cache-hit != 'true'
|
||||
with:
|
||||
path: ${{ steps.yarn-cache.outputs.dir }}
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
registry-url: https://registry.npmjs.org/ # Needed for auth
|
||||
- name: cache all node_modules
|
||||
id: cache-modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: ${{ runner.os }}-v${{ matrix.node-version }}-node_modules-${{ hashFiles('yarn.lock', '**/package.json') }}
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
if: steps.cache-modules.outputs.cache-hit != 'true'
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
- name: cache global yarn cache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
if: steps.cache-modules.outputs.cache-hit != 'true'
|
||||
with:
|
||||
path: ${{ steps.yarn-cache.outputs.dir }}
|
||||
|
||||
@@ -69,7 +69,7 @@ jobs:
|
||||
registry-url: https://registry.npmjs.org/ # Needed for auth
|
||||
- name: cache all node_modules
|
||||
id: cache-modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: ${{ runner.os }}-v${{ matrix.node-version }}-node_modules-${{ hashFiles('yarn.lock', '**/package.json') }}
|
||||
@@ -78,7 +78,7 @@ jobs:
|
||||
if: steps.cache-modules.outputs.cache-hit != 'true'
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
- name: cache global yarn cache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
if: steps.cache-modules.outputs.cache-hit != 'true'
|
||||
with:
|
||||
path: ${{ steps.yarn-cache.outputs.dir }}
|
||||
@@ -165,7 +165,7 @@ jobs:
|
||||
registry-url: https://registry.npmjs.org/ # Needed for auth
|
||||
- name: cache all node_modules
|
||||
id: cache-modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: ${{ runner.os }}-v${{ matrix.node-version }}-node_modules-${{ hashFiles('yarn.lock', '**/package.json') }}
|
||||
@@ -174,7 +174,7 @@ jobs:
|
||||
if: steps.cache-modules.outputs.cache-hit != 'true'
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
- name: cache global yarn cache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
if: steps.cache-modules.outputs.cache-hit != 'true'
|
||||
with:
|
||||
path: ${{ steps.yarn-cache.outputs.dir }}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
name: Approve renovate lock file changes
|
||||
on:
|
||||
pull_request_target:
|
||||
paths:
|
||||
- '.github/workflows/sync_renovate-changesets.yml'
|
||||
- '**/yarn.lock'
|
||||
|
||||
jobs:
|
||||
generate-changeset:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.actor == 'renovate[bot]' && github.repository == 'backstage/backstage'
|
||||
steps:
|
||||
- name: Approve
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
github-token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }}
|
||||
script: |
|
||||
const owner = 'backstage';
|
||||
const repo = 'backstage';
|
||||
|
||||
const r = await github.rest.pulls.listFiles({
|
||||
owner,
|
||||
repo,
|
||||
pull_number: context.issue.number,
|
||||
});
|
||||
|
||||
if (r.data.some((f) => f.filename.split('/').slice(-1)[0] !== 'yarn.lock')) {
|
||||
console.log('skipping approval since some files are not yarn.lock');
|
||||
return;
|
||||
}
|
||||
|
||||
await github.rest.pulls.createReview({
|
||||
owner,
|
||||
repo,
|
||||
pull_number: context.issue.number,
|
||||
event: 'APPROVE'
|
||||
})
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
registry-url: https://registry.npmjs.org/ # Needed for auth
|
||||
- name: cache all node_modules
|
||||
id: cache-modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: ${{ runner.os }}-v${{ matrix.node-version }}-node_modules-${{ hashFiles('yarn.lock', '**/package.json') }}
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
if: steps.cache-modules.outputs.cache-hit != 'true'
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
- name: cache global yarn cache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
if: steps.cache-modules.outputs.cache-hit != 'true'
|
||||
with:
|
||||
path: ${{ steps.yarn-cache.outputs.dir }}
|
||||
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
registry-url: https://registry.npmjs.org/ # Needed for auth
|
||||
- name: cache all node_modules
|
||||
id: cache-modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: ${{ runner.os }}-v${{ matrix.node-version }}-node_modules-${{ hashFiles('yarn.lock', '**/package.json') }}
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
if: steps.cache-modules.outputs.cache-hit != 'true'
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
- name: cache global yarn cache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
if: steps.cache-modules.outputs.cache-hit != 'true'
|
||||
with:
|
||||
path: ${{ steps.yarn-cache.outputs.dir }}
|
||||
|
||||
@@ -12,10 +12,18 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
# Vale does not support file excludes, so we use the script to generate a list of files instead
|
||||
# The action also does not allow args or a local config file to be passed in, so the files array
|
||||
# also contains an "--config=.github/vale/config.ini" option
|
||||
- name: generate vale args
|
||||
id: generate
|
||||
run: echo "::set-output name=args::$(node scripts/check-docs-quality.js --ci-args)"
|
||||
|
||||
- name: documentation quality check
|
||||
uses: errata-ai/vale-action@v1.4.0
|
||||
# Whitelist excluding ADOPTERS, CHANGELOG and OWNERS (no exclude flag exists)
|
||||
uses: errata-ai/vale-action@v1.5.0
|
||||
with:
|
||||
files: '[".changeset", ".github", "contrib", "docs", "microsite", "packages", "plugins", "CONTRIBUTING.md", "CODE_OF_CONDUCT.md", "GOVERNANCE.md", "README.md"]'
|
||||
# This also contains --config=.github/vale/config.ini ... :/
|
||||
files: '${{ steps.generate.outputs.args }}'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -48,7 +48,7 @@ jobs:
|
||||
registry-url: https://registry.npmjs.org/ # Needed for auth
|
||||
- name: cache all node_modules
|
||||
id: cache-modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: ${{ runner.os }}-v${{ matrix.node-version }}-node_modules-${{ hashFiles('yarn.lock', '**/package.json') }}
|
||||
@@ -59,7 +59,7 @@ jobs:
|
||||
- name: setup chrome
|
||||
uses: browser-actions/setup-chrome@latest
|
||||
- name: cache global yarn cache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
if: steps.cache-modules.outputs.cache-hit != 'true'
|
||||
with:
|
||||
path: ${{ steps.yarn-cache.outputs.dir }}
|
||||
@@ -78,3 +78,7 @@ jobs:
|
||||
yarn e2e-test run
|
||||
env:
|
||||
BACKSTAGE_TEST_DISABLE_DOCKER: 1
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_HOST: localhost
|
||||
POSTGRES_PORT: ${{ job.services.postgres.ports[5432] }}
|
||||
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
registry-url: https://registry.npmjs.org/ # Needed for auth
|
||||
- name: cache all node_modules
|
||||
id: cache-modules
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: ${{ runner.os }}-v${{ matrix.node-version }}-node_modules-${{ hashFiles('yarn.lock', '**/package.json') }}
|
||||
@@ -40,7 +40,7 @@ jobs:
|
||||
if: steps.cache-modules.outputs.cache-hit != 'true'
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
- name: cache global yarn cache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
if: steps.cache-modules.outputs.cache-hit != 'true'
|
||||
with:
|
||||
path: ${{ steps.yarn-cache.outputs.dir }}
|
||||
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
id: yarn-cache
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
- name: cache global yarn cache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ steps.yarn-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
|
||||
|
||||
@@ -130,6 +130,7 @@ site
|
||||
|
||||
# Local configuration files
|
||||
*.local.yaml
|
||||
!packages/create-app/templates/default-app/app-config.local.yaml
|
||||
|
||||
# Sensitive credentials
|
||||
*-credentials.yaml
|
||||
|
||||
+12
-7
@@ -26,7 +26,7 @@ _If you're using Backstage in your organization, please try to add your company
|
||||
| [Acast.com](https://acast.com) | [Olle Lundberg](https://github.com/lndbrg) | Developer portal with tech docs, service catalog and a bunch of other internal tooling |
|
||||
| [Lunar](https://lunar.app) | [Jacob Valdemar](https://github.com/JacobValdemar) | Internal developer portal for service overview and insights, API documentation, technical guides, onboarding guides and RFC's. |
|
||||
| [Trendyol](https://trendyol.com) | [Gamze Senturk](https://github.com/gmzsenturk), [Mert Can Bilgic](https://github.com/mertcb) | The Developer Portal has been called `Pandora`. Provides an overview of Trendyol tech ecosystem. TechDocs, Catalog, Custom Plugins and Theme. |
|
||||
| [Peloton](https://www.onepeloton.com/) | [Matt Waldron](https://github.com/daftgopher) | Creating our first developer portal and tech-docs. Exploring Service Catalog, Tech Insights and Cost Insights as well. |
|
||||
| [Peloton](https://www.onepeloton.com/) | [Matt Waldron](https://github.com/daftgopher) | Creating our first developer portal and tech-docs. Exploring Service Catalog, Tech Insights and Cost Insights as well. |
|
||||
| [TELUS](https://telus.com) | [Seb Barre](https://github.com/sbarre) | The Go-to place to find answers about development and delivery at TELUS. |
|
||||
| [Brex](https://www.brex.com/) | [Vamsi Chitters](https://github.com/vamsikc) | A centralized UI to understand how a service fits in the whole Brex architecture and manage a team’s engineering dependencies. |
|
||||
| [Oriflame](https://www.oriflame.com/) | [Oriflame](https://github.com/oriflame) | Internal developer portal for services, single page apps and packages overview, API documentation, technical guides, tech-radar and more. |
|
||||
@@ -34,7 +34,7 @@ _If you're using Backstage in your organization, please try to add your company
|
||||
| [Netflix](https://www.netflix.com/) | [bleathem](https://github.com/bleathem) | Our Backstage implementation will be the front door to a unified experience connecting our internal platform products across important workflows with integrated knowledge and support. |
|
||||
| [b.well](https://www.icanbwell.com/) | [Jacob Rosales](https://github.com/jrosales) | Foundation for our engineering portal and cloud insights. |
|
||||
| [PagerDuty](https://www.pagerduty.com/) | [Mark Shaw](https://github.com/markshawtoronto) | Developer portal, initially focused on software templates and tech-docs. |
|
||||
| [MoonShiner](https://moonshiner.at) | [Fabian Hippmann](https://github.com/FabianHippmann) | Developer portal - helps us keep track of our customer projects, onboard new developers & improve our development process 🌕🚀🧑🚀 |
|
||||
| [MoonShiner](https://moonshiner.at) | [Fabian Hippmann](https://github.com/FabianHippmann) | Developer portal - helps us keep track of our customer projects, onboard new developers & improve our development process 🌕🚀🧑🚀 |
|
||||
| [FundApps](https://www.fundapps.co/) | [Elliot Greenwood](https://github.com/egnwd) | Developer Portal - A place for us to keep track of our projects and documentation for all services and processes |
|
||||
| [DAZN](https://dazn.com/) | [Lou Bichard](https://twitter.com/loujaybee), [Marco Crivellaro](https://github.com/crivetechie), [Alex Hollerith](mailto:alex.hollerith@dazn.com) | Ingesting all of DAZN's repos for the catalog, migrating our internal platform apps (pull request boards, release information, inner source marketplace etc) to Backstage plugins (where applicable). |
|
||||
| [HelloFresh](https://www.hellofresh.de/) | [@iammuho](https://github.com/iammuho), [@ElenaForester](https://github.com/ElenaForester), [@diegomarangoni](https://github.com/diegomarangoni) | Our developer portal at HelloFresh - Spread across an organisation of 500+ engineers globally. |
|
||||
@@ -113,8 +113,13 @@ _If you're using Backstage in your organization, please try to add your company
|
||||
| [SIX](https://www.six-group.com/) | [@jbadeau](https://github.com/jbadeau), [@tomassatka](https://github.com/tomassatka) | Internal DevOps portal hosting our software and dataset catalog, as well as custom plugins for observability, service virtualization, deployments, incident managment and quality metrics. |
|
||||
| [Raiffeisen Bank International](https://www.rbinternational.com/) | [Daniel Baumgartner](https://github.com/dabarbi) | From developers for developers: software catalog, techdocs and heavy use of scaffolder to drive reuse on engineering level forward. Part of inner source initiative. Multi national setup coming. |
|
||||
| [Spread Group](https://www.spreadgroup.com/) | [Luna Stadler](https://github.com/heyLu), [Iván González](https://github.com/ivangonzalezacuna) | Internal Developer Portal, an overview of all running software, architecture documentation and more; replacing and unifying a variety of internal tools. |
|
||||
| [RD Station](https://rdstation.com) | [Rogerio Angeliski](https://github.com/angeliski), [Paula Assis](https://github.com/paulassis), [Guilherme Eric](https://github.com/guilhermeeric), [Daniela Adamatti](https://github.com/daniadamatti), [Luana Negreiros](https://github.com/luananegreiros) | Developer portal, scaffolding, services catalog. We are looking to centralize automations and information for the whole engineering team . | |
|
||||
| [Resuelve Tu Deuda](https://resuelve.mx)| [Iván Álvarez](https://github.com/ivanhoe), [Jorge Medina](https://github.com/jorgearma1982) | Internal developer portal, service catalog, tech docs, api doc
|
||||
| [Pachama](https://pachama.com/) | [Aron Gates](https://github.com/agates4) | Internal Developer Portal, a catalog of all microservices, architecture documentation, and templates to generate developer resources. |
|
||||
| [SEEK](https://www.seek.com.au) | [Jahred Hope](https://github.com/jahredhope) | Developer portal for developer tooling and technical documentation. |
|
||||
| [Marks & Spencer](https://www.marksandspencer.com/) | [Kamal Cheriyath](https://github.com/kcheriyath) | Centralised discovery, adoption and devops automation hub for Engineering & Architecture. |
|
||||
| [RD Station](https://rdstation.com) | [Rogerio Angeliski](https://github.com/angeliski), [Paula Assis](https://github.com/paulassis), [Guilherme Eric](https://github.com/guilhermeeric), [Daniela Adamatti](https://github.com/daniadamatti), [Luana Negreiros](https://github.com/luananegreiros) | Developer portal, scaffolding, services catalog. We are looking to centralize automations and information for the whole engineering team . |
|
||||
| [Resuelve Tu Deuda](https://resuelve.mx) | [Iván Álvarez](https://github.com/ivanhoe), [Jorge Medina](https://github.com/jorgearma1982) | Internal developer portal, service catalog, tech docs, api doc |
|
||||
| [Pachama](https://pachama.com/) | [Aron Gates](https://github.com/agates4) | Internal Developer Portal, a catalog of all microservices, architecture documentation, and templates to generate developer resources. |
|
||||
| [SEEK](https://www.seek.com.au) | [Jahred Hope](https://github.com/jahredhope) | Developer portal for developer tooling and technical documentation. |
|
||||
| [Marks & Spencer](https://www.marksandspencer.com/) | [Kamal Cheriyath](https://github.com/kcheriyath) | Centralised discovery, adoption and devops automation hub for Engineering & Architecture. |
|
||||
| [McKesson](https://www.mckesson.com/) | [Agnel Antony](https://github.com/aantony2) | Internal Developer Platform for developer gated CI/CD templates, technical documentation, cloud automation service catalog, etc. |
|
||||
| [World Fuel Services](https://www.wfscorp.com/) | [Anirudh Kurapathi](https://github.com/anirudhkurapati), [Alex Kwon](https://github.com/alexkwon), [Lester Hernandez](https://github.com/lhernandez-wfscorp), [Avi Boru](https://github.com/aviboru), [Vardhan Annapureddy](https://github.com/harshaaws) | Internal Developer Portal, service catalog product, API's, Software Templates, tech docs and more. |
|
||||
| [leboncoin](https://www.leboncoin.fr/) | [Andy Ladjadj](https://github.com/aladjadj) | Centralize our multiple UI in a single portal. Simplify onbording, new features and harmonize how people search information. Core features (catalog,api,docs,scafolder) are good to start the adoption. status: internal beta. |
|
||||
| [Contentful](https://www.contentful.com) | [James Bourne](https://github.com/jamesmbourne) | Centralized documentation of service ownership, APIs, and documentation, and new service creation with a custom scaffolder - [full case study with Roadie](https://roadie.io/case-studies/maintaining-velocity-through-hypergrowth-contentful/). |
|
||||
| [Back Market](https://www.backmarket.com) | [Sami Farhat](https://github.com/skfarhat) | Internal Developer Portal featuring catalog, tech-radar, ownership management, component creation (scaffolder) and centralized infrastructure management -- probably more to come. |
|
||||
|
||||
+2
-2
@@ -16,7 +16,7 @@ No one likes bugs. Report bugs as an issue [here](https://github.com/backstage/b
|
||||
|
||||
### Fix bugs or build new features
|
||||
|
||||
Look through the GitHub issues for [bugs](https://github.com/backstage/backstage/labels/bugs), [good first issues](https://github.com/backstage/backstage/labels/good%20first%20issue) or [help wanted](https://github.com/backstage/backstage/labels/help%20wanted).
|
||||
Look through the GitHub issues for [bugs](https://github.com/backstage/backstage/labels/bug), [good first issues](https://github.com/backstage/backstage/labels/good%20first%20issue) or [help wanted](https://github.com/backstage/backstage/labels/help%20wanted).
|
||||
|
||||
### Build a plugin
|
||||
|
||||
@@ -78,7 +78,7 @@ If you're contributing to the backend or CLI tooling, be mindful of cross-platfo
|
||||
|
||||
Also be sure to skim through our [ADRs](docs/architecture-decisions) to see if they cover what you're working on. In particular [ADR006: Avoid React.FC and React.SFC](docs/architecture-decisions/adr006-avoid-react-fc.md) is one to look out for.
|
||||
|
||||
If there are any updates in `markdown` file please make sure to run `yarn run lint:docs`. Though it is checked on `lint-staged`. It is required to install [vale](https://docs.errata.ai/vale/install) `1.4.0` separately and make sure it is accessed by global command.
|
||||
If there are any updates in `markdown` file please make sure to run `yarn run lint:docs`. Though it is checked on `lint-staged`. It is required to install [vale](https://docs.errata.ai/vale/install) separately and make sure it is accessed by global command.
|
||||
|
||||
## Developer Certificate of Origin
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@ There are a few things to pay attention to, in order to make the documentation s
|
||||
|
||||
API documenter will not recognize arrow functions as functions, but rather as a constant that shows up in the list of exported variables. By declaring functions using the `function` keyword, they will show up in the list of functions. They will also get a much nicer documentation page for the individual function that shows information about parameters and return types.
|
||||
|
||||
This also extends to React components, since API documenter doesn't have any special handling of those. By always defining exported React components using the `function` keyword, we make them show up among the list of functions in the API reference, where they are then easily discoverable through the `(props)` args (which you should be sure to include!).
|
||||
This also extends to React components, since API documenter doesn't have any special handling of those. By always defining exported React components using the `function` keyword, we make them show up among the list of functions in the API reference, where they are then easily discoverable through the `(props)` argument (which you should be sure to include!).
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -378,6 +378,8 @@ auth:
|
||||
clientId: ${AUTH_ATLASSIAN_CLIENT_ID}
|
||||
clientSecret: ${AUTH_ATLASSIAN_CLIENT_SECRET}
|
||||
scopes: ${AUTH_ATLASSIAN_SCOPES}
|
||||
myproxy:
|
||||
development: {}
|
||||
costInsights:
|
||||
engineerCost: 200000
|
||||
products:
|
||||
|
||||
@@ -64,8 +64,8 @@ if (process.env.HTTPS_PROXY) {
|
||||
|
||||
If your development environment is in the cloud (like with [AWS Cloud9](https://aws.amazon.com/cloud9/) or an instance of [Theia](https://theia-ide.org/)), you will need to update your configuration.
|
||||
|
||||
You will probably need to make some changes in `app-config.yaml` (or another config file like `app-config.local.yaml` if you've created it, see the [configuration doc](https://backstage.io/docs/conf/#supplying-configuration)).
|
||||
The exact values will depend on your setup but for instance, if your public url is `https://your-public-url.com` and the port `3000` and `8080` are open:
|
||||
You will probably need to make some changes in `app-config.yaml` (or another config file like `app-config.local.yaml` if you've created it, see the [configuration doc](https://backstage.io/docs/conf/#supplying-configuration)).
|
||||
The exact values will depend on your setup but for instance, if your public URL is `https://your-public-url.com` and the port `3000` and `8080` are open:
|
||||
|
||||
```yaml
|
||||
app:
|
||||
|
||||
@@ -18,6 +18,17 @@ yarn install
|
||||
yarn cypress run
|
||||
```
|
||||
|
||||
Note that the tests expect to run against a built application, so you'll want to
|
||||
run a Docker image and either create an `app-config.cypress.yaml` or pass the
|
||||
necessary environment variables:
|
||||
|
||||
```sh
|
||||
yarn tsc
|
||||
yarn build
|
||||
yarn workspace example-backend build-image
|
||||
docker run -p 7007:7007 example-backend
|
||||
```
|
||||
|
||||
You can open up the `cypress` console by using `yarn cypress open`.
|
||||
|
||||
You can also run towards any Backstage installation by using the Cypress Environment Variable overrides.
|
||||
|
||||
+3
-3
@@ -1036,9 +1036,9 @@ type-fest@^0.21.3:
|
||||
integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
|
||||
|
||||
typescript@^4.1.3:
|
||||
version "4.1.3"
|
||||
resolved "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7"
|
||||
integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==
|
||||
version "4.6.4"
|
||||
resolved "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz#caa78bbc3a59e6a5c510d35703f6a09877ce45e9"
|
||||
integrity sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==
|
||||
|
||||
universalify@^2.0.0:
|
||||
version "2.0.0"
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 284 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 21 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 181 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 297 KiB |
@@ -74,7 +74,7 @@ export class ProviderAAuthProvider implements OAuthProviderHandlers {
|
||||
clientID: options.clientId,
|
||||
clientSecret: options.clientSecret,
|
||||
callbackURL: options.callbackUrl,
|
||||
passReqToCallback: false as true,
|
||||
passReqToCallback: false,
|
||||
response_type: 'code',
|
||||
/// ... etc
|
||||
}
|
||||
@@ -230,7 +230,7 @@ name.
|
||||
### Test the new provider
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ The GitHub provider is a structure with three configuration keys:
|
||||
- `clientSecret`: The client secret tied to the generated client ID.
|
||||
- `enterpriseInstanceUrl` (optional): The base URL for a GitHub Enterprise
|
||||
instance, e.g. `https://ghe.<company>.com`. Only needed for GitHub Enterprise.
|
||||
- `callbackUrl` (optional): The callback url that GitHub will use when
|
||||
- `callbackUrl` (optional): The callback URL that GitHub will use when
|
||||
initiating an OAuth flow, e.g.
|
||||
`https://your-intermediate-service.com/handler`. Only needed if Backstage is
|
||||
not the immediate receiver (e.g. one OAuth app for many backstage instances).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
id: provider
|
||||
id: gcp-iap-auth
|
||||
title: Google Identity-Aware Proxy Provider
|
||||
sidebar_label: Google IAP
|
||||
# prettier-ignore
|
||||
@@ -43,7 +43,8 @@ Add a `providerFactories` entry to the router in
|
||||
`packages/backend/plugin/auth.ts`.
|
||||
|
||||
```ts
|
||||
import { createGcpIapProvider } from '@backstage/plugin-auth-backend';
|
||||
import { providers } from '@backstage/plugin-auth-backend';
|
||||
import { stringifyEntityRef } from '@backstage/catalog-model';
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
@@ -54,7 +55,7 @@ export default async function createPlugin(
|
||||
database: env.database,
|
||||
discovery: env.discovery,
|
||||
providerFactories: {
|
||||
'gcp-iap': createGcpIapProvider({
|
||||
'gcp-iap': providers.gcpIap.create({
|
||||
// Replace the auth handler if you want to customize the returned user
|
||||
// profile info (can be left out; the default implementation is shown
|
||||
// below which only returns the email). You may want to amend this code
|
||||
@@ -71,12 +72,10 @@ export default async function createPlugin(
|
||||
// Somehow compute the Backstage token claims. Just some dummy code
|
||||
// shown here, but you may want to query your LDAP server, or
|
||||
// GSuite or similar, based on the IAP token sub/email claims
|
||||
const id = `user:default/${iapToken.email.split('@')[0]}`;
|
||||
const fullEnt = ['group:default/team-name'];
|
||||
const token = await ctx.tokenIssuer.issueToken({
|
||||
claims: { sub: id, ent: fullEnt },
|
||||
});
|
||||
return { id, token };
|
||||
const id = iapToken.email.split('@')[0];
|
||||
const sub = stringifyEntityRef({ kind: 'User', name: id });
|
||||
const ent = [sub, stringifyEntityRef({ kind: 'Group', name: 'team-name' });
|
||||
return ctx.issueToken({ claims: { sub, ent } });
|
||||
},
|
||||
},
|
||||
}),
|
||||
@@ -91,23 +90,8 @@ sign-in mechanism to poll that endpoint through the IAP, on the user's behalf.
|
||||
|
||||
## Frontend Changes
|
||||
|
||||
All Backstage apps need a `SignInPage` to be configured. Its purpose is to
|
||||
establish who the user is and what their identifying credentials are, blocking
|
||||
rendering the rest of the UI until that's complete, and then keeping those
|
||||
credentials fresh.
|
||||
|
||||
When using IAP Proxy authentication, the Backstage UI will only be loaded once
|
||||
the user has already successfully completely authenticated themselves with the
|
||||
IAP and has an active session, so we don't want to make the user have to go
|
||||
through a _second_ layer of authentication flows after that.
|
||||
|
||||
As such, we want to not display a sign-in page visually at all. Instead, we will
|
||||
pick a `SignInPage` implementation component which knows how to silently make
|
||||
requests to the backend provider we configured above, and just trusting its
|
||||
output to properly represent the current user. Luckily, Backstage comes with a
|
||||
component for this purpose out of the box.
|
||||
|
||||
Update your `createApp` call in `packages/app/src/App.tsx`, as follows.
|
||||
It is recommended to use the `ProxiedSignInPage` for this provider, which is
|
||||
installed in `packages/app/src/App.tsx` like this:
|
||||
|
||||
```diff
|
||||
+import { ProxiedSignInPage } from '@backstage/core-components';
|
||||
@@ -117,5 +101,4 @@ Update your `createApp` call in `packages/app/src/App.tsx`, as follows.
|
||||
+ SignInPage: props => <ProxiedSignInPage {...props} provider="gcp-iap" />,
|
||||
```
|
||||
|
||||
After this, your app should be ready to leverage the Identity-Aware Proxy for
|
||||
authentication!
|
||||
See the [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) section for more information.
|
||||
|
||||
@@ -186,16 +186,59 @@ async ({ profile: { email } }, ctx) => {
|
||||
const ownershipRefs = getDefaultOwnershipRefs(entity);
|
||||
|
||||
// The last step is to issue the token, where we might provide more options in the future.
|
||||
const token = ctx.issueToken({
|
||||
return ctx.issueToken({
|
||||
claims: {
|
||||
sub: stringifyEntityRef(entity),
|
||||
ent: ownershipRefs,
|
||||
},
|
||||
});
|
||||
return { token };
|
||||
};
|
||||
```
|
||||
|
||||
## Sign-In without Users in the Catalog
|
||||
|
||||
While populating the catalog with organizational data unlocks more powerful ways
|
||||
to browse your software ecosystem, it might not always be a viable or prioritized
|
||||
option. However, even if you do not have user entities populated in your catalog, you
|
||||
can still sign in users. As there are currently no built-in sign-in resolvers for
|
||||
this scenario you will need to implement your own.
|
||||
|
||||
Signing in a user that doesn't exist in the catalog is as simple as skipping the
|
||||
catalog lookup step from the above example. Rather than looking up the user, we
|
||||
instead immediately issue a token using whatever information is available. One caveat
|
||||
is that it can be tricky to determine the ownership references, although it can
|
||||
be achieved for example through a lookup to an external service. You typically
|
||||
want to at least use the user itself as a lone ownership reference.
|
||||
|
||||
```ts
|
||||
import { DEFAULT_NAMESPACE, stringifyEntityRef, } from '@backstage/catalog-model';
|
||||
|
||||
// This example only shows the resolver function itself.
|
||||
async ({ profile }, ctx) => {
|
||||
if (!profile.email) {
|
||||
throw new Error(
|
||||
'Login failed, user profile does not contain an email',
|
||||
);
|
||||
}
|
||||
// We again use the local part of the email as the user name.
|
||||
const [localPart] = profile.email.split('@');
|
||||
|
||||
// By using `stringifyEntityRef` we ensure that the reference is formatted correctly
|
||||
const userEntityRef = stringifyEntityRef({
|
||||
kind: 'User',
|
||||
name: localPart,
|
||||
namespace: DEFAULT_NAMESPACE,
|
||||
});
|
||||
|
||||
return ctx.issueToken({
|
||||
claims: {
|
||||
sub: userEntityRef,
|
||||
ent: [userEntityRef],
|
||||
},
|
||||
});
|
||||
},
|
||||
```
|
||||
|
||||
## AuthHandler
|
||||
|
||||
Similar to a custom sign-in resolver, you can also write a custom auth handler
|
||||
|
||||
@@ -21,6 +21,7 @@ Backstage comes with many common authentication providers in the core library:
|
||||
- [GitHub](github/provider.md)
|
||||
- [GitLab](gitlab/provider.md)
|
||||
- [Google](google/provider.md)
|
||||
- [Google IAP](google/gcp-iap-auth.md)
|
||||
- [Okta](okta/provider.md)
|
||||
- [OneLogin](onelogin/provider.md)
|
||||
- [OAuth2Proxy](oauth2-proxy/provider.md)
|
||||
@@ -126,6 +127,64 @@ allows allowing guest access:
|
||||
bindRoutes({ bind }) {
|
||||
```
|
||||
|
||||
## Sign-In with Proxy Providers
|
||||
|
||||
Some auth providers are so-called "proxy" providers, meaning they're meant to be used
|
||||
behind an authentication proxy. Examples of these are
|
||||
[AWS ALB](https://github.com/backstage/backstage/blob/master/contrib/docs/tutorials/aws-alb-aad-oidc-auth.md),
|
||||
[GCP IAP](./google/gcp-iap-auth.md), and [OAuth2 Proxy](./oauth2-proxy/provider.md).
|
||||
|
||||
When using a proxy provider, you'll end up wanting to use a different sign-in page, as
|
||||
there is no need for further user interaction once you've signed in towards the proxy.
|
||||
All the sign-in page needs to do is to call the `/refresh` endpoint of the auth providers
|
||||
to get the existing session, which is exactly what the `ProxiedSignInPage` does. The only
|
||||
thing you need to do to configure the `ProxiedSignInPage` is to pass the ID of the provider like this:
|
||||
|
||||
```tsx
|
||||
const app = createApp({
|
||||
...,
|
||||
components: {
|
||||
SignInPage: props => <ProxiedSignInPage {...props} provider="awsalb" />,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
A downside of this method is that it can be cumbersome to set up for local development.
|
||||
As a workaround for this, it's possible to dynamically select the sign-in page based on
|
||||
what environment the app is running in, and then use a different sign-in method for local
|
||||
development, if one is needed at all. Depending on the exact setup, one might choose to
|
||||
select the sign-in method based on the `process.env.NODE_ENV` environment variable,
|
||||
by checking the `hostname` of the current location, or by accessing the configuration API
|
||||
to read a configuration value. For example:
|
||||
|
||||
```tsx
|
||||
const app = createApp({
|
||||
...,
|
||||
components: {
|
||||
SignInPage: props => {
|
||||
const configApi = useApi(configApiRef);
|
||||
if (configApi.getString('auth.environment') === 'development') {
|
||||
return (
|
||||
<SignInPage
|
||||
{...props}
|
||||
provider={{
|
||||
id: 'google-auth-provider',
|
||||
title: 'Google',
|
||||
message: 'Sign In using Google',
|
||||
apiRef: googleAuthApiRef,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return <ProxiedSignInPage {...props} provider="gcpiap" />;
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
When using multiple auth providers like this, it's important that you configure the different
|
||||
sign-in resolvers so that they resolve to the same identity regardless of the method used.
|
||||
|
||||
## For Plugin Developers
|
||||
|
||||
The Backstage frontend core APIs provide a set of Utility APIs for plugin developers
|
||||
|
||||
@@ -20,86 +20,52 @@ The provider configuration can be added to your `app-config.yaml` under the root
|
||||
|
||||
```yaml
|
||||
auth:
|
||||
environment: development
|
||||
providers:
|
||||
oauth2proxy: {}
|
||||
```
|
||||
|
||||
Right now no configuration options are supported. To make use of the provider,
|
||||
make sure that your `oauth2-proxy` is configured correctly and provides a custom
|
||||
`X-OAUTH2-PROXY-ID-TOKEN` header. To do so, enable the
|
||||
`--set-authorization-header=true` of your `oauth2-proxy` and forward the
|
||||
`Authorization` header as `X-OAUTH2-PROXY-ID-TOKEN`. For more details check the
|
||||
[configuration docs](https://oauth2-proxy.github.io/oauth2-proxy/configuration).
|
||||
Right now no configuration options are supported, but the empty object is needed
|
||||
to enable the provider in the auth backend.
|
||||
|
||||
_Example for kubernetes ingress:_
|
||||
To use the `oauth2proxy` provider you must also configure it with a sign-in resolver.
|
||||
For more information about the sign-in process in general, see the
|
||||
[Sign-in Identities and Resolvers](../identity-resolver.md) documentation.
|
||||
|
||||
```bash
|
||||
# forward the authorization header from the auth request in the X-OAUTH2-PROXY-ID-TOKEN header
|
||||
auth_request_set $name_upstream_authorization $upstream_http_authorization;
|
||||
proxy_set_header X-OAUTH2-PROXY-ID-TOKEN $name_upstream_authorization;
|
||||
```
|
||||
For the `oauth2proxy` provider, the sign-in result is quite different than other providers.
|
||||
Because it's a proxy provider that can be configured to forward information through
|
||||
arbitrary headers, the auth result simply just gives you access to the HTTP headers
|
||||
of the incoming request. Using these you can either extract the information directly,
|
||||
or grab ID or access tokens to look up additional information and/or validate the request.
|
||||
|
||||
## Adding the provider to the Backstage backend
|
||||
|
||||
When using `oauth2proxy` auth you can configure it as described
|
||||
[here](https://backstage.io/docs/auth/identity-resolver).
|
||||
|
||||
- use the following code below to introduce changes to
|
||||
`packages/backend/plugin/auth.ts`:
|
||||
A simple sign-in resolver might for example look like this:
|
||||
|
||||
```ts
|
||||
providerFactories: {
|
||||
oauth2proxy: createOauth2ProxyProvider<{
|
||||
id: string;
|
||||
email: string;
|
||||
}>({
|
||||
authHandler: async input => {
|
||||
const { email } = input.fullProfile;
|
||||
|
||||
return {
|
||||
profile: {
|
||||
email,
|
||||
},
|
||||
};
|
||||
},
|
||||
signIn: {
|
||||
resolver: async (signInInfo, ctx) => {
|
||||
const { preferred_username: id } = signInInfo.result.fullProfile;
|
||||
const sub = `user:default/${id}`;
|
||||
|
||||
const token = await ctx.tokenIssuer.issueToken({
|
||||
claims: { sub, ent: [`group:default/optional-user-group`] },
|
||||
});
|
||||
|
||||
return { id, token };
|
||||
},
|
||||
},
|
||||
}),
|
||||
}
|
||||
providers.oauth2Proxy.create({
|
||||
signIn: {
|
||||
async resolver({ result }, ctx) {
|
||||
const name = result.getHeader('x-forwarded-user');
|
||||
if (!name) {
|
||||
throw new Error('Request did not contain a user')
|
||||
}
|
||||
return ctx.signInWithCatalogUser({
|
||||
entityRef: { name },
|
||||
});
|
||||
},
|
||||
},
|
||||
}),
|
||||
```
|
||||
|
||||
## Adding the provider to the Backstage frontend
|
||||
|
||||
All Backstage apps need a `SignInPage` to be configured. Its purpose is to
|
||||
establish who the user is and what their identifying credentials are, blocking
|
||||
rendering the rest of the UI until that's complete, and then keeping those
|
||||
credentials fresh.
|
||||
|
||||
When using the OAuth2-Proxy, the Backstage UI can only be accessed after the
|
||||
user has already been authenticated at the proxy. Instead of showing the user
|
||||
another login page when accessing Backstage, it will handle the login in the
|
||||
background. Backstage provides for this case the `ProxiedSignInPage` component
|
||||
which has no UI.
|
||||
|
||||
Update your `createApp` call in `packages/app/src/App.tsx`, as follows.
|
||||
It is recommended to use the `ProxiedSignInPage` for this provider, which is
|
||||
installed in `packages/app/src/App.tsx` like this:
|
||||
|
||||
```diff
|
||||
+import { ProxiedSignInPage } from '@backstage/core-components';
|
||||
|
||||
const app = createApp({
|
||||
components: {
|
||||
+ SignInPage: props => <ProxiedSignInPage {...props} provider="oauth2proxy" />,
|
||||
```
|
||||
|
||||
After this, your app should be ready to leverage the OAuth2-Proxy for
|
||||
authentication!
|
||||
See the [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) section for more information.
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
---
|
||||
id: troubleshooting
|
||||
title: Troubleshooting Auth
|
||||
description: Guidance for various issues that one might run into when setting up authentication
|
||||
---
|
||||
|
||||
Auth is tricky and doesn't always work as expected. Below you'll find some of the common
|
||||
problems one might run into when setting up authentication, as well as some general
|
||||
troubleshooting tips.
|
||||
|
||||
## Sign-in fails with "... provider is not configured to support sign-in"
|
||||
|
||||
This happens if you try to sign in using an auth provider that has not been
|
||||
configured to allow sign-in. See the [Sign-in Identities and Resolvers](./identity-resolver.md)
|
||||
page for information about how to configure and customize sign-in.
|
||||
|
||||
As part of the 1.1 release of Backstage we removed the default implementations
|
||||
of all sign-in resolvers. This was a necessary security fix as well as a step
|
||||
towards providing more clarity in the configuration of the sign-in process.
|
||||
You may encounter this error if you are upgrading from a previous version, in
|
||||
which case you would need to configure a sign-in resolver as described above.
|
||||
|
||||
## Auth fails with "Auth provider registered for ... is misconfigured"
|
||||
|
||||
This will typically only happen during development, as in a production build the auth
|
||||
backend will fail to start up altogether if a provider is misconfigured.
|
||||
|
||||
Double check that your configuration for the provider is correct. Note that environment variables
|
||||
such as `AUTH_OAUTH2_CLIENT_ID` must be set and will **NOT** be picked up from `.env` files.
|
||||
You can use the `yarn backstage-cli config:print --lax` command to print your local configuration.
|
||||
|
||||
The backend logs should also provide insight into why the configuration of the provider
|
||||
fails. In working setup the backend should log something like `"Configuring provider, oauth2"`,
|
||||
while it with otherwise log a warning like `"Skipping oauth2 auth provider, ..."`.
|
||||
|
||||
## Auth fails with "Login failed; caused by NotAllowedError: Origin '...' is not allowed"
|
||||
|
||||
This will happen if the origin of the configured `app.baseUrl` in the auth backend does not
|
||||
match the origin that the frontend is being accessed at. Make sure that `app.baseUrl` matches
|
||||
what a user sees in the browser address bar.
|
||||
|
||||
If you wish to support multiple different origins at once, there is an experimental configuration
|
||||
that lets you do this. The `auth.experimentalExtraAllowedOrigins` key accepts a list of origin
|
||||
glob patterns where sign-in should be allowed from.
|
||||
|
||||
## Sign-in fails with the error "User not found"
|
||||
|
||||
Many built-in sign-in resolvers require user entities to be present in the catalog. This
|
||||
error is encountered if authentication is successful, but a matching user entity is not
|
||||
present in the catalog. If you wish to enable sign-in without having users be represented
|
||||
in the catalog data, see the method that's documented in the
|
||||
[sign-in resolver documentation](./identity-resolver.md#sign-in-without-users-in-the-catalog).
|
||||
|
||||
If you want to customize this error message, you can create a custom sign-in resolver and
|
||||
catch the `NotFoundError` thrown by `ctx.signInWithCatalogUser` or `ctx.findCatalogUser`.
|
||||
|
||||
## General troubleshooting
|
||||
|
||||
This section contains some general troubleshooting tips.
|
||||
|
||||
### Stepping through authentication manually
|
||||
|
||||
Authentication happens in a popup window that redirects to the identity providers authorization
|
||||
endpoint. Once auth is complete the identity provider will redirect back to the auth backend,
|
||||
which immediately serves a simple HTML page that posts the result back to the main window, which
|
||||
then closes the popup.
|
||||
|
||||
Because the popup is closed automatically it can sometimes be difficult to inspect the auth
|
||||
flow, especially if one wants to debug the cookies that are being set. One way around this is to
|
||||
manually head to the `/start` endpoint of the provider, which is the page that the popup will
|
||||
point to initially. For example, if you want to troubleshoot GitHub auth locally, you'd head
|
||||
to `http://localhost:7007/api/auth/github/start?env=development`. Note that the `env` parameter
|
||||
needs to be set, and it's possible that you may need to set the `scope` parameter for some providers
|
||||
as well.
|
||||
|
||||
Once you've stepped through the auth flow you should end up at the `/handler/frame` endpoint, which displays
|
||||
an empty page. This is where the result is normally posted back to the main window, but since we've
|
||||
reached it using the manual flow that won't happen. You can still inspect the result though, both
|
||||
by viewing the source code of the page, or printing the value of the `authResponse` variable in the console.
|
||||
|
||||
### Inspecting the refresh call
|
||||
|
||||
If you're running into problems with session persistence, such as users being signed out when reloading
|
||||
the page, it will be something that's going wrong with the call to the `/refresh` endpoint of the
|
||||
auth provider. Head to the network inspector and filter by `/refresh`. Find the `GET` request towards
|
||||
`<backend.baseUrl>/api/auth/<provider>/refresh` and inspect the request.
|
||||
|
||||
Note that extra calls to the refresh endpoint may be made by the frontend in order to check whether
|
||||
auth providers have an existing session. This means that there might be multiple calls, including some
|
||||
that are failing. Make sure you're looking at the refresh call to the provider that you're troubleshooting,
|
||||
and don't worry about other failing refresh calls.
|
||||
|
||||
### Inspecting the contents of a Backstage token
|
||||
|
||||
The Backstage token that's issues during sign-in is a plain JWT. You can inspect the contents using
|
||||
any tool that supports JWTs, or you can parse the payload yourself in for example the browser console
|
||||
or a Node.js REPL:
|
||||
|
||||
```js
|
||||
atob(token.split('.')[1]);
|
||||
```
|
||||
@@ -161,7 +161,7 @@ $file: ./my-secret.txt
|
||||
|
||||
The `$include` keyword can be used to load configuration values from an external
|
||||
file. It's able to load and parse data from `.json`, `.yml`, and `.yaml` files.
|
||||
It's also possible to include a url fragment (`#`) to point to a value at the
|
||||
It's also possible to include a URL fragment (`#`) to point to a value at the
|
||||
given path in the file, using a dot-separated list of keys.
|
||||
|
||||
For example, the following would read `my-secret-key` from `my-secrets.json`:
|
||||
|
||||
@@ -96,8 +96,8 @@ root of the repo to speed up the build by reducing build context size:
|
||||
```text
|
||||
.git
|
||||
node_modules
|
||||
packages
|
||||
!packages/backend/dist
|
||||
packages/*/src
|
||||
packages/*/node_modules
|
||||
plugins
|
||||
```
|
||||
|
||||
|
||||
@@ -149,7 +149,6 @@ import {
|
||||
import { PluginEnvironment } from '../types';
|
||||
import { DefaultCatalogCollator } from '@backstage/plugin-catalog-backend';
|
||||
import { Router } from 'express';
|
||||
import { Duration } from 'luxon';
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
@@ -163,9 +162,9 @@ export default async function createPlugin(
|
||||
});
|
||||
|
||||
const every10MinutesSchedule = env.scheduler.createScheduledTaskRunner({
|
||||
frequency: Duration.fromObject({ minutes: 10 }),
|
||||
timeout: Duration.fromObject({ minutes: 15 }),
|
||||
initialDelay: Duration.fromObject({ seconds: 3 }),
|
||||
frequency: { minutes: 10 },
|
||||
timeout: { minutes: 15 },
|
||||
initialDelay: { seconds: 3 },
|
||||
});
|
||||
|
||||
indexBuilder.addCollator({
|
||||
@@ -294,20 +293,18 @@ which are responsible for providing documents
|
||||
number of collators with the `IndexBuilder` like this:
|
||||
|
||||
```typescript
|
||||
import { Duration } from 'luxon';
|
||||
|
||||
const indexBuilder = new IndexBuilder({ logger: env.logger, searchEngine });
|
||||
|
||||
const every10MinutesSchedule = env.scheduler.createScheduledTaskRunner({
|
||||
frequency: Duration.fromObject({ minutes: 10 }),
|
||||
timeout: Duration.fromObject({ minutes: 15 }),
|
||||
initialDelay: Duration.fromObject({ seconds: 3 }),
|
||||
frequency: { minutes: 10 },
|
||||
timeout: { minutes: 15 },
|
||||
initialDelay: { seconds: 3 },
|
||||
});
|
||||
|
||||
const everyHourSchedule = env.scheduler.createScheduledTaskRunner({
|
||||
frequency: Duration.fromObject({ hours: 1 }),
|
||||
timeout: Duration.fromObject({ minutes: 90 }),
|
||||
initialDelay: Duration.fromObject({ seconds: 3 }),
|
||||
frequency: { hours: 1 },
|
||||
timeout: { minutes: 90 },
|
||||
initialDelay: { seconds: 3 },
|
||||
});
|
||||
|
||||
indexBuilder.addCollator({
|
||||
@@ -332,9 +329,9 @@ a scheduled `TaskRunner` to pass into the `schedule` value, like this:
|
||||
|
||||
```typescript {3}
|
||||
const every10MinutesSchedule = env.scheduler.createScheduledTaskRunner({
|
||||
frequency: Duration.fromObject({ minutes: 10 }),
|
||||
timeout: Duration.fromObject({ minutes: 15 }),
|
||||
initialDelay: Duration.fromObject({ seconds: 3 }),
|
||||
frequency: { minutes: 10 },
|
||||
timeout: { minutes: 15 },
|
||||
initialDelay: { seconds: 3 },
|
||||
});
|
||||
|
||||
indexBuilder.addCollator({
|
||||
|
||||
@@ -67,11 +67,24 @@ getting started guide.
|
||||
import { DefaultTechDocsCollatorFactory } from '@backstage/plugin-techdocs-backend';
|
||||
```
|
||||
|
||||
2. Register the `DefaultTechDocsCollatorFactory` with the IndexBuilder.
|
||||
2. If there isn't an existing schedule you'd like to run the collator on, be
|
||||
sure to create it first. Something like...
|
||||
|
||||
```typescript
|
||||
import { Duration } from 'luxon';
|
||||
|
||||
const every10MinutesSchedule = env.scheduler.createScheduledTaskRunner({
|
||||
frequency: Duration.fromObject({ seconds: 600 }),
|
||||
timeout: Duration.fromObject({ seconds: 900 }),
|
||||
initialDelay: Duration.fromObject({ seconds: 3 }),
|
||||
});
|
||||
```
|
||||
|
||||
3. Register the `DefaultTechDocsCollatorFactory` with the IndexBuilder.
|
||||
|
||||
```typescript
|
||||
indexBuilder.addCollator({
|
||||
defaultRefreshIntervalSeconds: 600,
|
||||
schedule: every10MinutesSchedule,
|
||||
factory: DefaultTechDocsCollatorFactory.fromConfig(env.config, {
|
||||
discovery: env.discovery,
|
||||
logger: env.logger,
|
||||
|
||||
@@ -231,7 +231,6 @@ You should now be able to add this class to your backend in
|
||||
`packages/backend/src/plugins/catalog.ts`:
|
||||
|
||||
```diff
|
||||
+import { Duration } from 'luxon';
|
||||
+import { FrobsProvider } from '../path/to/class';
|
||||
|
||||
export default async function createPlugin(
|
||||
@@ -248,8 +247,8 @@ You should now be able to add this class to your backend in
|
||||
+ await env.scheduler.scheduleTask({
|
||||
+ id: 'run_frobs_refresh',
|
||||
+ fn: async () => { await frobs.run(); },
|
||||
+ frequency: Duration.fromObject({ minutes: 30 }),
|
||||
+ timeout: Duration.fromObject({ minutes: 10 }),
|
||||
+ frequency: { minutes: 30 },
|
||||
+ timeout: { minutes: 10 },
|
||||
+ });
|
||||
```
|
||||
|
||||
|
||||
@@ -76,17 +76,19 @@ TechDocs packages:
|
||||
|
||||
TechDocs promoted to v1.0! To understand how this change affects the package, please check out our [versioning policy](https://backstage.io/docs/overview/versioning-policy).
|
||||
|
||||
**v1.2** 🚧
|
||||
|
||||
With the Backstage 1.2 release, we plan to introduce the [TechDocs Addon Framework](https://github.com/backstage/backstage/issues/9636) for augmenting the TechDocs experience at read-time.
|
||||
|
||||
In addition to the framework itself, we'll be open sourcing a `<ReportIssue />` addon, helping you to create a feedback loop that drives up documentation quality and fosters a documentation culture at your organization.
|
||||
|
||||
### **Future work 🔮**
|
||||
|
||||
Some of the following items are coming soon and some are potential ideas.
|
||||
|
||||
- [TechDocs Addon Framework](https://github.com/backstage/backstage/issues/9636)
|
||||
- Contribute to and deploy from a marketplace of TechDocs Addons
|
||||
- Addon: Highlight text and raise an Issue to create a feedback loop to drive up documentation quality
|
||||
- Addon: MDX (allows you to use JSX in your Markdown content)
|
||||
- Better integration with
|
||||
[Scaffolder V2](https://github.com/backstage/backstage/issues/2771) (e.g. easy to choose and plug documentation template with Software Templates)
|
||||
- Static site generator agnostic
|
||||
- Static site generator agnostic, including possible support for MDX (allowing you to use JSX in your Markdown content)
|
||||
- Possible to configure several aspects about TechDocs (e.g. URL, homepage,
|
||||
theme)
|
||||
|
||||
|
||||
@@ -0,0 +1,218 @@
|
||||
---
|
||||
id: addons
|
||||
title: TechDocs Addons
|
||||
description: How to find, use, or create TechDocs Addons.
|
||||
---
|
||||
|
||||
> Note: This page contains documentation for features that have not yet been
|
||||
> released on a [main-line version](https://backstage.io/docs/overview/versioning-policy#main-release-line)
|
||||
> of Backstage and TechDocs. We plan to make Addons generally available in
|
||||
> Backstage v1.2.
|
||||
|
||||
## Concepts
|
||||
|
||||
TechDocs is a centralized platform for publishing, viewing, and discovering
|
||||
technical documentation across an entire organization. It's a solid foundation!
|
||||
But it doesn't solve higher-order documentation needs on its own: how do you
|
||||
create and reinforce a culture of documentation? How do you build trust in the
|
||||
quality of technical documentation?
|
||||
|
||||
TechDocs Addons are a mechanism by which you can customize the TechDocs
|
||||
experience in order to try and address some of these higher-order needs.
|
||||
|
||||
### Addons
|
||||
|
||||
An Addon is just a react component. Like any react component, it can retrieve
|
||||
and render data using normal Backstage or native hooks, APIs, and components.
|
||||
Props can be used to configure its behavior, where appropriate.
|
||||
|
||||
### Locations
|
||||
|
||||
Addons declare a `location` where they will be rendered. Most locations are
|
||||
representative of physical spaces in the TechDocs UI:
|
||||
|
||||
- `Header`: For Addons which fill up the header from the right, on the same
|
||||
line as the title.
|
||||
- `Subheader`: For Addons that sit below the header but above all content.
|
||||
This is a great location for tooling/configuration of TechDocs display.
|
||||
- `PrimarySidebar`: Left of the content, above of the navigation.
|
||||
- `SecondarySidebar`: Right of the content, above the table of contents.
|
||||
- `Content`: A special location intended for Addons which augment the
|
||||
statically generated content of the documentation itself.
|
||||
- `Component`: A [proposed-but-not-yet-implemented](https://github.com/backstage/backstage/issues/11109)
|
||||
virtual location, aimed at simplifying a common type of Addon.
|
||||
|
||||
<img data-zoomable src="../../assets/techdocs/addon-locations.png" alt="TechDocs Addon Location Guide" />
|
||||
|
||||
### Addon Registry
|
||||
|
||||
The installation and configuration of Addons happens within a Backstage app's
|
||||
frontend. Addons are imported from plugins and added underneath a registry
|
||||
component called `<TechDocsAddons>`. This registry can be configured for both
|
||||
the TechDocs Reader page as well as the Entity docs page.
|
||||
|
||||
Addons are rendered in the order in which they are registered.
|
||||
|
||||
## Installing and using Addons
|
||||
|
||||
Addons can be installed and configured in much the same way as extensions for
|
||||
other Backstage plugins: by adding them underneath an extension registry
|
||||
component (`<TechDocsAddons>`) under the route representing the TechDocs Reader
|
||||
page in your `App.tsx`:
|
||||
|
||||
```tsx
|
||||
// packages/app/src/App.tsx
|
||||
|
||||
import { TechDocsReaderPage } from '@backstage/plugin-techdocs';
|
||||
import { TechDocsAddons } from '@backstage/plugin-techdocs-react/alpha';
|
||||
import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib';
|
||||
|
||||
// ...
|
||||
|
||||
<Route path="/docs/:namespace/:kind/:name/*" element={<TechDocsReaderPage />}>
|
||||
<TechDocsAddons>
|
||||
<ReportIssue />
|
||||
{/* Other addons can be added here. */}
|
||||
</TechDocsAddons>
|
||||
</Route>;
|
||||
```
|
||||
|
||||
The process for configuring Addons on the documentation tab on the entity page
|
||||
is very similar; instead of adding the `<TechDocsAddons>` registry under a
|
||||
`<Route>`, you'd add it as a child of `<EntityTechdocsContent />`:
|
||||
|
||||
```tsx
|
||||
// packages/app/src/components/catalog/EntityPage.tsx
|
||||
|
||||
import { EntityLayout } from '@backstage/plugin-catalog';
|
||||
import { EntityTechdocsContent } from '@backstage/plugin-techdocs';
|
||||
import { TechDocsAddons } from '@backstage/plugin-techdocs-react/alpha';
|
||||
import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib';
|
||||
|
||||
// ...
|
||||
|
||||
<EntityLayout.Route path="/docs" title="Docs">
|
||||
<EntityTechdocsContent>
|
||||
<TechDocsAddons>
|
||||
<ReportIssue />
|
||||
{/* Other addons can be added here. */}
|
||||
</TechDocsAddons>
|
||||
</EntityTechdocsContent>
|
||||
</EntityLayout.Route>;
|
||||
```
|
||||
|
||||
Note that on the entity page, because the Catalog plugin is responsible for the
|
||||
page header, TechDocs Addons whose location is `Header` will not be rendered.
|
||||
|
||||
## Available Addons
|
||||
|
||||
Addons can, in principle, be provided by any plugin! To make it easier to
|
||||
discover available Addons, we've compiled a list of them here:
|
||||
|
||||
| Addon | Package/Plugin | Description |
|
||||
| ---------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [`<ReportIssue />`](https://backstage.io/docs/reference/plugin-techdocs-module-addons-contrib.reportissue) | `@backstage/plugin-techdocs-module-addons-contrib` | Allows TechDocs users to select a portion of text on a TechDocs page and open an issue against the repository that contains the documentation, populating the issue description with the selected text according to a configurable template. |
|
||||
|
||||
Got an Addon to contribute? Feel free to add a row above!
|
||||
|
||||
## Creating an Addon
|
||||
|
||||
The simplest Addons are plain old react components that get rendered in
|
||||
specific locations within a TechDocs site. To package such a react component as
|
||||
an Addon, follow these steps:
|
||||
|
||||
1. Write the component in your plugin like any other component
|
||||
2. Create, provide, and export the component from your plugin
|
||||
|
||||
```ts
|
||||
// plugins/your-plugin/src/plugin.ts
|
||||
|
||||
import {
|
||||
createTechDocsAddonExtension,
|
||||
TechDocsAddonLocations,
|
||||
} from '@backstage/plugin-techdocs-react/alpha';
|
||||
import { CatGifComponent, CatGifComponentProps } from './addons';
|
||||
|
||||
// ...
|
||||
|
||||
// You must "provide" your Addon, just like any extension, via your plugin.
|
||||
export const CatGif = yourPlugin.provide(
|
||||
// This function "creates" the Addon given a component and location. If your
|
||||
// component can be configured via props, pass the prop type here too.
|
||||
createTechDocsAddonExtension<CatGifComponentProps>({
|
||||
name: 'CatGif',
|
||||
location: TechDocsAddonLocations.Header,
|
||||
component: CatGifComponent,
|
||||
}),
|
||||
);
|
||||
```
|
||||
|
||||
### Addons in the Content location
|
||||
|
||||
Beyond the "render a component in a region" use-case, it's also possible for
|
||||
Addons to access and manipulate a TechDocs site's DOM; this could be used to,
|
||||
for example, load and instantiate client-side diagramming libraries, replace
|
||||
elements with dynamically loaded content, etc.
|
||||
|
||||
This type of Addon is still expressed as a react component, but instead of
|
||||
returning a react element to be rendered, it updates the DOM via side-effects
|
||||
(e.g. with `useEffect`). Access to the DOM is made available via utility hooks
|
||||
provided by the Addon framework.
|
||||
|
||||
```tsx
|
||||
// plugins/your-plugin/src/addons/MakeAllImagesCatGifs.tsx
|
||||
|
||||
import React, { useEffect } from 'react';
|
||||
import { useShadowRootElements } from '@backstage/plugin-techdocs-react/alpha';
|
||||
|
||||
// This is a normal react component; in order to make it an Addon, you would
|
||||
// still create and provide it via your plugin as described above. The only
|
||||
// difference is that you'd set `location` to `TechDocsAddonLocations.Content`.
|
||||
export const MakeAllImagesCatGifsAddon = () => {
|
||||
// This hook can be used to get references to specific elements. If you need
|
||||
// access to the whole shadow DOM, use the the underlying useShadowRoot()
|
||||
// hook instead.
|
||||
const images = useShadowRootElements<HTMLImageElement>(['img']);
|
||||
|
||||
useEffect(() => {
|
||||
images.forEach(img => {
|
||||
if (img.src !== 'https://example.com/cat.gif') {
|
||||
img.src = 'https://example.com/cat.gif';
|
||||
}
|
||||
});
|
||||
}, [images]);
|
||||
|
||||
// Nothing to render directly, so we can just return null.
|
||||
return null;
|
||||
};
|
||||
```
|
||||
|
||||
### Testing Addons
|
||||
|
||||
Install `@backstage/plugin-techdocs-addons-test-utils` as a `devDependency` in
|
||||
your plugin for access to utilities that make testing such Addons easier.
|
||||
|
||||
A test for the above Addon might look something like this:
|
||||
|
||||
```tsx
|
||||
// plugins/your-plugin/src/addons/MakeAllImagesCatGifs.test.tsx
|
||||
import { TechDocsAddonTester } from '@backstage/plugin-techdocs-addons-test-utils';
|
||||
|
||||
// Note: import your actual addon (the one provided by your plugin).
|
||||
import { MakeAllImagesCatGifs } from '../plugin.ts';
|
||||
|
||||
describe('MakeAllImagesCatGifs', () => {
|
||||
it('replaces img srcs with cat gif', async () => {
|
||||
const { getByTestId } = await TechDocsAddonTester.buildAddonsInTechDocs([
|
||||
<MakeAllImagesCatGifs />,
|
||||
])
|
||||
.withDom(<img data-testid="fixture" src="http://example.com/dog.jpg" />)
|
||||
.renderWithEffects();
|
||||
|
||||
expect(getByTestId('fixture')).toHaveAttribute(
|
||||
'src',
|
||||
'https://example.com/cat.gif',
|
||||
);
|
||||
});
|
||||
});
|
||||
```
|
||||
@@ -18,8 +18,8 @@ GitLab, etc.) and passes the files to the generator for next steps.
|
||||
|
||||
There are two kinds of preparers available -
|
||||
|
||||
1. Common Git Preparer - Uses `git clone` on any repository url.
|
||||
2. Url Reader - Uses source code hosting provider's API to download files.
|
||||
1. Common Git Preparer - Uses `git clone` on any repository URL.
|
||||
2. URL Reader - Uses source code hosting provider's API to download files.
|
||||
(Faster and recommended)
|
||||
|
||||
### TechDocs Generator
|
||||
@@ -96,10 +96,6 @@ Documentation generated by TechDocs is generated as static HTML sites. The
|
||||
TechDocs Reader was therefore created to be able to integrate pre-generated HTML
|
||||
sites with the Backstage UI.
|
||||
|
||||
The TechDocs Reader purpose is also to open up the opportunity to integrate
|
||||
TechDocs widgets for a customized full-featured TechDocs experience.
|
||||
([coming soon V.3](./README.md#project-roadmap))
|
||||
|
||||
[TechDocs Reader](https://github.com/backstage/backstage/blob/master/plugins/techdocs/src/reader/README.md)
|
||||
|
||||
## Transformers
|
||||
@@ -110,3 +106,19 @@ transform the HTML content on pre and post render (e.g. rewrite docs links or
|
||||
modify css).
|
||||
|
||||
[Transformers API docs](https://github.com/backstage/backstage/blob/master/plugins/techdocs/src/reader/README.md)
|
||||
|
||||
## TechDocs Addons
|
||||
|
||||
Addons (introduced in Backstage v1.2) are client-side, React-based extensions
|
||||
that can be used to augment the TechDocs experience at read-time. They offer a
|
||||
mechanism for configuring the TechDocs Reader to better suit your
|
||||
organization's needs.
|
||||
|
||||
Addons can dynamically load and display information anywhere in the TechDocs
|
||||
Reader, including within the statically generated content itself.
|
||||
|
||||
Addons should not be confused with `mkdocs` plugins, which may be used to
|
||||
customize a TechDocs site's content at build-time. While it's possible to take
|
||||
advantage of some `mkdocs` plugins, not all such plugins play well with
|
||||
TechDocs (primarily, but not exclusively, for security reasons). Addons offer
|
||||
an alternative.
|
||||
|
||||
@@ -461,7 +461,7 @@ Since the new SDK doesn't use the old way authentication, we don't need the keys
|
||||
|
||||
The new SDK needs the OpenStack Swift connection URL for connecting the Swift.
|
||||
So you need to add a new key called `openStackSwift.swiftUrl` and give the
|
||||
OpenStack Swift url here. Example url should look like that:
|
||||
OpenStack Swift URL here. Example URL should look like that:
|
||||
`https://example.com:6780/swift/v1`
|
||||
|
||||
##### That's it!
|
||||
|
||||
@@ -24,7 +24,7 @@ the code.
|
||||
- [`.github/`](https://github.com/backstage/backstage/tree/master/.github) -
|
||||
Standard GitHub folder. It contains - amongst other things - our workflow
|
||||
definitions and templates. Worth noting is the
|
||||
[styles](https://github.com/backstage/backstage/tree/master/.github/styles)
|
||||
[vale](https://github.com/backstage/backstage/tree/master/.github/vale)
|
||||
sub-folder which is used for a markdown spellchecker.
|
||||
|
||||
- [`.yarn/`](https://github.com/backstage/backstage/tree/master/.yarn) -
|
||||
@@ -212,9 +212,6 @@ future.
|
||||
common for companies to have their own npm registry, and this file makes sure
|
||||
that this folder always uses the public registry.
|
||||
|
||||
- [`.vale.ini`](https://github.com/backstage/backstage/tree/master/.vale.ini) -
|
||||
[Spell checker](https://github.com/errata-ai/vale) for Markdown files.
|
||||
|
||||
- [`.yarnrc`](https://github.com/backstage/backstage/tree/master/.yarnrc) -
|
||||
Enforces "our" version of Yarn.
|
||||
|
||||
|
||||
@@ -70,8 +70,8 @@ builder.addEntityProvider(
|
||||
...AwsS3EntityProvider.fromConfig(env.config, {
|
||||
logger: env.logger,
|
||||
schedule: env.scheduler.createScheduledTaskRunner({
|
||||
frequency: Duration.fromObject({ minutes: 30 }),
|
||||
timeout: Duration.fromObject({ minutes: 3 }),
|
||||
frequency: { minutes: 30 },
|
||||
timeout: { minutes: 3 },
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -33,8 +33,8 @@ builder.addEntityProvider(
|
||||
...GerritEntityProvider.fromConfig(env.config, {
|
||||
logger: env.logger,
|
||||
schedule: env.scheduler.createScheduledTaskRunner({
|
||||
frequency: Duration.fromObject({ minutes: 30 }),
|
||||
timeout: Duration.fromObject({ minutes: 3 }),
|
||||
frequency: { minutes: 30 },
|
||||
timeout: { minutes: 3 },
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -34,9 +34,9 @@ a structure with up to six elements:
|
||||
- `baseUrl` (optional): Needed if the Gerrit instance is not reachable at
|
||||
the base of the `host` option (e.g. `https://gerrit.company.com`) set the
|
||||
address here. This is the address that you would open in a browser.
|
||||
- `cloneUrl` (optional): The base url for HTTP clones. Will default to `baseUrl` if
|
||||
- `cloneUrl` (optional): The base URL for HTTP clones. Will default to `baseUrl` if
|
||||
not set. The address used to clone a repo is the `cloneUrl` plus the repo name.
|
||||
- `gitilesBaseUrl` (optional): This is needed for creating a valid user-friendly url
|
||||
- `gitilesBaseUrl` (optional): This is needed for creating a valid user-friendly URL
|
||||
that can be used for browsing the content of the provider. If not set a default
|
||||
value will be created in the same way as the "baseUrl" option. There is no
|
||||
requirement to have Gitiles for the Backstage Gerrit integration but without it
|
||||
|
||||
+105
-16
@@ -19,22 +19,72 @@ entities that mirror your org setup.
|
||||
|
||||
## Installation
|
||||
|
||||
See the [discovery](discovery.md) article for installation instructions.
|
||||
This guide will use the Entity Provider method. If you for some reason prefer
|
||||
the Processor method (not recommended), it is described separately below.
|
||||
|
||||
The provider is not installed by default, therefore you have to add a dependency
|
||||
to `@backstage/plugin-catalog-backend-module-github` to your backend package.
|
||||
|
||||
```bash
|
||||
# From your Backstage root directory
|
||||
yarn add --cwd packages/backend @backstage/plugin-catalog-backend-module-github
|
||||
```
|
||||
|
||||
> Note: When configuring to use a Provider instead of a Processor you do not
|
||||
> need to add a _location_ pointing to your GitHub server/organization
|
||||
|
||||
Update the catalog plugin initialization in your backend to add the provider and
|
||||
schedule it:
|
||||
|
||||
```diff
|
||||
// packages/backend/src/plugins/catalog.ts
|
||||
+import { GitHubOrgEntityProvider } from '@backstage/plugin-catalog-backend-module-github';
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
): Promise<Router> {
|
||||
const builder = await CatalogBuilder.create(env);
|
||||
|
||||
+ // The org URL below needs to match a configured integrations.github entry
|
||||
+ // specified in your app-config.
|
||||
+ builder.addEntityProvider(
|
||||
+ GitHubOrgEntityProvider.fromConfig(env.config, {
|
||||
+ id: 'production',
|
||||
+ orgUrl: 'https://github.com/backstage',
|
||||
+ logger: env.logger,
|
||||
+ schedule: env.scheduler.createScheduledTaskRunner({
|
||||
+ frequency: { minutes: 60 },
|
||||
+ timeout: { minutes: 15 },
|
||||
+ }),
|
||||
+ }),
|
||||
+ );
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
The following configuration enables an import of the teams and users under the
|
||||
org `https://github.com/my-org-name` on public GitHub.
|
||||
As mentioned above, you also must have some configuration in your app-config
|
||||
that describes the targets that you want to import. This lets the entity
|
||||
provider know what authorization to use, and what the API endpoints are. You may
|
||||
or may not have such an entry already added since before:
|
||||
|
||||
```yaml
|
||||
catalog:
|
||||
locations:
|
||||
- type: github-org
|
||||
target: https://github.com/my-org-name
|
||||
rules:
|
||||
- allow: [User, Group]
|
||||
integrations:
|
||||
github:
|
||||
# example for public github
|
||||
- host: github.com
|
||||
token: ${GITHUB_TOKEN}
|
||||
# example for a private GitHub Enterprise instance
|
||||
- host: ghe.example.net
|
||||
apiBaseUrl: https://ghe.example.net/api/v3
|
||||
token: ${GHE_TOKEN}
|
||||
```
|
||||
|
||||
These examples use `${}` placeholders to reference environment variables. This
|
||||
is often suitable for production setups, but also means that you will have to
|
||||
supply those variables to the backend as it starts up. If you want, for local
|
||||
development in particular, you can experiment first by putting the actual tokens
|
||||
in a mirrored config directly in your `app-config.local.yaml` as well.
|
||||
|
||||
If Backstage is configured to use GitHub Apps authentication you must grant
|
||||
`Read-Only` access for `Members` under `Organization` in order to ingest users
|
||||
correctly. You can modify the app's permissions under the organization settings,
|
||||
@@ -47,11 +97,50 @@ that must be approved first before the changes are applied.**
|
||||
|
||||

|
||||
|
||||
Locations point out the specific org(s) you want to import. The `type` of these
|
||||
locations must be `github-org`, and the `target` must point to the exact URL of
|
||||
some organization. You can have several such location entries if needed.
|
||||
## Using a Processor instead of a Provider
|
||||
|
||||
The authorization for loading org information comes from a configured
|
||||
[GitHub integration](locations.md#configuration). When using a personal access
|
||||
token, the token needs to have at least the scopes `read:org`, `read:user`, and
|
||||
`user:email` in the given `target`.
|
||||
An alternative to using the Provider for ingesting organizational entities is to
|
||||
use a Processor. This is the old way that's based on registering locations with
|
||||
the proper type and target, triggering the processor to run.
|
||||
|
||||
The drawback of this method is that it will leave orphaned Group/User entities
|
||||
whenever they are deleted on your GitHub server, and you cannot control the
|
||||
frequency with which they are refreshed, separately from other processors.
|
||||
|
||||
### Processor Installation
|
||||
|
||||
The `GithubOrgReaderProcessor` is not registered by default, so you have to
|
||||
install and register it in the catalog plugin:
|
||||
|
||||
```bash
|
||||
# From your Backstage root directory
|
||||
yarn add --cwd packages/backend @backstage/plugin-catalog-backend-module-github
|
||||
```
|
||||
|
||||
```typescript
|
||||
// packages/backend/src/plugins/catalog.ts
|
||||
import { GithubOrgReaderProcessor } from '@backstage/plugin-catalog-backend-module-github';
|
||||
// ...
|
||||
builder.addProcessor(
|
||||
GithubOrgReaderProcessor.fromConfig(env.config, { logger: env.logger }),
|
||||
);
|
||||
```
|
||||
|
||||
### Processor Configuration
|
||||
|
||||
The integration section of your app-config needs to be set up in the same way as
|
||||
for the Entity Provider - see above.
|
||||
|
||||
In addition to that, you typically want to add a few static locations to your
|
||||
app-config, which reference your organizations to import. The following
|
||||
configuration enables an import of the teams and users under the org
|
||||
`https://github.com/my-org-name` on public GitHub.
|
||||
|
||||
```yaml
|
||||
catalog:
|
||||
locations:
|
||||
- type: github-org
|
||||
target: https://github.com/my-org-name
|
||||
rules:
|
||||
- allow: [User, Group]
|
||||
```
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user