Merge branch 'master' into hchb/azgittags

This commit is contained in:
mo
2022-05-04 13:40:50 -05:00
473 changed files with 9214 additions and 2573 deletions
+5
View File
@@ -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/*`).
+5
View File
@@ -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.
+5
View File
@@ -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.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-api-docs': patch
---
Updated dependency `graphiql` to `^1.8.8`.
+20
View File
@@ -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: [ /* ... */ ],
});
```
+5
View File
@@ -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`.
+5
View File
@@ -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.
+18
View File
@@ -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
});
```
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/core-components': patch
---
Announce external links to screen readers
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli': patch
---
Fixed coverage configuration when using `BACKSTAGE_NEXT_TESTS`.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-common': patch
---
Update types to match the new version of `@keyv/redis`
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/plugin-tech-insights-node': minor
---
**BREAKING**: The `FactRetrieverContext` type now contains an additional
field: `tokenManager`.
+36
View File
@@ -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 },
});
```
+5
View File
@@ -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.
+18
View File
@@ -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
```
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli': patch
---
Extended lint rule to prevents imports of stories or tests from production code.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-tech-insights-backend-module-jsonfc': patch
---
Updated usages of `buildTechInsightsContext` in README.
+5
View File
@@ -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.
+24
View File
@@ -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,
}),
);
```
+9
View File
@@ -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.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-user-settings': patch
---
Added alternative text to profile picture
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend-module-gerrit': patch
---
Fix incorrect main path in `publishConfig`
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/core-components': patch
---
Added optional anchorOrigin alignment prop to AlertDisplay
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder': patch
---
Allow validation for custom field extension with type object
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend': patch
---
Minor internal tweak to support TypeScript 4.6
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-rollbar-backend': patch
---
Updated README to include clearer installation instructions on how to install and configure.
+5
View File
@@ -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.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/core-components': patch
---
Add an aria-label to the support button to improve accessibility for screen readers
+6
View File
@@ -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.
+5
View File
@@ -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
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-react': patch
---
Added menu parent role for menu items accessibility
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-org': patch
---
Fix linking ownership card to catalog owner filter when namespaces are used
+49 -1
View File
@@ -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"
]
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-api-docs': patch
---
Updated dependency `@asyncapi/react-component` to `1.0.0-next.37`.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder': patch
---
Updated dependency `use-immer` to `^0.7.0`.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-api-docs': patch
---
Updated dependency `@asyncapi/react-component` to `1.0.0-next.38`.
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/plugin-scaffolder': patch
'@backstage/plugin-techdocs': patch
---
Updated dependency `event-source-polyfill` to `1.0.26`.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder': patch
---
Updated dependency `@codemirror/legacy-modes` to `^0.20.0`.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-graphiql': patch
---
Updated dependency `@types/codemirror` to `^0.0.109`.
+7
View File
@@ -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.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli': patch
---
Added the ability to help a user get started with a new organization
+5
View File
@@ -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`.
+28
View File
@@ -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"
}
```
+20
View File
@@ -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>;
```
+5
View File
@@ -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.
+6
View File
@@ -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.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli': patch
---
Updated `create-github-app` command to prompt for read or write permissions to simplify setup.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-tasks': patch
---
Correctly set next run time for tasks
+15
View File
@@ -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"
},
```
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-react': patch
---
Make Menu item on filters accessible through keyboard
+2 -2
View File
@@ -3,6 +3,6 @@ docs
cypress
microsite
node_modules
packages
!packages/backend/dist
packages/*/src
packages/*/node_modules
plugins
+2
View File
@@ -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
+6
View File
@@ -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));
}
+2 -2
View File
@@ -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 }}
+2 -2
View File
@@ -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 }}
+4 -4
View File
@@ -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'
})
+2 -2
View File
@@ -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 }}
+11 -3
View File
@@ -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 }}
+6 -2
View File
@@ -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] }}
+2 -2
View File
@@ -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 }}
+1 -1
View File
@@ -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') }}
+1
View File
@@ -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
View File
@@ -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 teams engineering dependencies. |
| [Oriflame](https://www.oriflame.com/) | [Oriflame](https://github.com/oriflame) | Internal developer portal for services, single page apps and packages overview, API documentation, technical guides, tech-radar and more. |
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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!).
![image](https://user-images.githubusercontent.com/4984472/133120461-59d74c3e-ebd9-44f9-900d-cc30f54a3cd2.png)
+2
View File
@@ -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:
+11
View File
@@ -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
View File
@@ -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

+2 -2
View File
@@ -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.
+1 -1
View File
@@ -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).
+11 -28
View File
@@ -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.
+45 -2
View File
@@ -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
+59
View File
@@ -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
+28 -62
View File
@@ -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.
+101
View File
@@ -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]);
```
+1 -1
View File
@@ -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`:
+2 -2
View File
@@ -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
```
+12 -15
View File
@@ -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({
+15 -2
View File
@@ -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 },
+ });
```
+7 -5
View File
@@ -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)
+218
View File
@@ -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 -6
View File
@@ -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!
+1 -4
View File
@@ -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.
+2 -2
View File
@@ -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 },
}),
}),
);
+2 -2
View File
@@ -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 },
}),
}),
);
+2 -2
View File
@@ -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
View File
@@ -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.**
![email](../../assets/integrations/github/email.png)
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