Merge remote-tracking branch 'origin/master' into reconfigure
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-org': patch
|
||||
---
|
||||
|
||||
Fixed overflow bug of name and email on EntitiyMembersListCard component which can occur on specific 'screen width' + ’character length' combinations
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/integration': minor
|
||||
---
|
||||
|
||||
added the possibility to handle raw Gitlab URLs with nested namespaces
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
Create a menu in the sub header of documentation pages, it is responsible for rendering TechDocs addons that allow users to customize their reading experience.
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
'@backstage/plugin-kubernetes': patch
|
||||
'@backstage/plugin-kubernetes-backend': patch
|
||||
'@backstage/plugin-kubernetes-common': patch
|
||||
---
|
||||
|
||||
Add support for 'oidc' as authProvider for kubernetes authentication
|
||||
and adds optional 'oidcTokenProvider' config value. This will allow
|
||||
users to authenticate to kubernetes cluster using id tokens obtained
|
||||
from the configured auth provider in their backstage instance.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
---
|
||||
|
||||
Add ability to customize `Read More` destination with `readMoreUrl` prop for `MissingAnnotationEmptyState` component.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
---
|
||||
|
||||
Don't set the background color on an Avatar component that has a picture.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-module-addons-contrib': patch
|
||||
---
|
||||
|
||||
Improved inline/type documentation for the <ReportIssue /> addon.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-auth-backend': patch
|
||||
---
|
||||
|
||||
The Auth0 adapter no longer disables session refreshing.
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-react': patch
|
||||
---
|
||||
|
||||
Create a new addon location called "Settings", it is designed for addons that allow users to customize the reading experience in documentation pages.
|
||||
|
||||
Usage example:
|
||||
|
||||
```tsx
|
||||
const TextSize = techdocsModuleAddonsContribPlugin.provide(
|
||||
createTechDocsAddonExtension({
|
||||
name: 'TextSize',
|
||||
location: TechDocsAddonLocations.Settings,
|
||||
component: TextSizeAddon,
|
||||
}),
|
||||
);
|
||||
```
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
'@backstage/backend-common': patch
|
||||
---
|
||||
|
||||
**DEPRECATION**: Server-to-server authentication tokens issued from a
|
||||
`TokenManager` (specifically, `ServerTokenManager`) now has an expiry time set,
|
||||
for one hour in the future from when issued. This improves security. The ability
|
||||
to pass in and validate tokens that either have a missing `exp` claim, or an
|
||||
`exp` claim that expired in the past, is now deprecated. Trying to do so will
|
||||
lead to logged warnings, and in a future release will instead lead to errors.
|
||||
|
||||
It was always the case that users of this interface were expected to call its
|
||||
`getToken()` method for every outgoing call and never hold on to any given token
|
||||
for reuse. But this now has become even more important advice to heed, and you
|
||||
should verify that you do not hold on to and reuse tokens such as these in your
|
||||
own code.
|
||||
+47
-3
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"mode": "pre",
|
||||
"mode": "exit",
|
||||
"tag": "next",
|
||||
"initialVersions": {
|
||||
"example-app": "0.2.70",
|
||||
@@ -151,36 +151,53 @@
|
||||
"@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"
|
||||
"@backstage/plugin-techdocs-addons-test-utils": "0.0.0",
|
||||
"@backstage/plugin-codescene": "0.0.0"
|
||||
},
|
||||
"changesets": [
|
||||
"afraid-insects-do",
|
||||
"backend-common-slips-away",
|
||||
"backend-common-twist-your-ankle",
|
||||
"beige-glasses-swim",
|
||||
"beige-panthers-dream",
|
||||
"big-teachers-dress",
|
||||
"brave-starfishes-try",
|
||||
"breezy-days-prove",
|
||||
"bright-panthers-guess",
|
||||
"chatty-forks-bathe",
|
||||
"chatty-pears-nail",
|
||||
"clever-trains-greet",
|
||||
"cool-mice-sit",
|
||||
"cool-ties-share",
|
||||
"curly-parrots-applaud",
|
||||
"cyan-boxes-double",
|
||||
"dirty-clocks-poke",
|
||||
"dirty-ducks-suffer",
|
||||
"dirty-eagles-hunt",
|
||||
"dull-waves-marry",
|
||||
"early-crabs-help",
|
||||
"early-lemons-add",
|
||||
"eighty-chicken-retire",
|
||||
"empty-mugs-bow",
|
||||
"empty-planes-destroy",
|
||||
"empty-poems-lick",
|
||||
"fair-kings-retire",
|
||||
"fair-pigs-mate",
|
||||
"fast-stingrays-guess",
|
||||
"fluffy-poems-sell",
|
||||
"fluffy-sloths-deliver",
|
||||
"fresh-panthers-arrive",
|
||||
"funny-lamps-turn",
|
||||
"fuzzy-seahorses-teach",
|
||||
"gentle-penguins-kick",
|
||||
"giant-cheetahs-thank",
|
||||
"good-beans-knock",
|
||||
"grumpy-panthers-peel",
|
||||
"hip-adults-collect",
|
||||
"hip-monkeys-hide",
|
||||
"honest-kids-live",
|
||||
"hot-peaches-give",
|
||||
"hungry-chefs-return",
|
||||
"hungry-goats-mate",
|
||||
"kind-cats-clap",
|
||||
"lazy-zebras-pay",
|
||||
@@ -196,6 +213,7 @@
|
||||
"nasty-humans-give",
|
||||
"nasty-paws-move",
|
||||
"new-beds-argue",
|
||||
"nice-parrots-lie",
|
||||
"nine-actors-fly",
|
||||
"nine-geese-rest",
|
||||
"odd-apples-smash",
|
||||
@@ -204,14 +222,27 @@
|
||||
"perfect-penguins-rescue",
|
||||
"pink-mayflies-rhyme",
|
||||
"polite-planets-learn",
|
||||
"pretty-readers-grow",
|
||||
"renovate-05696d1",
|
||||
"renovate-4b92131",
|
||||
"renovate-5970cc2",
|
||||
"renovate-759d9d5",
|
||||
"renovate-9466904",
|
||||
"renovate-abcbd6e",
|
||||
"renovate-abcbd6e2",
|
||||
"renovate-b063c4b",
|
||||
"renovate-bf43c44",
|
||||
"renovate-bf63f74",
|
||||
"renovate-ca619fc",
|
||||
"rotten-impalas-clap",
|
||||
"search-dry-wolves-join",
|
||||
"search-heavy-llamas-worry",
|
||||
"search-the-worst-of-you",
|
||||
"serious-apricots-collect",
|
||||
"seven-deers-rule",
|
||||
"seven-panthers-pump",
|
||||
"shiny-apes-design",
|
||||
"shiny-moles-study",
|
||||
"shiny-students-approve",
|
||||
"short-chicken-act",
|
||||
"short-dodos-sparkle",
|
||||
@@ -219,9 +250,11 @@
|
||||
"silver-readers-deliver",
|
||||
"six-buckets-tap",
|
||||
"sixty-llamas-change",
|
||||
"small-eggs-guess",
|
||||
"smart-ghosts-search",
|
||||
"spotty-plums-rule",
|
||||
"stale-pigs-reply",
|
||||
"stale-pugs-kiss",
|
||||
"strong-mangos-sell",
|
||||
"swift-bugs-share",
|
||||
"swift-parrots-hammer",
|
||||
@@ -229,16 +262,27 @@
|
||||
"tasty-drinks-teach",
|
||||
"techdocs-changeset-not-found",
|
||||
"techdocs-five-hundred-ml",
|
||||
"techdocs-hot-berries-collect",
|
||||
"techdocs-loose-seal-blooth",
|
||||
"techdocs-low-calorie-drink",
|
||||
"techdocs-money-banana-stand",
|
||||
"techdocs-nice-boats-wonder",
|
||||
"techdocs-quick-owls-smile",
|
||||
"techdocs-touch-screen-wipes",
|
||||
"techdocs-vitamin-well-reload",
|
||||
"thick-bees-brush",
|
||||
"thick-tools-dream",
|
||||
"three-tips-hunt",
|
||||
"tough-forks-carry",
|
||||
"tricky-laws-thank",
|
||||
"tricky-phones-sing",
|
||||
"violet-steaks-knock",
|
||||
"warm-suns-wonder",
|
||||
"wicked-vans-press",
|
||||
"wild-pigs-work",
|
||||
"wise-emus-wait"
|
||||
"wise-countries-watch",
|
||||
"wise-doors-hammer",
|
||||
"wise-emus-wait",
|
||||
"witty-lions-reply"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-search-backend-module-elasticsearch': patch
|
||||
---
|
||||
|
||||
Fix issue where `nextPageCursor` is defined on the last page of results
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
---
|
||||
|
||||
Update the rendering of links in the entity inspector so that values starting with `https?://` are rendered as links as well.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-codescene': patch
|
||||
---
|
||||
|
||||
Updated dependency `@testing-library/user-event` to `^14.0.0`.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
Updated dependency `event-source-polyfill` to `1.0.26`.
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
'@backstage/plugin-codescene': patch
|
||||
'@backstage/plugin-sonarqube': patch
|
||||
---
|
||||
|
||||
Updated dependency `rc-progress` to `3.3.2`.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
'@backstage/plugin-catalog': patch
|
||||
---
|
||||
|
||||
Sidebar NAV now includes aria-label. Component AboutField now uses h2 variant instead of subtitle2 (font properties unchanged)
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-search': patch
|
||||
---
|
||||
|
||||
Introduced a `<SearchModalProvider>`, which can optionally be placed higher up in the react tree in order to allow control of search modal visibility from outside the modal itself.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
---
|
||||
|
||||
Fixed multiple scrolls appearing on Page when added InfoCard with external bottom link
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
---
|
||||
|
||||
Add ARIA landmark( <main>), & label and a heading to OAuthRequestDialog. Removed nested interactive control (button).
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend': patch
|
||||
---
|
||||
|
||||
Updated parseEntityTransformParams to handle keys with '.' in them. This will allow for querying of entities based off annotations such as 'backstage.io/orgin-location' or other entity field keys that have '.' in them.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
---
|
||||
|
||||
Properly highlight `SidebarSubmenuItem` dropdown items on hover, use ellipsis styling on long labels in `SidebarSubmenu`, allow `icon` and `to` properties to be optional on `SidebarSubmenuItem`, and fix `SidebarPage` padding to be responsive to pinned state
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-graph': patch
|
||||
---
|
||||
|
||||
Fix kind filter error in the dev app
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-app-api': patch
|
||||
---
|
||||
|
||||
Fix SAML session schema to no longer require the (deprecated) id, to unbreak session data storage.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
---
|
||||
|
||||
Add controls to Storybook stories
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-module-addons-contrib': patch
|
||||
---
|
||||
|
||||
Create a TechDocs `<TextSize/>` addon that allows users to set a font size in the browser's local storage for the text of documentation pages.
|
||||
|
||||
Here's an example on how to use it in a Backstage app:
|
||||
|
||||
```diff
|
||||
import {
|
||||
DefaultTechDocsHome,
|
||||
TechDocsIndexPage,
|
||||
TechDocsReaderPage,
|
||||
} from '@backstage/plugin-techdocs';
|
||||
import { TechDocsAddons } from '@backstage/plugin-techdocs-react/alpha';
|
||||
+import { TextSize } from '@backstage/plugin-techdocs-module-addons-contrib';
|
||||
|
||||
const AppRoutes = () => {
|
||||
<FlatRoutes>
|
||||
// other plugin routes
|
||||
<Route path="/docs" element={<TechDocsIndexPage />}>
|
||||
<DefaultTechDocsHome />
|
||||
</Route>
|
||||
<Route
|
||||
path="/docs/:namespace/:kind/:name/*"
|
||||
element={<TechDocsReaderPage />}
|
||||
>
|
||||
<TechDocsAddons>
|
||||
+ <TextSize />
|
||||
</TechDocsAddons>
|
||||
</Route>
|
||||
</FlatRoutes>;
|
||||
};
|
||||
```
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
'@backstage/create-app': patch
|
||||
---
|
||||
|
||||
Integrates TechDocs add-ons with the app package so add-ons are configured when creating an app using the Backstage CLI. To apply these changes to an existing application do the following:
|
||||
|
||||
1. Add the `@backstage/plugin-techdocs-react` and `@backstage/plugin-techdocs-module-addons-contrib` packages to your app's dependencies;
|
||||
2. And then register the `<ReportIssue/ >` Addon in your `packages/app/src/App.tsx` file, there where you define a route to `<TechDocsReaderPage />`:
|
||||
|
||||
```diff
|
||||
import {
|
||||
DefaultTechDocsHome,
|
||||
TechDocsIndexPage,
|
||||
TechDocsReaderPage,
|
||||
} from '@backstage/plugin-techdocs';
|
||||
+ import { TechDocsAddons } from '@backstage/plugin-techdocs-react';
|
||||
+ import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib';
|
||||
|
||||
// ...
|
||||
|
||||
const AppRoutes = () => {
|
||||
<FlatRoutes>
|
||||
// ... other plugin routes
|
||||
<Route path="/docs" element={<TechDocsIndexPage />}>
|
||||
<DefaultTechDocsHome />
|
||||
</Route>
|
||||
<Route
|
||||
path="/docs/:namespace/:kind/:name/*"
|
||||
element={<TechDocsReaderPage />}
|
||||
>
|
||||
+ <TechDocsAddons>
|
||||
+ <ReportIssue />
|
||||
+ </TechDocsAddons>
|
||||
</Route>
|
||||
</FlatRoutes>;
|
||||
};
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-home': patch
|
||||
---
|
||||
|
||||
Display entity titles in `StarredEntities` home page card (if defined) and don't show entities which no longer exist
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
---
|
||||
|
||||
Fix `EntityTypeFilter` so generating available types is case insensitive
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-graphiql': patch
|
||||
'@backstage/plugin-api-docs': patch
|
||||
---
|
||||
|
||||
Add the dependency `graphql-ws` to fix the latest release of `@graphiql/toolkit` that has a missing dependency
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-react': major
|
||||
'@backstage/plugin-techdocs-addons-test-utils': major
|
||||
'@backstage/plugin-techdocs-module-addons-contrib': major
|
||||
---
|
||||
|
||||
The TechDocs Addon framework is now generally available.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
Add a `sub-route` path on the EntityDocs page to fix the blank screen error when navigating using sidebar links.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
Loading SVGs correctly with `bota` with extended characters
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-react': patch
|
||||
---
|
||||
|
||||
Added overload signatures for `createTechDocsAddonExtension` to handle TechDocs addons without props.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-node': patch
|
||||
---
|
||||
|
||||
Updated the default version of the `@spotify/techdocs` container used when `techdocs.generator.runIn` is `docker` to `v1.0.3`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-addons-test-utils': patch
|
||||
---
|
||||
|
||||
Fixed a bug preventing testing of TechDocs Addons whose dom contained `<img />` tags.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-addons-test-utils': patch
|
||||
---
|
||||
|
||||
The `TechDocsAddonTester` class may now be extended if custom test configuration is needed.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-backend': patch
|
||||
---
|
||||
|
||||
Fixed a bug that could cause TechDocs index generation to hang and fail when an underlying TechDocs site's `search_index.json` was empty.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
Hidden exports related to experimental TechDocs reader functionality have been removed and can no longer be imported. In the unlikely event you were using these exports, you can now take advantage of the officially supported and generally available TechDocs Addon framework instead.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@techdocs/cli': patch
|
||||
---
|
||||
|
||||
Update `techdocs-cli serve`'s `proxyEndpoint` to match the base URL of the embedded techdocs app.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-module-addons-contrib': patch
|
||||
---
|
||||
|
||||
Introducing the Expandable Navigation addon, which lets you expand and collapse the TechDocs main navigation and store your preference in local storage.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-addons-test-utils': patch
|
||||
---
|
||||
|
||||
Fixed a type bug preventing `buildAddonsInTechDocs().withApis()` from being called with multiple partial API implementations.
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
'@backstage/create-app': patch
|
||||
---
|
||||
|
||||
Implement highlighting matching terms in search results. To enable this for an existing app, make the following changes:
|
||||
|
||||
```diff
|
||||
// packages/app/src/components/search/SearchPage.tsx
|
||||
...
|
||||
- {results.map(({ type, document }) => {
|
||||
+ {results.map(({ type, document, highlight }) => {
|
||||
switch (type) {
|
||||
case 'software-catalog':
|
||||
return (
|
||||
<CatalogSearchResultListItem
|
||||
key={document.location}
|
||||
result={document}
|
||||
+ highlight={highlight}
|
||||
/>
|
||||
);
|
||||
case 'techdocs':
|
||||
return (
|
||||
<TechDocsSearchResultListItem
|
||||
key={document.location}
|
||||
result={document}
|
||||
+ highlight={highlight}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<DefaultResultListItem
|
||||
key={document.location}
|
||||
result={document}
|
||||
+ highlight={highlight}
|
||||
/>
|
||||
);
|
||||
}
|
||||
})}
|
||||
...
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
---
|
||||
|
||||
Added a chevron Indicator when the sidebar is collapsed and has a sub-menu
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
'@backstage/plugin-catalog': patch
|
||||
'@backstage/plugin-search': patch
|
||||
'@backstage/plugin-search-react': patch
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
Updated search result components to support rendering content with highlighted matched terms
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-auth-backend': minor
|
||||
---
|
||||
|
||||
Removed the explicit `disableRefresh` option from `OAuthAdapter`. Refresh can still be disabled for a provider by not implementing the `refresh` method.
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@backstage/plugin-search-backend-module-elasticsearch': patch
|
||||
'@backstage/plugin-search-backend-node': patch
|
||||
'@backstage/plugin-search-common': patch
|
||||
---
|
||||
|
||||
Support generating highlighted matched terms in search result data
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-org': patch
|
||||
---
|
||||
|
||||
Include namespace in `MyGroupSidebarItem` if not default and remove root item routing if there are multiple groups
|
||||
@@ -3,7 +3,7 @@
|
||||
extends: ['config:base', ':disableDependencyDashboard', ':gitSignOff'],
|
||||
rangeStrategy: 'update-lockfile',
|
||||
// @elastic/elasticsearch is ignored due to licensing issues. See #10992
|
||||
ignoreDeps: ['@elastic/elasticsearch'],
|
||||
ignoreDeps: ['@elastic/elasticsearch', 'event-source-polyfill'],
|
||||
packageRules: [
|
||||
{
|
||||
matchSourceUrlPrefixes: ['https://github.com/spotify/web-scripts'],
|
||||
|
||||
@@ -16,14 +16,14 @@ jobs:
|
||||
label:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# THESE SCRIPTS SHOULD BE INLINED AND NOT IN REPO
|
||||
# DUE TO THE TOKEN PERMISSIONS THAT ARE GIVEN
|
||||
# TO THE WORKFLOW. THIS SCRIPT WILL AND SHOULD
|
||||
# RUN FROM THE BASE REPO ALL TIMES.
|
||||
- uses: actions/github-script@v6
|
||||
id: fix-labels
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# THIS SCRIPT SHOULD BE INLINED AND NOT IN REPO
|
||||
# DUE TO THE TOKEN PERMISSIONS THAT ARE GIVEN
|
||||
# TO THE WORKFLOW. THIS SCRIPT WILL AND SHOULD
|
||||
# RUN FROM THE BASE REPO ALL TIMES.
|
||||
script: |
|
||||
if (['opened', 'synchronize'].includes('${{ github.event.action }}')) {
|
||||
// if it's the author, always add awaiting-review label
|
||||
@@ -48,3 +48,37 @@ jobs:
|
||||
console.log(e)
|
||||
});
|
||||
}
|
||||
|
||||
- name: Add PRs to review board
|
||||
uses: actions/github-script@v6
|
||||
if: github.event.action == 'opened' || github.event.action == 'reopened'
|
||||
env:
|
||||
PROJECT_ID: PN_kwDOBFKqdc02LQ
|
||||
with:
|
||||
github-token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }}
|
||||
script: |
|
||||
const prLookup = await github.graphql(`
|
||||
query($owner: String!, $repo: String!, $number: Int!){
|
||||
repository(owner: $owner, name: $repo) {
|
||||
pullRequest(number: $number) {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`, context.issue);
|
||||
|
||||
await github.graphql(`
|
||||
mutation($projectId: ID!, $contentId: ID!) {
|
||||
addProjectNextItem(input: {
|
||||
projectId: $projectId,
|
||||
contentId: $contentId,
|
||||
}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`, {
|
||||
projectId: process.env.PROJECT_ID,
|
||||
contentId: prLookup.repository.pullRequest.id
|
||||
})
|
||||
|
||||
@@ -55,8 +55,7 @@ jobs:
|
||||
run: ls microsite/build/backstage && ls microsite/build/backstage/storybook
|
||||
|
||||
- name: Deploy both microsite and storybook to gh-pages
|
||||
uses: JamesIves/github-pages-deploy-action@3.7.1
|
||||
uses: JamesIves/github-pages-deploy-action@v4.3.3
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
BRANCH: gh-pages
|
||||
FOLDER: microsite/build/backstage
|
||||
branch: gh-pages
|
||||
folder: microsite/build/backstage
|
||||
|
||||
@@ -45,6 +45,6 @@ jobs:
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
- name: Upload Snyk report
|
||||
uses: github/codeql-action/upload-sarif@v1
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
with:
|
||||
sarif_file: snyk.sarif
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
@@ -54,7 +54,7 @@ jobs:
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
@@ -68,4 +68,4 @@ jobs:
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
uses: github/codeql-action/analyze@v2
|
||||
|
||||
@@ -54,7 +54,7 @@ jobs:
|
||||
console.log(`creating comment on PR #${pull.number}`);
|
||||
const body = `
|
||||
Thanks for the contribution!
|
||||
All commits need to be DCO signed before merging. Please refer to the the [DCO section in CONTRIBUTING.md](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md#developer-certificate-of-origin) or the [DCO](${checks.data.check_runs[0].html_url}) status for more info.
|
||||
All commits need to be DCO signed before they are reviewed. Please refer to the the [DCO section in CONTRIBUTING.md](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md#developer-certificate-of-origin) or the [DCO](${checks.data.check_runs[0].html_url}) status for more info.
|
||||
<!-- dco -->`;
|
||||
await github.rest.issues.createComment({
|
||||
repo,
|
||||
|
||||
@@ -124,3 +124,6 @@ _If you're using Backstage in your organization, please try to add your company
|
||||
| [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. |
|
||||
| [Avalia Systems](https://avalia.io) | [Olivier Liechti](https://github.com/wasadigi), [Fabio Velloso](https://github.com/fabiovelloso) | Innersource, software analytics, knowledge base for 360 software assessments, collaborative applications, hub for tracking and sharing IP assets. |
|
||||
| [Albert Heijn](https://ah.technology) | [Joost Hofman](https://github.com/joosthofman), [Reindrich Geerman](https://github.com/reinst) | Single point of entry for all our engineers (Developer portal), Tech radar, catalog, templates (paved roads) and tech documentation. |
|
||||
| [Wise, formerly TransferWise](https://wise.com) | [Andrew Beveridge](https://github.com/beveradb) | It's early days for us, we're trying to start small with catalog, tech docs and unified search. Future ambitious vision includes scaffolder for one-click component addition, building out integrations with CI/CD tooling, kubernetes clusters, monitoring/alerting tooling etc. and aiming for a frictionless "golden path" for engineers! 🚀 |
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ describe('TechDocs', () => {
|
||||
|
||||
it('should navigate to the TechDocs home page from the URL', () => {
|
||||
cy.visit('/docs');
|
||||
|
||||
cy.wait(500);
|
||||
|
||||
cy.contains('Documentation');
|
||||
@@ -45,15 +46,12 @@ describe('TechDocs', () => {
|
||||
|
||||
it('should navigate to a specific TechDocs entity from the "Overview" tab', () => {
|
||||
cy.visit('/docs');
|
||||
cy.contains('techdocs-e2e-fixture')
|
||||
.parents()
|
||||
.eq(2)
|
||||
.contains('Read Docs')
|
||||
.click();
|
||||
|
||||
cy.contains('techdocs-e2e-fixture').click();
|
||||
|
||||
cy.location().should(loc => {
|
||||
expect(loc.pathname).to.eq(
|
||||
'/docs/default/Component/techdocs-e2e-fixture',
|
||||
'/docs/default/component/techdocs-e2e-fixture',
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -84,7 +82,6 @@ describe('TechDocs', () => {
|
||||
cy.visit(
|
||||
'/docs/default/Component/techdocs-e2e-fixture/sub-page-two#section-23',
|
||||
);
|
||||
cy.waitSectionTwoPage();
|
||||
|
||||
// This is used to test the post-render behavior of the techdocs Reader
|
||||
cy.wait(500);
|
||||
@@ -101,10 +98,43 @@ describe('TechDocs', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Rendering TechDocs Addons', () => {
|
||||
it('should render a content addon', () => {
|
||||
cy.visit('/docs/default/Component/techdocs-e2e-fixture');
|
||||
|
||||
cy.contains('e2e Fixture Documentation');
|
||||
|
||||
// highlight a snippet of text
|
||||
cy.getTechDocsShadowRoot()
|
||||
.find('article > p')
|
||||
.then($el => {
|
||||
const el = $el[0];
|
||||
const document = el.ownerDocument;
|
||||
const range = document.createRange();
|
||||
range.selectNodeContents(el);
|
||||
document?.getSelection()?.removeAllRanges();
|
||||
document?.getSelection()?.addRange(range);
|
||||
});
|
||||
|
||||
cy.document().trigger('selectionchange');
|
||||
|
||||
// wait for new issue default debounce time
|
||||
cy.wait(600);
|
||||
|
||||
// assert that the new issue button has a right url
|
||||
cy.getTechDocsShadowRoot()
|
||||
.contains('Open new Github issue')
|
||||
.should(
|
||||
'have.attr',
|
||||
'href',
|
||||
'https://github.com/backstage/backstage/issues/new?title=Documentation%20feedback%3A%20This%20is%20a%20basic%20documentation%20used%20for%20end-to-end%20tests.&body=%23%23%20Documentation%20Feedback%20%F0%9F%93%9D%0A%0A%20%23%23%23%23%20The%20highlighted%20text%3A%20%0A%0A%20%3E%20This%20is%20a%20basic%20documentation%20used%20for%20end-to-end%20tests.%0A%0A%20%23%23%23%23%20The%20comment%20on%20the%20text%3A%20%0A%20_%3Ereplace%20this%20line%20with%20your%20comment%3C_%0A%0A%20___%0ABackstage%20URL%3A%20%3Chttp%3A%2F%2Flocalhost%3A7007%2Fdocs%2Fdefault%2FComponent%2Ftechdocs-e2e-fixture%3E%20%0AMarkdown%20URL%3A%20%3Chttps%3A%2F%2Fgithub.com%2Fbackstage%2Fbackstage%2Fblob%2Fmaster%2Fcypress%2Ffixtures%2Fdocs%2Findex.md%3E',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Navigating within TechDocs', () => {
|
||||
it('should navigate to a specific TechDocs page via the navigation bar', () => {
|
||||
cy.visit('/docs/default/Component/techdocs-e2e-fixture');
|
||||
cy.waitHomePage();
|
||||
|
||||
cy.getTechDocsShadowRoot().within(() => {
|
||||
cy.getTechDocsNavigation()
|
||||
@@ -118,14 +148,18 @@ describe('TechDocs', () => {
|
||||
describe('Navigating within a TechDocs page', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/docs/default/Component/techdocs-e2e-fixture/sub-page-two');
|
||||
cy.waitSectionTwoPage();
|
||||
});
|
||||
|
||||
it('should navigate to a specific fragment within the page via the table of contents - Level 1', () => {
|
||||
return cy.getTechDocsShadowRoot().within(() => {
|
||||
// Section 3
|
||||
cy.getTechDocsTableOfContents().within(() => {
|
||||
cy.get('> div > div > nav > ul > li:nth-child(3) > a').click();
|
||||
});
|
||||
cy.getTechDocsTableOfContents()
|
||||
.find('a')
|
||||
.contains('Section 2.3')
|
||||
.click();
|
||||
|
||||
// wait scroll timeout
|
||||
cy.wait(500);
|
||||
|
||||
cy.isInViewport('#section-23');
|
||||
});
|
||||
@@ -136,20 +170,20 @@ describe('TechDocs', () => {
|
||||
cy.isNotInViewport('#sub-section-222');
|
||||
// Section 2.2
|
||||
cy.getTechDocsTableOfContents()
|
||||
.find(
|
||||
'> div > div > nav > ul > li:nth-child(2) > nav > ul > li:nth-child(2) > a',
|
||||
)
|
||||
.find('a')
|
||||
.contains('Section 2.2.2')
|
||||
.click();
|
||||
|
||||
// wait scroll timeout
|
||||
cy.wait(500);
|
||||
|
||||
cy.isInViewport('#sub-section-222');
|
||||
});
|
||||
});
|
||||
|
||||
it('should navigate to a specific TechDocs page fragment from a link', () => {
|
||||
return cy.getTechDocsShadowRoot().within(() => {
|
||||
cy.get('.md-content > article')
|
||||
.contains('Link to Section 1.1')
|
||||
.click();
|
||||
cy.get('article').contains('Link to Section 1.1').click();
|
||||
|
||||
cy.location().should(loc => {
|
||||
expect(loc.pathname).to.eq(
|
||||
@@ -162,7 +196,7 @@ describe('TechDocs', () => {
|
||||
|
||||
it('should navigate to the next page within a TechDocs entity', () => {
|
||||
return cy.getTechDocsShadowRoot().within(() => {
|
||||
cy.get('.md-footer-nav__link--next').click();
|
||||
cy.get('footer a').contains('Sub-page 3').click();
|
||||
|
||||
cy.location().should(loc => {
|
||||
expect(loc.pathname).to.eq(
|
||||
@@ -174,7 +208,7 @@ describe('TechDocs', () => {
|
||||
|
||||
it('should navigate to the previous page within a TechDocs entity', () => {
|
||||
return cy.getTechDocsShadowRoot().within(() => {
|
||||
cy.get('.md-footer-nav__link--prev').click();
|
||||
cy.get('footer a').contains('Sub-page 1').click();
|
||||
|
||||
cy.location().should(loc => {
|
||||
expect(loc.pathname).to.eq(
|
||||
|
||||
@@ -25,7 +25,7 @@ Cypress.Commands.add('loginAsGuest', () => {
|
||||
});
|
||||
|
||||
Cypress.Commands.add('getTechDocsShadowRoot', () => {
|
||||
cy.get('[data-testid="techdocs-content-shadowroot"]').shadow();
|
||||
cy.get('[data-testid="techdocs-native-shadowroot"]').shadow();
|
||||
});
|
||||
|
||||
Cypress.Commands.add('isNotInViewport', element => {
|
||||
@@ -57,11 +57,11 @@ Cypress.Commands.add('isInViewport', element => {
|
||||
});
|
||||
|
||||
Cypress.Commands.add('getTechDocsTableOfContents', () => {
|
||||
cy.get('[data-md-component="toc"]');
|
||||
cy.get('[data-md-type="toc"]');
|
||||
});
|
||||
|
||||
Cypress.Commands.add('getTechDocsNavigation', () => {
|
||||
cy.get('[data-md-component="navigation"]');
|
||||
cy.get('[data-md-type="navigation"]');
|
||||
});
|
||||
|
||||
Cypress.Commands.add('mockSockJSNode', () => {
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 297 KiB After Width: | Height: | Size: 1.9 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 80 KiB |
@@ -153,7 +153,6 @@ export const createOktaProvider: AuthProviderFactory = ({
|
||||
|
||||
// Wrap the OAuthProviderHandlers with OAuthProvider, which implements AuthProviderRouteHandlers
|
||||
return OAuthProvider.fromConfig(globalConfig, provider, {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
tokenIssuer,
|
||||
});
|
||||
|
||||
@@ -85,13 +85,14 @@ array. Users will see this value in the Software Catalog Kubernetes plugin.
|
||||
This determines how the Kubernetes client authenticates with the Kubernetes
|
||||
cluster. Valid values are:
|
||||
|
||||
| Value | Description |
|
||||
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `serviceAccount` | This will use a Kubernetes [service account](https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/) to access the Kubernetes API. When this is used the `serviceAccountToken` field should also be set. |
|
||||
| `google` | This will use a user's Google auth token from the [Google auth plugin](https://backstage.io/docs/auth/) to access the Kubernetes API. |
|
||||
| `aws` | This will use AWS credentials to access resources in EKS clusters |
|
||||
| `googleServiceAccount` | This will use the Google Cloud service account credentials to access resources in clusters |
|
||||
| `azure` | This will use [Azure Identity](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview) to access resources in clusters |
|
||||
| Value | Description |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `serviceAccount` | This will use a Kubernetes [service account](https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/) to access the Kubernetes API. When this is used the `serviceAccountToken` field should also be set. |
|
||||
| `google` | This will use a user's Google auth token from the [Google auth plugin](https://backstage.io/docs/auth/) to access the Kubernetes API. |
|
||||
| `aws` | This will use AWS credentials to access resources in EKS clusters |
|
||||
| `googleServiceAccount` | This will use the Google Cloud service account credentials to access resources in clusters |
|
||||
| `azure` | This will use [Azure Identity](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview) to access resources in clusters |
|
||||
| `oidc` | This will use [Oidc Tokens](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#openid-connect-tokens) to authenticate to the Kubernetes API. When this is used the `oidcTokenProvider` field should also be set. |
|
||||
|
||||
##### `clusters.\*.skipTLSVerify`
|
||||
|
||||
@@ -115,6 +116,33 @@ kubectl -n <NAMESPACE> get secret $(kubectl -n <NAMESPACE> get sa <SERVICE_ACCOU
|
||||
| base64 --decode
|
||||
```
|
||||
|
||||
##### `clusters.\*.oidcTokenProvider` (optional)
|
||||
|
||||
This field is to be used when using the `oidc` auth provider. It will use the id tokens
|
||||
from a configured [backstage auth provider](https://backstage.io/docs/auth/) to
|
||||
authenticate to the cluster. The selected `oidcTokenProvider` needs to be properly
|
||||
configured under `auth` for this to work.
|
||||
|
||||
```yaml
|
||||
kubernetes:
|
||||
clusterLocatorMethods:
|
||||
- type: 'config'
|
||||
clusters:
|
||||
- name: test-cluster
|
||||
url: http://localhost:8080
|
||||
authProvider: oidc
|
||||
oidcTokenProvider: okta # This value needs to match a config under auth.providers
|
||||
auth:
|
||||
providers:
|
||||
okta:
|
||||
development:
|
||||
clientId: ${AUTH_OKTA_CLIENT_ID}
|
||||
clientSecret: ${AUTH_OKTA_CLIENT_SECRET}
|
||||
audience: ${AUTH_OKTA_AUDIENCE}
|
||||
```
|
||||
|
||||
The following values are supported out-of-the-box by the frontend: `google`, `microsoft`, `okta`, `onelogin`.
|
||||
|
||||
##### `clusters.\*.dashboardUrl` (optional)
|
||||
|
||||
Specifies the link to the Kubernetes dashboard managing this cluster.
|
||||
|
||||
@@ -71,6 +71,7 @@ export const searchPage = (
|
||||
<CatalogResultListItem
|
||||
key={result.document.location}
|
||||
result={result.document}
|
||||
highlight={result.highlight}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
@@ -78,6 +79,7 @@ export const searchPage = (
|
||||
<DefaultResultListItem
|
||||
key={result.document.location}
|
||||
result={result.document}
|
||||
highlight={result.highlight}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -266,6 +268,7 @@ an example:
|
||||
<CatalogResultListItem
|
||||
key={result.document.location}
|
||||
result={result.document}
|
||||
highlight={result.highlight}
|
||||
/>
|
||||
);
|
||||
// ...
|
||||
|
||||
@@ -411,6 +411,29 @@ export class YourSearchEngine implements SearchEngine {
|
||||
}
|
||||
```
|
||||
|
||||
## How to customize search results highlighting styling
|
||||
|
||||
The default highlighting styling for matched terms in search results is your
|
||||
browsers default styles for the `<mark>` HTML tag. If you want to customize
|
||||
how highlighted terms look you can follow Backstage's guide on how to
|
||||
[Customize the look-and-feel of your App](https://backstage.io/docs/getting-started/app-custom-theme)
|
||||
to create an override with your preferred styling.
|
||||
|
||||
For example, the following will result in highlighted terms to be bold & underlined:
|
||||
|
||||
```jsx
|
||||
const highlightOverride = {
|
||||
BackstageHighlightedSearchResultText: {
|
||||
highlight: {
|
||||
color: 'inherit',
|
||||
backgroundColor: 'inherit',
|
||||
fontWeight: 'bold',
|
||||
textDecoration: 'underline',
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
[obj-mode]: https://nodejs.org/docs/latest-v14.x/api/stream.html#stream_object_mode
|
||||
[read-stream]: https://nodejs.org/docs/latest-v14.x/api/stream.html#stream_readable_streams
|
||||
[async-gen]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of#iterating_over_async_generators
|
||||
|
||||
@@ -82,13 +82,17 @@ With the Backstage 1.2 release, we plan to introduce the [TechDocs Addon Framewo
|
||||
|
||||
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 🔮**
|
||||
### **Next**
|
||||
|
||||
Some of the following items are coming soon and some are potential ideas.
|
||||
- What can we do in TechDocs to drive up documentation quality?
|
||||
|
||||
### **Someday/Maybe**
|
||||
|
||||
- Contribute to and deploy from a marketplace of TechDocs Addons
|
||||
- Addon: MDX (allows you to use JSX in your Markdown content)
|
||||
- Can we go static site generator agnostic?
|
||||
- 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, including possible support for MDX (allowing you to use JSX in your Markdown content)
|
||||
[Scaffolder V2](https://github.com/backstage/backstage/issues/2771) (e.g. easy to choose and apply documentation template with Software Templates)
|
||||
- Possible to configure several aspects about TechDocs (e.g. URL, homepage,
|
||||
theme)
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ representative of physical spaces in the TechDocs UI:
|
||||
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.
|
||||
- `Settings`: These addons are items added to the settings menu list and are designed to make
|
||||
the reader experience customizable, for example accessibility options.
|
||||
- `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
|
||||
@@ -109,9 +111,11 @@ page header, TechDocs Addons whose location is `Header` will not be rendered.
|
||||
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. |
|
||||
| Addon | Package/Plugin | Description |
|
||||
| ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [`<ExpandableNavigation />`](https://backstage.io/docs/reference/plugin-techdocs-module-addons-contrib.expandablenavigation) | `@backstage/plugin-techdocs-module-addons-contrib` | Allows TechDocs users to expand or collapse the entire TechDocs main navigation, and keeps the user's preferred state between documentation sites. |
|
||||
| [`<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. |
|
||||
| [`<TextSize />`](https://backstage.io/docs/reference/plugin-techdocs-module-addons-contrib.textsize) | `@backstage/plugin-techdocs-module-addons-contrib` | This TechDocs addon allows users to customize text size on documentation pages, they can select how much they want to increase or decrease the font size via slider or buttons. The default value for font size is 100% and this setting is kept in the browser's local storage whenever it is changed. |
|
||||
|
||||
Got an Addon to contribute? Feel free to add a row above!
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ Generate TechDocs documentation site using MkDocs.
|
||||
Options:
|
||||
--source-dir <PATH> Source directory containing mkdocs.yml and docs/ directory. (default: ".")
|
||||
--output-dir <PATH> Output directory containing generated TechDocs site. (default: "./site/")
|
||||
--docker-image <DOCKER_IMAGE> The mkdocs docker container to use (default: "spotify/techdocs:v1.0.2")
|
||||
--docker-image <DOCKER_IMAGE> The mkdocs docker container to use (default: "spotify/techdocs:v1.0.3")
|
||||
--no-pull Do not pull the latest docker image
|
||||
--no-docker Do not use Docker, use MkDocs executable and plugins in current user environment.
|
||||
--techdocs-ref <HOST_TYPE:URL> The repository hosting documentation source files e.g.
|
||||
|
||||
@@ -54,8 +54,48 @@ const AppRoutes = () => {
|
||||
};
|
||||
```
|
||||
|
||||
That's it! But now, we need the TechDocs Backend plugin for the frontend to
|
||||
work.
|
||||
It would be nice to decorate your pages with something else... Having a link that redirects you to a new issue page when you highlight text in your documentation would be really cool, right? Let's learn how to do this using the TechDocs Addon Framework!
|
||||
|
||||
With the [TechDocs Addon framework](https://backstage.io/docs/features/techdocs/addons#installing-and-using-addons), you can render React components in documentation pages and these Addons can be provided by any Backstage plugin. The framework is exported by the [@backstage/plugin-techdocs-react](https://www.npmjs.com/package/@backstage/plugin-techdocs-react) package and there is a `<ReportIssue />` Addon in the [@backstage/plugin-techdocs-module-addons-contrib](https://www.npmjs.com/package/@backstage/plugin-techdocs-module-addons-contrib) package for you to use once you have these two dependencies installed:
|
||||
|
||||
```diff
|
||||
import {
|
||||
DefaultTechDocsHome,
|
||||
TechDocsIndexPage,
|
||||
TechDocsReaderPage,
|
||||
} from '@backstage/plugin-techdocs';
|
||||
+ import { TechDocsAddons } from '@backstage/plugin-techdocs-react';
|
||||
+ import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib';
|
||||
|
||||
// ...
|
||||
|
||||
const AppRoutes = () => {
|
||||
<FlatRoutes>
|
||||
// ... other plugin routes
|
||||
<Route path="/docs" element={<TechDocsIndexPage />}>
|
||||
<DefaultTechDocsHome />
|
||||
</Route>
|
||||
<Route
|
||||
path="/docs/:namespace/:kind/:name/*"
|
||||
element={<TechDocsReaderPage />}
|
||||
>
|
||||
+ <TechDocsAddons>
|
||||
+ <ReportIssue />
|
||||
+ </TechDocsAddons>
|
||||
</Route>
|
||||
</FlatRoutes>;
|
||||
};
|
||||
```
|
||||
|
||||
I know, you're curious to see how it looks, aren't you? See the image below:
|
||||
|
||||
<img data-zoomable src="../../assets/techdocs/report-issue-addon.png" alt="TechDocs Report Issue Add-on" />
|
||||
|
||||
By clicking the open new issue button, you will be redirected to the new issue page according to the source code provider you are using:
|
||||
|
||||
<img data-zoomable src="../../assets/techdocs/report-issue-template.png" alt="TechDocs Report Issue Template" />
|
||||
|
||||
That's it! Now, we need the TechDocs Backend plugin for the frontend to work.
|
||||
|
||||
## Adding TechDocs Backend plugin
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ Plugins should export a rule factory that provides type-safety that ensures comp
|
||||
|
||||
```typescript
|
||||
import type { Entity } from '@backstage/plugin-catalog-model';
|
||||
import { createCatalogPermissionRule } from '@backstage/plugin-catalog-backend';
|
||||
import { createCatalogPermissionRule } from '@backstage/plugin-catalog-backend/alpha';
|
||||
import { createConditionFactory } from '@backstage/plugin-permission-node';
|
||||
|
||||
export const isInSystemRule = createCatalogPermissionRule({
|
||||
|
||||
@@ -50,7 +50,7 @@ Let's change the policy to the following:
|
||||
+ import {
|
||||
+ catalogConditions,
|
||||
+ createCatalogConditionalDecision,
|
||||
+ } from '@backstage/plugin-catalog-backend';
|
||||
+ } from '@backstage/plugin-catalog-backend/alpha';
|
||||
+ import {
|
||||
+ catalogEntityDeletePermission,
|
||||
+ } from '@backstage/plugin-catalog-common';
|
||||
@@ -103,7 +103,7 @@ import {
|
||||
import {
|
||||
catalogConditions,
|
||||
createCatalogConditionalDecision,
|
||||
} from '@backstage/plugin-catalog-backend';
|
||||
} from '@backstage/plugin-catalog-backend/alpha';
|
||||
- import {
|
||||
- catalogEntityDeletePermission,
|
||||
- } from '@backstage/plugin-catalog-common';
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,73 @@
|
||||
# Release v1.2.0-next.3
|
||||
|
||||
## @backstage/core-components@0.9.4-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 52c02ac02b: Don't set the background color on an Avatar component that has a picture.
|
||||
- 3603014e0e: Add ARIA landmark( <main>), & label and a heading to OAuthRequestDialog. Removed nested interactive control (button).
|
||||
- 2025d7c123: Properly highlight `SidebarSubmenuItem` dropdown items on hover, use ellipsis styling on long labels in `SidebarSubmenu`, allow `icon` and `to` properties to be optional on `SidebarSubmenuItem`, and fix `SidebarPage` padding to be responsive to pinned state
|
||||
|
||||
## @backstage/plugin-home@0.4.21-next.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 69093c5f91: Display entity titles in `StarredEntities` home page card (if defined) and don't show entities which no longer exist
|
||||
- Updated dependencies
|
||||
- @backstage/core-components@0.9.4-next.2
|
||||
|
||||
## @backstage/plugin-kubernetes@0.6.5-next.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 447e060872: Add support for 'oidc' as authProvider for kubernetes authentication
|
||||
and adds optional 'oidcTokenProvider' config value. This will allow
|
||||
users to authenticate to kubernetes cluster using id tokens obtained
|
||||
from the configured auth provider in their backstage instance.
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-kubernetes-common@0.2.10-next.1
|
||||
- @backstage/core-components@0.9.4-next.2
|
||||
|
||||
## @backstage/plugin-kubernetes-backend@0.5.1-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 447e060872: Add support for 'oidc' as authProvider for kubernetes authentication
|
||||
and adds optional 'oidcTokenProvider' config value. This will allow
|
||||
users to authenticate to kubernetes cluster using id tokens obtained
|
||||
from the configured auth provider in their backstage instance.
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-kubernetes-common@0.2.10-next.1
|
||||
|
||||
## @backstage/plugin-kubernetes-common@0.2.10-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 447e060872: Add support for 'oidc' as authProvider for kubernetes authentication
|
||||
and adds optional 'oidcTokenProvider' config value. This will allow
|
||||
users to authenticate to kubernetes cluster using id tokens obtained
|
||||
from the configured auth provider in their backstage instance.
|
||||
|
||||
## @backstage/plugin-org@0.5.5-next.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2025d7c123: Include namespace in `MyGroupSidebarItem` if not default and remove root item routing if there are multiple groups
|
||||
- Updated dependencies
|
||||
- @backstage/core-components@0.9.4-next.2
|
||||
|
||||
## @backstage/plugin-scaffolder@1.2.0-next.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- cc8ddd0979: revert dependency `event-source-polyfill` to `1.0.25`
|
||||
- Updated dependencies
|
||||
- @backstage/core-components@0.9.4-next.2
|
||||
|
||||
## @backstage/plugin-techdocs@1.1.1-next.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- cc8ddd0979: revert dependency `event-source-polyfill` to `1.0.25`
|
||||
- Updated dependencies
|
||||
- @backstage/core-components@0.9.4-next.2
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: Adopters Community Sessions
|
||||
date: April 20, 2022
|
||||
category: Upcoming
|
||||
category: Meetup
|
||||
description: Adopters Community Session ✨. It's the monthly meetup where we all come together to listen to the latest maintainer updates, learn from each other about adopting, share exciting new demos or discuss any relevant topic like developer effectiveness, developer experience, developer portals, etc.
|
||||
youtubeUrl: https://youtu.be/mFi_X58igzk
|
||||
youtubeImgUrl: https://backstage.io/img/b-sessions.png
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: Contributor Community Sessions
|
||||
date: April 27, 2022
|
||||
category: Upcoming
|
||||
category: Meetup
|
||||
description: Join the maintainers and contributors for the Contributor Community Sessions
|
||||
youtubeUrl: https://youtu.be/evf_LV0KzIk
|
||||
youtubeImgUrl: https://backstage.io/img/b-sessions.png
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Adopters Community Sessions
|
||||
date: May 18, 2022
|
||||
category: Upcoming
|
||||
description: Adopters Community Session ✨. It's the monthly meetup where we all come together to listen to the latest maintainer updates, learn from each other about adopting, share exciting new demos or discuss any relevant topic like developer effectiveness, developer experience, developer portals, etc.
|
||||
youtubeUrl: https://youtu.be/dEd1fl3wRv
|
||||
youtubeImgUrl: https://backstage.io/img/b-sessions.png
|
||||
rsvpUrl: https://calendar.google.com/calendar/embed?src=c_qup9gbhn9sqpuao6trttd8mk5s@group.calendar.google.com
|
||||
eventUrl: https://github.com/backstage/community/issues/46
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Configuration as Data
|
||||
author: kpt
|
||||
authorUrl: https://kpt.dev
|
||||
category: Configuration
|
||||
description: Configuration GUI over GitOps using kpt, with WYSIWYG editing, review and approval, versioning and undo, and package cloning and upgrades.
|
||||
documentation: https://github.com/GoogleContainerTools/kpt-backstage-plugins/tree/main/plugins/cad
|
||||
iconUrl: https://github.com/GoogleContainerTools/kpt/blob/main/logo/KptLogoSmall.png?raw=true
|
||||
npmPackageName: '@kpt/backstage-plugin-cad'
|
||||
@@ -34,7 +34,7 @@ const Background = props => {
|
||||
<Block.Container style={{ justifyContent: 'flex-start' }}>
|
||||
<Block.MediaFrame>
|
||||
<iframe
|
||||
src="https://www.youtube.com/embed/mFi_X58igzk"
|
||||
src="https://www.youtube.com/embed/dEd1fl3wRvo"
|
||||
title="YouTube video player"
|
||||
frameborder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
@@ -45,7 +45,7 @@ const Background = props => {
|
||||
<iframe
|
||||
width="300"
|
||||
height="500"
|
||||
src="https://www.youtube.com/live_chat?v=mFi_X58igzk&embed_domain=backstage.io&dark_theme=1"
|
||||
src="https://www.youtube.com/live_chat?v=dEd1fl3wRvo&embed_domain=backstage.io&dark_theme=1"
|
||||
></iframe>
|
||||
</Block.MediaFrame>
|
||||
</Block.Container>
|
||||
|
||||
+2
-2
@@ -49,7 +49,7 @@
|
||||
"@types/react": "^17",
|
||||
"@types/react-dom": "^17"
|
||||
},
|
||||
"version": "1.2.0-next.1",
|
||||
"version": "1.2.0-next.3",
|
||||
"dependencies": {
|
||||
"@manypkg/get-packages": "^1.1.3",
|
||||
"@microsoft/api-documenter": "^7.17.11",
|
||||
@@ -68,7 +68,7 @@
|
||||
"concurrently": "^7.0.0",
|
||||
"eslint-plugin-notice": "^0.9.10",
|
||||
"fs-extra": "10.1.0",
|
||||
"husky": "^7.0.4",
|
||||
"husky": "^8.0.0",
|
||||
"lerna": "^4.0.0",
|
||||
"lint-staged": "^12.2.0",
|
||||
"minimist": "^1.2.5",
|
||||
|
||||
@@ -1,5 +1,56 @@
|
||||
# example-app
|
||||
|
||||
## 0.2.71-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/core-components@0.9.4-next.1
|
||||
- @backstage/plugin-kubernetes@0.6.5-next.2
|
||||
- @backstage/plugin-org@0.5.5-next.2
|
||||
- @backstage/plugin-techdocs@1.1.1-next.2
|
||||
- @backstage/plugin-techdocs-react@0.1.1-next.2
|
||||
- @backstage/plugin-scaffolder@1.2.0-next.2
|
||||
- @backstage/plugin-graphiql@0.2.37-next.1
|
||||
- @backstage/config@1.0.1-next.0
|
||||
- @backstage/plugin-catalog@1.2.0-next.2
|
||||
- @backstage/plugin-techdocs-module-addons-contrib@0.1.0-next.2
|
||||
- @backstage/cli@0.17.1-next.2
|
||||
- @backstage/plugin-search@0.8.1-next.2
|
||||
- @backstage/plugin-search-react@0.2.0-next.2
|
||||
- @backstage/plugin-search-common@0.3.4-next.0
|
||||
- @backstage/plugin-azure-devops@0.1.21-next.2
|
||||
- @backstage/plugin-catalog-react@1.1.0-next.2
|
||||
- @backstage/catalog-model@1.0.2-next.0
|
||||
- @backstage/core-app-api@1.0.2-next.1
|
||||
- @backstage/core-plugin-api@1.0.2-next.1
|
||||
- @backstage/integration-react@1.1.0-next.2
|
||||
- @backstage/plugin-catalog-import@0.8.8-next.2
|
||||
- @backstage/plugin-code-coverage@0.1.32-next.2
|
||||
- @backstage/plugin-cost-insights@0.11.27-next.1
|
||||
- @backstage/plugin-home@0.4.21-next.2
|
||||
- @backstage/plugin-lighthouse@0.3.5-next.2
|
||||
- @backstage/plugin-permission-react@0.4.1-next.1
|
||||
- @backstage/plugin-stack-overflow@0.1.1-next.2
|
||||
- @backstage/plugin-airbrake@0.3.5-next.2
|
||||
- @backstage/plugin-api-docs@0.8.5-next.2
|
||||
- @backstage/plugin-badges@0.2.29-next.2
|
||||
- @backstage/plugin-catalog-graph@0.2.17-next.2
|
||||
- @backstage/plugin-circleci@0.3.5-next.2
|
||||
- @backstage/plugin-cloudbuild@0.3.5-next.2
|
||||
- @backstage/plugin-explore@0.3.36-next.2
|
||||
- @backstage/plugin-github-actions@0.5.5-next.2
|
||||
- @backstage/plugin-gocd@0.1.11-next.2
|
||||
- @backstage/plugin-jenkins@0.7.4-next.2
|
||||
- @backstage/plugin-kafka@0.3.5-next.2
|
||||
- @backstage/plugin-newrelic-dashboard@0.1.13-next.2
|
||||
- @backstage/plugin-pagerduty@0.3.32-next.2
|
||||
- @backstage/plugin-rollbar@0.4.5-next.2
|
||||
- @backstage/plugin-sentry@0.3.43-next.2
|
||||
- @backstage/plugin-tech-insights@0.2.1-next.2
|
||||
- @backstage/plugin-todo@0.2.7-next.2
|
||||
- @backstage/plugin-catalog-common@1.0.2-next.0
|
||||
|
||||
## 0.2.71-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
+47
-47
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "example-app",
|
||||
"version": "0.2.71-next.1",
|
||||
"version": "0.2.71-next.2",
|
||||
"private": true,
|
||||
"backstage": {
|
||||
"role": "frontend"
|
||||
@@ -8,58 +8,58 @@
|
||||
"bundled": true,
|
||||
"dependencies": {
|
||||
"@backstage/app-defaults": "^1.0.2-next.0",
|
||||
"@backstage/catalog-model": "^1.0.1",
|
||||
"@backstage/cli": "^0.17.1-next.1",
|
||||
"@backstage/config": "^1.0.0",
|
||||
"@backstage/core-app-api": "^1.0.2-next.0",
|
||||
"@backstage/core-components": "^0.9.4-next.0",
|
||||
"@backstage/core-plugin-api": "^1.0.2-next.0",
|
||||
"@backstage/integration-react": "^1.1.0-next.1",
|
||||
"@backstage/plugin-airbrake": "^0.3.5-next.1",
|
||||
"@backstage/plugin-api-docs": "^0.8.5-next.1",
|
||||
"@backstage/plugin-azure-devops": "^0.1.21-next.1",
|
||||
"@backstage/catalog-model": "^1.0.2-next.0",
|
||||
"@backstage/cli": "^0.17.1-next.2",
|
||||
"@backstage/config": "^1.0.1-next.0",
|
||||
"@backstage/core-app-api": "^1.0.2-next.1",
|
||||
"@backstage/core-components": "^0.9.4-next.1",
|
||||
"@backstage/core-plugin-api": "^1.0.2-next.1",
|
||||
"@backstage/integration-react": "^1.1.0-next.2",
|
||||
"@backstage/plugin-airbrake": "^0.3.5-next.2",
|
||||
"@backstage/plugin-api-docs": "^0.8.5-next.2",
|
||||
"@backstage/plugin-azure-devops": "^0.1.21-next.2",
|
||||
"@backstage/plugin-apache-airflow": "^0.1.13-next.0",
|
||||
"@backstage/plugin-badges": "^0.2.29-next.1",
|
||||
"@backstage/plugin-catalog": "^1.2.0-next.1",
|
||||
"@backstage/plugin-catalog-common": "^1.0.1",
|
||||
"@backstage/plugin-catalog-graph": "^0.2.17-next.1",
|
||||
"@backstage/plugin-catalog-import": "^0.8.8-next.1",
|
||||
"@backstage/plugin-catalog-react": "^1.1.0-next.1",
|
||||
"@backstage/plugin-circleci": "^0.3.5-next.1",
|
||||
"@backstage/plugin-cloudbuild": "^0.3.5-next.1",
|
||||
"@backstage/plugin-code-coverage": "^0.1.32-next.1",
|
||||
"@backstage/plugin-cost-insights": "^0.11.27-next.0",
|
||||
"@backstage/plugin-explore": "^0.3.36-next.1",
|
||||
"@backstage/plugin-badges": "^0.2.29-next.2",
|
||||
"@backstage/plugin-catalog": "^1.2.0-next.2",
|
||||
"@backstage/plugin-catalog-common": "^1.0.2-next.0",
|
||||
"@backstage/plugin-catalog-graph": "^0.2.17-next.2",
|
||||
"@backstage/plugin-catalog-import": "^0.8.8-next.2",
|
||||
"@backstage/plugin-catalog-react": "^1.1.0-next.2",
|
||||
"@backstage/plugin-circleci": "^0.3.5-next.2",
|
||||
"@backstage/plugin-cloudbuild": "^0.3.5-next.2",
|
||||
"@backstage/plugin-code-coverage": "^0.1.32-next.2",
|
||||
"@backstage/plugin-cost-insights": "^0.11.27-next.1",
|
||||
"@backstage/plugin-explore": "^0.3.36-next.2",
|
||||
"@backstage/plugin-gcalendar": "^0.3.1-next.1",
|
||||
"@backstage/plugin-gcp-projects": "^0.3.24-next.0",
|
||||
"@backstage/plugin-github-actions": "^0.5.5-next.1",
|
||||
"@backstage/plugin-gocd": "^0.1.11-next.1",
|
||||
"@backstage/plugin-graphiql": "^0.2.37-next.0",
|
||||
"@backstage/plugin-home": "^0.4.21-next.1",
|
||||
"@backstage/plugin-jenkins": "^0.7.4-next.1",
|
||||
"@backstage/plugin-kafka": "^0.3.5-next.1",
|
||||
"@backstage/plugin-kubernetes": "^0.6.5-next.1",
|
||||
"@backstage/plugin-lighthouse": "^0.3.5-next.1",
|
||||
"@backstage/plugin-github-actions": "^0.5.5-next.2",
|
||||
"@backstage/plugin-gocd": "^0.1.11-next.2",
|
||||
"@backstage/plugin-graphiql": "^0.2.37-next.1",
|
||||
"@backstage/plugin-home": "^0.4.21-next.2",
|
||||
"@backstage/plugin-jenkins": "^0.7.4-next.2",
|
||||
"@backstage/plugin-kafka": "^0.3.5-next.2",
|
||||
"@backstage/plugin-kubernetes": "^0.6.5-next.2",
|
||||
"@backstage/plugin-lighthouse": "^0.3.5-next.2",
|
||||
"@backstage/plugin-newrelic": "^0.3.23-next.0",
|
||||
"@backstage/plugin-newrelic-dashboard": "^0.1.13-next.1",
|
||||
"@backstage/plugin-org": "^0.5.5-next.1",
|
||||
"@backstage/plugin-pagerduty": "0.3.32-next.1",
|
||||
"@backstage/plugin-permission-react": "^0.4.1-next.0",
|
||||
"@backstage/plugin-rollbar": "^0.4.5-next.1",
|
||||
"@backstage/plugin-scaffolder": "^1.2.0-next.1",
|
||||
"@backstage/plugin-search": "^0.8.1-next.1",
|
||||
"@backstage/plugin-search-react": "^0.2.0-next.1",
|
||||
"@backstage/plugin-search-common": "^0.3.3",
|
||||
"@backstage/plugin-sentry": "^0.3.43-next.1",
|
||||
"@backstage/plugin-newrelic-dashboard": "^0.1.13-next.2",
|
||||
"@backstage/plugin-org": "^0.5.5-next.2",
|
||||
"@backstage/plugin-pagerduty": "0.3.32-next.2",
|
||||
"@backstage/plugin-permission-react": "^0.4.1-next.1",
|
||||
"@backstage/plugin-rollbar": "^0.4.5-next.2",
|
||||
"@backstage/plugin-scaffolder": "^1.2.0-next.2",
|
||||
"@backstage/plugin-search": "^0.8.1-next.2",
|
||||
"@backstage/plugin-search-react": "^0.2.0-next.2",
|
||||
"@backstage/plugin-search-common": "^0.3.4-next.0",
|
||||
"@backstage/plugin-sentry": "^0.3.43-next.2",
|
||||
"@backstage/plugin-shortcuts": "^0.2.6-next.0",
|
||||
"@backstage/plugin-stack-overflow": "^0.1.1-next.1",
|
||||
"@backstage/plugin-stack-overflow": "^0.1.1-next.2",
|
||||
"@backstage/plugin-tech-radar": "^0.5.12-next.0",
|
||||
"@backstage/plugin-techdocs": "^1.1.1-next.1",
|
||||
"@backstage/plugin-techdocs-react": "^0.1.1-next.1",
|
||||
"@backstage/plugin-techdocs-module-addons-contrib": "^0.1.0-next.1",
|
||||
"@backstage/plugin-todo": "^0.2.7-next.1",
|
||||
"@backstage/plugin-techdocs": "^1.1.1-next.2",
|
||||
"@backstage/plugin-techdocs-react": "^0.1.1-next.2",
|
||||
"@backstage/plugin-techdocs-module-addons-contrib": "^0.1.0-next.2",
|
||||
"@backstage/plugin-todo": "^0.2.7-next.2",
|
||||
"@backstage/plugin-user-settings": "^0.4.4-next.0",
|
||||
"@backstage/plugin-tech-insights": "^0.2.1-next.1",
|
||||
"@backstage/plugin-tech-insights": "^0.2.1-next.2",
|
||||
"@backstage/theme": "^0.2.15",
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
@@ -80,7 +80,7 @@
|
||||
"zen-observable": "^0.8.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/test-utils": "^1.1.0-next.1",
|
||||
"@backstage/test-utils": "^1.1.0-next.2",
|
||||
"@rjsf/core": "^3.2.1",
|
||||
"@testing-library/cypress": "^8.0.2",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
|
||||
@@ -70,7 +70,11 @@ import {
|
||||
techdocsPlugin,
|
||||
} from '@backstage/plugin-techdocs';
|
||||
import { TechDocsAddons } from '@backstage/plugin-techdocs-react';
|
||||
import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib';
|
||||
import {
|
||||
ExpandableNavigation,
|
||||
ReportIssue,
|
||||
TextSize,
|
||||
} from '@backstage/plugin-techdocs-module-addons-contrib';
|
||||
import {
|
||||
UserSettingsPage,
|
||||
UserSettingsTab,
|
||||
@@ -182,7 +186,9 @@ const routes = (
|
||||
>
|
||||
{techDocsPage}
|
||||
<TechDocsAddons>
|
||||
<ExpandableNavigation />
|
||||
<ReportIssue />
|
||||
<TextSize />
|
||||
</TechDocsAddons>
|
||||
</Route>
|
||||
<Route
|
||||
|
||||
@@ -180,7 +180,7 @@ export const SearchModal = ({ toggleModal }: { toggleModal: () => void }) => {
|
||||
<SearchResult>
|
||||
{({ results }) => (
|
||||
<List>
|
||||
{results.map(({ type, document }) => {
|
||||
{results.map(({ type, document, highlight }) => {
|
||||
let resultItem;
|
||||
switch (type) {
|
||||
case 'software-catalog':
|
||||
@@ -188,6 +188,7 @@ export const SearchModal = ({ toggleModal }: { toggleModal: () => void }) => {
|
||||
<CatalogSearchResultListItem
|
||||
key={document.location}
|
||||
result={document}
|
||||
highlight={highlight}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
@@ -196,6 +197,7 @@ export const SearchModal = ({ toggleModal }: { toggleModal: () => void }) => {
|
||||
<TechDocsSearchResultListItem
|
||||
key={document.location}
|
||||
result={document}
|
||||
highlight={highlight}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
@@ -204,6 +206,7 @@ export const SearchModal = ({ toggleModal }: { toggleModal: () => void }) => {
|
||||
<DefaultResultListItem
|
||||
key={document.location}
|
||||
result={document}
|
||||
highlight={highlight}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -132,13 +132,14 @@ const SearchPage = () => {
|
||||
<SearchResult>
|
||||
{({ results }) => (
|
||||
<List>
|
||||
{results.map(({ type, document }) => {
|
||||
{results.map(({ type, document, highlight }) => {
|
||||
switch (type) {
|
||||
case 'software-catalog':
|
||||
return (
|
||||
<CatalogSearchResultListItem
|
||||
key={document.location}
|
||||
result={document}
|
||||
highlight={highlight}
|
||||
/>
|
||||
);
|
||||
case 'techdocs':
|
||||
@@ -146,6 +147,7 @@ const SearchPage = () => {
|
||||
<TechDocsSearchResultListItem
|
||||
key={document.location}
|
||||
result={document}
|
||||
highlight={highlight}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
@@ -153,6 +155,7 @@ const SearchPage = () => {
|
||||
<DefaultResultListItem
|
||||
key={document.location}
|
||||
result={document}
|
||||
highlight={highlight}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# @backstage/backend-common
|
||||
|
||||
## 0.13.3-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- e0a6360b80: Added a `stream()` method to complement the `buffer()` method on `ReadUrlResponse`. A `ReadUrlResponseFactory` utility class is now also available, providing a simple, consistent way to provide a valid `ReadUrlResponse`.
|
||||
|
||||
This method, though optional for now, will be required on the responses of `UrlReader.readUrl()` implementations in a future release.
|
||||
|
||||
- 4b811aafce: 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/*`).
|
||||
- Updated dependencies
|
||||
- @backstage/cli-common@0.1.9-next.0
|
||||
- @backstage/config@1.0.1-next.0
|
||||
- @backstage/config-loader@1.1.1-next.1
|
||||
- @backstage/integration@1.2.0-next.1
|
||||
|
||||
## 0.13.3-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -617,18 +617,20 @@ export class ServerTokenManager implements TokenManager {
|
||||
// (undocumented)
|
||||
static fromConfig(
|
||||
config: Config,
|
||||
options: {
|
||||
logger: Logger;
|
||||
},
|
||||
options: ServerTokenManagerOptions,
|
||||
): ServerTokenManager;
|
||||
// (undocumented)
|
||||
getToken(): Promise<{
|
||||
token: string;
|
||||
}>;
|
||||
// (undocumented)
|
||||
static noop(): TokenManager;
|
||||
}
|
||||
|
||||
// @public
|
||||
export interface ServerTokenManagerOptions {
|
||||
logger: Logger;
|
||||
}
|
||||
|
||||
// @public
|
||||
export type ServiceBuilder = {
|
||||
loadConfig(config: Config): ServiceBuilder;
|
||||
@@ -687,10 +689,8 @@ export interface StatusCheckHandlerOptions {
|
||||
|
||||
// @public
|
||||
export interface TokenManager {
|
||||
// (undocumented)
|
||||
authenticate: (token: string) => Promise<void>;
|
||||
// (undocumented)
|
||||
getToken: () => Promise<{
|
||||
authenticate(token: string): Promise<void>;
|
||||
getToken(): Promise<{
|
||||
token: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/backend-common",
|
||||
"description": "Common functionality library for Backstage backends",
|
||||
"version": "0.13.3-next.1",
|
||||
"version": "0.13.3-next.2",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"private": false,
|
||||
@@ -34,11 +34,11 @@
|
||||
"start": "backstage-cli package start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/cli-common": "^0.1.8",
|
||||
"@backstage/config": "^1.0.0",
|
||||
"@backstage/config-loader": "^1.1.1-next.0",
|
||||
"@backstage/cli-common": "^0.1.9-next.0",
|
||||
"@backstage/config": "^1.0.1-next.0",
|
||||
"@backstage/config-loader": "^1.1.1-next.1",
|
||||
"@backstage/errors": "^1.0.0",
|
||||
"@backstage/integration": "^1.2.0-next.0",
|
||||
"@backstage/integration": "^1.2.0-next.1",
|
||||
"@backstage/types": "^1.0.0",
|
||||
"@google-cloud/storage": "^5.8.0",
|
||||
"@manypkg/get-packages": "^1.1.3",
|
||||
@@ -91,8 +91,8 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/backend-test-utils": "^0.1.24-next.0",
|
||||
"@backstage/cli": "^0.17.1-next.1",
|
||||
"@backstage/backend-test-utils": "^0.1.24-next.1",
|
||||
"@backstage/cli": "^0.17.1-next.2",
|
||||
"@types/archiver": "^5.1.0",
|
||||
"@types/base64-stream": "^1.0.2",
|
||||
"@types/compression": "^1.7.0",
|
||||
|
||||
@@ -13,11 +13,12 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { getVoidLogger } from '../logging/voidLogger';
|
||||
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { ServerTokenManager } from './ServerTokenManager';
|
||||
import { Logger } from 'winston';
|
||||
import * as jose from 'jose';
|
||||
import { Logger } from 'winston';
|
||||
import { getVoidLogger } from '../logging/voidLogger';
|
||||
import { ServerTokenManager } from './ServerTokenManager';
|
||||
import { TokenManager } from './types';
|
||||
|
||||
const emptyConfig = new ConfigReader({});
|
||||
@@ -35,6 +36,7 @@ describe('ServerTokenManager', () => {
|
||||
|
||||
afterEach(() => {
|
||||
process.env = env;
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
describe('getToken', () => {
|
||||
@@ -166,6 +168,42 @@ describe('ServerTokenManager', () => {
|
||||
/invalid server token/i,
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw for expired tokens, and re-issue new ones', async () => {
|
||||
jest.useFakeTimers();
|
||||
const warn = jest.spyOn(logger, 'warn');
|
||||
|
||||
const tokenManager = ServerTokenManager.fromConfig(configWithSecret, {
|
||||
logger,
|
||||
});
|
||||
|
||||
const { token: token1 } = await tokenManager.getToken();
|
||||
await expect(tokenManager.authenticate(token1)).resolves.not.toThrow();
|
||||
expect(warn.mock.calls.length).toBe(0);
|
||||
|
||||
// Right before the reissue timeout, it still returns the same token
|
||||
jest.advanceTimersByTime(9 * 60 * 1000);
|
||||
const { token: token1Again } = await tokenManager.getToken();
|
||||
expect(token1).toEqual(token1Again);
|
||||
await expect(tokenManager.authenticate(token1)).resolves.not.toThrow();
|
||||
expect(warn.mock.calls.length).toBe(0);
|
||||
|
||||
// Right after the reissue timeout, the old ones are still valid but returning a new token
|
||||
jest.advanceTimersByTime(2 * 60 * 1000);
|
||||
const { token: token2 } = await tokenManager.getToken();
|
||||
expect(token1).not.toEqual(token2);
|
||||
await expect(tokenManager.authenticate(token1)).resolves.not.toThrow();
|
||||
await expect(tokenManager.authenticate(token2)).resolves.not.toThrow();
|
||||
expect(warn.mock.calls.length).toBe(0);
|
||||
|
||||
// After expiry of the first one, it gets warnings but the newest one is still valid
|
||||
jest.advanceTimersByTime(52 * 60 * 1000);
|
||||
await expect(tokenManager.authenticate(token1)).resolves.not.toThrow();
|
||||
await expect(tokenManager.authenticate(token2)).resolves.not.toThrow();
|
||||
expect(warn.mock.calls[0][0]).toMatchInlineSnapshot(
|
||||
'"#### DEPRECATION WARNING: #### Server-to-server token had an expired exp claim, support for this has been deprecated and will result in errors in a future release"',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fromConfig', () => {
|
||||
@@ -242,7 +280,7 @@ describe('ServerTokenManager', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('ServerTokenManager.noop', () => {
|
||||
describe('noop', () => {
|
||||
let noopTokenManager: TokenManager;
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -14,12 +14,22 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { base64url, generateSecret, SignJWT, jwtVerify, exportJWK } from 'jose';
|
||||
import { Config } from '@backstage/config';
|
||||
import { AuthenticationError } from '@backstage/errors';
|
||||
import { TokenManager } from './types';
|
||||
import { AuthenticationError, NotAllowedError } from '@backstage/errors';
|
||||
import { base64url, exportJWK, generateSecret, jwtVerify, SignJWT } from 'jose';
|
||||
import { DateTime, Duration } from 'luxon';
|
||||
import { Logger } from 'winston';
|
||||
import { TokenManager } from './types';
|
||||
|
||||
const TOKEN_ALG = 'HS256';
|
||||
const TOKEN_SUB = 'backstage-server';
|
||||
const TOKEN_EXPIRY_AFTER = Duration.fromObject({ hours: 1 });
|
||||
const TOKEN_REISSUE_AFTER = Duration.fromObject({ minutes: 10 });
|
||||
|
||||
/**
|
||||
* A token manager that issues static dummy tokens and never fails
|
||||
* authentication. This can be useful for testing.
|
||||
*/
|
||||
class NoopTokenManager implements TokenManager {
|
||||
public readonly isInsecureServerTokenManager: boolean = true;
|
||||
|
||||
@@ -30,6 +40,18 @@ class NoopTokenManager implements TokenManager {
|
||||
async authenticate() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for {@link ServerTokenManager}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface ServerTokenManagerOptions {
|
||||
/**
|
||||
* The logger to use.
|
||||
*/
|
||||
logger: Logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and validates tokens for use during backend-to-backend
|
||||
* authentication.
|
||||
@@ -37,44 +59,51 @@ class NoopTokenManager implements TokenManager {
|
||||
* @public
|
||||
*/
|
||||
export class ServerTokenManager implements TokenManager {
|
||||
private verificationKeys: Uint8Array[];
|
||||
private readonly options: ServerTokenManagerOptions;
|
||||
private readonly verificationKeys: Uint8Array[];
|
||||
private signingKey: Uint8Array;
|
||||
private privateKeyPromise?: Promise<void>;
|
||||
private logger: Logger;
|
||||
private privateKeyPromise: Promise<void> | undefined;
|
||||
private currentTokenPromise: Promise<{ token: string }> | undefined;
|
||||
private warnedForMissingExpClaim = false;
|
||||
private warnedForExpiredExpClaim = false;
|
||||
|
||||
/**
|
||||
* Creates a token manager that issues static dummy tokens and never fails
|
||||
* authentication. This can be useful for testing.
|
||||
*/
|
||||
static noop(): TokenManager {
|
||||
return new NoopTokenManager();
|
||||
}
|
||||
|
||||
static fromConfig(config: Config, options: { logger: Logger }) {
|
||||
const { logger } = options;
|
||||
|
||||
static fromConfig(config: Config, options: ServerTokenManagerOptions) {
|
||||
const keys = config.getOptionalConfigArray('backend.auth.keys');
|
||||
if (keys?.length) {
|
||||
return new ServerTokenManager(
|
||||
keys.map(key => key.getString('secret')),
|
||||
logger,
|
||||
options,
|
||||
);
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
throw new Error(
|
||||
'You must configure at least one key in backend.auth.keys for production.',
|
||||
);
|
||||
}
|
||||
|
||||
// For development, if a secret has not been configured, we auto generate a secret instead of throwing.
|
||||
logger.warn(
|
||||
options.logger.warn(
|
||||
'Generated a secret for backend-to-backend authentication: DEVELOPMENT USE ONLY.',
|
||||
);
|
||||
return new ServerTokenManager([], logger);
|
||||
return new ServerTokenManager([], options);
|
||||
}
|
||||
|
||||
private constructor(secrets: string[], logger: Logger) {
|
||||
private constructor(secrets: string[], options: ServerTokenManagerOptions) {
|
||||
if (!secrets.length && process.env.NODE_ENV !== 'development') {
|
||||
throw new Error(
|
||||
'No secrets provided when constructing ServerTokenManager',
|
||||
);
|
||||
}
|
||||
this.logger = logger;
|
||||
this.options = options;
|
||||
this.verificationKeys = secrets.map(s => base64url.decode(s));
|
||||
this.signingKey = this.verificationKeys[0];
|
||||
}
|
||||
@@ -86,11 +115,13 @@ export class ServerTokenManager implements TokenManager {
|
||||
'Key generation is not supported outside of the dev environment',
|
||||
);
|
||||
}
|
||||
|
||||
if (this.privateKeyPromise) {
|
||||
return this.privateKeyPromise;
|
||||
}
|
||||
|
||||
const promise = (async () => {
|
||||
const secret = await generateSecret('HS256');
|
||||
const secret = await generateSecret(TOKEN_ALG);
|
||||
const jwk = await exportJWK(secret);
|
||||
this.verificationKeys.push(base64url.decode(jwk.k ?? ''));
|
||||
this.signingKey = this.verificationKeys[0];
|
||||
@@ -98,13 +129,15 @@ export class ServerTokenManager implements TokenManager {
|
||||
})();
|
||||
|
||||
try {
|
||||
// If we fail to generate a new key, we need to clear the state so that
|
||||
// the next caller will try to generate another key.
|
||||
this.privateKeyPromise = promise;
|
||||
await promise;
|
||||
} catch (error) {
|
||||
this.logger.error(`Failed to generate new key, ${error}`);
|
||||
// If we fail to generate a new key, we need to clear the state so that
|
||||
// the next caller will try to generate another key.
|
||||
this.options.logger.error(`Failed to generate new key, ${error}`);
|
||||
delete this.privateKeyPromise;
|
||||
}
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
@@ -112,26 +145,83 @@ export class ServerTokenManager implements TokenManager {
|
||||
if (!this.verificationKeys.length) {
|
||||
await this.generateKeys();
|
||||
}
|
||||
const sub = 'backstage-server';
|
||||
const jwt = await new SignJWT({ alg: 'HS256' })
|
||||
.setProtectedHeader({ alg: 'HS256', sub: sub })
|
||||
.setSubject('backstage-server')
|
||||
.sign(this.signingKey);
|
||||
return { token: jwt };
|
||||
|
||||
if (this.currentTokenPromise) {
|
||||
return this.currentTokenPromise;
|
||||
}
|
||||
|
||||
const result = Promise.resolve().then(async () => {
|
||||
const jwt = await new SignJWT({})
|
||||
.setProtectedHeader({ alg: TOKEN_ALG })
|
||||
.setSubject(TOKEN_SUB)
|
||||
.setExpirationTime(
|
||||
DateTime.now().plus(TOKEN_EXPIRY_AFTER).toUnixInteger(),
|
||||
)
|
||||
.sign(this.signingKey);
|
||||
return { token: jwt };
|
||||
});
|
||||
|
||||
this.currentTokenPromise = result;
|
||||
|
||||
result
|
||||
.then(() => {
|
||||
setTimeout(() => {
|
||||
this.currentTokenPromise = undefined;
|
||||
}, TOKEN_REISSUE_AFTER.toMillis());
|
||||
})
|
||||
.catch(() => {
|
||||
this.currentTokenPromise = undefined;
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async authenticate(token: string): Promise<void> {
|
||||
let verifyError = undefined;
|
||||
|
||||
for (const key of this.verificationKeys) {
|
||||
try {
|
||||
await jwtVerify(token, key);
|
||||
// If the verify succeeded, return
|
||||
const {
|
||||
protectedHeader: { alg },
|
||||
payload: { sub, exp },
|
||||
} = await jwtVerify(token, key, {
|
||||
// TODO(freben): Holding on to tokens and reusing them is deprecated; remove this tolerance in a future release
|
||||
clockTolerance: 3e9,
|
||||
});
|
||||
|
||||
if (alg !== TOKEN_ALG) {
|
||||
throw new NotAllowedError(`Illegal alg "${alg}"`);
|
||||
}
|
||||
|
||||
if (sub !== TOKEN_SUB) {
|
||||
throw new NotAllowedError(`Illegal sub "${sub}"`);
|
||||
}
|
||||
|
||||
// TODO(freben): Passing in tokens without an exp is deprecated; change this warning to an error in a future release
|
||||
if (typeof exp !== 'number') {
|
||||
if (!this.warnedForMissingExpClaim) {
|
||||
this.warnedForMissingExpClaim = true;
|
||||
this.options.logger.warn(
|
||||
`#### DEPRECATION WARNING: #### Server-to-server token had no exp claim, support for this has been deprecated and will result in errors in a future release`,
|
||||
);
|
||||
}
|
||||
}
|
||||
// TODO(freben): Holding on to tokens and reusing them is deprecated; remove this tolerance in a future release
|
||||
else if (exp * 1000 < Date.now()) {
|
||||
if (!this.warnedForExpiredExpClaim) {
|
||||
this.warnedForExpiredExpClaim = true;
|
||||
this.options.logger.warn(
|
||||
`#### DEPRECATION WARNING: #### Server-to-server token had an expired exp claim, support for this has been deprecated and will result in errors in a future release`,
|
||||
);
|
||||
}
|
||||
}
|
||||
return;
|
||||
} catch (e) {
|
||||
// Catch the verify exception and continue
|
||||
verifyError = e;
|
||||
}
|
||||
}
|
||||
|
||||
throw new AuthenticationError(`Invalid server token: ${verifyError}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,4 +15,5 @@
|
||||
*/
|
||||
|
||||
export { ServerTokenManager } from './ServerTokenManager';
|
||||
export type { ServerTokenManagerOptions } from './ServerTokenManager';
|
||||
export type { TokenManager } from './types';
|
||||
|
||||
@@ -20,6 +20,20 @@
|
||||
* @public
|
||||
*/
|
||||
export interface TokenManager {
|
||||
getToken: () => Promise<{ token: string }>;
|
||||
authenticate: (token: string) => Promise<void>;
|
||||
/**
|
||||
* Fetches a valid token.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* Tokens are valid for roughly one hour; the actual deadline is set in the
|
||||
* payload `exp` claim. Never hold on to tokens for reuse; always ask for a
|
||||
* new one for each outgoing request. This ensures that you always get a
|
||||
* valid, fresh one.
|
||||
*/
|
||||
getToken(): Promise<{ token: string }>;
|
||||
|
||||
/**
|
||||
* Validates a given token.
|
||||
*/
|
||||
authenticate(token: string): Promise<void>;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,29 @@
|
||||
# @backstage/backend-tasks
|
||||
|
||||
## 0.3.1-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 73480846dd: `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
|
||||
});
|
||||
```
|
||||
|
||||
- ebbec677e1: Correctly set next run time for tasks
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.13.3-next.2
|
||||
- @backstage/config@1.0.1-next.0
|
||||
|
||||
## 0.3.1-next.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/backend-tasks",
|
||||
"description": "Common distributed task management library for Backstage backends",
|
||||
"version": "0.3.1-next.0",
|
||||
"version": "0.3.1-next.1",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"private": false,
|
||||
@@ -33,8 +33,8 @@
|
||||
"start": "backstage-cli package start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.13.3-next.0",
|
||||
"@backstage/config": "^1.0.0",
|
||||
"@backstage/backend-common": "^0.13.3-next.2",
|
||||
"@backstage/config": "^1.0.1-next.0",
|
||||
"@backstage/errors": "^1.0.0",
|
||||
"@backstage/types": "^1.0.0",
|
||||
"@types/luxon": "^2.0.4",
|
||||
@@ -48,8 +48,8 @@
|
||||
"zod": "^3.9.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/backend-test-utils": "^0.1.24-next.0",
|
||||
"@backstage/cli": "^0.17.1-next.0",
|
||||
"@backstage/backend-test-utils": "^0.1.24-next.1",
|
||||
"@backstage/cli": "^0.17.1-next.2",
|
||||
"@types/cron": "^1.7.3",
|
||||
"wait-for-expect": "^3.0.2"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# @backstage/backend-test-utils
|
||||
|
||||
## 0.1.24-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.13.3-next.2
|
||||
- @backstage/config@1.0.1-next.0
|
||||
- @backstage/cli@0.17.1-next.2
|
||||
|
||||
## 0.1.24-next.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/backend-test-utils",
|
||||
"description": "Test helpers library for Backstage backends",
|
||||
"version": "0.1.24-next.0",
|
||||
"version": "0.1.24-next.1",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"private": false,
|
||||
@@ -34,9 +34,9 @@
|
||||
"start": "backstage-cli package start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.13.3-next.0",
|
||||
"@backstage/cli": "^0.17.1-next.0",
|
||||
"@backstage/config": "^1.0.0",
|
||||
"@backstage/backend-common": "^0.13.3-next.2",
|
||||
"@backstage/cli": "^0.17.1-next.2",
|
||||
"@backstage/config": "^1.0.1-next.0",
|
||||
"better-sqlite3": "^7.5.0",
|
||||
"knex": "^1.0.2",
|
||||
"msw": "^0.35.0",
|
||||
@@ -46,7 +46,7 @@
|
||||
"uuid": "^8.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.17.1-next.0"
|
||||
"@backstage/cli": "^0.17.1-next.2"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
|
||||
@@ -1,5 +1,45 @@
|
||||
# example-backend
|
||||
|
||||
## 0.2.71-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.13.3-next.2
|
||||
- @backstage/plugin-kubernetes-backend@0.5.1-next.1
|
||||
- @backstage/plugin-catalog-backend@1.1.2-next.2
|
||||
- @backstage/backend-tasks@0.3.1-next.1
|
||||
- @backstage/plugin-scaffolder-backend-module-rails@0.4.0-next.1
|
||||
- @backstage/plugin-scaffolder-backend@1.2.0-next.1
|
||||
- @backstage/config@1.0.1-next.0
|
||||
- @backstage/plugin-search-backend-node@0.6.1-next.1
|
||||
- @backstage/plugin-search-backend-module-elasticsearch@0.1.4-next.1
|
||||
- @backstage/plugin-search-backend-module-pg@0.3.3-next.1
|
||||
- @backstage/plugin-azure-devops-backend@0.3.11-next.1
|
||||
- example-app@0.2.71-next.2
|
||||
- @backstage/catalog-model@1.0.2-next.0
|
||||
- @backstage/integration@1.2.0-next.1
|
||||
- @backstage/plugin-app-backend@0.3.32-next.1
|
||||
- @backstage/plugin-auth-backend@0.13.1-next.2
|
||||
- @backstage/plugin-auth-node@0.2.1-next.1
|
||||
- @backstage/plugin-badges-backend@0.1.26-next.1
|
||||
- @backstage/plugin-code-coverage-backend@0.1.30-next.1
|
||||
- @backstage/plugin-graphql-backend@0.1.22-next.1
|
||||
- @backstage/plugin-jenkins-backend@0.1.22-next.1
|
||||
- @backstage/plugin-kafka-backend@0.2.25-next.1
|
||||
- @backstage/plugin-permission-backend@0.5.7-next.1
|
||||
- @backstage/plugin-permission-common@0.6.1-next.0
|
||||
- @backstage/plugin-permission-node@0.6.1-next.1
|
||||
- @backstage/plugin-proxy-backend@0.2.26-next.1
|
||||
- @backstage/plugin-rollbar-backend@0.1.29-next.2
|
||||
- @backstage/plugin-search-backend@0.5.2-next.1
|
||||
- @backstage/plugin-tech-insights-backend@0.4.0-next.2
|
||||
- @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.16-next.2
|
||||
- @backstage/plugin-tech-insights-node@0.3.0-next.2
|
||||
- @backstage/plugin-techdocs-backend@1.1.1-next.1
|
||||
- @backstage/plugin-todo-backend@0.1.29-next.1
|
||||
- @backstage/catalog-client@1.0.2-next.0
|
||||
|
||||
## 0.2.71-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "example-backend",
|
||||
"version": "0.2.71-next.1",
|
||||
"version": "0.2.71-next.2",
|
||||
"main": "dist/index.cjs.js",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -26,39 +26,39 @@
|
||||
"build-image": "docker build ../.. -f Dockerfile --tag example-backend"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.13.3-next.1",
|
||||
"@backstage/backend-tasks": "^0.3.1-next.0",
|
||||
"@backstage/catalog-client": "^1.0.1",
|
||||
"@backstage/catalog-model": "^1.0.1",
|
||||
"@backstage/config": "^1.0.0",
|
||||
"@backstage/integration": "^1.2.0-next.0",
|
||||
"@backstage/plugin-app-backend": "^0.3.32-next.0",
|
||||
"@backstage/plugin-auth-backend": "^0.13.1-next.1",
|
||||
"@backstage/plugin-auth-node": "^0.2.1-next.0",
|
||||
"@backstage/plugin-azure-devops-backend": "^0.3.11-next.0",
|
||||
"@backstage/plugin-badges-backend": "^0.1.26-next.0",
|
||||
"@backstage/plugin-catalog-backend": "^1.1.2-next.1",
|
||||
"@backstage/plugin-code-coverage-backend": "^0.1.30-next.0",
|
||||
"@backstage/plugin-graphql-backend": "^0.1.22-next.0",
|
||||
"@backstage/plugin-jenkins-backend": "^0.1.22-next.0",
|
||||
"@backstage/plugin-kubernetes-backend": "^0.5.1-next.0",
|
||||
"@backstage/plugin-kafka-backend": "^0.2.25-next.0",
|
||||
"@backstage/plugin-permission-backend": "^0.5.7-next.0",
|
||||
"@backstage/plugin-permission-common": "^0.6.0",
|
||||
"@backstage/plugin-permission-node": "^0.6.1-next.0",
|
||||
"@backstage/plugin-proxy-backend": "^0.2.26-next.0",
|
||||
"@backstage/plugin-rollbar-backend": "^0.1.29-next.1",
|
||||
"@backstage/plugin-scaffolder-backend": "^1.2.0-next.0",
|
||||
"@backstage/plugin-scaffolder-backend-module-rails": "^0.3.7-next.0",
|
||||
"@backstage/plugin-search-backend": "^0.5.2-next.0",
|
||||
"@backstage/plugin-search-backend-node": "^0.6.1-next.0",
|
||||
"@backstage/plugin-search-backend-module-elasticsearch": "^0.1.4-next.0",
|
||||
"@backstage/plugin-search-backend-module-pg": "^0.3.3-next.0",
|
||||
"@backstage/plugin-techdocs-backend": "^1.1.1-next.0",
|
||||
"@backstage/plugin-tech-insights-backend": "^0.4.0-next.1",
|
||||
"@backstage/plugin-tech-insights-node": "^0.3.0-next.1",
|
||||
"@backstage/plugin-tech-insights-backend-module-jsonfc": "^0.1.16-next.1",
|
||||
"@backstage/plugin-todo-backend": "^0.1.29-next.0",
|
||||
"@backstage/backend-common": "^0.13.3-next.2",
|
||||
"@backstage/backend-tasks": "^0.3.1-next.1",
|
||||
"@backstage/catalog-client": "^1.0.2-next.0",
|
||||
"@backstage/catalog-model": "^1.0.2-next.0",
|
||||
"@backstage/config": "^1.0.1-next.0",
|
||||
"@backstage/integration": "^1.2.0-next.1",
|
||||
"@backstage/plugin-app-backend": "^0.3.32-next.1",
|
||||
"@backstage/plugin-auth-backend": "^0.13.1-next.2",
|
||||
"@backstage/plugin-auth-node": "^0.2.1-next.1",
|
||||
"@backstage/plugin-azure-devops-backend": "^0.3.11-next.1",
|
||||
"@backstage/plugin-badges-backend": "^0.1.26-next.1",
|
||||
"@backstage/plugin-catalog-backend": "^1.1.2-next.2",
|
||||
"@backstage/plugin-code-coverage-backend": "^0.1.30-next.1",
|
||||
"@backstage/plugin-graphql-backend": "^0.1.22-next.1",
|
||||
"@backstage/plugin-jenkins-backend": "^0.1.22-next.1",
|
||||
"@backstage/plugin-kubernetes-backend": "^0.5.1-next.1",
|
||||
"@backstage/plugin-kafka-backend": "^0.2.25-next.1",
|
||||
"@backstage/plugin-permission-backend": "^0.5.7-next.1",
|
||||
"@backstage/plugin-permission-common": "^0.6.1-next.0",
|
||||
"@backstage/plugin-permission-node": "^0.6.1-next.1",
|
||||
"@backstage/plugin-proxy-backend": "^0.2.26-next.1",
|
||||
"@backstage/plugin-rollbar-backend": "^0.1.29-next.2",
|
||||
"@backstage/plugin-scaffolder-backend": "^1.2.0-next.1",
|
||||
"@backstage/plugin-scaffolder-backend-module-rails": "^0.4.0-next.1",
|
||||
"@backstage/plugin-search-backend": "^0.5.2-next.1",
|
||||
"@backstage/plugin-search-backend-node": "^0.6.1-next.1",
|
||||
"@backstage/plugin-search-backend-module-elasticsearch": "^0.1.4-next.1",
|
||||
"@backstage/plugin-search-backend-module-pg": "^0.3.3-next.1",
|
||||
"@backstage/plugin-techdocs-backend": "^1.1.1-next.1",
|
||||
"@backstage/plugin-tech-insights-backend": "^0.4.0-next.2",
|
||||
"@backstage/plugin-tech-insights-node": "^0.3.0-next.2",
|
||||
"@backstage/plugin-tech-insights-backend-module-jsonfc": "^0.1.16-next.2",
|
||||
"@backstage/plugin-todo-backend": "^0.1.29-next.1",
|
||||
"@gitbeaker/node": "^35.1.0",
|
||||
"@octokit/rest": "^18.5.3",
|
||||
"better-sqlite3": "^7.5.0",
|
||||
@@ -75,7 +75,7 @@
|
||||
"winston": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.17.1-next.1",
|
||||
"@backstage/cli": "^0.17.1-next.2",
|
||||
"@types/dockerode": "^3.3.0",
|
||||
"@types/express": "^4.17.6",
|
||||
"@types/express-serve-static-core": "^4.17.5",
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @backstage/catalog-client
|
||||
|
||||
## 1.0.2-next.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/catalog-model@1.0.2-next.0
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/catalog-client",
|
||||
"description": "An isomorphic client for the catalog backend",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.2-next.0",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -33,12 +33,12 @@
|
||||
"clean": "backstage-cli package clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/catalog-model": "^1.0.1",
|
||||
"@backstage/catalog-model": "^1.0.2-next.0",
|
||||
"@backstage/errors": "^1.0.0",
|
||||
"cross-fetch": "^3.1.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.17.1-next.0",
|
||||
"@backstage/cli": "^0.17.1-next.2",
|
||||
"@types/jest": "^26.0.7",
|
||||
"msw": "^0.35.0"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @backstage/catalog-model
|
||||
|
||||
## 1.0.2-next.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/config@1.0.1-next.0
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Location
|
||||
metadata:
|
||||
name: example-apis
|
||||
name: example-all
|
||||
description: A collection of all Backstage example entities, except users, groups, and templates
|
||||
spec:
|
||||
targets:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user