diff --git a/.changeset/clever-trains-greet.md b/.changeset/clever-trains-greet.md
new file mode 100644
index 0000000000..dc75f2f02a
--- /dev/null
+++ b/.changeset/clever-trains-greet.md
@@ -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: [ /* ... */ ],
+ });
+```
diff --git a/.changeset/fair-pigs-mate.md b/.changeset/fair-pigs-mate.md
new file mode 100644
index 0000000000..ce82e138b8
--- /dev/null
+++ b/.changeset/fair-pigs-mate.md
@@ -0,0 +1,6 @@
+---
+'@backstage/plugin-tech-insights-node': minor
+---
+
+**BREAKING**: The `FactRetrieverContext` type now contains an additional
+field: `tokenManager`.
diff --git a/.changeset/grumpy-panthers-peel.md b/.changeset/grumpy-panthers-peel.md
new file mode 100644
index 0000000000..ecf4397554
--- /dev/null
+++ b/.changeset/grumpy-panthers-peel.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-tech-insights-backend-module-jsonfc': patch
+---
+
+Updated usages of `buildTechInsightsContext` in README.
diff --git a/.changeset/metal-hairs-build.md b/.changeset/metal-hairs-build.md
new file mode 100644
index 0000000000..9ed8bba01b
--- /dev/null
+++ b/.changeset/metal-hairs-build.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-rollbar-backend': patch
+---
+
+Updated README to include clearer installation instructions on how to install and configure.
diff --git a/ADOPTERS.md b/ADOPTERS.md
index acdfc4bf29..1013b18421 100644
--- a/ADOPTERS.md
+++ b/ADOPTERS.md
@@ -118,5 +118,7 @@ _If you're using Backstage in your organization, please try to add your company
| [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. |
-| [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. |
+| [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. |
+
diff --git a/docs/assets/techdocs/addon-locations.png b/docs/assets/techdocs/addon-locations.png
new file mode 100644
index 0000000000..e535fe61aa
Binary files /dev/null and b/docs/assets/techdocs/addon-locations.png differ
diff --git a/docs/auth/add-auth-provider.md b/docs/auth/add-auth-provider.md
index 07d6869fe3..068ba01460 100644
--- a/docs/auth/add-auth-provider.md
+++ b/docs/auth/add-auth-provider.md
@@ -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
}
diff --git a/docs/features/techdocs/README.md b/docs/features/techdocs/README.md
index 2ac90f791b..c64d0b785d 100644
--- a/docs/features/techdocs/README.md
+++ b/docs/features/techdocs/README.md
@@ -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 `` 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)
diff --git a/docs/features/techdocs/addons.md b/docs/features/techdocs/addons.md
new file mode 100644
index 0000000000..0fba3b92e3
--- /dev/null
+++ b/docs/features/techdocs/addons.md
@@ -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.
+
+
+
+### 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 ``. 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 (``) 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';
+
+// ...
+
+}>
+
+
+ {/* Other addons can be added here. */}
+
+;
+```
+
+The process for configuring Addons on the documentation tab on the entity page
+is very similar; instead of adding the `` registry under a
+``, you'd add it as a child of ``:
+
+```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';
+
+// ...
+
+
+
+
+
+ {/* Other addons can be added here. */}
+
+
+;
+```
+
+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 |
+| ---------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [``](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({
+ 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(['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([
+ ,
+ ])
+ .withDom(
)
+ .renderWithEffects();
+
+ expect(getByTestId('fixture')).toHaveAttribute(
+ 'src',
+ 'https://example.com/cat.gif',
+ );
+ });
+});
+```
diff --git a/docs/features/techdocs/concepts.md b/docs/features/techdocs/concepts.md
index e34f58bc70..c96db5e3b7 100644
--- a/docs/features/techdocs/concepts.md
+++ b/docs/features/techdocs/concepts.md
@@ -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.
diff --git a/microsite/sidebars.json b/microsite/sidebars.json
index 81ad453429..43e9dd3978 100644
--- a/microsite/sidebars.json
+++ b/microsite/sidebars.json
@@ -109,6 +109,7 @@
"features/techdocs/techdocs-overview",
"features/techdocs/getting-started",
"features/techdocs/concepts",
+ "features/techdocs/addons",
"features/techdocs/architecture",
"features/techdocs/creating-and-publishing",
"features/techdocs/configuration",
diff --git a/packages/backend/src/plugins/techInsights.ts b/packages/backend/src/plugins/techInsights.ts
index 94ce27656a..80ac559859 100644
--- a/packages/backend/src/plugins/techInsights.ts
+++ b/packages/backend/src/plugins/techInsights.ts
@@ -38,6 +38,7 @@ export default async function createPlugin(
database: env.database,
scheduler: env.scheduler,
discovery: env.discovery,
+ tokenManager: env.tokenManager,
factRetrievers: [
createFactRetrieverRegistration({
cadence: '1 1 1 * *', // Example cron, At 01:01 on day-of-month 1.
diff --git a/plugins/auth-backend/src/providers/auth0/provider.ts b/plugins/auth-backend/src/providers/auth0/provider.ts
index b4446caa95..3181314540 100644
--- a/plugins/auth-backend/src/providers/auth0/provider.ts
+++ b/plugins/auth-backend/src/providers/auth0/provider.ts
@@ -71,6 +71,8 @@ export class Auth0AuthProvider implements OAuthHandlers {
clientSecret: options.clientSecret,
callbackURL: options.callbackUrl,
domain: options.domain,
+ // We need passReqToCallback set to false to get params, but there's
+ // no matching type signature for that, so instead behold this beauty
passReqToCallback: false as true,
},
(
diff --git a/plugins/auth-backend/src/providers/bitbucket/provider.ts b/plugins/auth-backend/src/providers/bitbucket/provider.ts
index b149aa6d28..905181333a 100644
--- a/plugins/auth-backend/src/providers/bitbucket/provider.ts
+++ b/plugins/auth-backend/src/providers/bitbucket/provider.ts
@@ -94,9 +94,7 @@ export class BitbucketAuthProvider implements OAuthHandlers {
clientID: options.clientId,
clientSecret: options.clientSecret,
callbackURL: options.callbackUrl,
- // We need passReqToCallback set to false to get params, but there's
- // no matching type signature for that, so instead behold this beauty
- passReqToCallback: false as true,
+ passReqToCallback: false,
},
(
accessToken: any,
diff --git a/plugins/auth-backend/src/providers/google/provider.ts b/plugins/auth-backend/src/providers/google/provider.ts
index 66749c1177..233e28f750 100644
--- a/plugins/auth-backend/src/providers/google/provider.ts
+++ b/plugins/auth-backend/src/providers/google/provider.ts
@@ -73,9 +73,7 @@ export class GoogleAuthProvider implements OAuthHandlers {
clientID: options.clientId,
clientSecret: options.clientSecret,
callbackURL: options.callbackUrl,
- // We need passReqToCallback set to false to get params, but there's
- // no matching type signature for that, so instead behold this beauty
- passReqToCallback: false as true,
+ passReqToCallback: false,
},
(
accessToken: any,
diff --git a/plugins/auth-backend/src/providers/microsoft/provider.ts b/plugins/auth-backend/src/providers/microsoft/provider.ts
index 3c1110ab5e..0a4b67d667 100644
--- a/plugins/auth-backend/src/providers/microsoft/provider.ts
+++ b/plugins/auth-backend/src/providers/microsoft/provider.ts
@@ -83,7 +83,7 @@ export class MicrosoftAuthProvider implements OAuthHandlers {
callbackURL: options.callbackUrl,
authorizationURL: options.authorizationUrl,
tokenURL: options.tokenUrl,
- passReqToCallback: false as true,
+ passReqToCallback: false,
},
(
accessToken: any,
diff --git a/plugins/auth-backend/src/providers/oauth2/provider.ts b/plugins/auth-backend/src/providers/oauth2/provider.ts
index 8b0eac948a..8e0250cf2f 100644
--- a/plugins/auth-backend/src/providers/oauth2/provider.ts
+++ b/plugins/auth-backend/src/providers/oauth2/provider.ts
@@ -76,7 +76,7 @@ export class OAuth2AuthProvider implements OAuthHandlers {
callbackURL: options.callbackUrl,
authorizationURL: options.authorizationUrl,
tokenURL: options.tokenUrl,
- passReqToCallback: false as true,
+ passReqToCallback: false,
scope: options.scope,
customHeaders: options.includeBasicAuth
? {
diff --git a/plugins/auth-backend/src/providers/oidc/provider.ts b/plugins/auth-backend/src/providers/oidc/provider.ts
index ed6bdf8c34..aba9048cc7 100644
--- a/plugins/auth-backend/src/providers/oidc/provider.ts
+++ b/plugins/auth-backend/src/providers/oidc/provider.ts
@@ -146,7 +146,7 @@ export class OidcAuthProvider implements OAuthHandlers {
const strategy = new OidcStrategy(
{
client,
- passReqToCallback: false as true,
+ passReqToCallback: false,
},
(
tokenset: TokenSet,
diff --git a/plugins/auth-backend/src/providers/okta/provider.ts b/plugins/auth-backend/src/providers/okta/provider.ts
index f208564cb6..4e05ff4487 100644
--- a/plugins/auth-backend/src/providers/okta/provider.ts
+++ b/plugins/auth-backend/src/providers/okta/provider.ts
@@ -94,7 +94,7 @@ export class OktaAuthProvider implements OAuthHandlers {
clientSecret: options.clientSecret,
callbackURL: options.callbackUrl,
audience: options.audience,
- passReqToCallback: false as true,
+ passReqToCallback: false,
store: this.store,
response_type: 'code',
},
diff --git a/plugins/auth-backend/src/providers/onelogin/provider.ts b/plugins/auth-backend/src/providers/onelogin/provider.ts
index 06a57e4560..7dcc6455ac 100644
--- a/plugins/auth-backend/src/providers/onelogin/provider.ts
+++ b/plugins/auth-backend/src/providers/onelogin/provider.ts
@@ -71,7 +71,7 @@ export class OneLoginProvider implements OAuthHandlers {
clientID: options.clientId,
clientSecret: options.clientSecret,
callbackURL: options.callbackUrl,
- passReqToCallback: false as true,
+ passReqToCallback: false,
},
(
accessToken: any,
diff --git a/plugins/rollbar-backend/README.md b/plugins/rollbar-backend/README.md
index 2dcf6495dd..d28ee60181 100644
--- a/plugins/rollbar-backend/README.md
+++ b/plugins/rollbar-backend/README.md
@@ -4,6 +4,58 @@ Simple plugin that proxies requests to the [Rollbar](https://rollbar.com) API.
## Setup
+1. Install the plugin using:
+
+```bash
+# From your Backstage root directory
+yarn add --cwd packages/backend @backstage/plugin-rollbar-backend
+```
+
+2. Create a `rollbar.ts` file inside `packages/backend/src/plugins/`:
+
+```typescript
+import { createRouter } from '@backstage/plugin-rollbar-backend';
+import { Router } from 'express';
+import { PluginEnvironment } from '../types';
+
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise {
+ return await createRouter({
+ logger: env.logger,
+ config: env.config,
+ });
+}
+```
+
+3. Modify your `packages/backend/src/index.ts` to include:
+
+```diff
+ ...
+
+ import { Config } from '@backstage/config';
+ import app from './plugins/app';
++import rollbar from './plugins/rollbar';
+ import scaffolder from './plugins/scaffolder';
+
+ ...
+
+ async function main() {
+
+ ...
+
+ const authEnv = useHotMemoize(module, () => createEnv('auth'));
++ const rollbarEnv = useHotMemoize(module, () => createEnv('rollbar'));
+ const proxyEnv = useHotMemoize(module, () => createEnv('proxy'));
+
+ ...
+
+ const apiRouter = Router();
+ apiRouter.use('/catalog', await catalog(catalogEnv));
++ apiRouter.use('/rollbar', await rollbar(rollbarEnv));
+ apiRouter.use('/scaffolder', await scaffolder(scaffolderEnv));
+```
+
The following values are read from the configuration file.
```yaml
diff --git a/plugins/tech-insights-backend-module-jsonfc/README.md b/plugins/tech-insights-backend-module-jsonfc/README.md
index 70b2ef2c40..f61666d671 100644
--- a/plugins/tech-insights-backend-module-jsonfc/README.md
+++ b/plugins/tech-insights-backend-module-jsonfc/README.md
@@ -28,6 +28,7 @@ and modify the `techInsights.ts` file to contain a reference to the FactCheckers
config: env.config,
database: env.database,
discovery: env.discovery,
+ tokenManager: env.tokenManager,
factRetrievers: [myFactRetrieverRegistration],
+ factCheckerFactory: myFactCheckerFactory
});
diff --git a/plugins/tech-insights-backend/README.md b/plugins/tech-insights-backend/README.md
index ee6ef4c0cc..e88d150393 100644
--- a/plugins/tech-insights-backend/README.md
+++ b/plugins/tech-insights-backend/README.md
@@ -35,6 +35,7 @@ export default async function createPlugin(
database: env.database,
discovery: env.discovery,
scheduler: env.scheduler,
+ tokenManager: env.tokenManager,
factRetrievers: [], // Fact retrievers registrations you want tech insights to use
});
@@ -104,6 +105,7 @@ const builder = buildTechInsightsContext({
config: env.config,
database: env.database,
discovery: env.discovery,
+ tokenManager: env.tokenManager,
- factRetrievers: [],
+ factRetrievers: [myFactRetrieverRegistration],
});
@@ -119,6 +121,7 @@ const builder = buildTechInsightsContext({
config: env.config,
database: env.database,
discovery: env.discovery,
+ tokenManager: env.tokenManager,
- factRetrievers: [],
+ factRetrievers: process.env.MAIN_FACT_RETRIEVER_INSTANCE ? [myFactRetrieverRegistration] : [],
});
@@ -158,9 +161,12 @@ const myFactRetriever: FactRetriever = {
const catalogClient = new CatalogClient({
discoveryApi: discovery,
});
- const entities = await catalogClient.getEntities({
- filter: [{ kind: 'component' }],
- });
+ const entities = await catalogClient.getEntities(
+ {
+ filter: [{ kind: 'component' }],
+ },
+ { token },
+ );
/**
* snip: Do complex logic to retrieve facts from external system or calculate fact values
*/
@@ -214,6 +220,7 @@ and modify the `techInsights.ts` file to contain a reference to the FactChecker
config: env.config,
database: env.database,
discovery: env.discovery,
+ tokenManager: env.tokenManager,
factRetrievers: [myFactRetrieverRegistration],
+ factCheckerFactory: myFactCheckerFactory
});
@@ -273,6 +280,7 @@ export default async function createPlugin(
config: env.config,
database: env.database,
discovery: env.discovery,
+ tokenManager: env.tokenManager,
factRetrievers: [
createFactRetrieverRegistration({
cadence: '0 */6 * * *', // Run every 6 hours - https://crontab.guru/#0_*/6_*_*_*
diff --git a/plugins/tech-insights-backend/api-report.md b/plugins/tech-insights-backend/api-report.md
index 210aa50af9..9fee3be281 100644
--- a/plugins/tech-insights-backend/api-report.md
+++ b/plugins/tech-insights-backend/api-report.md
@@ -17,6 +17,7 @@ import { PluginEndpointDiscovery } from '@backstage/backend-common';
import { PluginTaskScheduler } from '@backstage/backend-tasks';
import { TechInsightCheck } from '@backstage/plugin-tech-insights-node';
import { TechInsightsStore } from '@backstage/plugin-tech-insights-node';
+import { TokenManager } from '@backstage/backend-common';
// @public
export const buildTechInsightsContext: <
@@ -95,6 +96,8 @@ export interface TechInsightsOptions<
logger: Logger;
// (undocumented)
scheduler: PluginTaskScheduler;
+ // (undocumented)
+ tokenManager: TokenManager;
}
// (No @packageDocumentation comment for this package)
diff --git a/plugins/tech-insights-backend/src/service/fact/FactRetrieverEngine.test.ts b/plugins/tech-insights-backend/src/service/fact/FactRetrieverEngine.test.ts
index 0617c0aedd..454711171f 100644
--- a/plugins/tech-insights-backend/src/service/fact/FactRetrieverEngine.test.ts
+++ b/plugins/tech-insights-backend/src/service/fact/FactRetrieverEngine.test.ts
@@ -22,7 +22,11 @@ import {
} from '@backstage/plugin-tech-insights-node';
import { FactRetrieverRegistry } from './FactRetrieverRegistry';
import { FactRetrieverEngine } from './FactRetrieverEngine';
-import { DatabaseManager, getVoidLogger } from '@backstage/backend-common';
+import {
+ DatabaseManager,
+ getVoidLogger,
+ ServerTokenManager,
+} from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { TestDatabaseId, TestDatabases } from '@backstage/backend-test-utils';
import { TaskScheduler } from '@backstage/backend-tasks';
@@ -129,6 +133,7 @@ describe('FactRetrieverEngine', () => {
factRetrieverContext: {
logger: getVoidLogger(),
config: ConfigReader.fromConfigs([]),
+ tokenManager: ServerTokenManager.noop(),
discovery: {
getBaseUrl: (_: string) => Promise.resolve('http://mock.url'),
getExternalBaseUrl: (_: string) => Promise.resolve('http://mock.url'),
diff --git a/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityMetadataFactRetriever.test.ts b/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityMetadataFactRetriever.test.ts
index 9d5c57637d..31400788b5 100644
--- a/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityMetadataFactRetriever.test.ts
+++ b/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityMetadataFactRetriever.test.ts
@@ -18,6 +18,7 @@ import { RELATION_OWNED_BY } from '@backstage/catalog-model';
import {
PluginEndpointDiscovery,
getVoidLogger,
+ ServerTokenManager,
} from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { GetEntitiesResponse } from '@backstage/catalog-client';
@@ -104,6 +105,7 @@ const handlerContext = {
discovery,
logger: getVoidLogger(),
config: ConfigReader.fromConfigs([]),
+ tokenManager: ServerTokenManager.noop(),
};
const entityFactRetriever = entityMetadataFactRetriever;
diff --git a/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityMetadataFactRetriever.ts b/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityMetadataFactRetriever.ts
index 26b1e4274b..caa19dbeaf 100644
--- a/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityMetadataFactRetriever.ts
+++ b/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityMetadataFactRetriever.ts
@@ -44,11 +44,19 @@ export const entityMetadataFactRetriever: FactRetriever = {
description: 'The entity has tags in metadata',
},
},
- handler: async ({ discovery, entityFilter }: FactRetrieverContext) => {
+ handler: async ({
+ discovery,
+ entityFilter,
+ tokenManager,
+ }: FactRetrieverContext) => {
+ const { token } = await tokenManager.getToken();
const catalogClient = new CatalogClient({
discoveryApi: discovery,
});
- const entities = await catalogClient.getEntities({ filter: entityFilter });
+ const entities = await catalogClient.getEntities(
+ { filter: entityFilter },
+ { token },
+ );
return entities.items.map((entity: Entity) => {
return {
diff --git a/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityOwnershipFactRetriever.test.ts b/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityOwnershipFactRetriever.test.ts
index 555f761ae8..7a77ef91c4 100644
--- a/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityOwnershipFactRetriever.test.ts
+++ b/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityOwnershipFactRetriever.test.ts
@@ -19,6 +19,7 @@ import { RELATION_OWNED_BY } from '@backstage/catalog-model';
import {
PluginEndpointDiscovery,
getVoidLogger,
+ ServerTokenManager,
} from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { GetEntitiesResponse } from '@backstage/catalog-client';
@@ -104,6 +105,7 @@ const handlerContext = {
discovery,
logger: getVoidLogger(),
config: ConfigReader.fromConfigs([]),
+ tokenManager: ServerTokenManager.noop(),
};
const entityFactRetriever = entityOwnershipFactRetriever;
diff --git a/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityOwnershipFactRetriever.ts b/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityOwnershipFactRetriever.ts
index b9a91e67f7..c1e9b2710e 100644
--- a/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityOwnershipFactRetriever.ts
+++ b/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityOwnershipFactRetriever.ts
@@ -42,11 +42,19 @@ export const entityOwnershipFactRetriever: FactRetriever = {
description: 'The spec.owner field is set and refers to a group',
},
},
- handler: async ({ discovery, entityFilter }: FactRetrieverContext) => {
+ handler: async ({
+ discovery,
+ entityFilter,
+ tokenManager,
+ }: FactRetrieverContext) => {
+ const { token } = await tokenManager.getToken();
const catalogClient = new CatalogClient({
discoveryApi: discovery,
});
- const entities = await catalogClient.getEntities({ filter: entityFilter });
+ const entities = await catalogClient.getEntities(
+ { filter: entityFilter },
+ { token },
+ );
return entities.items.map((entity: Entity) => {
return {
diff --git a/plugins/tech-insights-backend/src/service/fact/factRetrievers/techdocsFactRetriever.test.ts b/plugins/tech-insights-backend/src/service/fact/factRetrievers/techdocsFactRetriever.test.ts
index be9397942d..0c70f6c9f1 100644
--- a/plugins/tech-insights-backend/src/service/fact/factRetrievers/techdocsFactRetriever.test.ts
+++ b/plugins/tech-insights-backend/src/service/fact/factRetrievers/techdocsFactRetriever.test.ts
@@ -19,6 +19,7 @@ import { RELATION_OWNED_BY } from '@backstage/catalog-model';
import {
PluginEndpointDiscovery,
getVoidLogger,
+ ServerTokenManager,
} from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { GetEntitiesResponse } from '@backstage/catalog-client';
@@ -104,6 +105,7 @@ const handlerContext = {
discovery,
logger: getVoidLogger(),
config: ConfigReader.fromConfigs([]),
+ tokenManager: ServerTokenManager.noop(),
};
const entityFactRetriever = techdocsFactRetriever;
diff --git a/plugins/tech-insights-backend/src/service/fact/factRetrievers/techdocsFactRetriever.ts b/plugins/tech-insights-backend/src/service/fact/factRetrievers/techdocsFactRetriever.ts
index 2717f94475..6bc84f4aa9 100644
--- a/plugins/tech-insights-backend/src/service/fact/factRetrievers/techdocsFactRetriever.ts
+++ b/plugins/tech-insights-backend/src/service/fact/factRetrievers/techdocsFactRetriever.ts
@@ -40,11 +40,19 @@ export const techdocsFactRetriever: FactRetriever = {
description: 'The entity has a title in metadata',
},
},
- handler: async ({ discovery, entityFilter }: FactRetrieverContext) => {
+ handler: async ({
+ discovery,
+ entityFilter,
+ tokenManager,
+ }: FactRetrieverContext) => {
+ const { token } = await tokenManager.getToken();
const catalogClient = new CatalogClient({
discoveryApi: discovery,
});
- const entities = await catalogClient.getEntities({ filter: entityFilter });
+ const entities = await catalogClient.getEntities(
+ { filter: entityFilter },
+ { token },
+ );
return entities.items.map((entity: Entity) => {
return {
diff --git a/plugins/tech-insights-backend/src/service/router.test.ts b/plugins/tech-insights-backend/src/service/router.test.ts
index df2d471516..8513973598 100644
--- a/plugins/tech-insights-backend/src/service/router.test.ts
+++ b/plugins/tech-insights-backend/src/service/router.test.ts
@@ -19,6 +19,7 @@ import {
DatabaseManager,
getVoidLogger,
PluginDatabaseManager,
+ ServerTokenManager,
} from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import request from 'supertest';
@@ -74,6 +75,7 @@ describe('Tech Insights router tests', () => {
getBaseUrl: (_: string) => Promise.resolve('http://mock.url'),
getExternalBaseUrl: (_: string) => Promise.resolve('http://mock.url'),
},
+ tokenManager: ServerTokenManager.noop(),
});
const router = await createRouter({
diff --git a/plugins/tech-insights-backend/src/service/techInsightsContextBuilder.ts b/plugins/tech-insights-backend/src/service/techInsightsContextBuilder.ts
index 4f8f2ed928..e22bfbd253 100644
--- a/plugins/tech-insights-backend/src/service/techInsightsContextBuilder.ts
+++ b/plugins/tech-insights-backend/src/service/techInsightsContextBuilder.ts
@@ -21,6 +21,7 @@ import { Config } from '@backstage/config';
import {
PluginDatabaseManager,
PluginEndpointDiscovery,
+ TokenManager,
} from '@backstage/backend-common';
import {
FactChecker,
@@ -63,6 +64,7 @@ export interface TechInsightsOptions<
discovery: PluginEndpointDiscovery;
database: PluginDatabaseManager;
scheduler: PluginTaskScheduler;
+ tokenManager: TokenManager;
}
/**
@@ -104,6 +106,7 @@ export const buildTechInsightsContext = async <
database,
logger,
scheduler,
+ tokenManager,
} = options;
const factRetrieverRegistry = new FactRetrieverRegistry(factRetrievers);
@@ -121,6 +124,7 @@ export const buildTechInsightsContext = async <
config,
discovery,
logger,
+ tokenManager,
},
});
diff --git a/plugins/tech-insights-node/api-report.md b/plugins/tech-insights-node/api-report.md
index 7d9f2e00b7..bcccec65b5 100644
--- a/plugins/tech-insights-node/api-report.md
+++ b/plugins/tech-insights-node/api-report.md
@@ -10,6 +10,7 @@ import { Duration } from 'luxon';
import { DurationLike } from 'luxon';
import { Logger } from 'winston';
import { PluginEndpointDiscovery } from '@backstage/backend-common';
+import { TokenManager } from '@backstage/backend-common';
// @public
export type CheckValidationResponse = {
@@ -58,6 +59,7 @@ export type FactRetrieverContext = {
config: Config;
discovery: PluginEndpointDiscovery;
logger: Logger;
+ tokenManager: TokenManager;
entityFilter?:
| Record[]
| Record;
diff --git a/plugins/tech-insights-node/src/facts.ts b/plugins/tech-insights-node/src/facts.ts
index a5df4bae85..ffd3549bd5 100644
--- a/plugins/tech-insights-node/src/facts.ts
+++ b/plugins/tech-insights-node/src/facts.ts
@@ -15,7 +15,10 @@
*/
import { DateTime, Duration, DurationLike } from 'luxon';
import { Config } from '@backstage/config';
-import { PluginEndpointDiscovery } from '@backstage/backend-common';
+import {
+ PluginEndpointDiscovery,
+ TokenManager,
+} from '@backstage/backend-common';
import { Logger } from 'winston';
/**
@@ -135,6 +138,7 @@ export type FactRetrieverContext = {
config: Config;
discovery: PluginEndpointDiscovery;
logger: Logger;
+ tokenManager: TokenManager;
entityFilter?:
| Record[]
| Record;
diff --git a/yarn.lock b/yarn.lock
index 14680b9118..a8150451ea 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5041,9 +5041,9 @@
integrity sha512-6k/pU2jNlgYvKOy84vpCAZ8MGVwybvAdjzrh4UicCVOCPxz0LSBws1OE6O5TO4sPHaSw+yLfNzNK8RicGFc1Kw==
"@react-hookz/web@^13.0.0":
- version "13.2.1"
- resolved "https://registry.npmjs.org/@react-hookz/web/-/web-13.2.1.tgz#12b3bc30d2cced8b75690c6c3708f96cfdf58172"
- integrity sha512-ckHdvZ5rgblBscvHdPWAASH46FvfOGjnC+TG3ZtzkOEaYxFtXAzxgQyjjPS+veLuVEGLZ/9HdU6A2l24QBp+9w==
+ version "13.3.0"
+ resolved "https://registry.npmjs.org/@react-hookz/web/-/web-13.3.0.tgz#257e31049e92a121912fe1e67bdd01dbec5a203b"
+ integrity sha512-KswgkmqBVVDo6UnBFfssrojmDisogxC4jGZmd976R8YHoS3zdQJxjqICpOBSRohbRyYhYS9Cprw7BuV/CZcMaw==
dependencies:
"@react-hookz/deep-equal" "^1.0.1"
@@ -10337,9 +10337,9 @@ cypress-plugin-snapshots@^1.4.4:
unidiff "1.0.2"
cypress@^9.5.0:
- version "9.5.4"
- resolved "https://registry.npmjs.org/cypress/-/cypress-9.5.4.tgz#49d9272f62eba12f2314faf29c2a865610e87550"
- integrity sha512-6AyJAD8phe7IMvOL4oBsI9puRNOWxZjl8z1lgixJMcgJ85JJmyKeP6uqNA0dI1z14lmJ7Qklf2MOgP/xdAqJ/Q==
+ version "9.6.0"
+ resolved "https://registry.npmjs.org/cypress/-/cypress-9.6.0.tgz#84473b3362255fa8f5e627a596e58575c9e5320f"
+ integrity sha512-nNwt9eBQmSENamwa8LxvggXksfyzpyYaQ7lNBLgks3XZ6dPE/6BCQFBzeAyAPt/bNXfH3tKPkAyhiAZPYkWoEg==
dependencies:
"@cypress/request" "^2.88.10"
"@cypress/xvfb" "^1.2.4"
@@ -14421,9 +14421,9 @@ inquirer@^7.3.3:
through "^2.3.6"
inquirer@^8.0.0, inquirer@^8.1.1, inquirer@^8.2.0:
- version "8.2.2"
- resolved "https://registry.npmjs.org/inquirer/-/inquirer-8.2.2.tgz#1310517a87a0814d25336c78a20b44c3d9b7629d"
- integrity sha512-pG7I/si6K/0X7p1qU+rfWnpTE1UIkTONN1wxtzh0d+dHXtT/JG6qBgLxoyHVsQa8cFABxAPh0pD6uUUHiAoaow==
+ version "8.2.3"
+ resolved "https://registry.npmjs.org/inquirer/-/inquirer-8.2.3.tgz#9c0b8a3fda91fdb00590557ec8530160e908c6e7"
+ integrity sha512-jmoBlmWUChXgVi1wGDZsD7pWCaibJKmL+8+E2jaiWiRj8OlJLwQdQQS2CIjgvdg8UUHX+oyagQKicVVcqwxi9Q==
dependencies:
ansi-escapes "^4.2.1"
chalk "^4.1.1"
@@ -14439,6 +14439,7 @@ inquirer@^8.0.0, inquirer@^8.1.1, inquirer@^8.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"
through "^2.3.6"
+ wrap-ansi "^7.0.0"
internal-slot@^1.0.3:
version "1.0.3"
@@ -21288,9 +21289,9 @@ react-virtualized-auto-sizer@^1.0.6:
integrity sha512-7tQ0BmZqfVF6YYEWcIGuoR3OdYe8I/ZFbNclFlGOC3pMqunkYF/oL30NCjSGl9sMEb17AnzixDz98Kqc3N76HQ==
react-window@^1.8.6:
- version "1.8.6"
- resolved "https://registry.npmjs.org/react-window/-/react-window-1.8.6.tgz#d011950ac643a994118632665aad0c6382e2a112"
- integrity sha512-8VwEEYyjz6DCnGBsd+MgkD0KJ2/OXFULyDtorIiTz+QzwoP94tBoA7CnbtyXMm+cCeAUER5KJcPtWl9cpKbOBg==
+ version "1.8.7"
+ resolved "https://registry.npmjs.org/react-window/-/react-window-1.8.7.tgz#5e9fd0d23f48f432d7022cdb327219353a15f0d4"
+ integrity sha512-JHEZbPXBpKMmoNO1bNhoXOOLg/ujhL/BU4IqVU9r8eQPcy5KQnGHIHDRkJ0ns9IM5+Aq5LNwt3j8t3tIrePQzA==
dependencies:
"@babel/runtime" "^7.0.0"
memoize-one ">=3.1.1 <6"