Merge branch 'master' into feat/myGroupsPickerPresentationApi
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-defaults': patch
|
||||
---
|
||||
|
||||
Add access restrictions to the JWKS external access method config schema
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/frontend-plugin-api': patch
|
||||
---
|
||||
|
||||
Fixing issue with extension blueprints `inputs` merging.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-react': patch
|
||||
---
|
||||
|
||||
Fixed a bug in `DefaultTableOutputs` where output elements overlapped on smaller screen sizes
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog': patch
|
||||
---
|
||||
|
||||
The entity relation cards available for the new frontend system via `/alpha` now have more accurate and granular default filters.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-plugin-api': patch
|
||||
---
|
||||
|
||||
Added `createBackendFeatureLoader`, which can be used to create an installable backend feature that can in turn load in additional backend features in a dynamic way.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/frontend-plugin-api': patch
|
||||
---
|
||||
|
||||
Added support for using the `params` in other properties of the `createExtensionBlueprint` options by providing a callback.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/frontend-test-utils': patch
|
||||
---
|
||||
|
||||
Added new APIs for testing extensions
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-app-api': patch
|
||||
---
|
||||
|
||||
Added support for the latest version of `BackendFeature`s from `@backstage/backend-plugin-api`, including feature loaders.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-test-utils': patch
|
||||
---
|
||||
|
||||
Internal updates to support latest version of `BackendFeauture`s from `@backstage/backend-plugin-api`.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
'@backstage/plugin-scaffolder-node': patch
|
||||
---
|
||||
|
||||
Add support for status filtering in scaffolder tasks endpoint
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-permission-common': patch
|
||||
---
|
||||
|
||||
Add the MetadataResponse type from @backstage/plugin-permission-node, since this
|
||||
type might be used in frontend code.
|
||||
@@ -0,0 +1,43 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-confluence-to-markdown': patch
|
||||
'@backstage/plugin-auth-backend-module-cloudflare-access-provider': patch
|
||||
'@backstage/plugin-search-backend-module-stack-overflow-collator': patch
|
||||
'@backstage/plugin-scaffolder-backend-module-bitbucket-server': patch
|
||||
'@backstage/plugin-scaffolder-backend-module-bitbucket-cloud': patch
|
||||
'@backstage/plugin-catalog-backend-module-bitbucket-server': patch
|
||||
'@backstage/plugin-auth-backend-module-microsoft-provider': patch
|
||||
'@backstage/plugin-auth-backend-module-aws-alb-provider': patch
|
||||
'@backstage/plugin-scaffolder-backend-module-bitbucket': patch
|
||||
'@backstage/plugin-scaffolder-backend-module-gerrit': patch
|
||||
'@backstage/plugin-scaffolder-backend-module-sentry': patch
|
||||
'@backstage/plugin-catalog-backend-module-puppetdb': patch
|
||||
'@backstage/plugin-scaffolder-backend-module-gitea': patch
|
||||
'@backstage/plugin-catalog-backend-module-msgraph': patch
|
||||
'@backstage/plugin-search-backend-module-techdocs': patch
|
||||
'@backstage/plugin-catalog-backend-module-gerrit': patch
|
||||
'@backstage/plugin-catalog-backend-module-github': patch
|
||||
'@backstage/plugin-catalog-backend-module-gitlab': patch
|
||||
'@backstage/plugin-search-backend-module-explore': patch
|
||||
'@backstage/plugin-catalog-backend-module-azure': patch
|
||||
'@backstage/plugin-notifications-backend': patch
|
||||
'@backstage/plugin-kubernetes-backend': patch
|
||||
'@backstage/plugin-notifications-node': patch
|
||||
'@backstage/plugin-permission-backend': patch
|
||||
'@backstage/backend-defaults': patch
|
||||
'@backstage/backend-app-api': patch
|
||||
'@backstage/plugin-devtools-backend': patch
|
||||
'@backstage/plugin-techdocs-backend': patch
|
||||
'@backstage/backend-common': patch
|
||||
'@backstage/plugin-catalog-backend': patch
|
||||
'@backstage/plugin-kubernetes-node': patch
|
||||
'@backstage/plugin-signals-backend': patch
|
||||
'@backstage/config-loader': patch
|
||||
'@backstage/plugin-proxy-backend': patch
|
||||
'@backstage/plugin-auth-backend': patch
|
||||
'@backstage/create-app': patch
|
||||
'@backstage/plugin-app-backend': patch
|
||||
'@backstage/plugin-auth-node': patch
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Make sure node-fetch is version 2.7.0 or greater
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-bitbucket-cloud': patch
|
||||
---
|
||||
|
||||
Added autocompletion support for resource `branches`
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-azure': patch
|
||||
---
|
||||
|
||||
Added examples for publish:azure action and updated its test cases
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
'@backstage/plugin-permission-node': patch
|
||||
---
|
||||
|
||||
The MetadataResponse type has been moved to @backstage/plugin-permission-common
|
||||
to match the recent move of MetadataResponseSerializedRule, and should be
|
||||
imported from there going forward. To avoid an immediate breaking change, this
|
||||
type is still re-exported from this package, but is marked as deprecated and
|
||||
will be removed in a future release.
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
'@backstage/frontend-test-utils': patch
|
||||
'@backstage/frontend-app-api': patch
|
||||
'@backstage/core-compat-api': patch
|
||||
'@backstage/plugin-app-visualizer': patch
|
||||
---
|
||||
|
||||
Updated usage of `useRouteRef`, which can now always return `undefined`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Switched the `process` polyfill to use `require.resolve` for greater compatability.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-gitlab': patch
|
||||
---
|
||||
|
||||
Added test cases for gitlab:issues:create examples
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
Allow for more granular control of TechDocsReaderPage styling. Theme overrides can now be provided to TechDocs without affecting the theme in other areas of Backstage.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
'@backstage/plugin-search-backend-node': patch
|
||||
'@backstage/plugin-search-backend': patch
|
||||
'@backstage/plugin-search-common': patch
|
||||
'@backstage/plugin-search-react': patch
|
||||
'@backstage/plugin-search': patch
|
||||
---
|
||||
|
||||
Fix package metadata
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/backend-plugin-api': patch
|
||||
'@backstage/backend-defaults': patch
|
||||
---
|
||||
|
||||
The `SchedulerService` now allows tasks with `frequency: { trigger: 'manual' }`. This means that the task will not be scheduled, but rather run only when manually triggered with `SchedulerService.triggerTask`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-github': patch
|
||||
---
|
||||
|
||||
Added examples for github:repo:create action and improved test cases
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
'@backstage/backend-plugin-api': patch
|
||||
---
|
||||
|
||||
Added `createBackendFeatureLoader`, which can be used to programmatically select and install backend features.
|
||||
|
||||
A feature loader can return an list of features to be installed, for example in the form on an `Array` or other for of iterable, which allows for the loader to be defined as a generator function. Both synchronous and asynchronous loaders are supported.
|
||||
|
||||
Additionally, a loader can depend on services in its implementation, with the restriction that it can only depend on root-scoped services, and it may not override services that have already been instantiated.
|
||||
|
||||
```ts
|
||||
const searchLoader = createBackendFeatureLoader({
|
||||
deps: {
|
||||
config: coreServices.rootConfig,
|
||||
},
|
||||
*loader({ config }) {
|
||||
// Example of a custom config flag to enable search
|
||||
if (config.getOptionalString('customFeatureToggle.search')) {
|
||||
yield import('@backstage/plugin-search-backend/alpha');
|
||||
yield import('@backstage/plugin-search-backend-module-catalog/alpha');
|
||||
yield import('@backstage/plugin-search-backend-module-explore/alpha');
|
||||
yield import('@backstage/plugin-search-backend-module-techdocs/alpha');
|
||||
}
|
||||
},
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-tasks': patch
|
||||
---
|
||||
|
||||
The `PluginTaskScheduler` now allows tasks with `frequency: { trigger: 'manual' }`. This means that the task will not be scheduled, but rather run only when manually triggered with `PluginTaskScheduler.triggerTask`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog': minor
|
||||
---
|
||||
|
||||
Introduces the HasSubdomainsCard component that displays the subdomains of a given domain
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-app-api': patch
|
||||
---
|
||||
|
||||
Update the `ServiceRegister` implementation to enable registering multiple service implementations for a given service ref.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-notifications-backend': patch
|
||||
---
|
||||
|
||||
Allow using notifications without users in the catalog
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-auth-node': minor
|
||||
---
|
||||
|
||||
**BREAKING**: Sign-in resolvers configured via `.signIn.resolvers` now take precedence over sign-in resolvers passed to `signInResolver` option of `createOAuthProviderFactory`. This effectively makes sign-in resolvers passed via the `signInResolver` the default one, which you can then override through configuration.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/frontend-plugin-api': patch
|
||||
---
|
||||
|
||||
Add support for accessing extensions definitions provided by a plugin via `plugin.getExtension(...)`. For this to work the extensions must be defined using the v2 format, typically using an extension blueprint.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
TechDocs redirect feature now includes a notification to the user before they are redirected.
|
||||
@@ -190,41 +190,62 @@
|
||||
"@backstage/plugin-techdocs-common": "0.0.0"
|
||||
},
|
||||
"changesets": [
|
||||
"angry-dolphins-camp",
|
||||
"big-eagles-grab",
|
||||
"blue-pumas-cheer",
|
||||
"breezy-jeans-tie",
|
||||
"breezy-rings-fly",
|
||||
"bright-donkeys-buy",
|
||||
"bright-trainers-brake",
|
||||
"calm-crabs-drop",
|
||||
"chilly-days-peel",
|
||||
"chilly-trains-sleep",
|
||||
"clever-pans-brake",
|
||||
"cool-insects-remember",
|
||||
"cool-schools-vanish",
|
||||
"create-app-1722413762",
|
||||
"cuddly-zebras-crash",
|
||||
"curvy-pillows-joke",
|
||||
"cyan-shrimps-push",
|
||||
"dry-squids-tap",
|
||||
"dull-ghosts-double",
|
||||
"early-trees-dance",
|
||||
"eighty-emus-leave",
|
||||
"eighty-jokes-deny",
|
||||
"eighty-mirrors-flow",
|
||||
"fair-hairs-mix",
|
||||
"fair-pumas-hang",
|
||||
"fast-bulldogs-relax",
|
||||
"few-wasps-hug",
|
||||
"flat-plums-grow",
|
||||
"forty-ties-agree",
|
||||
"forty-ties-disagree",
|
||||
"friendly-cherries-applaud",
|
||||
"friendly-chicken-cry",
|
||||
"friendly-feet-refuse",
|
||||
"gentle-dryers-smile",
|
||||
"good-steaks-report",
|
||||
"green-planets-reflect",
|
||||
"grumpy-owls-suffer",
|
||||
"healthy-timers-divide",
|
||||
"heavy-numbers-love",
|
||||
"hip-fishes-guess",
|
||||
"hip-hairs-exist",
|
||||
"khaki-lamps-peel",
|
||||
"late-games-protect",
|
||||
"light-pianos-exercise",
|
||||
"little-bulldogs-guess",
|
||||
"little-suns-fly",
|
||||
"mean-apricots-perform",
|
||||
"metal-planes-nail",
|
||||
"metal-rice-call",
|
||||
"mighty-apricots-taste",
|
||||
"mighty-dolls-retire",
|
||||
"mighty-geckos-kiss",
|
||||
"modern-parrots-protect",
|
||||
"neat-bears-divide",
|
||||
"neat-gifts-join",
|
||||
"neat-socks-cheer",
|
||||
"new-scissors-try",
|
||||
"nice-peas-retire",
|
||||
"nine-cherries-decide",
|
||||
@@ -236,16 +257,26 @@
|
||||
"orange-gifts-protect",
|
||||
"pink-gorillas-brake",
|
||||
"plenty-tools-exist",
|
||||
"purple-carrots-crash",
|
||||
"quick-roses-juggle",
|
||||
"rare-foxes-compete",
|
||||
"red-radios-promise",
|
||||
"renovate-147ac48",
|
||||
"renovate-f04beb1",
|
||||
"rich-mugs-dress",
|
||||
"selfish-bees-think",
|
||||
"seven-eggs-admire",
|
||||
"shaggy-dodos-applaud",
|
||||
"shy-games-poke",
|
||||
"shy-waves-share",
|
||||
"silly-candles-sin",
|
||||
"silly-cycles-tan",
|
||||
"six-rats-kick",
|
||||
"slow-ducks-rush",
|
||||
"slow-ligers-drum",
|
||||
"slow-toes-jog",
|
||||
"small-bottles-cough",
|
||||
"small-ears-poke",
|
||||
"small-spoons-shout",
|
||||
"smooth-countries-relate",
|
||||
"soft-gorillas-refuse",
|
||||
@@ -258,15 +289,23 @@
|
||||
"sweet-oranges-buy",
|
||||
"swift-kings-sparkle",
|
||||
"tall-snakes-fix",
|
||||
"tasty-ads-rescue",
|
||||
"thick-hotels-know",
|
||||
"thirty-adults-grab",
|
||||
"thirty-paws-hope",
|
||||
"tiny-oranges-pretend",
|
||||
"tough-goats-hang",
|
||||
"tough-lies-repair",
|
||||
"tricky-ducks-juggle",
|
||||
"two-emus-work",
|
||||
"violet-jokes-wave",
|
||||
"warm-monkeys-marry",
|
||||
"wicked-bobcats-teach",
|
||||
"wild-eggs-exist",
|
||||
"wise-spiders-walk",
|
||||
"witty-bears-behave",
|
||||
"witty-geese-battle",
|
||||
"witty-timers-marry",
|
||||
"young-games-visit",
|
||||
"young-peaches-shake"
|
||||
]
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-test-utils': patch
|
||||
---
|
||||
|
||||
Update the `ServiceFactoryTester` to be able to test services that enables multi implementation installation.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
---
|
||||
|
||||
Fix undefined in the title of Scaffolder Runs on the page load
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-api-docs': patch
|
||||
---
|
||||
|
||||
Updated dependency `@graphiql/react` to `^0.23.0`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-plugin-api': patch
|
||||
---
|
||||
|
||||
Fixed a type issue where plugin and modules depending on multiton services would not receive the correct type.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-backend': patch
|
||||
---
|
||||
|
||||
Update configuration schema to match actual behavior
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-notifications-backend-module-email': patch
|
||||
---
|
||||
|
||||
Add support for stream transport for debugging purposes
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-defaults': patch
|
||||
---
|
||||
|
||||
Update the `UrlReader` service to depends on multiple instances of `UrlReaderFactoryProvider` service.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
TechDocs now supports the `mkdocs-redirects` plugin. Redirects defined using the `mkdocs-redirect` plugin will be handled automatically in TechDocs. Redirecting to external urls is not supported. In the case that an external redirect url is provided, TechDocs will redirect to the current documentation site home.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-kubernetes-backend': patch
|
||||
---
|
||||
|
||||
Add `kubernetes.clusterLocatorMethods[].clusters[].customResources` to the configuration schema.
|
||||
This was already documented and supported by the plugin.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/create-app': patch
|
||||
---
|
||||
|
||||
Included permission config and enabled it out of the box
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-common': patch
|
||||
---
|
||||
|
||||
Internal type refactor.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/frontend-plugin-api': patch
|
||||
---
|
||||
|
||||
Support merging of `inputs` in extension blueprints, but stop merging `output`. In addition, the original factory in extension blueprints now returns a data container that both provides access to the returned data, but can also be forwarded as output.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-compat-api': patch
|
||||
---
|
||||
|
||||
Both `compatWrapper` and `convertLegacyRouteRef` now support converting from the new system to the old.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-react': patch
|
||||
---
|
||||
|
||||
Fix null check in `isJsonObject` utility function for scaffolder review state component
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
'@backstage/backend-plugin-api': minor
|
||||
---
|
||||
|
||||
The `createServiceRef` function now accepts a new boolean `multiple` option. The `multiple` option defaults to `false` and when set to `true`, it enables that multiple implementation are installed for the created service ref.
|
||||
|
||||
We're looking for ways to make it possible to augment services without the need to replace the entire service.
|
||||
|
||||
Typical example of that being the ability to install support for additional targets for the `UrlReader` service without replacing the service itself. This achieves that by allowing us to define services that can have multiple simultaneous implementation, allowing the `UrlReader` implementation to depend on such a service to collect all possible implementation of support for external targets:
|
||||
|
||||
```diff
|
||||
// @backstage/backend-defaults
|
||||
|
||||
+ export const urlReaderFactoriesServiceRef = createServiceRef<ReaderFactory>({
|
||||
+ id: 'core.urlReader.factories',
|
||||
+ scope: 'plugin',
|
||||
+ multiton: true,
|
||||
+ });
|
||||
|
||||
...
|
||||
|
||||
export const urlReaderServiceFactory = createServiceFactory({
|
||||
service: coreServices.urlReader,
|
||||
deps: {
|
||||
config: coreServices.rootConfig,
|
||||
logger: coreServices.logger,
|
||||
+ factories: urlReaderFactoriesServiceRef,
|
||||
},
|
||||
- async factory({ config, logger }) {
|
||||
+ async factory({ config, logger, factories }) {
|
||||
return UrlReaders.default({
|
||||
config,
|
||||
logger,
|
||||
+ factories,
|
||||
});
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
With that, you can then add more custom `UrlReader` factories by installing more implementations of the `urlReaderFactoriesServiceRef` in your backend instance. Something like:
|
||||
|
||||
```ts
|
||||
// packages/backend/index.ts
|
||||
import { createServiceFactory } from '@backstage/backend-plugin-api';
|
||||
import { urlReaderFactoriesServiceRef } from '@backstage/backend-defaults';
|
||||
...
|
||||
|
||||
backend.add(createServiceFactory({
|
||||
service: urlReaderFactoriesServiceRef,
|
||||
deps: {},
|
||||
async factory() {
|
||||
return CustomUrlReader.factory;
|
||||
},
|
||||
}));
|
||||
|
||||
...
|
||||
|
||||
```
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@backstage/frontend-plugin-api': minor
|
||||
---
|
||||
|
||||
**BREAKING**: All types of route refs are always considered optional by `useRouteRef`, which means the caller must always handle a potential `undefined` return value. Related to this change, the `optional` option from `createExternalRouteRef` has been removed, since it is no longer necessary.
|
||||
|
||||
This is released as an immediate breaking change as we expect the usage of the new route refs to be extremely low or zero, since plugins that support the new system will still use route refs and `useRouteRef` from `@backstage/core-plugin-api` in combination with `convertLegacyRouteRef` from `@backstage/core-compat-api`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-defaults': patch
|
||||
---
|
||||
|
||||
Avoid excessive numbers of error listeners on cache clients
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-notifications': minor
|
||||
---
|
||||
|
||||
By default, set notification as read when opening snackbar or web notification link
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
'@backstage/frontend-plugin-api': patch
|
||||
'@backstage/frontend-test-utils': patch
|
||||
---
|
||||
|
||||
Added support for being able to override extension definitions.
|
||||
|
||||
```tsx
|
||||
const TestCard = EntityCardBlueprint.make({
|
||||
...
|
||||
});
|
||||
|
||||
TestCard.override({
|
||||
// override attachment points
|
||||
attachTo: { id: 'something-else', input: 'overridden' },
|
||||
// extend the config schema
|
||||
config: {
|
||||
schema: {
|
||||
newConfig: z => z.string().optional(),
|
||||
}
|
||||
},
|
||||
// override factory
|
||||
*factory(originalFactory, { inputs, config }){
|
||||
const originalOutput = originalFactory();
|
||||
|
||||
yield coreExentsionData.reactElement(
|
||||
<Wrapping>
|
||||
{originalOutput.get(coreExentsionData.reactElement)}
|
||||
</Wrapping>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-github': patch
|
||||
---
|
||||
|
||||
Added examples for action github:pages and improved its test cases
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-search-backend-node': patch
|
||||
'@backstage/plugin-catalog-node': patch
|
||||
---
|
||||
|
||||
Explicit declare if the service ref accepts `single` or `multiple` implementations.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/frontend-test-utils': patch
|
||||
---
|
||||
|
||||
Deprecate existing `ExtensionCreators` in favour of their new Blueprint counterparts.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
'@backstage/frontend-test-utils': patch
|
||||
---
|
||||
|
||||
Refactor `.make` method on Blueprints into two different methods, `.make` and `.makeWithOverrides`.
|
||||
|
||||
When using `createExtensionBlueprint` you can define parameters for the factory function, if you wish to take advantage of these parameters you should use `.make` when creating an extension instance of a Blueprint. If you wish to override more things other than the standard `attachTo`, `name`, `namespace` then you should use `.makeWithOverrides` instead.
|
||||
|
||||
`.make` is reserved for simple creation of extension instances from Blueprints using higher level parameters, whereas `.makeWithOverrides` is lower level and you have more control over the final extension.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': minor
|
||||
---
|
||||
|
||||
Added field extension `RepoBranchPicker` that supports autocompletion for Bitbucket
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-app-api': patch
|
||||
---
|
||||
|
||||
Added configuration for the `packages` options to config schema
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-node': patch
|
||||
---
|
||||
|
||||
Fix TechDocs Edit URL for nested docs
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-sentry': patch
|
||||
---
|
||||
|
||||
Added test cases for sentry:project:create examples
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
Fixed issue where header styles were incorrectly generated when themes used CSS variables to define font size.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
---
|
||||
|
||||
Entity page extensions created for the new frontend system via the `/alpha` exports will now be enabled by default.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-notifications-backend-module-email': patch
|
||||
---
|
||||
|
||||
Notification email processor supports allowing or denying specific email addresses from receiving notifications
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-bitbucket-cloud-common': patch
|
||||
---
|
||||
|
||||
Added method `listBranchesByRepository` to `BitbucketCloudClient`
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/catalog-model': minor
|
||||
---
|
||||
|
||||
Introduce an optional spec.type attribute on the Domain and System entity kinds
|
||||
@@ -245,6 +245,7 @@ Monorepo
|
||||
monorepos
|
||||
msgraph
|
||||
msw
|
||||
multiton
|
||||
mutex
|
||||
mutexes
|
||||
mysql
|
||||
|
||||
@@ -51,7 +51,7 @@ jobs:
|
||||
|
||||
- run: yarn build-storybook
|
||||
|
||||
- uses: chromaui/action@5991575112b472a4fa85429f29cc17e2fb83a2a2 # v11
|
||||
- uses: chromaui/action@fdbe7756d4dbf493e2fbb822df73be7accd07e1c # v11
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# projectToken intentionally shared to allow collaborators to run Chromatic on forks
|
||||
|
||||
@@ -193,7 +193,7 @@ backend.add(import('@backstage/plugin-auth-backend-module-github-provider'));
|
||||
backend.add(customAuth);
|
||||
```
|
||||
|
||||
Check out [the naming patterns article](../backend-system/architecture/07-naming-patterns.md) for what rules
|
||||
Check out [the naming patterns article](../backend-system/architecture/08-naming-patterns.md) for what rules
|
||||
apply regarding how to form valid IDs. In this example we also put the module
|
||||
declaration directly in `packages/backend/src/index.ts` but that's just for
|
||||
simplicity. You can place it anywhere you like, including in other packages, and
|
||||
|
||||
@@ -38,7 +38,7 @@ export const fooServiceRef = createServiceRef<FooService>({
|
||||
|
||||
The `fooServiceRef` that we create above should be exported, and can then be used to declare a dependency on the `FooService` interface and receive an implementation of it at runtime.
|
||||
|
||||
When creating a service reference you need to give it an ID. This ID needs to be globally unique, and should generally be of the format `'<pluginId>.<serviceName>'`. For more naming patterns surrounding services, see the [naming patterns](./07-naming-patterns.md#services) page.
|
||||
When creating a service reference you need to give it an ID. This ID needs to be globally unique, and should generally be of the format `'<pluginId>.<serviceName>'`. For more naming patterns surrounding services, see the [naming patterns](./08-naming-patterns.md#services) page.
|
||||
|
||||
A note on naming: the frontend and backend systems intentionally use the separate names "APIs" and "Services" for concepts that are quite similar. This is to avoid confusion between the two, both in documentation and discussion, but also in code. While the two systems are quite similar, they are not identical, and they can't be used interchangeably.
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ Plugins provide the actual base features of a Backstage backend. Each plugin ope
|
||||
|
||||
## Defining a Plugin
|
||||
|
||||
Plugins are created using the `createBackendPlugin` function, and should typically be exported from a plugin package. All plugins must have an ID and a `register` method, where the ID matches the plugin ID in the package name, without the `-backend` suffix. See also the [dedicated section](./07-naming-patterns.md) about proper naming patterns.
|
||||
Plugins are created using the `createBackendPlugin` function, and should typically be exported from a plugin package. All plugins must have an ID and a `register` method, where the ID matches the plugin ID in the package name, without the `-backend` suffix. See also the [dedicated section](./08-naming-patterns.md) about proper naming patterns.
|
||||
|
||||
```ts
|
||||
// plugins/example-backend/src/plugin.ts
|
||||
|
||||
@@ -52,7 +52,7 @@ This allows you to install the module in your backend instance by just referenci
|
||||
|
||||
```ts
|
||||
backend.add(
|
||||
import('backstage-plugin-catalog-backend-module-example-processor'),
|
||||
import('@internal/backstage-plugin-catalog-backend-module-example-processor'),
|
||||
);
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
---
|
||||
id: feature-loaders
|
||||
title: Backend Feature Loaders
|
||||
sidebar_label: Feature Loaders
|
||||
# prettier-ignore
|
||||
description: Backend feature loaders
|
||||
---
|
||||
|
||||
Backend feature loaders are used to programmatically select and install features in a Backstage backend. They can service a wide range of use cases, such as enabling or disabling features based on static configuration, dynamically load features at runtime, or conditionally load features based on the state of a system.
|
||||
|
||||
Feature loaders are defined using the `createBackendFeatureLoader` function, exported by `@backstage/backend-plugin-api`. It accepts a `loader` function, as well as an optional `deps` object for declaring service dependencies. Unlike plugins and modules, feature loaders are limited to only depending on root-scoped services, but that still allows access to for example the [root config](../core-services/root-config.md) and [root logger](../core-services/root-logger.md) services.
|
||||
|
||||
The `loader` function can be defined in many different ways, with the main requirement being that it returns a list of `BackendFeature`s in some form. A backend feature is the kind of object that you can pass to `backend.add(...)`, for example services factories, plugins, modules, or even other feature loaders. The `loader` function can be synchronous or asynchronous, and can be defined as a generator function to allow for more complex logic.
|
||||
|
||||
## Examples
|
||||
|
||||
The following are a few example of how feature loaders can be used:
|
||||
|
||||
### Simple list of features
|
||||
|
||||
A feature loader can simply return a list of features to be installed:
|
||||
|
||||
```ts
|
||||
export default createBackendFeatureLoader({
|
||||
loader() {
|
||||
return [
|
||||
import('@backstage/plugin-search-backend/alpha'),
|
||||
import('@backstage/plugin-search-backend-module-catalog/alpha'),
|
||||
import('@backstage/plugin-search-backend-module-explore/alpha'),
|
||||
import('@backstage/plugin-search-backend-module-techdocs/alpha'),
|
||||
];
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
It can also encapsulate a collection of custom features:
|
||||
|
||||
```ts
|
||||
export default createBackendFeatureLoader({
|
||||
// Async loader is fine too
|
||||
async loader() {
|
||||
return [
|
||||
createBackendPlugin({
|
||||
...
|
||||
}),
|
||||
createBackendModule({
|
||||
...
|
||||
}),
|
||||
]
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### Conditional loading
|
||||
|
||||
A feature loader can access root-scoped services, such as the config service. This allows for conditional loading of features based on configuration. It is often convenient to use a generator function for this purpose:
|
||||
|
||||
```ts
|
||||
export default createBackendFeatureLoader({
|
||||
deps: {
|
||||
config: coreServices.rootConfig,
|
||||
},
|
||||
// The `*` in front of the function name makes it a generator function
|
||||
*loader({ config }) {
|
||||
// Example of a custom config flag to enable search
|
||||
if (config.getOptionalString('customFeatureToggle.search')) {
|
||||
yield import('@backstage/plugin-search-backend/alpha');
|
||||
yield import('@backstage/plugin-search-backend-module-catalog/alpha');
|
||||
yield import('@backstage/plugin-search-backend-module-explore/alpha');
|
||||
yield import('@backstage/plugin-search-backend-module-techdocs/alpha');
|
||||
}
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### Dynamic logic
|
||||
|
||||
A feature loader can also be asynchronous, and for example fetch data from an external source to determine which features to load:
|
||||
|
||||
```ts
|
||||
export default createBackendFeatureLoader({
|
||||
// The `async *` in front of the function name makes it an async generator function.
|
||||
async *loader() {
|
||||
const localMetadata = await readMetadataFromDisk();
|
||||
|
||||
if (localMetadata.enableSearch) {
|
||||
yield import('@backstage/plugin-search-backend/alpha');
|
||||
yield import('@backstage/plugin-search-backend-module-catalog/alpha');
|
||||
|
||||
const remoteMetadata = await fetchMetadata();
|
||||
|
||||
if (remoteMetadata.enableExplore) {
|
||||
yield import('@backstage/plugin-search-backend-module-explore/alpha');
|
||||
}
|
||||
if (remoteMetadata.enableTechDocs) {
|
||||
yield import('@backstage/plugin-search-backend-module-techdocs/alpha');
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
```
|
||||
@@ -68,7 +68,7 @@ that's specific to your plugin. In the example above, the logger might tag
|
||||
messages with your plugin ID, and the HTTP router might prefix API routes with
|
||||
your plugin ID, depending on the implementation used.
|
||||
|
||||
See [the article on naming patterns](../architecture/07-naming-patterns.md) for
|
||||
See [the article on naming patterns](../architecture/08-naming-patterns.md) for
|
||||
details on how to best choose names/IDs for plugins and related backend system
|
||||
items.
|
||||
|
||||
@@ -124,7 +124,7 @@ export const catalogModuleExampleCustomProcessor = createBackendModule({
|
||||
export { catalogModuleExampleCustomProcessor as default } from './module';
|
||||
```
|
||||
|
||||
See [the article on naming patterns](../architecture/07-naming-patterns.md) for
|
||||
See [the article on naming patterns](../architecture/08-naming-patterns.md) for
|
||||
details on how to best choose names/IDs for modules and related backend system
|
||||
items.
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@ The following example is how you can override the root logger service to add add
|
||||
|
||||
```ts
|
||||
import { coreServices } from '@backstage/backend-plugin-api';
|
||||
import { WinstonLogger } from '@backstage/backend-app-api';
|
||||
import { WinstonLogger } from '@backstage/backend-defaults/rootLogger';
|
||||
import { createConfigSecretEnumerator } from '@backstage/backend-defaults/rootConfig';
|
||||
|
||||
const backend = createBackend();
|
||||
|
||||
@@ -43,6 +44,12 @@ backend.add(
|
||||
transports: [new transports.Console()],
|
||||
});
|
||||
|
||||
const secretEnumerator = await createConfigSecretEnumerator({
|
||||
logger,
|
||||
});
|
||||
logger.addRedactions(secretEnumerator(config));
|
||||
config.subscribe?.(() => logger.addRedactions(secretEnumerator(config)));
|
||||
|
||||
return logger;
|
||||
},
|
||||
}),
|
||||
|
||||
@@ -1243,6 +1243,18 @@ system belongs to, e.g. `artists`. This field is optional.
|
||||
| --------------------------------------- | ------------------------------------------ | ----------------------------------------------------------------------------- |
|
||||
| [`Domain`](#kind-domain) (default) | Same as this entity, typically `default` | [`partOf`, and reverse `hasPart`](well-known-relations.md#partof-and-haspart) |
|
||||
|
||||
### `spec.type` [optional]
|
||||
|
||||
The type of system. There is currently no enforced set of values for this field,
|
||||
so it is left up to the adopting organization to choose a nomenclature that
|
||||
matches their catalog hierarchy. This field is optional.
|
||||
|
||||
Some common values for this field could be:
|
||||
|
||||
- `product`
|
||||
- `service`
|
||||
- `feature-set`
|
||||
|
||||
## Kind: Domain
|
||||
|
||||
Describes the following entity kind:
|
||||
@@ -1303,6 +1315,18 @@ which the domain is a part, e.g. `audio`. This field is optional.
|
||||
| --------------------------------------- | ------------------------------------------ | ----------------------------------------------------------------------------- |
|
||||
| [`Domain`](#kind-domain) (default) | Same as this entity, typically `default` | [`partOf`, and reverse `hasPart`](well-known-relations.md#partof-and-haspart) |
|
||||
|
||||
### `spec.type` [optional]
|
||||
|
||||
The type of domain. There is currently no enforced set of values for this field,
|
||||
so it is left up to the adopting organization to choose a nomenclature that
|
||||
matches their catalog hierarchy. This field is optional.
|
||||
|
||||
Some common values for this field could be:
|
||||
|
||||
- `product-area`
|
||||
- `product-group`
|
||||
- `bundle`
|
||||
|
||||
## Kind: Location
|
||||
|
||||
Describes the following entity kind:
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
---
|
||||
id: dry-run-testing
|
||||
title: Dry Run Testing
|
||||
description: How to enable and implement dry run testing in actions
|
||||
---
|
||||
|
||||
Scaffolder templates can be tested using the dry run feature of scaffolder actions. This allows you to simulate the effects of running a scaffolder action without making any actual changes to your environment, for example creating a webhook in Github. Once dry run is enabled in the scaffolder action, you can add handling to actions you use in your scaffolder templates to define how an action should operate in a dry run scenario.
|
||||
|
||||
## Enabling dry run testing
|
||||
|
||||
To enable dry run for your scaffolder action you need to add `supportsDryRun: true` to the configuration object of `createTemplateAction` in the function where the behavior of your action is defined:
|
||||
|
||||
```typescript
|
||||
export function exampleAction() {
|
||||
return createTemplateAction<{
|
||||
example: string;
|
||||
}>({
|
||||
id: 'action:example',
|
||||
description: 'Example action',
|
||||
schema: {
|
||||
input: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
example: {
|
||||
title: 'example',
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
supportsDryRun: true,
|
||||
async handler(ctx) {
|
||||
...
|
||||
},
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
## Adding handling for dry run
|
||||
|
||||
To add handling for dry run functionality you need to add a check for `ctx.isDryRun` inside the handler of the configuration object which is being passed into `createTemplateAction` in the function where the behavior of your action is defined. Once the check is successful, you can perform the desired actions expected in a dry run, e.g. outputting non-sensitive inputs.
|
||||
|
||||
```typescript
|
||||
async handler(ctx) {
|
||||
...
|
||||
|
||||
// If this is a dry run, log and return
|
||||
if (ctx.isDryRun) {
|
||||
ctx.logger.info(`Dry run complete`);
|
||||
return;
|
||||
}
|
||||
|
||||
...
|
||||
},
|
||||
```
|
||||
|
||||
## Testing dry run handling
|
||||
|
||||
You will also need to add tests for the dry run handling, for example:
|
||||
|
||||
```typescript
|
||||
it('should not perform action during dry run', async () => {
|
||||
...
|
||||
|
||||
// Create the context object with the necessary properties for a dry run
|
||||
const ctx = {
|
||||
...mockContext,
|
||||
isDryRun: true,
|
||||
input: {
|
||||
...
|
||||
},
|
||||
};
|
||||
|
||||
// Call the handler with the context
|
||||
await action.handler(ctx);
|
||||
|
||||
expect(...);
|
||||
});
|
||||
```
|
||||
@@ -441,3 +441,30 @@ repoUrl:
|
||||
`secretsKey` is the key used within the template secrets context to store the credential and `additionalScopes` is any additional permission scopes to request.
|
||||
|
||||
The supported `additionalScopes` values are `gerrit`, `github`, `gitlab`, `bitbucket`, and `azure`.
|
||||
|
||||
## RepoBranchPicker
|
||||
|
||||
The input props that can be specified under `ui:options` for the `RepoBranchPicker` field extension.
|
||||
|
||||
### `requestUserCredentials`
|
||||
|
||||
If defined will request user credentials to auth against the given SCM platform.
|
||||
|
||||
```yaml
|
||||
repoUrl:
|
||||
title: Repository Branch
|
||||
type: string
|
||||
ui:field: RepoBranchPicker
|
||||
ui:options:
|
||||
requestUserCredentials:
|
||||
secretsKey: USER_OAUTH_TOKEN
|
||||
additionalScopes:
|
||||
github:
|
||||
- workflow:write
|
||||
```
|
||||
|
||||
`secretsKey` is the key used within the template secrets context to store the credential and `additionalScopes` is any additional permission scopes to request.
|
||||
|
||||
The supported `additionalScopes` values are `gerrit`, `github`, `gitlab`, `bitbucket`, and `azure`.
|
||||
|
||||
If you're also using the `RepoUrlPicker` field extension, you should simply duplicate this part from there.
|
||||
|
||||
@@ -477,6 +477,34 @@ template can be published to multiple providers.
|
||||
Note, that you will need to configure an [authentication provider](../../auth/index.md#configuring-authentication-providers), alongside the
|
||||
[`ScmAuthApi`](../../auth/index.md#scaffolder-configuration-software-templates) for your source code management (SCM) service to make this feature work.
|
||||
|
||||
### The Repository Branch Picker
|
||||
|
||||
Similar to the repository picker, there is a picker for branches to support autocompletion. A full example could look like this:
|
||||
|
||||
```yaml
|
||||
- title: Choose a branch
|
||||
required:
|
||||
- repoBranch
|
||||
properties:
|
||||
repoBranch:
|
||||
title: Repository Branch
|
||||
type: string
|
||||
ui:field: RepoBranchPicker
|
||||
ui:options:
|
||||
requestUserCredentials:
|
||||
secretsKey: USER_OAUTH_TOKEN
|
||||
```
|
||||
|
||||
Passing the `requestUserCredentials` object is required for autocompletion to work.
|
||||
If you're also using the repository picker, you should simply duplicate this part from there.
|
||||
For more information regarding the `requestUserCredentials` object, please refer to the [Using the Users `oauth` token](#using-the-users-oauth-token) section under [The Repository Picker](#the-repository-picker).
|
||||
|
||||
For a list of all possible `ui:options` input props for `RepoBranchPicker`, please visit [here](./ui-options-examples.md#repobranchpicker).
|
||||
|
||||
The `RepoBranchPicker` is a custom field that we provide part of the
|
||||
`plugin-scaffolder`. You can provide your own custom fields by
|
||||
[writing your own Custom Field Extensions](./writing-custom-field-extensions.md)
|
||||
|
||||
### Accessing the signed-in users details
|
||||
|
||||
Sometimes when authoring templates, you'll want to access the user that is running the template, and get details from the profile or the users `Entity` in the Catalog.
|
||||
|
||||
@@ -20,7 +20,7 @@ techdocs:
|
||||
# spin up the techdocs-container docker image or to run mkdocs locally (assuming all the dependencies are taken care of).
|
||||
# You want to change this to 'local' if you are running Backstage using your own custom Docker setup and want to avoid running
|
||||
# into Docker in Docker situation. Read more here
|
||||
# https://backstage.io/docs/features/techdocs/getting-started#disable-docker-in-docker-situation-optional
|
||||
# https://backstage.io/docs/features/techdocs/getting-started/#disabling-docker-in-docker-situation-optional
|
||||
|
||||
runIn: 'docker'
|
||||
|
||||
|
||||
@@ -101,23 +101,26 @@ export const IndexPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h1>Index Page</h1>
|
||||
<a
|
||||
{/* highlight-start */}
|
||||
href={getDetailsPath({
|
||||
kind: 'component',
|
||||
namespace: 'default',
|
||||
name: 'foo',
|
||||
})}
|
||||
{/* highlight-end */}
|
||||
>
|
||||
See "Foo" details
|
||||
</a>
|
||||
{/* highlight-next-line */}
|
||||
{getDetailsPath && (
|
||||
<a
|
||||
{/* highlight-start */}
|
||||
href={getDetailsPath({
|
||||
kind: 'component',
|
||||
namespace: 'default',
|
||||
name: 'foo',
|
||||
})}
|
||||
{/* highlight-end */}
|
||||
>
|
||||
See "Foo" details
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
We use the `useRouteRef` hook to create a link generator function that returns the details page path. We then call the link generator, passing it an object with the kind, namespace, and name. These parameters are used to construct a concrete path to the "Foo" details page.
|
||||
We use the `useRouteRef` hook to create a link generator function that returns the details page path. First we need to check whether the route is available, the link generator function will be `undefined` if it isn't. We then call the link generator, passing it an object with the kind, namespace, and name. These parameters are used to construct a concrete path to the "Foo" details page.
|
||||
|
||||
Let's see how the details page can get the parameters from the URL:
|
||||
|
||||
@@ -176,8 +179,11 @@ export const IndexPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<h1>Index Page</h1>
|
||||
{/* highlight-next-line */}
|
||||
<a href={getCreateComponentPath()}>Create Component</a>
|
||||
{/* highlight-start */}
|
||||
{getCreateComponentPath && (
|
||||
<a href={getCreateComponentPath()}>Create Component</a>
|
||||
)}
|
||||
{/* highlight-end */}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -289,42 +295,6 @@ export const createComponentExternalRouteRef = createExternalRouteRef({
|
||||
});
|
||||
```
|
||||
|
||||
### Optional External Route References
|
||||
|
||||
It is possible to define an `ExternalRouteRef` as optional, so it is not required to bind it in the app.
|
||||
|
||||
```tsx title="plugins/catalog/src/routes.ts"
|
||||
import { createExternalRouteRef } from '@backstage/frontend-plugin-api';
|
||||
|
||||
export const createComponentExternalRouteRef = createExternalRouteRef({
|
||||
// highlight-next-line
|
||||
optional: true,
|
||||
});
|
||||
```
|
||||
|
||||
When calling `useRouteRef` with an optional external route, its return signature is changed to `RouteFunc | undefined`, and the returned value can be used to decide whether a certain link should be displayed or if an action should be taken:
|
||||
|
||||
```tsx title="plugins/catalog/src/components/IndexPage.tsx"
|
||||
import React from 'react';
|
||||
import { useRouteRef } from '@backstage/frontend-plugin-api';
|
||||
import { createComponentExternalRouteRef } from '../routes';
|
||||
|
||||
export const IndexPage = () => {
|
||||
const getCreateComponentPath = useRouteRef(createComponentExternalRouteRef);
|
||||
return (
|
||||
<div>
|
||||
<h1>Index Page</h1>
|
||||
{/* Rendering the link only if the getCreateComponentPath is defined */}
|
||||
{/* highlight-start */}
|
||||
{getCreateComponentPath && (
|
||||
<a href={getCreateComponentPath()}>Create Component</a>
|
||||
)}
|
||||
{/* highlight-end */}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## Sub Route References
|
||||
|
||||
The last kind of route ref that can be created is a `SubRouteRef`, which can be used to create a route ref with a fixed path relative to an absolute `RouteRef`. They are useful if you have a page that internally is mounted at a sub route of a page extension component, and you want other plugins to be able to route to that page. And they can be a useful utility to handle routing within a plugin itself as well.
|
||||
@@ -368,17 +338,21 @@ import { DetailsPage } from './DetailsPage';
|
||||
|
||||
export const IndexPage = () => {
|
||||
const { pathname } = useLocation();
|
||||
|
||||
// highlight-start
|
||||
const getIndexPath = useRouteRef(indexRouteRef);
|
||||
const getDetailsPath = useRouteRef(detailsSubRouteRef);
|
||||
// highlight-end
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>Index Page</h1>
|
||||
{/* Linking to the details sub route */}
|
||||
{pathname === getIndexPath() ? (
|
||||
// highlight-start
|
||||
{/* highlight-start */}
|
||||
{pathname === getIndexPath?.() ? (
|
||||
<a
|
||||
{/* Setting the details sub route params */}
|
||||
href={getDetailsPath({
|
||||
href={getDetailsPath?.({
|
||||
kind: 'component',
|
||||
namespace: 'default',
|
||||
name: 'foo',
|
||||
@@ -386,13 +360,14 @@ export const IndexPage = () => {
|
||||
>
|
||||
Show details
|
||||
</a>
|
||||
// highlight-end
|
||||
{/* highlight-end */}
|
||||
) : (
|
||||
// highlight-next-line
|
||||
<a href={getIndexPath()}>Hide details</a>
|
||||
{/* highlight-next-line */}
|
||||
<a href={getIndexPath?.()}>Hide details</a>
|
||||
)}
|
||||
{/* Registering the details sub route */}
|
||||
<Routes>
|
||||
{/* highlight-next-line */}
|
||||
<Route path={detailsSubRouteRef.path} element={<DetailsPage />} />
|
||||
</Routes>
|
||||
</div>
|
||||
|
||||
@@ -28,6 +28,51 @@ app:
|
||||
|
||||
If your [`app-config.yaml`](https://github.com/backstage/backstage/blob/e0506af8fc54074a160fb91c83d6cae8172d3bb3/app-config.yaml#L5) file does not have this configuration, you may have to adjust your [`packages/app/public/index.html`](https://github.com/backstage/backstage/blob/e0506af8fc54074a160fb91c83d6cae8172d3bb3/packages/app/public/index.html#L69) to include the Datadog RUM `init()` section manually.
|
||||
|
||||
Please note that the env value MUST be specified at build time
|
||||
|
||||
:::note
|
||||
In case after a proper configuration, the events still are not being captured: Copy and paste this section in to your `packages/app/public/index.html` under the `<head>` tag.
|
||||
|
||||
```html
|
||||
<% if (config.has('app.datadogRum')) { %>
|
||||
<script>
|
||||
(function (h, o, u, n, d) {
|
||||
h = h[d] = h[d] || {
|
||||
q: [],
|
||||
onReady: function (c) {
|
||||
h.q.push(c);
|
||||
},
|
||||
};
|
||||
d = o.createElement(u);
|
||||
d.async = 1;
|
||||
d.src = n;
|
||||
n = o.getElementsByTagName(u)[0];
|
||||
n.parentNode.insertBefore(d, n);
|
||||
})(
|
||||
window,
|
||||
document,
|
||||
'script',
|
||||
'https://www.datadoghq-browser-agent.com/datadog-rum-v3.js',
|
||||
'DD_RUM',
|
||||
);
|
||||
DD_RUM.onReady(function () {
|
||||
DD_RUM.init({
|
||||
clientToken: '<%= config.getString("app.datadogRum.clientToken") %>',
|
||||
applicationId: '<%= config.getString("app.datadogRum.applicationId") %>',
|
||||
site: '<%= config.getOptionalString("app.datadogRum.site") || "datadoghq.com" %>',
|
||||
service: 'backstage',
|
||||
env: '<%= config.getString("app.datadogRum.env") %>',
|
||||
sampleRate:
|
||||
'<%= config.getOptionalNumber("app.datadogRum.sessionSampleRate") || 100 %>',
|
||||
sessionReplaySampleRate:
|
||||
'<%= config.getOptionalNumber("app.datadogRum.sessionReplaySampleRate") || 0 %>',
|
||||
trackInteractions: true,
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<% } %>
|
||||
```
|
||||
|
||||
The `clientToken` and `applicationId` are generated from the Datadog RUM page
|
||||
following
|
||||
[these instructions](https://docs.datadoghq.com/real_user_monitoring/browser/).
|
||||
|
||||
@@ -0,0 +1,320 @@
|
||||
---
|
||||
id: index
|
||||
title: Getting Started
|
||||
description: How to get started with the notifications and signals
|
||||
---
|
||||
|
||||
The Backstage Notifications System provides a way for plugins and external services to send notifications to Backstage users.
|
||||
These notifications are displayed in the dedicated page of the Backstage frontend UI or by frontend plugins per specific scenarios.
|
||||
Additionally, notifications can be sent to external channels (like email) via "processors" implemented within plugins.
|
||||
|
||||
Notifications can be optionally integrated with the signals (a push mechanism) to ensure users receive them immediately.
|
||||
|
||||
### Upgrade to the latest version of Backstage
|
||||
|
||||
To ensure your version of Backstage has all the latest notifications and signals related functionality, it’s important to upgrade to the latest version. The [Backstage upgrade helper](https://backstage.github.io/upgrade-helper/) is a great tool to help ensure that you’ve made all the necessary changes during the upgrade!
|
||||
|
||||
## About notifications
|
||||
|
||||
Notifications are messages sent to either individual users or groups.
|
||||
They are not intended for inter-process communication of any kind.
|
||||
|
||||
There are two basic types of notifications:
|
||||
|
||||
- **Broadcast**: Messages sent to all users of Backstage.
|
||||
- **Entity**: Messages delivered to specific listed entities, such as Users or Groups.
|
||||
|
||||
Example of use-cases:
|
||||
|
||||
- System-wide announcements or alerts
|
||||
- Notifications for component owners: e.g., build failures, successful deployments, new vulnerabilities
|
||||
- Notifications for individuals: e.g., updates you have subscribed to, new required training courses
|
||||
- Notifications pertaining to a particular entity in the catalog: A notification might apply to an entity and the owning team.
|
||||
|
||||
## Installation in Older Environments
|
||||
|
||||
Newer versions of instances created by the create-app have both the notifications and signals plugins included by default, this section can be skipped right to the Configuration.
|
||||
|
||||
Following installation instructions are valid for enabling the plugins in older environments.
|
||||
|
||||
### Add Notifications Backend
|
||||
|
||||
```bash
|
||||
yarn workspace backend add @backstage/plugin-notifications-backend
|
||||
```
|
||||
|
||||
Add the notifications to your `backend/src/index.ts`:
|
||||
|
||||
```ts
|
||||
const backend = createBackend();
|
||||
// ...
|
||||
backend.add(import('@backstage/plugin-notifications-backend'));
|
||||
```
|
||||
|
||||
### Add Notifications Frontend
|
||||
|
||||
```bash
|
||||
yarn workspace app add @backstage/notifications
|
||||
```
|
||||
|
||||
To add the notifications main menu, add following to your `packages/app/src/components/Root/Root.tsx`:
|
||||
|
||||
```tsx
|
||||
import { NotificationsSidebarItem } from '@backstage/plugin-notifications';
|
||||
|
||||
<SidebarPage>
|
||||
<Sidebar>
|
||||
<SidebarGroup>
|
||||
// ...
|
||||
<NotificationsSidebarItem />
|
||||
</SidebarGroup>
|
||||
</Sidebar>
|
||||
</SidebarPage>;
|
||||
```
|
||||
|
||||
Also add the route to notifications to `packages/app/src/App.tsx`:
|
||||
|
||||
```tsx
|
||||
import { NotificationsPage } from '@backstage/plugin-notifications';
|
||||
|
||||
<FlatRoutes>
|
||||
// ...
|
||||
<Route path="/notifications" element={<NotificationsPage />} />
|
||||
</FlatRoutes>;
|
||||
```
|
||||
|
||||
### Optional: Add Signals Backend
|
||||
|
||||
Optionally add Signals to your backend by
|
||||
|
||||
```bash
|
||||
yarn workspace backend add @backstage/plugin-signals-backend
|
||||
```
|
||||
|
||||
Add the signals to your `backend/src/index.ts`:
|
||||
|
||||
```ts
|
||||
const backend = createBackend();
|
||||
// ...
|
||||
backend.add(import('@backstage/plugin-signals-backend'));
|
||||
```
|
||||
|
||||
### Optional: Signals Frontend
|
||||
|
||||
The use of signals is optional but improves user experience.
|
||||
|
||||
Start with:
|
||||
|
||||
```bash
|
||||
yarn workspace app add @backstage/plugin-signals
|
||||
```
|
||||
|
||||
To install the plugin, you have to add the following to your `packages/app/src/plugins.ts`:
|
||||
|
||||
```ts
|
||||
export { signalsPlugin } from '@backstage/plugin-signals';
|
||||
```
|
||||
|
||||
And make sure that your `packages/app/src/App.tsx` contains:
|
||||
|
||||
```ts
|
||||
import * as plugins from './plugins';
|
||||
|
||||
const app = createApp({
|
||||
// ...
|
||||
plugins: Object.values(plugins),
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
If the signals plugin is properly configured, it will be automatically discovered by the notifications plugin and used.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Notifications Backend
|
||||
|
||||
The Notifications backend plugin provides an API to create notifications, list notifications per logged-in user, and search based on parameters.
|
||||
|
||||
The plugin uses a relational [database](https://backstage.io/docs/getting-started/config/database) for persistence, no specifics are introduced in this context.
|
||||
|
||||
No additional configuration in the app-config is needed, except for optional additional modules for `processors`.
|
||||
|
||||
### Notifications Frontend
|
||||
|
||||
The recipients of notifications have to be entities in the catalog, e.g. of the User or Group kind.
|
||||
|
||||
Otherwise no specific configuration is needed for the front-end notifications plugin.
|
||||
|
||||
All parametrization is done through component properties, such as the `NotificationsSidebarItem`, which can be used as an active left-side menu item in the front-end.
|
||||
|
||||

|
||||
|
||||
In the `packages/app/src/components/Root/Root.tsx`, tweak the [properties](https://backstage.io/docs/reference/plugin-notifications.notificationssidebaritem) of the `<NotificationsSidebarItem />` per specific needs.
|
||||
|
||||
## Use
|
||||
|
||||
New notifications can be sent either by a backend plugin or an external service through the REST API.
|
||||
|
||||
### Backend
|
||||
|
||||
Regardless of technical feasibility, a backend plugin should avoid directly accessing the notifications REST API.
|
||||
Instead, it should integrate with the `@backstage/plugin-notifications-node` to `send` (create) a new notification.
|
||||
|
||||
The reasons for this approach include the propagation of authorization in the API request and improved maintenance and backward compatibility in the future.
|
||||
|
||||
```ts
|
||||
import { notificationService } from '@backstage/plugin-notifications-node';
|
||||
|
||||
export const myPlugin = createBackendPlugin({
|
||||
pluginId: 'myPlugin',
|
||||
register(env) {
|
||||
env.registerInit({
|
||||
deps: {
|
||||
// ...
|
||||
notificationService: notificationService,
|
||||
},
|
||||
async init({ config, logger, httpRouter, notificationService }) {
|
||||
httpRouter.use(
|
||||
await createRouter({
|
||||
// ...
|
||||
notificationService,
|
||||
}),
|
||||
);
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
To emit a new notification:
|
||||
|
||||
```ts
|
||||
notificationService.send({
|
||||
recipients /* of the broadcast or entity type */,
|
||||
payload /* actual message */,
|
||||
});
|
||||
```
|
||||
|
||||
Refer the [API documentation](https://github.com/backstage/backstage/blob/master/plugins/notifications-node/api-report.md) for further details.
|
||||
|
||||
### Signals
|
||||
|
||||
The use of signals with notifications is optional but generally enhances user experience and performance.
|
||||
|
||||
When a notification is created, a new signal is emitted to a general-purpose message bus to announce it to subscribed listeners.
|
||||
|
||||
The frontend maintains a persistent connection (WebSocket) to receive these announcements from the notifications channel.
|
||||
The specific details of the updated or created notification should be retrieved via a request to the notifications API, except for new notifications, where the payload is included in the signal for performance reasons.
|
||||
|
||||
In a frontend plugin, to subscribe for notifications' signals:
|
||||
|
||||
```ts
|
||||
import { useSignal } from '@backstage/plugin-signals-react';
|
||||
|
||||
const { lastSignal } = useSignal<NotificationSignal>('notifications');
|
||||
|
||||
React.useEffect(() => {
|
||||
/* ... */
|
||||
}, [lastSignal, notificationsApi]);
|
||||
```
|
||||
|
||||
### Consuming Notifications
|
||||
|
||||
In a front-end plugin, the simplest way to query a notification is by its ID:
|
||||
|
||||
```ts
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
import { notificationsApiRef } from '@backstage/plugin-notifications';
|
||||
|
||||
const notificationsApi = useApi(notificationsApiRef);
|
||||
|
||||
notificationsApi.getNotification(yourId);
|
||||
|
||||
// or with connection to signals:
|
||||
notificationsApi.getNotification(lastSignal.notification_id);
|
||||
```
|
||||
|
||||
### Extending Notifications via Processors
|
||||
|
||||
The notifications can be extended with `NotificationProcessor`. These processors allow to decorate notifications before they are sent or/and send the notifications to external services.
|
||||
|
||||
Depending on the needs, a processor can modify the content of a notification or route it to different systems like email, Slack, or other services.
|
||||
|
||||
A good example of how to write a processor is the [Email Processor](https://github.com/backstage/backstage/tree/master/plugins/notifications-backend-module-email).
|
||||
|
||||
Start off by creating a notification processor:
|
||||
|
||||
```ts
|
||||
import { Notification } from '@backstage/plugin-notifications-common';
|
||||
import { NotificationProcessor } from '@backstage/plugin-notifications-node';
|
||||
|
||||
class MyNotificationProcessor implements NotificationProcessor {
|
||||
async decorate(notification: Notification): Promise<Notification> {
|
||||
if (notification.origin === 'plugin-my-plugin') {
|
||||
notification.payload.icon = 'my-icon';
|
||||
}
|
||||
return notification;
|
||||
}
|
||||
|
||||
async send(notification: Notification): Promise<void> {
|
||||
nodemailer.sendEmail({
|
||||
from: 'backstage',
|
||||
to: 'user',
|
||||
subject: notification.payload.title,
|
||||
text: notification.payload.description,
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Both of the processing functions are optional, and you can implement only one of them.
|
||||
|
||||
Add the notification processor to the notification system by:
|
||||
|
||||
```ts
|
||||
import { notificationsProcessingExtensionPoint } from '@backstage/plugin-notifications-node';
|
||||
import { Notification } from '@backstage/plugin-notifications-common';
|
||||
|
||||
export const myPlugin = createBackendPlugin({
|
||||
pluginId: 'myPlugin',
|
||||
register(env) {
|
||||
env.registerInit({
|
||||
deps: {
|
||||
notifications: notificationsProcessingExtensionPoint,
|
||||
// ...
|
||||
},
|
||||
async init({ notifications }) {
|
||||
// ...
|
||||
notifications.addProcessor(new MyNotificationProcessor());
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### External Services
|
||||
|
||||
When the emitter of a notification is a Backstage backend plugin, it is mandatory to use the integration via `@backstage/plugin-notifications-node` as described above.
|
||||
|
||||
If the emitter is a service external to Backstage, an HTTP POST request can be issued directly to the API, assuming that authentication is properly configured.
|
||||
Refer to the [service-to-service auth documentation](https://backstage.io/docs/auth/service-to-service-auth) for more details, focusing on the Static Tokens section for the simplest setup option.
|
||||
|
||||
An example request for creating a broadcast notification might look like:
|
||||
|
||||
```bash
|
||||
curl -X POST https://[BACKSTAGE_BACKEND]/api/notifications -H "Content-Type: application/json" -H "Authorization: Bearer YOUR_BASE64_SHARED_KEY_TOKEN" -d '{"recipients":{"type":"broadcast"},"payload": {"title": "Title of broadcast message","link": "http://foo.com/bar","severity": "high","topic": "The topic"}}'
|
||||
```
|
||||
|
||||
## Additional info
|
||||
|
||||
An example of a backend plugin sending notifications can be found in https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-notifications.
|
||||
|
||||
Sources of the notifications and signal plugins:
|
||||
|
||||
- https://github.com/backstage/backstage/blob/master/plugins/notifications
|
||||
|
||||
- https://github.com/backstage/backstage/blob/master/plugins/notifications-backend
|
||||
|
||||
- https://github.com/backstage/backstage/blob/master/plugins/notifications-node
|
||||
|
||||
- https://github.com/backstage/backstage/blob/master/plugins/signals-react
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 135 KiB |
@@ -199,7 +199,8 @@ const routes = (
|
||||
<RequirePermission permission={todoListCreatePermission}>
|
||||
<TodoListPage />
|
||||
</RequirePermission>
|
||||
{/* highlight-add-end */}}
|
||||
{/* highlight-add-end */}
|
||||
}>
|
||||
{/* ... */}
|
||||
</Route>
|
||||
</FlatRoutes>
|
||||
|
||||
@@ -17,7 +17,12 @@ See how to install Datadog Events in your app
|
||||
|
||||
### New Backend
|
||||
|
||||
The backend supplies a central logging service, [`rootLogger`](../backend-system/core-services/root-logger.md), as well as a plugin based logger, [`logger`](../backend-system/core-services/logger.md) from `coreServices`. To add additional granularity to your logs, you can create children from the plugin based logger, using the `.child()` method and provide is with JSON data. For example, if you wanted to log items for a specific span in your plugin, you could do
|
||||
The backend supplies a central logging service,
|
||||
[`rootLogger`](../backend-system/core-services/root-logger.md), as well as a plugin
|
||||
based logger, [`logger`](../backend-system/core-services/logger.md) from `coreServices`.
|
||||
To add additional granularity to your logs, you can create children from the plugin
|
||||
based logger, using the `.child()` method and provide is with JSON data. For example,
|
||||
if you wanted to log items for a specific span in your plugin, you could do
|
||||
|
||||
```ts
|
||||
export function createRouter({ logger }) {
|
||||
@@ -37,7 +42,9 @@ export function createRouter({ logger }) {
|
||||
}
|
||||
```
|
||||
|
||||
You can also add additional metadata to all logs for your Backstage instance by overriding the `rootLogger` implementation, you can see an example in [the `logger` docs](../backend-system/core-services/logger.md#configuring-the-service).
|
||||
You can also add additional metadata to all logs for your Backstage instance by
|
||||
overriding the `rootLogger` implementation, you can see an example in
|
||||
[the `rootLogger` docs](../backend-system/core-services/root-logger.md#configuring-the-service).
|
||||
|
||||
### Old Backend
|
||||
|
||||
@@ -63,9 +70,19 @@ An example log line could look as follows:
|
||||
|
||||
## Health Checks
|
||||
|
||||
### New Backend
|
||||
### New Backend (post 1.29.0)
|
||||
|
||||
The new backend is moving towards health checks being plugin-based, as such there is no current plugin for providing a health check route. You can add this yourself easily though,
|
||||
The new backend provides a `RootHealthService` which implements
|
||||
`/.backstage/health/v1/readiness` and `/.backstage/health/v1/liveness` endpoints
|
||||
to provide health checks for the entire backend instance.
|
||||
|
||||
You can read more about this new service and how to customize it in the
|
||||
[Root Health Service documentation](../backend-system/core-services/root-health.md).
|
||||
|
||||
### New Backend (pre 1.29.0)
|
||||
|
||||
The new backend is moving towards health checks being plugin-based, as such there is no
|
||||
current plugin for providing a health check route. You can add this yourself easily though,
|
||||
|
||||
```ts
|
||||
import {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -4,9 +4,9 @@ author: Deepankumar
|
||||
authorUrl: https://github.com/deepan10
|
||||
category: Infrastructure
|
||||
description: Explore Azure Storage Blobs in Backstage.
|
||||
documentation: https://github.com/deepan10/backstage-plugins/tree/main/plugins/azure-storage
|
||||
documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/azure-storage-explorer/plugins/azure-storage
|
||||
iconUrl: /img/azure-storage-folder.png
|
||||
npmPackageName: 'backstage-plugin-azure-storage'
|
||||
npmPackageName: '@backstage-community/plugin-azure-storage-explorer'
|
||||
tags:
|
||||
- Azure
|
||||
- Azure Storage
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: VeeCode Infracost
|
||||
author: VeeCode Platform
|
||||
authorUrl: https://platform.vee.codes/
|
||||
category: FinOps
|
||||
description: The Infracost plug-in works in conjunction with terraform and provides a graphical representation and cost estimate data for your entity at your respective provider.
|
||||
documentation: https://platform.vee.codes/plugin/Infracost
|
||||
iconUrl: https://veecode-platform.github.io/support/imgs/logo_5.svg
|
||||
npmPackageName: '@veecode-platform/backstage-plugin-infracost'
|
||||
tags:
|
||||
- finops
|
||||
- infracost
|
||||
- estimate
|
||||
- terraform
|
||||
addedDate: '2024-07-25'
|
||||
@@ -6,7 +6,7 @@ category: Discovery
|
||||
description: Visualize, understand and optimize your team's tech health.
|
||||
documentation: https://roadie.io/backstage/plugins/tech-insights/
|
||||
iconUrl: https://roadie.io/images/logos/tech-insights.png
|
||||
npmPackageName: '@backstage/plugin-tech-insights'
|
||||
npmPackageName: '@backstage-community/plugin-tech-insights'
|
||||
tags:
|
||||
- tech-insights
|
||||
- reporting
|
||||
|
||||
@@ -121,7 +121,8 @@
|
||||
"features/software-templates/writing-custom-step-layouts",
|
||||
"features/software-templates/authorizing-scaffolder-template-details",
|
||||
"features/software-templates/migrating-to-rjsf-v5",
|
||||
"features/software-templates/migrating-from-v1beta2-to-v1beta3"
|
||||
"features/software-templates/migrating-from-v1beta2-to-v1beta3",
|
||||
"features/software-templates/dry-run-testing"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -296,6 +297,7 @@
|
||||
"conf/writing",
|
||||
"conf/defining"
|
||||
],
|
||||
"Notifications": ["notifications/index"],
|
||||
"Auth and identity": [
|
||||
"auth/index",
|
||||
{
|
||||
@@ -393,6 +395,7 @@
|
||||
"backend-system/architecture/plugins",
|
||||
"backend-system/architecture/extension-points",
|
||||
"backend-system/architecture/modules",
|
||||
"backend-system/architecture/feature-loaders",
|
||||
"backend-system/architecture/naming-patterns"
|
||||
]
|
||||
},
|
||||
|
||||
@@ -64,6 +64,7 @@ nav:
|
||||
- Writing Custom Actions: 'features/software-templates/writing-custom-actions.md'
|
||||
- Writing Custom Step Layouts: 'features/software-templates/writing-custom-step-layouts.md'
|
||||
- Migrating from v1beta2 to v1beta3 templates: 'features/software-templates/migrating-from-v1beta2-to-v1beta3.md'
|
||||
- Dry Run Testing: 'features/software-templates/dry-run-testing.md'
|
||||
- Backstage Search:
|
||||
- Overview: 'features/search/README.md'
|
||||
- Getting Started: 'features/search/getting-started.md'
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "root",
|
||||
"version": "1.30.0-next.2",
|
||||
"version": "1.30.0-next.3",
|
||||
"private": true,
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
# @backstage/app-defaults
|
||||
|
||||
## 1.5.10-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-permission-react@0.4.25-next.1
|
||||
- @backstage/core-app-api@1.14.2-next.0
|
||||
- @backstage/core-components@0.14.10-next.0
|
||||
- @backstage/core-plugin-api@1.9.3
|
||||
- @backstage/theme@0.5.6
|
||||
|
||||
## 1.5.10-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@backstage/app-defaults",
|
||||
"version": "1.5.10-next.1",
|
||||
"version": "1.5.10-next.2",
|
||||
"description": "Provides the default wiring of a Backstage App",
|
||||
"backstage": {
|
||||
"role": "web-library"
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# app-next-example-plugin
|
||||
|
||||
## 0.0.14-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/frontend-plugin-api@0.7.0-next.2
|
||||
- @backstage/core-components@0.14.10-next.0
|
||||
|
||||
## 0.0.14-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -7,7 +7,7 @@ import { BackstagePlugin } from '@backstage/frontend-plugin-api';
|
||||
import { default as React_2 } from 'react';
|
||||
|
||||
// @public (undocumented)
|
||||
const examplePlugin: BackstagePlugin<{}, {}>;
|
||||
const examplePlugin: BackstagePlugin<{}, {}, {}>;
|
||||
export default examplePlugin;
|
||||
|
||||
// @public (undocumented)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "app-next-example-plugin",
|
||||
"version": "0.0.14-next.1",
|
||||
"version": "0.0.14-next.2",
|
||||
"description": "Backstage internal example plugin",
|
||||
"backstage": {
|
||||
"role": "frontend-plugin",
|
||||
|
||||
@@ -1,5 +1,48 @@
|
||||
# example-app-next
|
||||
|
||||
## 0.0.14-next.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-scaffolder-react@1.11.0-next.2
|
||||
- @backstage/plugin-catalog@1.22.0-next.2
|
||||
- @backstage/frontend-plugin-api@0.7.0-next.2
|
||||
- @backstage/cli@0.27.0-next.3
|
||||
- @backstage/frontend-app-api@0.7.5-next.2
|
||||
- @backstage/core-compat-api@0.2.8-next.2
|
||||
- @backstage/plugin-app-visualizer@0.1.9-next.2
|
||||
- @backstage/plugin-search-common@1.2.14-next.1
|
||||
- @backstage/plugin-search-react@1.7.14-next.2
|
||||
- @backstage/plugin-search@1.4.15-next.2
|
||||
- @backstage/plugin-api-docs@0.11.8-next.2
|
||||
- @backstage/plugin-techdocs@1.10.8-next.2
|
||||
- @backstage/plugin-scaffolder@1.24.0-next.2
|
||||
- @backstage/plugin-catalog-react@1.12.3-next.2
|
||||
- @backstage/plugin-catalog-graph@0.4.8-next.3
|
||||
- @backstage/plugin-catalog-import@0.12.2-next.2
|
||||
- @backstage/plugin-org@0.6.28-next.2
|
||||
- @backstage/plugin-user-settings@0.8.11-next.2
|
||||
- @backstage/plugin-home@0.7.9-next.2
|
||||
- @backstage/plugin-kubernetes@0.11.13-next.2
|
||||
- @backstage/plugin-catalog-common@1.0.26-next.1
|
||||
- @backstage/plugin-permission-react@0.4.25-next.1
|
||||
- @backstage/app-defaults@1.5.10-next.2
|
||||
- @backstage/catalog-model@1.5.0
|
||||
- @backstage/config@1.2.0
|
||||
- @backstage/core-app-api@1.14.2-next.0
|
||||
- @backstage/core-components@0.14.10-next.0
|
||||
- @backstage/core-plugin-api@1.9.3
|
||||
- @backstage/integration-react@1.1.30-next.0
|
||||
- @backstage/theme@0.5.6
|
||||
- @backstage/plugin-auth-react@0.1.5-next.0
|
||||
- @backstage/plugin-catalog-unprocessed-entities@0.2.7-next.0
|
||||
- @backstage/plugin-kubernetes-cluster@0.0.14-next.2
|
||||
- @backstage/plugin-notifications@0.2.4-next.0
|
||||
- @backstage/plugin-signals@0.0.9-next.0
|
||||
- @backstage/plugin-techdocs-module-addons-contrib@1.1.13-next.0
|
||||
- @backstage/plugin-techdocs-react@1.2.7-next.0
|
||||
|
||||
## 0.0.14-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "example-app-next",
|
||||
"version": "0.0.14-next.2",
|
||||
"version": "0.0.14-next.3",
|
||||
"private": true,
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -47,9 +47,11 @@ const IndexPage = createPageExtension({
|
||||
return (
|
||||
<div>
|
||||
op
|
||||
<div>
|
||||
<Link to={page1Link()}>Page 1</Link>
|
||||
</div>
|
||||
{page1Link && (
|
||||
<div>
|
||||
<Link to={page1Link()}>Page 1</Link>
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<Link to="/home">Home</Link>
|
||||
</div>
|
||||
@@ -82,10 +84,10 @@ const Page1 = createPageExtension({
|
||||
return (
|
||||
<div>
|
||||
<h1>This is page 1</h1>
|
||||
<Link to={indexLink()}>Go back</Link>
|
||||
{indexLink && <Link to={indexLink()}>Go back</Link>}
|
||||
<Link to="./page2">Page 2</Link>
|
||||
{/* <Link to={page2Link()}>Page 2</Link> */}
|
||||
<Link to={xLink()}>Page X</Link>
|
||||
{xLink && <Link to={xLink()}>Page X</Link>}
|
||||
|
||||
<div>
|
||||
Sub-page content:
|
||||
@@ -115,7 +117,7 @@ const ExternalPage = createPageExtension({
|
||||
return (
|
||||
<div>
|
||||
<h1>This is page X</h1>
|
||||
<Link to={indexLink()}>Go back</Link>
|
||||
{indexLink && <Link to={indexLink()}>Go back</Link>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user