diff --git a/.changeset/afraid-planets-crash.md b/.changeset/afraid-planets-crash.md
new file mode 100644
index 0000000000..b31a492f3d
--- /dev/null
+++ b/.changeset/afraid-planets-crash.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-app-api': minor
+---
+
+**BREAKING**: Renamed `RootHttpRouterConfigureOptions` to `RootHttpRouterConfigureContext`, and removed the unused type `ServiceOrExtensionPoint`.
diff --git a/.changeset/brave-lemons-chew.md b/.changeset/brave-lemons-chew.md
new file mode 100644
index 0000000000..61bf7cc6af
--- /dev/null
+++ b/.changeset/brave-lemons-chew.md
@@ -0,0 +1,6 @@
+---
+'@backstage/plugin-playlist-backend': patch
+'@backstage/plugin-catalog-backend': patch
+---
+
+Minor improvements to the descriptions provided with permission rules schemas
diff --git a/.changeset/breezy-ears-rule.md b/.changeset/breezy-ears-rule.md
new file mode 100644
index 0000000000..753554187d
--- /dev/null
+++ b/.changeset/breezy-ears-rule.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog-backend-module-gitlab': patch
+---
+
+The config now consistently uses the term 'instance' to refer to a single GitLab API host.
diff --git a/.changeset/bright-plums-cough.md b/.changeset/bright-plums-cough.md
new file mode 100644
index 0000000000..9af30f002e
--- /dev/null
+++ b/.changeset/bright-plums-cough.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-plugin-api': minor
+---
+
+**BREAKING**: Split out the hook for both lifecycle services so that the first parameter of `addShutdownHook` is the hook function, and the second is the options.
diff --git a/.changeset/bright-teachers-compete.md b/.changeset/bright-teachers-compete.md
new file mode 100644
index 0000000000..3cc900d613
--- /dev/null
+++ b/.changeset/bright-teachers-compete.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-plugin-api': minor
+---
+
+**BREAKING**: The plugin ID option passed to `createBackendPlugin` is now `pluginId`, rather than just `id`. This is to make it match `createBackendModule` more closely.
diff --git a/.changeset/brown-kings-wait.md b/.changeset/brown-kings-wait.md
new file mode 100644
index 0000000000..db3fc0ee86
--- /dev/null
+++ b/.changeset/brown-kings-wait.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog': patch
+---
+
+The list of entities takes into account the title when its different from the name to sort the entities.
diff --git a/.changeset/chatty-lemons-reply.md b/.changeset/chatty-lemons-reply.md
new file mode 100644
index 0000000000..118f832646
--- /dev/null
+++ b/.changeset/chatty-lemons-reply.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-search-backend-module-elasticsearch': patch
+---
+
+Export `decodeElasticSearchPageCursor` utility function
diff --git a/.changeset/chilled-brooms-jog.md b/.changeset/chilled-brooms-jog.md
new file mode 100644
index 0000000000..d848246b2b
--- /dev/null
+++ b/.changeset/chilled-brooms-jog.md
@@ -0,0 +1,7 @@
+---
+'@backstage/backend-common': patch
+---
+
+**BREAKING**: The `CacheClient` interface must now also implement the `withOptions` method. The `.get()` method has also received a type parameter that helps ensure that `undefined` in the event of a cache miss is handled.
+
+Added a `cacheToPluginCacheManager` helper that converts a `CacheService` into a legacy `PluginCacheManager` instance.
diff --git a/.changeset/chilled-sheep-collect.md b/.changeset/chilled-sheep-collect.md
new file mode 100644
index 0000000000..b944685e16
--- /dev/null
+++ b/.changeset/chilled-sheep-collect.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-test-utils': patch
+---
+
+Removed unnecessary `@backstage/cli` dependency.
diff --git a/.changeset/cool-spoons-bathe.md b/.changeset/cool-spoons-bathe.md
new file mode 100644
index 0000000000..b6bcaf89aa
--- /dev/null
+++ b/.changeset/cool-spoons-bathe.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-lighthouse-backend': minor
+---
+
+Introduce Lighthouse Backend Plugin to run scheduled Lighthouse Audits
diff --git a/.changeset/dull-fishes-suffer.md b/.changeset/dull-fishes-suffer.md
new file mode 100644
index 0000000000..54baae404e
--- /dev/null
+++ b/.changeset/dull-fishes-suffer.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-plugin-api': patch
+---
+
+Removed the unused `TypesToServiceRef` type
diff --git a/.changeset/dull-pianos-shave.md b/.changeset/dull-pianos-shave.md
new file mode 100644
index 0000000000..8fae999bda
--- /dev/null
+++ b/.changeset/dull-pianos-shave.md
@@ -0,0 +1,5 @@
+---
+'@backstage/core-components': patch
+---
+
+Added aria labels on the support button and sidebar
diff --git a/.changeset/eight-vans-drum.md b/.changeset/eight-vans-drum.md
new file mode 100644
index 0000000000..8e815a1701
--- /dev/null
+++ b/.changeset/eight-vans-drum.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-lighthouse-common': minor
+---
+
+Introduce @backstage/plugin-lighthouse-common with the API implementation
diff --git a/.changeset/eighty-knives-repeat.md b/.changeset/eighty-knives-repeat.md
new file mode 100644
index 0000000000..3e32a3589d
--- /dev/null
+++ b/.changeset/eighty-knives-repeat.md
@@ -0,0 +1,6 @@
+---
+'@backstage/backend-app-api': patch
+'@backstage/backend-common': patch
+---
+
+Updated to match the new `CacheService` interface.
diff --git a/.changeset/eleven-shoes-crash.md b/.changeset/eleven-shoes-crash.md
new file mode 100644
index 0000000000..8013f311d5
--- /dev/null
+++ b/.changeset/eleven-shoes-crash.md
@@ -0,0 +1,6 @@
+---
+'@backstage/plugin-scaffolder-react': patch
+'@backstage/plugin-scaffolder': patch
+---
+
+scaffolder/next: Implementing a simple `OngoingTask` page
diff --git a/.changeset/few-meals-buy.md b/.changeset/few-meals-buy.md
new file mode 100644
index 0000000000..c49eb8c7ac
--- /dev/null
+++ b/.changeset/few-meals-buy.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog-backend-module-aws': patch
+---
+
+Update to import `LocationSpec` from the correct package.
diff --git a/.changeset/few-moons-accept.md b/.changeset/few-moons-accept.md
new file mode 100644
index 0000000000..c790e837c8
--- /dev/null
+++ b/.changeset/few-moons-accept.md
@@ -0,0 +1,5 @@
+---
+'@backstage/cli': patch
+---
+
+Replaced several monorepo lint rules with new rules from `@backstage/eslint-plugin`. See the [README](https://github.com/import-js/eslint-plugin-import/blob/main/packages/eslint-plugin/README.md) for a full list of rules.
diff --git a/.changeset/few-trees-cross.md b/.changeset/few-trees-cross.md
new file mode 100644
index 0000000000..ed70c3bddb
--- /dev/null
+++ b/.changeset/few-trees-cross.md
@@ -0,0 +1,5 @@
+---
+'@backstage/cli': patch
+---
+
+Fixed Webpack loader patterns so that they properly match the file suffix only.
diff --git a/.changeset/four-tables-fix.md b/.changeset/four-tables-fix.md
new file mode 100644
index 0000000000..f17f57e253
--- /dev/null
+++ b/.changeset/four-tables-fix.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-test-utils': patch
+---
+
+Added explicit return type signature for `mockServices.config()`.
diff --git a/.changeset/friendly-chefs-rule.md b/.changeset/friendly-chefs-rule.md
new file mode 100644
index 0000000000..872a36b5ae
--- /dev/null
+++ b/.changeset/friendly-chefs-rule.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch
+---
+
+Removing extra imports for `run` script as `TestBackend` auto loads the default factories
diff --git a/.changeset/great-goats-talk.md b/.changeset/great-goats-talk.md
new file mode 100644
index 0000000000..92a1cd59ee
--- /dev/null
+++ b/.changeset/great-goats-talk.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-api-docs': minor
+---
+
+Adds a new tRPC API definition widget which users can utilize to integrate their tRPC API definitions into Backstage.
diff --git a/.changeset/green-adults-retire.md b/.changeset/green-adults-retire.md
new file mode 100644
index 0000000000..c13e8d664f
--- /dev/null
+++ b/.changeset/green-adults-retire.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-dev-utils': minor
+---
+
+Introduced a new package for backend development utilities. Similar to how `@backstage/dev-utils` is used in the frontend.
diff --git a/.changeset/green-guests-flow.md b/.changeset/green-guests-flow.md
new file mode 100644
index 0000000000..688ff17dd9
--- /dev/null
+++ b/.changeset/green-guests-flow.md
@@ -0,0 +1,8 @@
+---
+'@backstage/backend-test-utils': patch
+'@backstage/backend-app-api': patch
+'@backstage/backend-common': patch
+'@backstage/plugin-catalog-backend': patch
+---
+
+Updated usage of the lifecycle service.
diff --git a/.changeset/grumpy-fireants-drop.md b/.changeset/grumpy-fireants-drop.md
new file mode 100644
index 0000000000..92b08663f4
--- /dev/null
+++ b/.changeset/grumpy-fireants-drop.md
@@ -0,0 +1,5 @@
+---
+'@backstage/codemods': patch
+---
+
+Moved `commander` to being a regular dependency.
diff --git a/.changeset/hip-chairs-double.md b/.changeset/hip-chairs-double.md
new file mode 100644
index 0000000000..e2b03f2e66
--- /dev/null
+++ b/.changeset/hip-chairs-double.md
@@ -0,0 +1,19 @@
+---
+'@backstage/plugin-tech-radar': patch
+---
+
+Deprecate `RadarEntry.url` - use `RadarEntry.links` instead
+
+```diff
+- url: 'https://www.javascript.com/',
+ key: 'javascript',
+ id: 'javascript',
+ title: 'JavaScript',
+ quadrant: 'languages',
+ links: [
++ {
++ url: 'https://www.javascript.com/',
++ title: 'Learn more',
++ },
+ ],
+```
diff --git a/.changeset/hip-onions-tan.md b/.changeset/hip-onions-tan.md
new file mode 100644
index 0000000000..01be0d4867
--- /dev/null
+++ b/.changeset/hip-onions-tan.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-search-backend': patch
+---
+
+Change the router's response to include the error message instead of its object type in case it fails during a search query because the messages have more info.
diff --git a/.changeset/hip-pugs-teach.md b/.changeset/hip-pugs-teach.md
new file mode 100644
index 0000000000..4a3820cecc
--- /dev/null
+++ b/.changeset/hip-pugs-teach.md
@@ -0,0 +1,12 @@
+---
+'@backstage/plugin-techdocs-module-addons-contrib': patch
+'@backstage/plugin-techdocs-addons-test-utils': patch
+'@backstage/plugin-apollo-explorer': patch
+'@backstage/plugin-cicd-statistics': patch
+'@backstage/plugin-codescene': patch
+'@backstage/plugin-dynatrace': patch
+'@backstage/plugin-org-react': patch
+'@backstage/plugin-playlist': patch
+---
+
+Depend on `@material-ui/core` version `^4.12.2` like all other in-repo packages
diff --git a/.changeset/hip-tables-prove.md b/.changeset/hip-tables-prove.md
new file mode 100644
index 0000000000..bc2c4e83d6
--- /dev/null
+++ b/.changeset/hip-tables-prove.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-test-utils': patch
+---
+
+Updated the `mockServices.rootLogger` options to accept a single level option instead.
diff --git a/.changeset/hot-wasps-cover.md b/.changeset/hot-wasps-cover.md
new file mode 100644
index 0000000000..e142980b56
--- /dev/null
+++ b/.changeset/hot-wasps-cover.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-common': patch
+---
+
+Updated to work with the new `type: 'pem'` with `createHttpServer` from `@backstage/backend-app-api`
diff --git a/.changeset/hungry-stingrays-type.md b/.changeset/hungry-stingrays-type.md
new file mode 100644
index 0000000000..8cb11f67a5
--- /dev/null
+++ b/.changeset/hungry-stingrays-type.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-techdocs-backend': patch
+---
+
+Keep the tech docs sync event stream alive even if it is taking a while to build.
diff --git a/.changeset/itchy-chairs-punch.md b/.changeset/itchy-chairs-punch.md
new file mode 100644
index 0000000000..034a9bbdae
--- /dev/null
+++ b/.changeset/itchy-chairs-punch.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-plugin-api': patch
+---
+
+Aligned opaque type markers to all use a `$$type` property with namespacing.
diff --git a/.changeset/little-jars-lay.md b/.changeset/little-jars-lay.md
new file mode 100644
index 0000000000..f8851f7adc
--- /dev/null
+++ b/.changeset/little-jars-lay.md
@@ -0,0 +1,14 @@
+---
+'@backstage/plugin-user-settings-backend': patch
+'@backstage/plugin-scaffolder-backend': patch
+'@backstage/plugin-periskop-backend': patch
+'@backstage/backend-common': patch
+'@backstage/plugin-catalog-backend': patch
+'@backstage/plugin-bazaar-backend': patch
+'@backstage/plugin-events-backend': patch
+'@backstage/plugin-kafka-backend': patch
+'@backstage/plugin-proxy-backend': patch
+'@backstage/plugin-app-backend': patch
+---
+
+Updated usage of `createBackendPlugin`.
diff --git a/.changeset/long-chefs-burn.md b/.changeset/long-chefs-burn.md
new file mode 100644
index 0000000000..03a7b76db9
--- /dev/null
+++ b/.changeset/long-chefs-burn.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-app-api': patch
+---
+
+Updated database factory to pass service deps required for restoring database state during development.
diff --git a/.changeset/many-pans-unite.md b/.changeset/many-pans-unite.md
new file mode 100644
index 0000000000..59c068cec1
--- /dev/null
+++ b/.changeset/many-pans-unite.md
@@ -0,0 +1,5 @@
+---
+'@backstage/catalog-model': minor
+---
+
+Adds the tRPC API type to the catalog.
diff --git a/.changeset/mean-squids-kneel.md b/.changeset/mean-squids-kneel.md
new file mode 100644
index 0000000000..41a1bd4086
--- /dev/null
+++ b/.changeset/mean-squids-kneel.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-vault': patch
+---
+
+Surface additional context and details to the Backstage UI when the Vault plugin encounters non-successful HTTP responses from the Vault API.
diff --git a/.changeset/nasty-beans-accept.md b/.changeset/nasty-beans-accept.md
index 05ccb64c33..51b3e88e49 100644
--- a/.changeset/nasty-beans-accept.md
+++ b/.changeset/nasty-beans-accept.md
@@ -1,5 +1,5 @@
---
-'@backstage/create-app': minor
+'@backstage/create-app': patch
---
Update `SearchPage` template to use `SearchResult` extensions.
diff --git a/.changeset/nasty-kids-deny.md b/.changeset/nasty-kids-deny.md
new file mode 100644
index 0000000000..4a434eb1f6
--- /dev/null
+++ b/.changeset/nasty-kids-deny.md
@@ -0,0 +1,5 @@
+---
+'@backstage/theme': patch
+---
+
+Use same table header color as @backstage/core-components Table to meet accessibility color contrast requirements. This change affects material-ui tables.
diff --git a/.changeset/neat-schools-raise.md b/.changeset/neat-schools-raise.md
new file mode 100644
index 0000000000..b778ba8795
--- /dev/null
+++ b/.changeset/neat-schools-raise.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-kubernetes-backend': patch
+---
+
+Kubernetes proxy endpoint now accepts content types that are not json
diff --git a/.changeset/nervous-phones-shout.md b/.changeset/nervous-phones-shout.md
new file mode 100644
index 0000000000..a4e46b3be9
--- /dev/null
+++ b/.changeset/nervous-phones-shout.md
@@ -0,0 +1,6 @@
+---
+'@backstage/backend-test-utils': patch
+'@backstage/backend-app-api': patch
+---
+
+Updates to match new `BackendFeature` type.
diff --git a/.changeset/new-pumpkins-sleep.md b/.changeset/new-pumpkins-sleep.md
new file mode 100644
index 0000000000..cc5b89806d
--- /dev/null
+++ b/.changeset/new-pumpkins-sleep.md
@@ -0,0 +1,6 @@
+---
+'@backstage/plugin-scaffolder': patch
+'@backstage/plugin-scaffolder-react': patch
+---
+
+bump `@rjsf` `v5` dependencies to 5.1.0
diff --git a/.changeset/nine-ravens-kiss.md b/.changeset/nine-ravens-kiss.md
new file mode 100644
index 0000000000..a507db6b03
--- /dev/null
+++ b/.changeset/nine-ravens-kiss.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-adr': minor
+---
+
+The `AdrSearchResultListItem` component is now a search result extension. This means that when rendered as a child of components that render search extensions, the `result`, `rank`, and `highlight` properties are optional. See the [documentation](https://backstage.io/docs/features/search/how-to-guides#how-to-render-search-results-using-extensions) for more details.
diff --git a/.changeset/odd-kangaroos-itch.md b/.changeset/odd-kangaroos-itch.md
new file mode 100644
index 0000000000..8529e5fe04
--- /dev/null
+++ b/.changeset/odd-kangaroos-itch.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog-graph': patch
+---
+
+Fix #16245: The CatalogGraphCard has parameter naming errors for CatalogGraphPage
diff --git a/.changeset/old-ways-know.md b/.changeset/old-ways-know.md
new file mode 100644
index 0000000000..60a1a923e8
--- /dev/null
+++ b/.changeset/old-ways-know.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-common': patch
+---
+
+The `DatabaseManager.forPlugin` method now accepts additional service dependencies. There is no need to update existing code to pass these dependencies.
diff --git a/.changeset/perfect-pears-care.md b/.changeset/perfect-pears-care.md
new file mode 100644
index 0000000000..2ea9f54a7f
--- /dev/null
+++ b/.changeset/perfect-pears-care.md
@@ -0,0 +1,7 @@
+---
+'@backstage/plugin-techdocs-backend': patch
+'@backstage/plugin-techdocs-node': patch
+'@techdocs/cli': patch
+---
+
+Added support for using a default `mkdocs.yml` configuration file when none is provided
diff --git a/.changeset/poor-moons-confess.md b/.changeset/poor-moons-confess.md
index 7fbdc292ed..7489a3c9f1 100644
--- a/.changeset/poor-moons-confess.md
+++ b/.changeset/poor-moons-confess.md
@@ -1,5 +1,5 @@
---
-'@backstage/plugin-catalog-backend-module-incremental-ingestion': minor
+'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch
---
-Return EventSubscriber from addIncrementalEntityProvider to hook up to EventsBackend
+Return `EventSubscriber` from `addIncrementalEntityProvider` to hook up to `EventsBackend`
diff --git a/.changeset/pre.json b/.changeset/pre.json
index 0d150702fb..01c51bcc4b 100644
--- a/.changeset/pre.json
+++ b/.changeset/pre.json
@@ -1,5 +1,5 @@
{
- "mode": "pre",
+ "mode": "exit",
"tag": "next",
"initialVersions": {
"example-app": "0.2.79",
@@ -195,39 +195,149 @@
"@backstage/plugin-vault": "0.1.8",
"@backstage/plugin-vault-backend": "0.2.6",
"@backstage/plugin-xcmetrics": "0.2.34",
- "@backstage/plugin-scaffolder-node": "0.0.0"
+ "@backstage/plugin-scaffolder-node": "0.0.0",
+ "@backstage/backend-dev-utils": "0.0.0",
+ "@backstage/eslint-plugin": "0.0.0",
+ "@backstage/plugin-entity-validation": "0.0.0",
+ "@backstage/plugin-graphql-voyager": "0.0.0",
+ "@backstage/plugin-lighthouse-backend": "0.0.0",
+ "@backstage/plugin-lighthouse-common": "0.0.0"
},
"changesets": [
+ "afraid-foxes-provide",
+ "afraid-planets-crash",
+ "brave-cougars-burn",
+ "breezy-ears-rule",
"bright-eagles-love",
+ "bright-plums-cough",
+ "bright-teachers-compete",
"brown-islands-own",
"calm-avocados-exercise",
+ "chatty-owls-care",
+ "chilled-sheep-collect",
+ "clean-queens-judge",
"cold-cycles-switch",
+ "cool-spoons-bathe",
"create-app-1674561612",
+ "cuddly-boxes-agree",
"cyan-deers-walk",
+ "dry-donkeys-cheer",
+ "dull-fishes-suffer",
+ "dull-gorillas-sing",
"eight-falcons-explode",
+ "eight-hotels-sparkle",
+ "eight-vans-drum",
+ "eleven-shoes-crash",
+ "few-moons-accept",
"flat-cups-itch",
+ "four-candles-add",
+ "four-rivers-enjoy",
+ "four-tables-fix",
+ "friendly-chefs-rule",
"friendly-scissors-shop",
+ "gold-bulldogs-talk",
"gold-lemons-eat",
"gold-masks-sleep",
+ "great-goats-talk",
+ "green-adults-retire",
+ "green-guests-flow",
+ "grumpy-bottles-stare",
+ "grumpy-fireants-drop",
+ "happy-cows-moo",
+ "hip-chairs-double",
+ "hip-onions-tan",
+ "hip-pugs-teach",
+ "hip-tables-prove",
+ "hot-lions-cover",
+ "hot-wasps-cover",
+ "hungry-news-fix",
+ "itchy-chairs-punch",
"itchy-goats-melt",
"khaki-toes-care",
+ "late-rice-crash",
"lazy-badgers-rule",
"lazy-badgers-try",
"lemon-tables-train",
+ "little-jars-lay",
+ "long-chefs-burn",
"lovely-ladybugs-taste",
+ "many-nails-joke",
+ "many-pans-unite",
+ "mean-squids-kneel",
+ "modern-cats-worry",
+ "nasty-beans-accept",
+ "neat-schools-raise",
+ "neat-zebras-run",
"nervous-apricots-whisper",
"nervous-mangos-rhyme",
+ "nervous-phones-shout",
+ "new-pumpkins-sleep",
+ "nine-glasses-invent",
+ "nine-guests-compete",
+ "nine-ravens-kiss",
+ "ninety-hats-serve",
+ "old-knives-wonder",
+ "old-ways-know",
"perfect-cheetahs-serve",
"pink-falcons-serve",
+ "poor-moons-confess",
+ "popular-dancers-join",
+ "pretty-ladybugs-taste",
+ "proud-glasses-live",
+ "purple-feet-smile",
"quick-ladybugs-reply",
+ "quick-mice-change",
+ "rare-berries-give",
"rare-melons-battle",
+ "red-kiwis-compare",
+ "renovate-0b349f9",
+ "renovate-0c3644c",
+ "renovate-53e8b07",
+ "rich-snakes-rest",
"rotten-mayflies-love",
+ "selfish-frogs-punch",
+ "serious-pigs-watch",
+ "sharp-lobsters-build",
"shiny-years-tap",
+ "short-apes-relate",
+ "shy-buses-mix",
+ "shy-steaks-invite",
+ "silent-peas-fly",
+ "silly-buckets-joke",
+ "silly-socks-lie",
"silly-turkeys-hang",
+ "silver-wolves-breathe",
+ "slow-carrots-sniff",
+ "slow-moles-sin",
+ "smart-dingos-raise",
+ "soft-actors-worry",
+ "soft-boxes-buy",
+ "soft-snails-notice",
"spotty-coats-clean",
"stale-dots-smile",
+ "stale-experts-punch",
+ "stupid-ladybugs-brake",
"swift-fishes-smash",
+ "tall-falcons-teach",
+ "tall-tables-hide",
+ "tall-years-relate",
+ "tasty-jobs-help",
+ "thick-clocks-pump",
+ "thick-tables-travel",
+ "thin-donkeys-attack",
+ "thin-scissors-press",
+ "tough-jeans-camp",
+ "twenty-islands-wonder",
"twenty-parents-relate",
+ "two-melons-lie",
+ "violet-tips-rhyme",
+ "weak-radios-sing",
+ "wicked-beers-walk",
+ "wild-donkeys-rescue",
+ "witty-moose-itch",
+ "yellow-roses-tell",
+ "young-beans-float",
+ "young-points-drop",
"young-singers-learn"
]
}
diff --git a/.changeset/proud-glasses-live.md b/.changeset/proud-glasses-live.md
new file mode 100644
index 0000000000..ded7a53ce7
--- /dev/null
+++ b/.changeset/proud-glasses-live.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-adr': patch
+---
+
+Support displaying an icon on `AdrSearchResultListItem`
diff --git a/.changeset/quick-mice-change.md b/.changeset/quick-mice-change.md
new file mode 100644
index 0000000000..aeee24a021
--- /dev/null
+++ b/.changeset/quick-mice-change.md
@@ -0,0 +1,6 @@
+---
+'@backstage/backend-test-utils': patch
+'@backstage/backend-defaults': patch
+---
+
+Use the new `*ServiceFactory` exports from `@backstage/backend-app-api`
diff --git a/.changeset/quiet-pets-count.md b/.changeset/quiet-pets-count.md
new file mode 100644
index 0000000000..bc7da8f3e7
--- /dev/null
+++ b/.changeset/quiet-pets-count.md
@@ -0,0 +1,6 @@
+---
+'@backstage/backend-test-utils': patch
+'@backstage/backend-app-api': patch
+---
+
+Updated usage of `ServiceFactory`.
diff --git a/.changeset/rare-berries-give.md b/.changeset/rare-berries-give.md
new file mode 100644
index 0000000000..39e360bf48
--- /dev/null
+++ b/.changeset/rare-berries-give.md
@@ -0,0 +1,5 @@
+---
+'@backstage/repo-tools': patch
+---
+
+Packages without a declared `backstage.role` are now ignored.
diff --git a/.changeset/red-kiwis-compare.md b/.changeset/red-kiwis-compare.md
new file mode 100644
index 0000000000..6045367105
--- /dev/null
+++ b/.changeset/red-kiwis-compare.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-app-api': patch
+---
+
+The shutdown signal handlers are now installed as part of the backend instance rather than the lifecycle service, and explicitly cause the process to exit.
diff --git a/.changeset/red-toes-suffer.md b/.changeset/red-toes-suffer.md
new file mode 100644
index 0000000000..3d819fb298
--- /dev/null
+++ b/.changeset/red-toes-suffer.md
@@ -0,0 +1,9 @@
+---
+'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch
+'@backstage/plugin-kubernetes-backend': patch
+'@backstage/plugin-playlist-backend': patch
+'@backstage/plugin-bazaar-backend': patch
+'@backstage/plugin-vault-backend': patch
+---
+
+Moving the backend-test-utils to devDependencies.
diff --git a/.changeset/renovate-53e8b07.md b/.changeset/renovate-53e8b07.md
new file mode 100644
index 0000000000..cb19d8fe8b
--- /dev/null
+++ b/.changeset/renovate-53e8b07.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-api-docs': patch
+---
+
+Updated dependency `@asyncapi/react-component` to `1.0.0-next.47`.
diff --git a/.changeset/rich-bags-sleep.md b/.changeset/rich-bags-sleep.md
new file mode 100644
index 0000000000..14312ac7f4
--- /dev/null
+++ b/.changeset/rich-bags-sleep.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-pagerduty': patch
+---
+
+The PagerDutyCard now supports an optional `readOnly` property (``) for suppressing the rendering of the "Create Incident" button from the Backstage UI.
diff --git a/.changeset/rotten-birds-build.md b/.changeset/rotten-birds-build.md
new file mode 100644
index 0000000000..e165129998
--- /dev/null
+++ b/.changeset/rotten-birds-build.md
@@ -0,0 +1,7 @@
+---
+'@backstage/plugin-microsoft-calendar': minor
+---
+
+Created a new plugin `@backstage/plugin-microsoft-calendar` to display events from a Microsoft Calendar.
+
+please refer to the [README.md](https://github.com/backstage/backstage/blob/master/plugins/microsoft-calendar/README.md) for step-by-step instructions to setup the plugin in your Backstage instance.
diff --git a/.changeset/selfish-frogs-punch.md b/.changeset/selfish-frogs-punch.md
new file mode 100644
index 0000000000..6484576af8
--- /dev/null
+++ b/.changeset/selfish-frogs-punch.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-plugin-api': minor
+---
+
+**BREAKING**: Switched out `LogMeta` type for `JsonObject`.
diff --git a/.changeset/serious-grapes-brush.md b/.changeset/serious-grapes-brush.md
new file mode 100644
index 0000000000..94eead7282
--- /dev/null
+++ b/.changeset/serious-grapes-brush.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog-backend-module-github': patch
+---
+
+Use github team slug and login annotations rather than entity name to infer location annotations
diff --git a/.changeset/serious-pigs-watch.md b/.changeset/serious-pigs-watch.md
new file mode 100644
index 0000000000..2efd8697f3
--- /dev/null
+++ b/.changeset/serious-pigs-watch.md
@@ -0,0 +1,10 @@
+---
+'@backstage/plugin-techdocs': patch
+'@backstage/plugin-catalog': patch
+'@backstage/plugin-explore': patch
+'@backstage/plugin-search-react': patch
+---
+
+`ListItem` wrapper component moved to `SearchResultListItemExtension` for all `*SearchResultListItems` that are exported as extensions. This is to make sure the list only contains list elements.
+
+Note: If you have implemented a custom result list item, we recommend you to remove the list item wrapper to avoid nested `
` elements.
diff --git a/.changeset/short-apes-relate.md b/.changeset/short-apes-relate.md
new file mode 100644
index 0000000000..d93c046a4d
--- /dev/null
+++ b/.changeset/short-apes-relate.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-app-api': minor
+---
+
+**BREAKING** Renaming `*Factory` exports to `*ServiceFactory` instead. For example `configFactory` now is exported as `configServiceFactory`.
diff --git a/.changeset/shy-buses-mix.md b/.changeset/shy-buses-mix.md
new file mode 100644
index 0000000000..b7db90d03c
--- /dev/null
+++ b/.changeset/shy-buses-mix.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-scaffolder-react': minor
+---
+
+refactor `createAsyncValidators` to be recursive to ensure validators are called in nested schemas.
diff --git a/.changeset/silent-peas-fly.md b/.changeset/silent-peas-fly.md
new file mode 100644
index 0000000000..8148cb5d12
--- /dev/null
+++ b/.changeset/silent-peas-fly.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-app-api': patch
+---
+
+Moved the options of the `config` and `rootHttpRouter` services out to the factories themselves, where they belong
diff --git a/.changeset/silly-buckets-joke.md b/.changeset/silly-buckets-joke.md
new file mode 100644
index 0000000000..113272c965
--- /dev/null
+++ b/.changeset/silly-buckets-joke.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog-backend-module-msgraph': patch
+---
+
+Fixed a bug reading the `user.select` field expected from the `app-config.yaml` configuration
diff --git a/.changeset/silly-socks-lie.md b/.changeset/silly-socks-lie.md
new file mode 100644
index 0000000000..ae7e1c0b2a
--- /dev/null
+++ b/.changeset/silly-socks-lie.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-entity-validation': minor
+---
+
+First implementation for the entity validation UI. For more information refer to its `README.md`.
diff --git a/.changeset/silver-badgers-heal.md b/.changeset/silver-badgers-heal.md
new file mode 100644
index 0000000000..b1f239c3dc
--- /dev/null
+++ b/.changeset/silver-badgers-heal.md
@@ -0,0 +1,35 @@
+---
+'@backstage/plugin-techdocs-module-addons-contrib': patch
+'@backstage/plugin-techdocs': patch
+---
+
+Create a TechDocs `` addon that allows users to open images in a light-box on documentation pages, they can navigate between images if there are several on one page.
+
+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 { LightBox } from '@backstage/plugin-techdocs-module-addons-contrib';
+
+const AppRoutes = () => {
+
+ // other plugin routes
+ }>
+
+
+ }
+ >
+
++
+
+
+ ;
+};
+```
diff --git a/.changeset/silver-wolves-breathe.md b/.changeset/silver-wolves-breathe.md
new file mode 100644
index 0000000000..8c1529e142
--- /dev/null
+++ b/.changeset/silver-wolves-breathe.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-sentry': minor
+---
+
+Add option to filter issues based on the time it was triggered
diff --git a/.changeset/slow-carrots-sniff.md b/.changeset/slow-carrots-sniff.md
new file mode 100644
index 0000000000..d32c2a281e
--- /dev/null
+++ b/.changeset/slow-carrots-sniff.md
@@ -0,0 +1,8 @@
+---
+'@backstage/plugin-catalog-backend-module-msgraph': minor
+---
+
+Improve performance when loading users via group membership.
+Users data is now loaded from a paged query, rather than having to make an extra call per user to load each user's profiles.
+
+Note, there are still additional per user calls made to load user avatars
diff --git a/.changeset/slow-moles-sin.md b/.changeset/slow-moles-sin.md
new file mode 100644
index 0000000000..02e1952312
--- /dev/null
+++ b/.changeset/slow-moles-sin.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-circleci': patch
+---
+
+Making workflow a link
diff --git a/.changeset/slow-sloths-do.md b/.changeset/slow-sloths-do.md
new file mode 100644
index 0000000000..2d86d477bf
--- /dev/null
+++ b/.changeset/slow-sloths-do.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog-graph': patch
+---
+
+Expose additional props on the `CatalogGraphCard` to allow for custom node & label rendering or kind/relation filtering.
diff --git a/.changeset/soft-actors-worry.md b/.changeset/soft-actors-worry.md
new file mode 100644
index 0000000000..5186499292
--- /dev/null
+++ b/.changeset/soft-actors-worry.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-app-api': minor
+---
+
+**BREAKING** `HttpServerCertificateOptions` when specified with a `key` and `cert` should also have the `type: 'pem'` instead of `type: 'plain'`
diff --git a/.changeset/soft-snails-notice.md b/.changeset/soft-snails-notice.md
new file mode 100644
index 0000000000..ed39ee9591
--- /dev/null
+++ b/.changeset/soft-snails-notice.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-scaffolder': patch
+---
+
+Prefer schema ordering of template properties during review content generation.
diff --git a/.changeset/spotty-spiders-love.md b/.changeset/spotty-spiders-love.md
new file mode 100644
index 0000000000..e0ac3b3cc7
--- /dev/null
+++ b/.changeset/spotty-spiders-love.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog': patch
+---
+
+Make catalog search result list a bit more customizable
diff --git a/.changeset/stale-experts-punch.md b/.changeset/stale-experts-punch.md
new file mode 100644
index 0000000000..85872bfffe
--- /dev/null
+++ b/.changeset/stale-experts-punch.md
@@ -0,0 +1,9 @@
+---
+'@backstage/plugin-user-settings-backend': patch
+'@backstage/plugin-periskop-backend': patch
+'@backstage/plugin-bazaar-backend': patch
+'@backstage/plugin-kafka-backend': patch
+'@backstage/plugin-proxy-backend': patch
+---
+
+Added a Backend System plugin feature
diff --git a/.changeset/sweet-yaks-taste.md b/.changeset/sweet-yaks-taste.md
new file mode 100644
index 0000000000..cbbbaea497
--- /dev/null
+++ b/.changeset/sweet-yaks-taste.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-cost-insights': patch
+---
+
+Fix bug in EntityCostsCard if cost aggregation array is empty. Allow title override on the Cost Insights Page
diff --git a/.changeset/tall-falcons-teach.md b/.changeset/tall-falcons-teach.md
new file mode 100644
index 0000000000..d6608a6597
--- /dev/null
+++ b/.changeset/tall-falcons-teach.md
@@ -0,0 +1,5 @@
+---
+'@backstage/core-components': patch
+---
+
+Navigation items in mobile sidebar now have aria label.
diff --git a/.changeset/tall-tables-hide.md b/.changeset/tall-tables-hide.md
new file mode 100644
index 0000000000..3e8011aff2
--- /dev/null
+++ b/.changeset/tall-tables-hide.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch
+---
+
+Updated README to include newer API options for incremental entity providers
diff --git a/.changeset/tall-years-relate.md b/.changeset/tall-years-relate.md
index 10198992ea..73a0e875b0 100644
--- a/.changeset/tall-years-relate.md
+++ b/.changeset/tall-years-relate.md
@@ -2,4 +2,4 @@
'@backstage/plugin-airbrake': patch
---
-Adds a boolean helper function to airbrake plugin for use on the EntityPage to show/hide airbrake tab depending on whether the entity's catalog-info.yml has an airbrake id set in the metadata
+Adds a boolean helper function to airbrake plugin for use on the EntityPage to show/hide airbrake tab depending on whether the entity's `catalog-info.yaml` has an airbrake id set in the metadata
diff --git a/.changeset/tasty-jobs-help.md b/.changeset/tasty-jobs-help.md
new file mode 100644
index 0000000000..ad1df8fb8c
--- /dev/null
+++ b/.changeset/tasty-jobs-help.md
@@ -0,0 +1,7 @@
+---
+'@backstage/plugin-graphql-voyager': minor
+---
+
+Add the new GraphQL Voyager tool as a plugin for backstage, expose necessary API and components needed for it.
+
+For more information on how to use this plugin and configure it, please navigate to the [README](https://github.com/backstage/backstage/tree/master/plugins/graphql-voyager/README.md) of the plugin.
diff --git a/.changeset/thick-tables-travel.md b/.changeset/thick-tables-travel.md
new file mode 100644
index 0000000000..d74ed18b8a
--- /dev/null
+++ b/.changeset/thick-tables-travel.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-events-node': patch
+---
+
+Make `EventParams` typed for implementing tidier event handling.
diff --git a/.changeset/thin-donkeys-attack.md b/.changeset/thin-donkeys-attack.md
new file mode 100644
index 0000000000..2fd0aebb6a
--- /dev/null
+++ b/.changeset/thin-donkeys-attack.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-test-utils': patch
+---
+
+Removed the `ref` from all `mockServices`.
diff --git a/.changeset/thin-scissors-press.md b/.changeset/thin-scissors-press.md
new file mode 100644
index 0000000000..2891d4ca66
--- /dev/null
+++ b/.changeset/thin-scissors-press.md
@@ -0,0 +1,6 @@
+---
+'@backstage/plugin-azure-sites': patch
+---
+
+Fixed `AzureSites` plugin start and stop issue #15904
+Fixed `AzureSites` UI load issue #15907
diff --git a/.changeset/three-geckos-press.md b/.changeset/three-geckos-press.md
new file mode 100644
index 0000000000..fc1af4fdc0
--- /dev/null
+++ b/.changeset/three-geckos-press.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-search': patch
+---
+
+Implement a `showCounts` option to display result counts per type in `SearchType.Accordion`
diff --git a/.changeset/tidy-kings-cough.md b/.changeset/tidy-kings-cough.md
new file mode 100644
index 0000000000..e908572c8b
--- /dev/null
+++ b/.changeset/tidy-kings-cough.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-kubernetes-backend': patch
+---
+
+The name of the header used to specify a cluster to the proxy endpoint is now visible in the API reference.
diff --git a/.changeset/tough-jeans-camp.md b/.changeset/tough-jeans-camp.md
new file mode 100644
index 0000000000..8c7a53190f
--- /dev/null
+++ b/.changeset/tough-jeans-camp.md
@@ -0,0 +1,5 @@
+---
+'@backstage/eslint-plugin': minor
+---
+
+Added a new ESLint plugin with common rules for Backstage projects. See the [README](https://github.com/import-js/eslint-plugin-import/blob/main/packages/eslint-plugin/README.md) for more details.
diff --git a/.changeset/twenty-islands-wonder.md b/.changeset/twenty-islands-wonder.md
new file mode 100644
index 0000000000..fe3c5a05c8
--- /dev/null
+++ b/.changeset/twenty-islands-wonder.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog-react': minor
+---
+
+Aligned buttons on "Unregister entity" dialog to keep them on the same line
diff --git a/.changeset/twenty-pugs-explain.md b/.changeset/twenty-pugs-explain.md
new file mode 100644
index 0000000000..9ac77d2ffb
--- /dev/null
+++ b/.changeset/twenty-pugs-explain.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-plugin-api': minor
+---
+
+**BREAKING**: The `CacheService` has been changed to remove the indirection of `getClient`, instead making the `CacheClient` methods directly available on the `CacheService`. In order to allow for the creation of clients with default options, there is now a new `.withOptions` method that must be implemented as part of the service interface.
diff --git a/.changeset/violet-tips-rhyme.md b/.changeset/violet-tips-rhyme.md
new file mode 100644
index 0000000000..c2d95cfbf9
--- /dev/null
+++ b/.changeset/violet-tips-rhyme.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-search': patch
+---
+
+Updated colors for each tab used on search modal, to improve color contrast. Aria label added to tabs wrapper component. `disableRipple` property on the `Tab` component removed to improve keyboard navigation indicator.
diff --git a/.changeset/weak-radios-sing.md b/.changeset/weak-radios-sing.md
new file mode 100644
index 0000000000..dff287b565
--- /dev/null
+++ b/.changeset/weak-radios-sing.md
@@ -0,0 +1,5 @@
+---
+'@backstage/cli': patch
+---
+
+Added an experimental mode for the `package start` command for backend packages. Enabled by setting `EXPERIMENTAL_BACKEND_START`.
diff --git a/.changeset/wicked-beers-walk.md b/.changeset/wicked-beers-walk.md
new file mode 100644
index 0000000000..160a171eb1
--- /dev/null
+++ b/.changeset/wicked-beers-walk.md
@@ -0,0 +1,5 @@
+---
+'@backstage/create-app': patch
+---
+
+Updated `packages/app/cypress/.eslintrc.json` to remove the unnecessary `import/no-extraneous-dependencies` rule.
diff --git a/.changeset/wild-donkeys-rescue.md b/.changeset/wild-donkeys-rescue.md
new file mode 100644
index 0000000000..43dc3743bb
--- /dev/null
+++ b/.changeset/wild-donkeys-rescue.md
@@ -0,0 +1,6 @@
+---
+'@backstage/backend-test-utils': patch
+'@backstage/backend-app-api': patch
+---
+
+Updated usages of `LogMeta`.
diff --git a/.changeset/wild-melons-shout.md b/.changeset/wild-melons-shout.md
new file mode 100644
index 0000000000..5a79612f22
--- /dev/null
+++ b/.changeset/wild-melons-shout.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-plugin-api': minor
+---
+
+Switch `ServiceFactory` to be an opaque type, keeping only the `service` field as public API, but also adding a type parameter for the service scope.
diff --git a/.changeset/yellow-roses-tell.md b/.changeset/yellow-roses-tell.md
new file mode 100644
index 0000000000..ad645df294
--- /dev/null
+++ b/.changeset/yellow-roses-tell.md
@@ -0,0 +1,5 @@
+---
+'@backstage/backend-plugin-api': minor
+---
+
+Switched `BackendFeature` to be an opaque type.
diff --git a/.changeset/young-beans-float.md b/.changeset/young-beans-float.md
new file mode 100644
index 0000000000..ef52b2080a
--- /dev/null
+++ b/.changeset/young-beans-float.md
@@ -0,0 +1,24 @@
+---
+'@backstage/plugin-lighthouse': minor
+---
+
+Require @backstage/plugin-lighthouse-common package where API implementation moved to.
+
+**BREAKING**: the following types have been moved to @backstage/plugin-lighthouse-common:
+
+- `Audit`
+- `AuditBase`
+- `AuditCompleted`
+- `AuditFailed`
+- `AuditRunning`
+- `FetchError`
+- `LASListRequest`
+- `LASListResponse`
+- `LighthouseApi`
+- `LighthouseCategoryAbbr`
+- `LighthouseCategoryId`
+- `LighthouseConfigSettings`
+- `LighthouseRestApi`
+- `TriggerAuditPayload`
+- `Website`
+- `WebsiteListResponse`
diff --git a/.changeset/young-points-drop.md b/.changeset/young-points-drop.md
new file mode 100644
index 0000000000..4309d54c2c
--- /dev/null
+++ b/.changeset/young-points-drop.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-catalog-backend-module-msgraph': patch
+---
+
+Increased default page size to 999 (from 100) to reduce the number of calls made to the Microsoft Graph API.
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 82d868a408..1c6171cb01 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -4,78 +4,78 @@
# The last matching pattern takes precedence.
# https://help.github.com/articles/about-codeowners/
-* @backstage/reviewers
-yarn.lock @backstage/reviewers @backstage-service
-*/yarn.lock @backstage/reviewers @backstage-service
-/.changeset/cost-insights-* @backstage/reviewers @backstage/silver-lining
-/.changeset @backstage/reviewers @backstage/techdocs-core
-/cypress/src/integration/plugins/techdocs.spec.ts @backstage/reviewers @backstage/techdocs-core
-/docs/assets/search @backstage/reviewers @backstage/techdocs-core
-/docs/features/search @backstage/reviewers @backstage/techdocs-core
-/docs/features/techdocs @backstage/reviewers @backstage/techdocs-core
-/docs/plugins/integrating-search-into-plugins.md @backstage/reviewers @backstage/techdocs-core
-/packages/techdocs-cli @backstage/reviewers @backstage/techdocs-core
-/packages/techdocs-cli-embedded-app @backstage/reviewers @backstage/techdocs-core
-/plugins/adr @backstage/reviewers @kuangp
-/plugins/adr-* @backstage/reviewers @kuangp
-/plugins/allure @backstage/reviewers @deepak-bhardwaj-ps
-/plugins/apache-airflow @backstage/reviewers @cmpadden
-/plugins/api-docs @backstage/reviewers @backstage/sda-se-reviewers
-/plugins/azure-devops @backstage/reviewers @marleypowell @awanlin
-/plugins/azure-devops-backend @backstage/reviewers @marleypowell @awanlin
-/plugins/azure-devops-common @backstage/reviewers @marleypowell @awanlin
-/plugins/bitbucket-cloud-common @backstage/reviewers @pjungermann
-/plugins/bitrise @backstage/reviewers @backstage/sda-se-reviewers
-/plugins/catalog @backstage/reviewers @backstage/catalog-core
-/plugins/catalog-* @backstage/reviewers @backstage/catalog-core
-/plugins/catalog-backend-module-aws @backstage/reviewers @backstage/catalog-core @pjungermann
-/plugins/catalog-backend-module-bitbucket-cloud @backstage/reviewers @backstage/catalog-core @pjungermann
-/plugins/catalog-backend-module-msgraph @backstage/reviewers @backstage/catalog-core @pjungermann
-/plugins/catalog-graph @backstage/reviewers @backstage/catalog-core @backstage/sda-se-reviewers
-/plugins/circleci @backstage/reviewers @adamdmharvey
-/plugins/cloudbuild @backstage/reviewers @trivago/ebarrios
-/plugins/code-coverage @backstage/reviewers @alde @nissayeva
-/plugins/code-coverage-backend @backstage/reviewers @alde @nissayeva
-/plugins/cost-insights @backstage/reviewers @backstage/silver-lining
-/plugins/cost-insights-* @backstage/reviewers @backstage/silver-lining
-/plugins/events-backend @backstage/reviewers @pjungermann
-/plugins/events-backend-module-aws-sqs @backstage/reviewers @pjungermann
-/plugins/events-backend-module-azure @backstage/reviewers @pjungermann
-/plugins/events-backend-module-bitbucket-cloud @backstage/reviewers @pjungermann
-/plugins/events-backend-module-gerrit @backstage/reviewers @pjungermann
-/plugins/events-backend-module-github @backstage/reviewers @pjungermann
-/plugins/events-backend-module-gitlab @backstage/reviewers @pjungermann
-/plugins/events-backend-test-utils @backstage/reviewers @pjungermann
-/plugins/events-node @backstage/reviewers @pjungermann
-/plugins/explore @backstage/reviewers @backstage/sda-se-reviewers
-/plugins/explore-react @backstage/reviewers @backstage/sda-se-reviewers
-/plugins/fossa @backstage/reviewers @backstage/sda-se-reviewers
-/plugins/gcalendar @backstage/reviewers @szubster @ptychu @kielosz @alexrybch
-/plugins/git-release-manager @backstage/reviewers @erikengervall
-/plugins/home @backstage/reviewers @backstage/techdocs-core
-/plugins/ilert @backstage/reviewers @yacut
-/plugins/jenkins @backstage/reviewers @timja
-/plugins/jenkins-backend @backstage/reviewers @timja
-/plugins/kafka @backstage/reviewers @nirga @andrewthauer
-/plugins/kafka-backend @backstage/reviewers @nirga @andrewthauer
-/plugins/kubernetes @backstage/reviewers @backstage/warpspeed
-/plugins/kubernetes-* @backstage/reviewers @backstage/warpspeed
-/plugins/newrelic-dashboard @backstage/reviewers @mufaddal7
-/plugins/playlist @backstage/reviewers @kuangp
-/plugins/playlist-* @backstage/reviewers @kuangp
-/plugins/rollbar @backstage/reviewers @andrewthauer
-/plugins/rollbar-backend @backstage/reviewers @andrewthauer
-/plugins/scaffolder-backend-module-rails @backstage/reviewers @angeliski
-/plugins/scaffolder-backend-module-yeoman @backstage/reviewers @pawelmitka
-/plugins/search @backstage/reviewers @backstage/techdocs-core
-/plugins/search-* @backstage/reviewers @backstage/techdocs-core
-/plugins/sonarqube @backstage/reviewers @backstage/sda-se-reviewers
-/plugins/stack-overflow @backstage/reviewers @backstage/techdocs-core
-/plugins/stack-overflow-backend @backstage/reviewers @backstage/techdocs-core
-/plugins/techdocs @backstage/reviewers @backstage/techdocs-core
-/plugins/techdocs-* @backstage/reviewers @backstage/techdocs-core
-/plugins/user-settings-backend @backstage/reviewers @backstage/sda-se-reviewers
-/tech-insights-backend @backstage/reviewers @xantier @iain-b
-/tech-insights-backend-module-jsonfc @backstage/reviewers @xantier @iain-b
-/tech-insights-tech-insights-common @backstage/reviewers @xantier @iain-b
-/tech-insights-tech-insights-node @backstage/reviewers @xantier @iain-b
+* @backstage/maintainers
+yarn.lock @backstage/maintainers @backstage-service
+*/yarn.lock @backstage/maintainers @backstage-service
+/.changeset/*.md
+/cypress/src/integration/plugins/techdocs.spec.ts @backstage/techdocs-core
+/docs/assets/search @backstage/techdocs-core
+/docs/features/search @backstage/techdocs-core
+/docs/features/techdocs @backstage/techdocs-core
+/docs/plugins/integrating-search-into-plugins.md @backstage/techdocs-core
+/packages/techdocs-cli @backstage/techdocs-core
+/packages/techdocs-cli-embedded-app @backstage/techdocs-core
+/plugins/adr @backstage/maintainers @kuangp
+/plugins/adr-* @backstage/maintainers @kuangp
+/plugins/allure @backstage/maintainers @deepak-bhardwaj-ps
+/plugins/apache-airflow @backstage/maintainers @cmpadden
+/plugins/api-docs @backstage/maintainers @backstage/sda-se-reviewers
+/plugins/azure-devops @backstage/maintainers @marleypowell @awanlin
+/plugins/azure-devops-backend @backstage/maintainers @marleypowell @awanlin
+/plugins/azure-devops-common @backstage/maintainers @marleypowell @awanlin
+/plugins/bitbucket-cloud-common @backstage/maintainers @pjungermann
+/plugins/bitrise @backstage/maintainers @backstage/sda-se-reviewers
+/plugins/catalog @backstage/maintainers @backstage/catalog-core
+/plugins/catalog-* @backstage/maintainers @backstage/catalog-core
+/plugins/catalog-backend-module-aws @backstage/maintainers @backstage/catalog-core @pjungermann
+/plugins/catalog-backend-module-bitbucket-cloud @backstage/maintainers @backstage/catalog-core @pjungermann
+/plugins/catalog-backend-module-msgraph @backstage/maintainers @backstage/catalog-core @pjungermann
+/plugins/catalog-graph @backstage/maintainers @backstage/catalog-core @backstage/sda-se-reviewers
+/plugins/circleci @backstage/maintainers @adamdmharvey
+/plugins/cloudbuild @backstage/maintainers @trivago/ebarrios
+/plugins/code-coverage @backstage/maintainers @alde @nissayeva
+/plugins/code-coverage-backend @backstage/maintainers @alde @nissayeva
+/plugins/cost-insights @backstage/maintainers @backstage/silver-lining
+/plugins/cost-insights-* @backstage/maintainers @backstage/silver-lining
+/plugins/events-backend @backstage/maintainers @pjungermann
+/plugins/events-backend-module-aws-sqs @backstage/maintainers @pjungermann
+/plugins/events-backend-module-azure @backstage/maintainers @pjungermann
+/plugins/events-backend-module-bitbucket-cloud @backstage/maintainers @pjungermann
+/plugins/events-backend-module-gerrit @backstage/maintainers @pjungermann
+/plugins/events-backend-module-github @backstage/maintainers @pjungermann
+/plugins/events-backend-module-gitlab @backstage/maintainers @pjungermann
+/plugins/events-backend-test-utils @backstage/maintainers @pjungermann
+/plugins/events-node @backstage/maintainers @pjungermann
+/plugins/explore @backstage/maintainers @backstage/sda-se-reviewers
+/plugins/explore-react @backstage/maintainers @backstage/sda-se-reviewers
+/plugins/fossa @backstage/maintainers @backstage/sda-se-reviewers
+/plugins/gcalendar @backstage/maintainers @szubster @ptychu @kielosz @alexrybch
+/plugins/git-release-manager @backstage/maintainers @erikengervall
+/plugins/home @backstage/techdocs-core
+/plugins/ilert @backstage/maintainers @yacut
+/plugins/jenkins @backstage/maintainers @timja
+/plugins/jenkins-backend @backstage/maintainers @timja
+/plugins/kafka @backstage/maintainers @nirga @andrewthauer
+/plugins/kafka-backend @backstage/maintainers @nirga @andrewthauer
+/plugins/kubernetes @backstage/maintainers @backstage/warpspeed
+/plugins/kubernetes-* @backstage/maintainers @backstage/warpspeed
+/plugins/microsoft-calendar @backstage/maintainers @abhay-soni-developer
+/plugins/newrelic-dashboard @backstage/maintainers @mufaddal7
+/plugins/playlist @backstage/maintainers @kuangp
+/plugins/playlist-* @backstage/maintainers @kuangp
+/plugins/rollbar @backstage/maintainers @andrewthauer
+/plugins/rollbar-backend @backstage/maintainers @andrewthauer
+/plugins/scaffolder-backend-module-rails @backstage/maintainers @angeliski
+/plugins/scaffolder-backend-module-yeoman @backstage/maintainers @pawelmitka
+/plugins/search @backstage/techdocs-core
+/plugins/search-* @backstage/techdocs-core
+/plugins/sonarqube @backstage/maintainers @backstage/sda-se-reviewers
+/plugins/stack-overflow @backstage/techdocs-core
+/plugins/stack-overflow-backend @backstage/techdocs-core
+/plugins/techdocs @backstage/techdocs-core
+/plugins/techdocs-* @backstage/techdocs-core
+/plugins/user-settings-backend @backstage/maintainers @backstage/sda-se-reviewers
+/tech-insights-backend @backstage/maintainers @xantier @iain-b
+/tech-insights-backend-module-jsonfc @backstage/maintainers @xantier @iain-b
+/tech-insights-tech-insights-common @backstage/maintainers @xantier @iain-b
+/tech-insights-tech-insights-node @backstage/maintainers @xantier @iain-b
diff --git a/.github/vale/Vocab/Backstage/accept.txt b/.github/vale/Vocab/Backstage/accept.txt
index d8c962ecc2..e6380a17f0 100644
--- a/.github/vale/Vocab/Backstage/accept.txt
+++ b/.github/vale/Vocab/Backstage/accept.txt
@@ -9,6 +9,7 @@ Airbrake
Airbrakes
Alaria
Alef
+allowlisted
Anddddd
Apdex
api
@@ -23,6 +24,7 @@ Avro
backend's
backported
backporting
+BEPs
Bigtable
Billett
bitbucket
@@ -95,6 +97,7 @@ dockerfiles
Dockerize
dockerode
Docusaurus
+Dominik
DOMPurify
don'ts
dynatrace
@@ -119,6 +122,7 @@ Firekube
Firestore
Fiverr
Francesco
+Frontside
gerrit
Gerrit
gitbeaker
@@ -138,6 +142,7 @@ Hackathons
haproxy
hardcoded
Helidon
+Henneke
Heroku
hoc
horizontalpodautoscalers
@@ -167,12 +172,14 @@ jsonnet
jsx
JWTs
Kaewkasi
+Kaswell
Keyv
Knex
KPIs
+Kuang
kubectl
kubernetes
-kubernetes
+Lainfiesta
ldap
learnings
Leasot
@@ -336,6 +343,7 @@ subfolders
subheader
subheaders
subkey
+subpath
subroutes
subtree
superfences
@@ -412,8 +420,3 @@ zod
Zolotusky
zoomable
zsh
-Lainfiesta
-allowlisted
-Dominik
-Henneke
-Kuang
diff --git a/.github/workflows/automate_changeset_feedback.yml b/.github/workflows/automate_changeset_feedback.yml
index e18aa9d428..aaf0bb1294 100644
--- a/.github/workflows/automate_changeset_feedback.yml
+++ b/.github/workflows/automate_changeset_feedback.yml
@@ -28,13 +28,13 @@ jobs:
ref: 'refs/pull/${{ github.event.pull_request.number }}/merge'
- name: fetch base
run: git fetch --depth 1 origin ${{ github.base_ref }}
- - uses: backstage/actions/changeset-feedback@v0.5.13
+ - uses: backstage/actions/changeset-feedback@v0.6.0
name: Generate feedback
with:
- diffRef: 'origin/master'
+ diff-ref: 'origin/master'
marker:
issue-number: ${{ github.event.pull_request.number }}
- botUsername: backstage-goalie[bot]
+ bot-username: backstage-goalie[bot]
app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }}
private-key: ${{ secrets.BACKSTAGE_GOALIE_PRIVATE_KEY }}
installation-id: ${{ secrets.BACKSTAGE_GOALIE_INSTALLATION_ID }}
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 10db591f4c..16573cf5b8 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -33,7 +33,7 @@ jobs:
registry-url: https://registry.npmjs.org/ # Needed for auth
- name: yarn install
- uses: backstage/actions/yarn-install@v0.5.13
+ uses: backstage/actions/yarn-install@v0.6.0
with:
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
@@ -63,7 +63,7 @@ jobs:
registry-url: https://registry.npmjs.org/ # Needed for auth
- name: yarn install
- uses: backstage/actions/yarn-install@v0.5.13
+ uses: backstage/actions/yarn-install@v0.6.0
with:
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
@@ -181,7 +181,7 @@ jobs:
registry-url: https://registry.npmjs.org/ # Needed for auth
- name: yarn install
- uses: backstage/actions/yarn-install@v0.5.13
+ uses: backstage/actions/yarn-install@v0.6.0
with:
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml
index dc221c1a1e..2e6573ede8 100644
--- a/.github/workflows/cron.yml
+++ b/.github/workflows/cron.yml
@@ -8,7 +8,7 @@ jobs:
cron:
runs-on: ubuntu-latest
steps:
- - uses: backstage/actions/cron@v0.5.13
+ - uses: backstage/actions/cron@v0.6.0
with:
app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }}
private-key: ${{ secrets.BACKSTAGE_GOALIE_PRIVATE_KEY }}
diff --git a/.github/workflows/deploy_docker-image.yml b/.github/workflows/deploy_docker-image.yml
index d8470d4124..909a36199c 100644
--- a/.github/workflows/deploy_docker-image.yml
+++ b/.github/workflows/deploy_docker-image.yml
@@ -26,7 +26,7 @@ jobs:
registry-url: https://registry.npmjs.org/ # Needed for auth
- name: yarn install
- uses: backstage/actions/yarn-install@v0.5.13
+ uses: backstage/actions/yarn-install@v0.6.0
with:
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
diff --git a/.github/workflows/deploy_nightly.yml b/.github/workflows/deploy_nightly.yml
index 5f337ace3e..c9cd22640c 100644
--- a/.github/workflows/deploy_nightly.yml
+++ b/.github/workflows/deploy_nightly.yml
@@ -26,7 +26,7 @@ jobs:
node-version: ${{ matrix.node-version }}
registry-url: https://registry.npmjs.org/ # Needed for auth
- name: yarn install
- uses: backstage/actions/yarn-install@v0.5.13
+ uses: backstage/actions/yarn-install@v0.6.0
with:
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
diff --git a/.github/workflows/deploy_packages.yml b/.github/workflows/deploy_packages.yml
index c05b850883..fa43271a96 100644
--- a/.github/workflows/deploy_packages.yml
+++ b/.github/workflows/deploy_packages.yml
@@ -68,7 +68,7 @@ jobs:
node-version: ${{ matrix.node-version }}
registry-url: https://registry.npmjs.org/ # Needed for auth
- name: yarn install
- uses: backstage/actions/yarn-install@v0.5.13
+ uses: backstage/actions/yarn-install@v0.6.0
with:
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
@@ -145,7 +145,7 @@ jobs:
node-version: ${{ matrix.node-version }}
registry-url: https://registry.npmjs.org/ # Needed for auth
- name: yarn install
- uses: backstage/actions/yarn-install@v0.5.13
+ uses: backstage/actions/yarn-install@v0.6.0
with:
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
diff --git a/.github/workflows/issue.yaml b/.github/workflows/issue.yaml
index d16d0b55d7..9f2e5827be 100644
--- a/.github/workflows/issue.yaml
+++ b/.github/workflows/issue.yaml
@@ -10,4 +10,4 @@ jobs:
if: github.repository == 'backstage/backstage'
steps:
- name: Issue sync
- uses: backstage/actions/issue-sync@v0.5.13
+ uses: backstage/actions/issue-sync@v0.6.0
diff --git a/.github/workflows/pr-review-comment.yaml b/.github/workflows/pr-review-comment.yaml
index 11b590809a..261ce56177 100644
--- a/.github/workflows/pr-review-comment.yaml
+++ b/.github/workflows/pr-review-comment.yaml
@@ -35,7 +35,7 @@ jobs:
const prNumber = artifact.name.slice('pr_number-'.length)
core.setOutput('pr-number', prNumber);
- - uses: backstage/actions/re-review@v0.5.13
+ - uses: backstage/actions/re-review@v0.6.0
with:
app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }}
private-key: ${{ secrets.BACKSTAGE_GOALIE_PRIVATE_KEY }}
diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml
index acbd11aece..db7d141abd 100644
--- a/.github/workflows/pr.yaml
+++ b/.github/workflows/pr.yaml
@@ -18,12 +18,12 @@ jobs:
if: github.repository == 'backstage/backstage' && ( github.event.pull_request || github.event.issue.pull_request )
steps:
- name: PR sync
- uses: backstage/actions/pr-sync@v0.5.13
+ uses: backstage/actions/pr-sync@v0.6.2
with:
github-token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }}
app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }}
private-key: ${{ secrets.BACKSTAGE_GOALIE_PRIVATE_KEY }}
installation-id: ${{ secrets.BACKSTAGE_GOALIE_INSTALLATION_ID }}
project-id: PVT_kwDOBFKqdc02LQ
- excluded-users: ${{ secrets.OOO_USERS }}
+ auto-assign: false
owning-teams: '@backstage/techdocs-core'
diff --git a/.github/workflows/sync_code-formatting.yml b/.github/workflows/sync_code-formatting.yml
index 19cc5f8045..b84fe5c2e6 100644
--- a/.github/workflows/sync_code-formatting.yml
+++ b/.github/workflows/sync_code-formatting.yml
@@ -20,7 +20,7 @@ jobs:
node-version: ${{ matrix.node-version }}
registry-url: https://registry.npmjs.org/ # Needed for auth
- name: yarn install
- uses: backstage/actions/yarn-install@v0.5.13
+ uses: backstage/actions/yarn-install@v0.6.0
with:
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
diff --git a/.github/workflows/sync_release-manifest.yml b/.github/workflows/sync_release-manifest.yml
index c6d00ecd28..8cf6991aaf 100644
--- a/.github/workflows/sync_release-manifest.yml
+++ b/.github/workflows/sync_release-manifest.yml
@@ -53,10 +53,6 @@ jobs:
github-token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }}
# TODO(Rugvip): Remove the create-app dispatch once we've been on the release version for a while
script: |
- const releaseVersion = require('./backstage/package.json').version;
- if(releaseVersion.includes('next')) {
- return;
- }
console.log('Dispatching upgrade helper sync');
await github.rest.actions.createWorkflowDispatch({
owner: 'backstage',
@@ -65,6 +61,6 @@ jobs:
ref: 'master',
inputs: {
version: require('./backstage/packages/create-app/package.json').version,
- releaseVersion
+ releaseVersion: require('./backstage/package.json').version
},
});
diff --git a/.github/workflows/sync_snyk-github-issues.yml b/.github/workflows/sync_snyk-github-issues.yml
index 9dcc9f63ef..dfd114c66a 100644
--- a/.github/workflows/sync_snyk-github-issues.yml
+++ b/.github/workflows/sync_snyk-github-issues.yml
@@ -23,7 +23,7 @@ jobs:
node-version: ${{ matrix.node-version }}
registry-url: https://registry.npmjs.org/ # Needed for auth
- name: yarn install
- uses: backstage/actions/yarn-install@v0.5.13
+ uses: backstage/actions/yarn-install@v0.6.0
with:
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
diff --git a/.github/workflows/uffizzi-build.yml b/.github/workflows/uffizzi-build.yml
index 5c8e179958..714b108898 100644
--- a/.github/workflows/uffizzi-build.yml
+++ b/.github/workflows/uffizzi-build.yml
@@ -27,7 +27,7 @@ jobs:
registry-url: https://registry.npmjs.org/
- name: yarn install
- uses: backstage/actions/yarn-install@v0.5.13
+ uses: backstage/actions/yarn-install@v0.6.0
with:
cache-prefix: linux-v16
diff --git a/.github/workflows/verify_e2e-linux.yml b/.github/workflows/verify_e2e-linux.yml
index f687e4f5a4..16ddb04086 100644
--- a/.github/workflows/verify_e2e-linux.yml
+++ b/.github/workflows/verify_e2e-linux.yml
@@ -52,7 +52,7 @@ jobs:
node-version: ${{ matrix.node-version }}
registry-url: https://registry.npmjs.org/ # Needed for auth
- name: yarn install
- uses: backstage/actions/yarn-install@v0.5.13
+ uses: backstage/actions/yarn-install@v0.6.0
with:
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
diff --git a/.github/workflows/verify_kubernetes.yml b/.github/workflows/verify_kubernetes.yml
index 7fbcf9fa3f..6d8a7682b5 100644
--- a/.github/workflows/verify_kubernetes.yml
+++ b/.github/workflows/verify_kubernetes.yml
@@ -28,7 +28,7 @@ jobs:
registry-url: https://registry.npmjs.org/ # Needed for auth
- name: yarn install
- uses: backstage/actions/yarn-install@v0.5.13
+ uses: backstage/actions/yarn-install@v0.6.0
with:
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
diff --git a/.github/workflows/verify_storybook.yml b/.github/workflows/verify_storybook.yml
index 0e63393af8..38b685c539 100644
--- a/.github/workflows/verify_storybook.yml
+++ b/.github/workflows/verify_storybook.yml
@@ -35,7 +35,7 @@ jobs:
node-version: ${{ matrix.node-version }}
registry-url: https://registry.npmjs.org/ # Needed for auth
- name: yarn install
- uses: backstage/actions/yarn-install@v0.5.13
+ uses: backstage/actions/yarn-install@v0.6.0
with:
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
- name: storybook yarn install
diff --git a/ADOPTERS.md b/ADOPTERS.md
index 965cf06727..4329a00664 100644
--- a/ADOPTERS.md
+++ b/ADOPTERS.md
@@ -186,7 +186,7 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/
| [Cho Tot](https://www.chotot.com) | [Chotot Team](mailto:sre@chotot.vn) | Internal developer portal, service catalog with CI/CD tools. |
| [William Hill](https://www.williamhillgroup.com/) | [Pat Mills](mailto:pat.mills@williamhill.com), [Nathan Flynn](mailto:nflynn@williamhill.co.uk), and [Nishkarsh Raj](mailto:nishkarsh.raj@williamhill.co.uk) | William Hill are leveraging Backstage to build our Engineering Portal. Our mission is to centralize the software catalog inventory to enable service discoverability, reduce the onboarding time for new Engineers, provide a single pane of glass to accelerate Developer Productivity and Save Engineers time. Our aspiration is to create an InnerSource community focussed on organization-wide patterns that are re-usable and can be self-served with the Scaffolder. |
| [Vodafone NewZealand Limited](https://vodafone.co.nz) | [Ankit Gupta](mailto:ankit.gupta@vodafone.nz), [DevOps COE](mailto:devopstooling@vodafone.nz) | Vodafone NZ are leveraging Backstage to build centralised and self service Engineering Portal. Our mission is to standardised Pipeline templates across the Engineering teams, One shop stop to create the pipelines and repository with a template approach which reduces creation part from days to minutes and no wait time for developers. A unified view for Azure DevOps pipeline, Azure Repo pull requests, Deployment status from Azure RedHat Openshift-ArgoCD and SonarQube Security and code quality scans report on a single pan to provide a streamlined view for all microservices across the app stack. |
-| [Coamo](http://www.coamo.com.br) | [@holiiveira](https://github.com/holiiveira), [@gpxlnx](https://github.com/gpxlnx) | We're starting to use it as the main tool of a DevOps platform. Our goal is to provide software templates, centralize our software catalog enabling efficient service discovery, and make it easy to manage the entire software ecosystem in one place. |
+| [Coamo](http://www.coamo.com.br) | [Henrique Oliveira](https://www.linkedin.com/in/oliveirah/), [Guilherme Xavier](https://br.linkedin.com/in/guilhermexavierlnx) | We're starting to use it as the main tool of a DevOps platform. Our goal is to provide software templates, centralize our software catalog enabling efficient service discovery, and make it easy to manage the entire software ecosystem in one place. |
| [Exclaimer](https://www.exclaimer.com/) | [Marley Powell](mailto:marley.powell@exclaimer.com) | Developer portal, service catalog and documentation |
| [Edge Consulting](https://egde.no/) | [Øyvind Brekkhus Sandåker](mailto:oyvindbs@egde.no) | Using it as a Software Catalog to get an overview of our systems, for ourselves and our customers. |
| [CRV](https://crv4all.com) | [Pepijn Schildkamp](mailto:pepijn.schildkamp@crv4all.com) |
diff --git a/STYLE.md b/STYLE.md
index 87e0644759..e38354ae1d 100644
--- a/STYLE.md
+++ b/STYLE.md
@@ -94,6 +94,13 @@ This section describes guidelines for designing public APIs. It can also be appl
/* ... */
}
+ // In order to make a private constructor available for testing you can use a
+ // static factory marked as `@internal`, which will not show up in the public API.
+ /** @internal */
+ static forTesting(internalOptions?: { ... }) {
+ return new DefaultImageLoader(internalOptions);
+ }
+
private constructor(/* ... */) {
/* ... */
}
diff --git a/cypress/.eslintrc.js b/cypress/.eslintrc.js
index a77de4a629..07f264452d 100644
--- a/cypress/.eslintrc.js
+++ b/cypress/.eslintrc.js
@@ -2,15 +2,6 @@ module.exports = {
extends: [require.resolve('@backstage/cli/config/eslint.backend')],
rules: {
'no-console': 0,
- 'import/no-extraneous-dependencies': [
- 'error',
- {
- devDependencies: true,
- optionalDependencies: false,
- peerDependencies: false,
- bundledDependencies: false,
- },
- ],
'jest/valid-expect': 'off',
'jest/expect-expect': 'off',
'no-restricted-syntax': 'off',
diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts
new file mode 100644
index 0000000000..fd4db77d61
--- /dev/null
+++ b/cypress/support/commands.ts
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ***********************************************
+// This example commands.ts shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+//
+// declare global {
+// namespace Cypress {
+// interface Chainable {
+// login(email: string, password: string): Chainable
+// drag(subject: string, options?: Partial): Chainable
+// dismiss(subject: string, options?: Partial): Chainable
+// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
+// }
+// }
+// }
diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts
new file mode 100644
index 0000000000..c71790471e
--- /dev/null
+++ b/cypress/support/e2e.ts
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// This example support/e2e.ts is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands';
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/cypress/yarn.lock b/cypress/yarn.lock
index ded043cdaf..36dd0b056d 100644
--- a/cypress/yarn.lock
+++ b/cypress/yarn.lock
@@ -1415,22 +1415,22 @@ __metadata:
linkType: hard
"typescript@npm:^4.1.3":
- version: 4.9.4
- resolution: "typescript@npm:4.9.4"
+ version: 4.9.5
+ resolution: "typescript@npm:4.9.5"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
- checksum: e782fb9e0031cb258a80000f6c13530288c6d63f1177ed43f770533fdc15740d271554cdae86701c1dd2c83b082cea808b07e97fd68b38a172a83dbf9e0d0ef9
+ checksum: ee000bc26848147ad423b581bd250075662a354d84f0e06eb76d3b892328d8d4440b7487b5a83e851b12b255f55d71835b008a66cbf8f255a11e4400159237db
languageName: node
linkType: hard
"typescript@patch:typescript@^4.1.3#~builtin":
- version: 4.9.4
- resolution: "typescript@patch:typescript@npm%3A4.9.4#~builtin::version=4.9.4&hash=a1c5e5"
+ version: 4.9.5
+ resolution: "typescript@patch:typescript@npm%3A4.9.5#~builtin::version=4.9.5&hash=a1c5e5"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
- checksum: 37f6e2c3c5e2aa5934b85b0fddbf32eeac8b1bacf3a5b51d01946936d03f5377fe86255d4e5a4ae628fd0cd553386355ad362c57f13b4635064400f3e8e05b9d
+ checksum: 2eee5c37cad4390385db5db5a8e81470e42e8f1401b0358d7390095d6f681b410f2c4a0c496c6ff9ebd775423c7785cdace7bcdad76c7bee283df3d9718c0f20
languageName: node
linkType: hard
diff --git a/docs/assets/auth/gcp-iap-jwt-audience-code-popup.png b/docs/assets/auth/gcp-iap-jwt-audience-code-popup.png
new file mode 100644
index 0000000000..72b69b3b01
Binary files /dev/null and b/docs/assets/auth/gcp-iap-jwt-audience-code-popup.png differ
diff --git a/docs/assets/permissions/permission-framework-overview.drawio.svg b/docs/assets/permissions/permission-framework-overview.drawio.svg
index c7e628f8a6..3740384748 100644
--- a/docs/assets/permissions/permission-framework-overview.drawio.svg
+++ b/docs/assets/permissions/permission-framework-overview.drawio.svg
@@ -1,4 +1,4 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/docs/assets/software-catalog/software-model-entities.drawio.svg b/docs/assets/software-catalog/software-model-entities.drawio.svg
old mode 100755
new mode 100644
index e14cc93e62..d087583245
--- a/docs/assets/software-catalog/software-model-entities.drawio.svg
+++ b/docs/assets/software-catalog/software-model-entities.drawio.svg
@@ -1,4 +1,4 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/docs/auth/google/gcp-iap-auth.md b/docs/auth/google/gcp-iap-auth.md
index f9a78bbc71..36eece85c5 100644
--- a/docs/auth/google/gcp-iap-auth.md
+++ b/docs/auth/google/gcp-iap-auth.md
@@ -29,7 +29,9 @@ auth:
jwtHeader: x-custom-header # Optional: Only if you are using a custom header for the IAP JWT
```
-You can find the project number and service ID in the Google Cloud Console.
+The full `audience` value can be obtained by visiting your [Identity-Aware Proxy Google Cloud console](https://console.cloud.google.com/security/iap), selecting your project, finding your Backend Service to proxy, clicking the 3 vertical dots then "Get JWT Audience Code", and copying from the resulting popup, which will look similar to the following:
+
+
This config section must be in place for the provider to load at all. Now let's
add the provider itself.
diff --git a/docs/backend-system/architecture/01-index.md b/docs/backend-system/architecture/01-index.md
index 88ba3262df..a9f08c7907 100644
--- a/docs/backend-system/architecture/01-index.md
+++ b/docs/backend-system/architecture/01-index.md
@@ -6,6 +6,8 @@ sidebar_label: System Architecture
description: The structure and architecture of the new Backend System and its component parts
---
+> **DISCLAIMER: The new backend system is under active development and is not considered stable**
+
## Building Blocks
This section introduces the high-level building blocks upon which this new
diff --git a/docs/backend-system/architecture/02-backends.md b/docs/backend-system/architecture/02-backends.md
index 69b74e7dd3..53670aba12 100644
--- a/docs/backend-system/architecture/02-backends.md
+++ b/docs/backend-system/architecture/02-backends.md
@@ -6,6 +6,8 @@ sidebar_label: Backend
description: Backend instances
---
+> **DISCLAIMER: The new backend system is under active development and is not considered stable**
+
## The Backend Instance
This is the main entry point for creating a backend. It does not have any functionality in and of itself, but is simply responsible for wiring things together.
diff --git a/docs/backend-system/architecture/03-services.md b/docs/backend-system/architecture/03-services.md
index 96b82d7e95..875cb3aaea 100644
--- a/docs/backend-system/architecture/03-services.md
+++ b/docs/backend-system/architecture/03-services.md
@@ -6,6 +6,8 @@ sidebar_label: Services
description: Services for backend plugins
---
+> **DISCLAIMER: The new backend system is under active development and is not considered stable**
+
Backend services provide shared functionality available to all backend plugins and modules. They are made available through service references that embed a type that represents the service interface, similar to how [Utility APIs](../../api/utility-apis.md) work in the Backstage frontend system. To use a service in your plugin or module you request an implementation of that service using the service reference.
The system surrounding services exists to provide a level of indirection between the service interfaces and their implementation. It is an implementation of dependency injection, where each backend instance is the dependency injection container. The implementation for each service is provided by a service factory, which encapsulates the logic for how each service instance is created.
@@ -59,7 +61,7 @@ class DefaultFooService implements FooService {
}
}
-export const fooFactory = createServiceFactory({
+export const fooServiceFactory = createServiceFactory({
service: fooServiceRef,
deps: { bar: barServiceRef },
factory({ bar }) {
@@ -73,7 +75,7 @@ To create a service factory we need to provide a reference to the `service` for
If you need the creation of the service instance to be asynchronous, you can make the `factory` function async. For example:
```ts
-export const fooFactory = createServiceFactory({
+export const fooServiceFactory = createServiceFactory({
service: fooServiceRef,
deps: {},
async factory() {
@@ -92,18 +94,18 @@ To install a service factory in a backend instance, we pass it in through the `s
```ts
const backend = createBackend({
- services: [fooFactory()],
+ services: [fooServiceFactory()],
});
```
-Note that we call `fooFactory` to create the service factory instance. This is because `createServiceFactory` always returns a factory function that creates the actual service factory. This is done to always allow for options to be added to the service factory in the future, without breaking existing code. To add options to your service factory, you wrap the object passed to `createServiceFactory` in a callback that accepts the desired options. For example:
+Note that we call `fooServiceFactory` to create the service factory instance. This is because `createServiceFactory` always returns a factory function that creates the actual service factory. This is done to always allow for options to be added to the service factory in the future, without breaking existing code. To add options to your service factory, you wrap the object passed to `createServiceFactory` in a callback that accepts the desired options. For example:
```ts
export interface FooFactoryOptions {
mode: 'eager' | 'lazy';
}
-export const fooFactory = createServiceFactory(
+export const fooServiceFactory = createServiceFactory(
(options?: FooFactoryOptions) => ({
service: fooServiceRef,
deps: { bar: barServiceRef },
@@ -118,7 +120,7 @@ This lets us use the options to customize the factory implementation in any way
```ts
const backend = createBackend({
- services: [fooFactory({ mode: 'eager' })],
+ services: [fooServiceFactory({ mode: 'eager' })],
});
```
@@ -162,7 +164,7 @@ Plugin scoped services have access to a plugin metadata service, which is a spec
The plugin metadata service is the base for all plugin specific customizations for services. For example, the default implementation of the plugin scoped logger service uses the plugin metadata service to attach the plugin ID as a field in all log messages:
```ts
-export const loggerFactory = createServiceFactory({
+export const loggerServiceFactory = createServiceFactory({
service: coreServices.logger,
deps: {
rootLogger: coreServices.rootLogger,
@@ -181,7 +183,7 @@ Some services may benefit from having a context that is shared across all instan
The root context is defined as part of the service factory by passing the `createRootContext` option:
```ts
-export const fooFactory = createServiceFactory({
+export const fooServiceFactory = createServiceFactory({
service: fooServiceRef,
deps: { rootLogger: coreServices.rootLogger, bar: barServiceRef },
createRootContext({ rootLogger }) {
diff --git a/docs/backend-system/architecture/04-plugins.md b/docs/backend-system/architecture/04-plugins.md
index f535268b2a..e73f086c43 100644
--- a/docs/backend-system/architecture/04-plugins.md
+++ b/docs/backend-system/architecture/04-plugins.md
@@ -6,6 +6,8 @@ sidebar_label: Plugins
description: Backend plugins
---
+> **DISCLAIMER: The new backend system is under active development and is not considered stable**
+
Plugins provide the actual base features of a Backstage backend. Each plugin operates completely independently of all other plugins and they only communicate with each other through network calls. This means that there is a strong degree of isolation between plugins, and that each plugin can be considered a separate microservice. While a default Backstage project has all plugins installed within a single backend, it is also possible to split this setup into multiple backends, with each backend housing one or more plugins.
## Defining a Plugin
@@ -20,7 +22,7 @@ import {
} from '@backstage/backend-plugin-api';
export const examplePlugin = createBackendPlugin({
- id: 'example',
+ pluginId: 'example',
register(env) {
env.registerInit({
deps: {
@@ -51,7 +53,7 @@ export interface ExamplePluginOptions {
export const examplePlugin = createBackendPlugin(
(options?: ExamplePluginOptions) => ({
- id: 'example',
+ pluginId: 'example',
register(env) {
env.registerInit({
deps: {
diff --git a/docs/backend-system/architecture/05-extension-points.md b/docs/backend-system/architecture/05-extension-points.md
index f82fde3561..278c565472 100644
--- a/docs/backend-system/architecture/05-extension-points.md
+++ b/docs/backend-system/architecture/05-extension-points.md
@@ -6,6 +6,8 @@ sidebar_label: Extension Points
description: Extension points of backend plugins
---
+> **DISCLAIMER: The new backend system is under active development and is not considered stable**
+
While plugins are able to accept options for lightweight forms of customization and extension, you quickly hit a limit where you need something more powerful to allow users to extend your plugin. For this purpose, the backend system provides a mechanism for plugins to provide extension points, which can be used to expose deeper customizations for your plugin. Extension points are used by modules, which are installed in the backend adjacent to plugins. Modules are covered more in-depth in the [next section](./06-modules.md).
Extension points are quite similar to services, in that they both encapsulate an interface in a reference object. The key difference is that extension points are registered and provided by plugins themselves, and do not have any factory associated with them. Extension points for a given plugin are also only accessible to modules that extend that same plugin.
@@ -42,7 +44,7 @@ class ActionsExtension implements ScaffolderActionsExtensionPoint {
export const scaffolderPlugin = createBackendPlugin(
{
- id: 'scaffolder',
+ pluginId: 'scaffolder',
register(env) {
const actionsExtensions = new ActionsExtension();
env.registerExtensionPoint(
diff --git a/docs/backend-system/architecture/06-modules.md b/docs/backend-system/architecture/06-modules.md
index 83428c7a26..2f359eaa75 100644
--- a/docs/backend-system/architecture/06-modules.md
+++ b/docs/backend-system/architecture/06-modules.md
@@ -6,6 +6,8 @@ sidebar_label: Modules
description: Modules for backend plugins
---
+> **DISCLAIMER: The new backend system is under active development and is not considered stable**
+
Backend modules are used to extend [plugins](./04-plugins.md) with additional features or change existing behavior. They must always be installed in the same backend instance as the plugin that they extend, and may only extend a single plugin. Modules interact with their target plugin using the [extension points](./05-extension-points.md) registered by the plugin, while also being able to depend on the [services](./03-services.md) of that plugin.
Both modules and plugins register an `init` method that is called during startup. In order to ensure that modules have registered all their extensions before the plugin starts up, all modules for each plugin are completely initialized before the plugin itself is initialized. In practice this means that all promises returned by each `init` method of the modules need to resolve before the plugin `init` method is called. This also means that it is not possible to further interact with the extension points once the `init` method has resolved.
diff --git a/docs/backend-system/architecture/07-naming-patterns.md b/docs/backend-system/architecture/07-naming-patterns.md
index 6bd7c412c3..b62e049f08 100644
--- a/docs/backend-system/architecture/07-naming-patterns.md
+++ b/docs/backend-system/architecture/07-naming-patterns.md
@@ -6,6 +6,8 @@ sidebar_label: Naming Patterns
description: Naming patterns in the backend system
---
+> **DISCLAIMER: The new backend system is under active development and is not considered stable**
+
These are the naming patterns to adhere to within the backend system. They help us keep exports consistent across packages and make it easier to understand the usage and intent of exports.
### Plugins
@@ -19,7 +21,7 @@ Example:
```ts
export const catalogPlugin = createBackendPlugin({
- id: 'catalog',
+ pluginId: 'catalog',
...
})
```
@@ -34,7 +36,7 @@ export const catalogPlugin = createBackendPlugin({
Example:
```ts
-export const catalogModuleGithubEntityProvider = createBackendPlugin({
+export const catalogModuleGithubEntityProvider = createBackendModule({
pluginId: 'catalog',
moduleId: 'githubEntityProvider',
...
@@ -64,12 +66,12 @@ export const catalogProcessingExtensionPoint = createExtensionPointService` | `LoggerService`, `DatabaseService` |
-| Reference | `ServiceRef` | `loggerServiceRef`, `databaseServiceRef` |
-| ID | `.` | `'core.rootHttpRouter'`, `'catalog.catalogClient'` |
-| Factory | `Factory` | `loggerFactory`, `databaseFactory` |
+| Description | Pattern | Examples |
+| ----------- | ---------------------- | -------------------------------------------------- |
+| Interface | `Service` | `LoggerService`, `DatabaseService` |
+| Reference | `ServiceRef` | `loggerServiceRef`, `databaseServiceRef` |
+| ID | `.` | `'core.rootHttpRouter'`, `'catalog.catalogClient'` |
+| Factory | `ServiceFactory` | `loggerServiceFactory`, `databaseServiceFactory` |
Example:
@@ -83,7 +85,7 @@ export const catalogClientServiceRef = createServiceRef({
...
})
-export const catalogClientFactory = createServiceFactory({
+export const catalogClientServiceFactory = createServiceFactory({
service: catalogClientServiceRef,
...
})
diff --git a/docs/backend-system/building-backends/01-index.md b/docs/backend-system/building-backends/01-index.md
index f810417ed7..bda2aa7eaa 100644
--- a/docs/backend-system/building-backends/01-index.md
+++ b/docs/backend-system/building-backends/01-index.md
@@ -6,6 +6,8 @@ sidebar_label: Overview
description: Building backends using the new backend system
---
+> **DISCLAIMER: The new backend system is under active development and is not considered stable**
+
> NOTE: If you have an existing backend that is not yet using the new backend
> system, see [migrating](./08-migrating.md).
@@ -59,11 +61,11 @@ All of these services can be replaced with your own implementations if you need
For example, let's say we want to customize the core configuration service to enable remote configuration loading. That would look something like this:
```ts
-import { configFactory } from '@backstage/backend-app-api';
+import { configServiceFactory } from '@backstage/backend-app-api';
const backend = createBackend({
services: [
- configFactory({
+ configServiceFactory({
remote: { reloadIntervalSeconds: 60 },
}),
],
@@ -158,11 +160,11 @@ A shared environment is defined using `createSharedEnvironment`. In this example
```ts
// packages/backend-env/src/index.ts
import { createSharedEnvironment } from '@backstage/backend-plugin-api';
-import { customDiscoveryFactory } from './customDiscoveryFactory';
+import { customDiscoveryServiceFactory } from './customDiscoveryServiceFactory';
export const env = createSharedEnvironment({
services: [
- customDiscoveryFactory(), // custom DiscoveryService implementation
+ customDiscoveryServiceFactory(), // custom DiscoveryService implementation
],
});
```
diff --git a/docs/backend-system/building-backends/08-migrating.md b/docs/backend-system/building-backends/08-migrating.md
index 6e0b84b10f..e503d627ef 100644
--- a/docs/backend-system/building-backends/08-migrating.md
+++ b/docs/backend-system/building-backends/08-migrating.md
@@ -6,6 +6,8 @@ sidebar_label: Migration Guide
description: How to migrate existing backends to the new backend system
---
+> **DISCLAIMER: The new backend system is under active development and is not considered stable**
+
## Overview
This section describes how to migrate an existing Backstage backend service
diff --git a/docs/backend-system/building-plugins-and-modules/01-index.md b/docs/backend-system/building-plugins-and-modules/01-index.md
index 01e35036aa..cae5052d04 100644
--- a/docs/backend-system/building-plugins-and-modules/01-index.md
+++ b/docs/backend-system/building-plugins-and-modules/01-index.md
@@ -6,6 +6,8 @@ sidebar_label: Overview
description: Building backend plugins and modules using the new backend system
---
+> **DISCLAIMER: The new backend system is under active development and is not considered stable**
+
> NOTE: If you have an existing backend and/or backend plugins that are not yet
> using the new backend system, see [migrating](./08-migrating.md).
@@ -34,7 +36,7 @@ import {
import { createExampleRouter } from './router';
export const examplePlugin = createBackendPlugin({
- id: 'example',
+ pluginId: 'example',
register(env) {
env.registerInit({
deps: {
@@ -181,7 +183,7 @@ that needs to be different across environments.
import { coreServices } from '@backstage/backend-plugin-api';
export const examplePlugin = createBackendPlugin({
- id: 'example',
+ pluginId: 'example',
register(env) {
env.registerInit({
deps: { config: coreServices.config },
@@ -214,7 +216,7 @@ export interface ExampleOptions {
export const examplePlugin = createBackendPlugin(
(options?: ExampleOptions) => ({
- id: 'example',
+ pluginId: 'example',
register(env) {
env.registerInit({
deps: {
diff --git a/docs/backend-system/building-plugins-and-modules/02-testing.md b/docs/backend-system/building-plugins-and-modules/02-testing.md
index 20bef6fec4..37c5698512 100644
--- a/docs/backend-system/building-plugins-and-modules/02-testing.md
+++ b/docs/backend-system/building-plugins-and-modules/02-testing.md
@@ -6,6 +6,8 @@ sidebar_label: Testing
description: Learn how to test your backend plugins and modules
---
+> **DISCLAIMER: The new backend system is under active development and is not considered stable**
+
Utilities for testing backend plugins and modules are available in
`@backstage/backend-test-utils`. This section describes those facilities.
diff --git a/docs/backend-system/building-plugins-and-modules/08-migrating.md b/docs/backend-system/building-plugins-and-modules/08-migrating.md
index ec003a6fec..687f4c1d5e 100644
--- a/docs/backend-system/building-plugins-and-modules/08-migrating.md
+++ b/docs/backend-system/building-plugins-and-modules/08-migrating.md
@@ -6,6 +6,8 @@ sidebar_label: Migration Guide
description: How to migrate existing backend plugins to the new backend system
---
+> **DISCLAIMER: The new backend system is under active development and is not considered stable**
+
Migrating an existing backend plugin to the new backend system is fairly straightforward. The process is similar across the majority of plugins which just return a `Router` that is then wired up in the `index.ts` file of your backend. The primary thing that we need to do is to make sure that the dependencies that are required by the plugin are available, and then registering the router with the HTTP router service.
Let's look at an example of migrating the Kubernetes backend plugin. In the existing (old) system, the kubernetes backend is structured like this:
@@ -44,7 +46,7 @@ import { Router } from 'express';
import { KubernetesBuilder } from './KubernetesBuilder';
export const kubernetesPlugin = createBackendPlugin({
- id: 'kubernetes',
+ pluginId: 'kubernetes',
register(env) {
env.registerInit({
deps: {
@@ -93,7 +95,7 @@ export interface KubernetesOptions {
}
const kubernetesPlugin = createBackendPlugin((options: KubernetesOptions) => ({
- id: 'kubernetes',
+ pluginId: 'kubernetes',
register(env) {
env.registerInit({
deps: {
@@ -180,7 +182,7 @@ class ClusterSupplier implements KubernetesClusterSupplierExtensionPoint {
}
export const kubernetesPlugin = createBackendPlugin({
- id: 'kubernetes',
+ pluginId: 'kubernetes',
register(env) {
const extensionPoint = new ClusterSupplier();
// We register the extension point with the backend, which allows modules to
diff --git a/docs/backend-system/core-services/01-index.md b/docs/backend-system/core-services/01-index.md
index 4ef9d75bde..b6682c2708 100644
--- a/docs/backend-system/core-services/01-index.md
+++ b/docs/backend-system/core-services/01-index.md
@@ -6,6 +6,8 @@ sidebar_label: Core Services
description: Core backend service APIs
---
+> **DISCLAIMER: The new backend system is under active development and is not considered stable**
+
The default backend provides several [core services](https://github.com/backstage/backstage/blob/master/packages/backend-plugin-api/src/services/definitions/coreServices.ts) out of the box which includes access to configuration, logging, URL Readers, databases and more.
All core services are available through the `coreServices` namespace in the `@backstage/backend-plugin-api` package.
@@ -31,7 +33,7 @@ import {
import { Router } from 'express';
createBackendPlugin({
- id: 'example',
+ pluginId: 'example',
register(env) {
env.registerInit({
deps: { http: coreServices.httpRouter },
@@ -57,11 +59,11 @@ There's additional configuration that you can optionally pass to setup the `http
You can configure these additional options by adding an override for the core service when calling `createBackend` like follows:
```ts
-import { httpRouterFactory } from '@backstage/backend-app-api';
+import { httpRouterServiceFactory } from '@backstage/backend-app-api';
const backend = createBackend({
services: [
- httpRouterFactory({
+ httpRouterServiceFactory({
getPath: (pluginId: string) => `/plugins/${pluginId}`,
}),
],
@@ -84,7 +86,7 @@ import {
import { Router } from 'express';
createBackendPlugin({
- id: 'example',
+ pluginId: 'example',
register(env) {
env.registerInit({
deps: {
@@ -114,11 +116,11 @@ There's additional options that you can pass to configure the root HTTP Router s
You can configure the root HTTP Router service by passing the options to the `createBackend` function.
```ts
-import { rootHttpRouterFactory } from '@backstage/backend-app-api';
+import { rootHttpRouterServiceFactory } from '@backstage/backend-app-api';
const backend = createBackend({
services: [
- rootHttpRouterFactory({
+ rootHttpRouterServiceFactory({
configure: ({ app, middleware, routes, config, logger, lifecycle }) => {
// the built in middleware is provided through an option in the configure function
app.use(middleware.helmet());
@@ -155,7 +157,7 @@ import {
} from '@backstage/backend-plugin-api';
createBackendPlugin({
- id: 'example',
+ pluginId: 'example',
register(env) {
env.registerInit({
deps: {
@@ -181,11 +183,11 @@ There's additional configuration that you can optionally pass to setup the `conf
You can configure these additional options by adding an override for the core service when calling `createBackend` like follows:
```ts
-import { configFactory } from '@backstage/backend-app-api';
+import { configServiceFactory } from '@backstage/backend-app-api';
const backend = createBackend({
services: [
- configFactory({
+ configServiceFactory({
argv: [
'--config',
'/backstage/app-config.development.yaml',
@@ -213,7 +215,7 @@ import {
} from '@backstage/backend-plugin-api';
createBackendPlugin({
- id: 'example',
+ pluginId: 'example',
register(env) {
env.registerInit({
deps: {
@@ -286,7 +288,7 @@ import {
} from '@backstage/backend-plugin-api';
createBackendPlugin({
- id: 'example',
+ pluginId: 'example',
register(env) {
env.registerInit({
deps: {
@@ -325,7 +327,7 @@ import {
import { resolvePackagePath } from '@backstage/backend-common';
createBackendPlugin({
- id: 'example',
+ pluginId: 'example',
register(env) {
env.registerInit({
deps: {
@@ -364,7 +366,7 @@ import {
import { fetch } from 'node-fetch';
createBackendPlugin({
- id: 'example',
+ pluginId: 'example',
register(env) {
env.registerInit({
deps: {
@@ -395,7 +397,7 @@ import {
import { Router } from 'express';
createBackendPlugin({
- id: 'example',
+ pluginId: 'example',
register(env) {
env.registerInit({
deps: {
@@ -436,11 +438,11 @@ There's additional configuration that you can optionally pass to setup the `iden
You can configure these additional options by adding an override for the core service when calling `createBackend` like follows:
```ts
-import { identityFactory } from '@backstage/backend-app-api';
+import { identityServiceFactory } from '@backstage/backend-app-api';
const backend = createBackend({
services: [
- identityFactory({
+ identityServiceFactory({
issuer: 'backstage',
algorithms: ['ES256', 'RS256'],
}),
@@ -463,7 +465,7 @@ import {
} from '@backstage/backend-plugin-api';
createBackendPlugin({
- id: 'example',
+ pluginId: 'example',
register(env) {
env.registerInit({
deps: {
@@ -477,10 +479,7 @@ createBackendPlugin({
// do some other stuff.
}, 1000);
- lifecycle.addShutdownHook({
- fn: () => clearInterval(interval),
- logger,
- });
+ lifecycle.addShutdownHook(() => clearInterval(interval));
},
});
},
@@ -497,17 +496,19 @@ The following example shows how to override the default implementation of the li
```ts
class MyCustomLifecycleService implements RootLifecycleService {
- constructor(private readonly logger: LoggerService) {
- ['SIGKILL', 'SIGTERM'].map(signal =>
- process.on(signal, () => this.shutdown()),
- );
- }
+ constructor(private readonly logger: LoggerService) {}
#isCalled = false;
- #shutdownTasks: Array = [];
+ #shutdownTasks: Array<{
+ hook: LifecycleServiceShutdownHook;
+ options?: LifecycleServiceShutdownOptions;
+ }> = [];
- addShutdownHook(options: LifecycleServiceShutdownHook): void {
- this.#shutdownTasks.push(options);
+ addShutdownHook(
+ hook: LifecycleServiceShutdownHook,
+ options?: LifecycleServiceShutdownOptions,
+ ): void {
+ this.#shutdownTasks.push({ hook, options });
}
async shutdown(): Promise {
@@ -518,10 +519,10 @@ class MyCustomLifecycleService implements RootLifecycleService {
this.logger.info(`Running ${this.#shutdownTasks.length} shutdown tasks...`);
await Promise.all(
- this.#shutdownTasks.map(async hook => {
- const { logger = this.logger } = hook;
+ this.#shutdownTasks.map(async ({ hook, options }) => {
+ const logger = options?.logger ?? this.logger;
try {
- await hook.fn();
+ await hook();
logger.info(`Shutdown hook succeeded`);
} catch (error) {
logger.error(`Shutdown hook failed, ${error}`);
@@ -562,7 +563,7 @@ import {
import { Router } from 'express';
createBackendPlugin({
- id: 'example',
+ pluginId: 'example',
register(env) {
env.registerInit({
deps: {
@@ -611,7 +612,7 @@ import {
import { fetch } from 'node-fetch';
createBackendPlugin({
- id: 'example',
+ pluginId: 'example',
register(env) {
env.registerInit({
deps: {
@@ -650,7 +651,7 @@ import {
import os from 'os';
createBackendPlugin({
- id: 'example',
+ pluginId: 'example',
register(env) {
env.registerInit({
deps: {
diff --git a/docs/features/kubernetes/proxy.md b/docs/features/kubernetes/proxy.md
new file mode 100644
index 0000000000..5848d62e3e
--- /dev/null
+++ b/docs/features/kubernetes/proxy.md
@@ -0,0 +1,87 @@
+---
+id: proxy
+title: Kubernetes Backend Proxy Endpoint
+sidebar_label: Proxy
+description: Interacting with the Kubernetes API in Backstage plugins
+---
+
+[Contributors](https://backstage.io/docs/overview/glossary#backstage-user-profiles) wanting to
+create developer portal experiences based on data from Kubernetes (e.g. for
+interacting with [Custom
+Resources](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/)
+beyond the default behaviors of the existing Kubernetes plugin) can leverage the
+Kubernetes backend plugin's proxy endpoint to allow them to make arbitrary
+requests to the [REST
+API](https://kubernetes.io/docs/reference/using-api/api-concepts/).
+
+Here is a snippet fetching namespaces from a cluster configured with the
+`google` [auth provider](https://backstage.io/docs/features/kubernetes/configuration#clustersauthprovider):
+
+```typescript
+import {
+ discoveryApiRef,
+ googleAuthApiRef,
+ useApi,
+} from '@backstage/core-plugin-api';
+
+const CLUSTER_NAME = ''; // use a known cluster name
+
+// get a bearer token from Google
+const googleAuthApi = useApi(googleAuthApiRef);
+const token = await googleAuthApi.getAccessToken(
+ 'https://www.googleapis.com/auth/cloud-platform',
+);
+
+const discoveryApi = useApi(discoveryApiRef);
+const kubernetesBaseUrl = await discoveryApi.getBaseUrl('kubernetes');
+const kubernetesProxyEndpoint = `${kubernetesBaseUrl}/proxy`;
+
+// fetch namespaces
+await fetch(`${kubernetesProxyEndpoint}/api/v1/namespaces`, {
+ method: 'GET',
+ headers: {
+ 'X-Kubernetes-Cluster': CLUSTER_NAME,
+ Authorization: `Bearer ${token}`,
+ },
+});
+```
+
+## How it works
+
+The proxy will interpret the
+[`X-Kubernetes-Cluster`
+header](https://backstage.io/docs/reference/plugin-kubernetes-backend.header_kubernetes_cluster)
+as the name of the cluster to target. This name will be compared to each cluster
+returned by all the configured [cluster
+locators](https://backstage.io/docs/features/kubernetes/configuration#clusterlocatormethods)
+-- the first cluster whose [`name` field](https://backstage.io/docs/features/kubernetes/configuration#clustersname) matches
+the value in the header will be targeted.
+
+Then the request will be forwarded verbatim (but with the endpoint's base URL
+prefix stripped) to the cluster.
+
+## Authentication
+
+Until some security and permission decisions are made (see [this
+conversation](https://github.com/backstage/backstage/pull/13026/files#r1029376939)
+for context), contributors consuming the proxy endpoint in their plugin code are
+responsible for negotiating their own bearer token out-of-band. This requires
+knowing some auth details about the cluster being contacted -- in practice, only
+clusters with [client side auth
+providers](https://backstage.io/docs/features/kubernetes/authentication#client-side-providers) can reasonably be reached.
+
+The proxy has no provisions for mTLS, so it cannot be used to connect to
+clusters using the [x509 Client
+Certs](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#x509-client-certs)
+authentication strategy. [Bearer
+tokens](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#putting-a-bearer-token-in-a-request)
+will be forwarded as-is.
+
+## Other known limitations
+
+The proxy as it was released in [Backstage
+1.9](https://github.com/backstage/backstage/blob/master/docs/releases/v1.9.0-changelog.md#patch-changes-15)
+has a known bug:
+
+- [#15901](https://github.com/backstage/backstage/issues/15901) - it cannot
+ reliably target clusters who share the same name with another located cluster.
diff --git a/docs/features/search/how-to-guides.md b/docs/features/search/how-to-guides.md
index 6f113630f6..b464168724 100644
--- a/docs/features/search/how-to-guides.md
+++ b/docs/features/search/how-to-guides.md
@@ -235,6 +235,20 @@ export const YourSearchResultListItemExtension = plugin.provide(
);
```
+If your list item accept props, you can extend the `SearchResultListItemExtensionProps` with your component specific props:
+
+```tsx
+export const YourSearchResultListItemExtension: (
+ props: SearchResultListItemExtensionProps,
+) => JSX.Element | null = plugin.provide(
+ createSearchResultListItemExtension({
+ name: 'YourSearchResultListItem',
+ component: () =>
+ import('./components').then(m => m.YourSearchResultListItem),
+ }),
+);
+```
+
Additionally, you can define a predicate function that receives a result and returns whether your extension should be used to render it or not:
```tsx
diff --git a/docs/features/software-catalog/external-integrations.md b/docs/features/software-catalog/external-integrations.md
index da4eb3d229..5fc2537712 100644
--- a/docs/features/software-catalog/external-integrations.md
+++ b/docs/features/software-catalog/external-integrations.md
@@ -89,23 +89,23 @@ export class FrobsProvider implements EntityProvider {
private readonly reader: UrlReader;
private connection?: EntityProviderConnection;
- /** [1] **/
+ /** [1] */
constructor(env: string, reader: UrlReader) {
this.env = env;
this.reader = reader;
}
- /** [2] **/
+ /** [2] */
getProviderName(): string {
return `frobs-${this.env}`;
}
- /** [3] **/
+ /** [3] */
async connect(connection: EntityProviderConnection): Promise {
this.connection = connection;
}
- /** [4] **/
+ /** [4] */
async run(): Promise {
if (!this.connection) {
throw new Error('Not initialized');
@@ -116,10 +116,10 @@ export class FrobsProvider implements EntityProvider {
);
const data = JSON.parse(await response.buffer()).toString();
- /** [5] **/
+ /** [5] */
const entities: Entity[] = frobsToEntities(data);
- /** [6] **/
+ /** [6] */
await this.connection.applyMutation({
type: 'full',
entities: entities.map(entity => ({
diff --git a/docs/features/software-catalog/system-model.md b/docs/features/software-catalog/system-model.md
index 409f3e8450..16ad48abcf 100644
--- a/docs/features/software-catalog/system-model.md
+++ b/docs/features/software-catalog/system-model.md
@@ -63,6 +63,17 @@ BigTable databases, Pub/Sub topics, S3 buckets or CDNs. Modelling them together
with components and systems will better allow us to visualize resource
footprint, and create tooling around them.
+##Organizational Entities
+
+### User
+
+A user describes a person, such as an employee, a contractor, or similar.
+
+### Group
+
+A group describes an organizational entity, such as for example a team, a
+business unit, or a loose collection of people in an interest group.
+
## Ecosystem Modeling
A large catalogue of components, APIs and resources can be highly granular and
@@ -108,3 +119,19 @@ domain would come with some documentation on how to accept payments for a new
product or use-case, share the same entity types in their APIs, and integrate
well with each other. Other domains could be “Content Ingestion”, “Ads” or
“Search”.
+
+##Other
+
+### Location
+
+A location is a marker that references other places to look for catalog data.
+
+### Type
+
+The type field in the system has no set meaning. It is up to the user to assign their own types and use them as desired, such as for link validation or creating custom UI components. Some common pre-defined types are depicted in the ecosystem modeling diagram.
+
+### Template
+
+A template definition describes both the parameters that are rendered in the
+frontend part of the scaffolding wizard, and the steps that are executed when
+scaffolding that component.
diff --git a/docs/features/software-templates/writing-custom-actions.md b/docs/features/software-templates/writing-custom-actions.md
index dfbd4b0a42..ffe3312501 100644
--- a/docs/features/software-templates/writing-custom-actions.md
+++ b/docs/features/software-templates/writing-custom-actions.md
@@ -168,5 +168,6 @@ scaffolder backend:
| Scaffolder Git Actions | [plugin-scaffolder-git-actions](https://www.npmjs.com/package/@mdude2314/backstage-plugin-scaffolder-git-actions) | [Drew Hill](https://github.com/arhill05) |
| Azure Pipeline Actions | [scaffolder-backend-module-azure-pipelines](https://www.npmjs.com/package/@parfuemerie-douglas/scaffolder-backend-module-azure-pipelines) | [Parfümerie Douglas](https://github.com/Parfuemerie-Douglas) |
| Azure Repository Actions | [scaffolder-backend-module-azure-repositories](https://www.npmjs.com/package/@parfuemerie-douglas/scaffolder-backend-module-azure-repositories) | [Parfümerie Douglas](https://github.com/Parfuemerie-Douglas) |
+| Snyk Import Project | [plugin-scaffolder-backend-module-snyk](https://www.npmjs.com/package/@ma11hewthomas/plugin-scaffolder-backend-module-snyk) | [Matthew Thomas](https://github.com/Ma11hewThomas) |
Have fun! 🚀
diff --git a/docs/features/software-templates/writing-templates.md b/docs/features/software-templates/writing-templates.md
index 71aa0ab758..a272f05f3f 100644
--- a/docs/features/software-templates/writing-templates.md
+++ b/docs/features/software-templates/writing-templates.md
@@ -112,11 +112,11 @@ steps which would be rendered as different steps in the scaffolder plugin
frontend.
Each `Step` is `JSONSchema` with some extra goodies for styling what it might
-look like in the frontend. For these steps we rely very heavily on this library:
-https://github.com/rjsf-team/react-jsonschema-form. They have some great docs
-too here: https://react-jsonschema-form.readthedocs.io/ and a playground where
-you can play around with some examples here
-https://rjsf-team.github.io/react-jsonschema-form.
+look like in the frontend. For these steps we rely very heavily on this
+[library](https://github.com/rjsf-team/react-jsonschema-form). They have some
+[great docs](https://rjsf-team.github.io/react-jsonschema-form/docs/) and a
+[playground](https://rjsf-team.github.io/react-jsonschema-form) where you can
+play around with some examples.
There's another option for that library called `uiSchema` which we've taken
advantage of, and we've merged it with the existing `JSONSchema` that you
diff --git a/docs/features/techdocs/addons.md b/docs/features/techdocs/addons.md
index fe1058b2ca..60999f599c 100644
--- a/docs/features/techdocs/addons.md
+++ b/docs/features/techdocs/addons.md
@@ -125,6 +125,7 @@ discover available Addons, we've compiled a list of them here:
| [``](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. |
| [``](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. |
| [``](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. |
+| [``](https://backstage.io/docs/reference/plugin-techdocs-module-addons-contrib.lightbox) | `@backstage/plugin-techdocs-module-addons-contrib` | This TechDocs addon allows users to open images in a light-box on documentation pages, they can navigate between images if there are several on one page. The image size of the light-box image is the same as the image size on the document page. |
Got an Addon to contribute? Feel free to add a row above!
diff --git a/docs/features/techdocs/getting-started.md b/docs/features/techdocs/getting-started.md
index c2070e7840..578a631798 100644
--- a/docs/features/techdocs/getting-started.md
+++ b/docs/features/techdocs/getting-started.md
@@ -262,12 +262,12 @@ You will have to install the `mkdocs` and `mkdocs-techdocs-core` package from
pip, as well as `graphviz` and `plantuml` from your OS package manager (e.g.
apt).
-You can do so by including the following lines in the last step of your
+You can do so by including the following lines right above `USER node` of your
`Dockerfile`:
```Dockerfile
RUN apt-get update && apt-get install -y python3 python3-pip
-RUN pip3 install mkdocs-techdocs-core==1.0.1
+RUN pip3 install mkdocs-techdocs-core==1.1.7
```
Please be aware that the version requirement could change, you need to check our
diff --git a/docs/integrations/azure/locations.md b/docs/integrations/azure/locations.md
index 3b3e3dd5ed..1fc476f418 100644
--- a/docs/integrations/azure/locations.md
+++ b/docs/integrations/azure/locations.md
@@ -28,3 +28,5 @@ The configuration is a structure with two elements:
- `host`: The DevOps host; only `dev.azure.com` is supported.
- `token` (optional): A personal access token as expected by Azure DevOps.
+
+> Note: The token should just be provided as the raw token generated by Azure DevOps using the format `raw_token` with no base64 encoding. Formatting and base64'ing is handled by dependent libraries handling the Azure DevOps API
diff --git a/docs/integrations/gitlab/discovery.md b/docs/integrations/gitlab/discovery.md
index dc0b911b3d..5a4dc8abdd 100644
--- a/docs/integrations/gitlab/discovery.md
+++ b/docs/integrations/gitlab/discovery.md
@@ -22,9 +22,9 @@ catalog:
yourProviderId:
host: gitlab-host # Identifies one of the hosts set up in the integrations
branch: main # Optional. Uses `master` as default
- group: example-group # Optional. Group and subgroup (if needed) to look for repositories. If not present the whole project will be scanned
+ group: example-group # Optional. Group and subgroup (if needed) to look for repositories. If not present the whole instance will be scanned
entityFilename: catalog-info.yaml # Optional. Defaults to `catalog-info.yaml`
- projectPattern: /[\s\S]*/ # Optional. Filters found projects based on provided patter. Defaults to `/[\s\S]*/`, what means to not filter anything
+ projectPattern: '[\s\S]*' # Optional. Filters found projects based on provided patter. Defaults to `[\s\S]*`, which means to not filter anything
schedule: # optional; same options as in TaskScheduleDefinition
# supports cron, ISO duration, "human duration" as used in code
frequency: { minutes: 30 }
diff --git a/docs/permissions/overview.md b/docs/permissions/overview.md
index b972814aeb..693f848c82 100644
--- a/docs/permissions/overview.md
+++ b/docs/permissions/overview.md
@@ -34,6 +34,8 @@ The permission framework was designed with a few key properties in mind:
4. An authorization decision is sent to the plugin from the permission backend.
+5. The user is either granted access or an error is shown. The plugin is responsible for implementing a response to the user.
+
## How do I get started?
See the "[getting started](./getting-started.md)" permission documentation for Backstage integrators.
diff --git a/docs/permissions/plugin-authors/01-setup.md b/docs/permissions/plugin-authors/01-setup.md
index 18de410612..a38b81e679 100644
--- a/docs/permissions/plugin-authors/01-setup.md
+++ b/docs/permissions/plugin-authors/01-setup.md
@@ -26,6 +26,9 @@ The source code is available here:
git checkout master -- plugins/example-todo-list/
git checkout master -- plugins/example-todo-list-backend/
git checkout master -- plugins/example-todo-list-common/
+ sed -i '' 's/workspace:\^/\*/g' plugins/example-todo-list/package.json
+ sed -i '' 's/workspace:\^/\*/g' plugins/example-todo-list-backend/package.json
+ sed -i '' 's/workspace:\^/\*/g' plugins/example-todo-list-common/package.json
for file in plugins/*; do mv "$file" "$OLDPWD/${file/example-todo/todo}"; done
cd -
```
@@ -37,15 +40,15 @@ The source code is available here:
2. Add these packages as dependencies for your Backstage app:
```
- $ yarn workspace backend add @internal/plugin-todo-list-backend@^1.0.0 @internal/plugin-todo-list-common@^1.0.0
- $ yarn workspace app add @internal/plugin-todo-list@^1.0.0
+ $ yarn workspace backend add @internal/plugin-todo-list-backend @internal/plugin-todo-list-common
+ $ yarn workspace app add @internal/plugin-todo-list
```
3. Include the backend and frontend plugin in your application:
Create a new `packages/backend/src/plugins/todolist.ts` with the following content:
- ```javascript
+ ```typescript
import { DefaultIdentityClient } from '@backstage/plugin-auth-node';
import { createRouter } from '@internal/plugin-todo-list-backend';
import { Router } from 'express';
diff --git a/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md b/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md
index 241b175987..2ceb8057f4 100644
--- a/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md
+++ b/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md
@@ -146,7 +146,7 @@ In order to test the logic above, the integrators of your backstage instance nee
- async handle(): Promise {
+ async handle(
+ request: PolicyQuery,
-+ user?: BackstageIdentityResponse,
++ _user?: BackstageIdentityResponse,
+ ): Promise {
+ if (isPermission(request.permission, todoListCreatePermission)) {
+ return {
@@ -204,7 +204,7 @@ First we'll clean up the `plugins/todo-list-backend/src/service/router.test.ts`:
const router = await createRouter({
logger: getVoidLogger(),
identity: {} as DefaultIdentityClient,
-+ permissions: toPermissionEvaluator,
++ permissions: permissionEvaluator,
});
app = express().use(router);
});
@@ -235,7 +235,7 @@ Then we want to update the `plugins/todo-list-backend/src/service/standaloneServ
+ ServerTokenManager,
} from '@backstage/backend-common';
import { DefaultIdentityClient } from '@backstage/plugin-auth-node';
- import { ServerPermissionClient } from '@backstage/plugin-permission-node';
++ import { ServerPermissionClient } from '@backstage/plugin-permission-node';
import { Server } from 'http';
import { Logger } from 'winston';
import { createRouter } from './router';
@@ -285,4 +285,44 @@ Then we want to update the `plugins/todo-list-backend/src/service/standaloneServ
module.hot?.accept();
```
+Finally, we need to update `plugins/todo-list-backend/src/plugin.ts`:
+
+```diff
+ import { loggerToWinstonLogger } from '@backstage/backend-common';
+ import {
+ coreServices,
+ createBackendPlugin,
+ } from '@backstage/backend-plugin-api';
+ import { createRouter } from './service/router';
+
+ /**
+ * The example TODO list backend plugin.
+ *
+ * @alpha
+ */
+ export const exampleTodoListPlugin = createBackendPlugin({
+ pluginId: 'exampleTodoList',
+ register(env) {
+ env.registerInit({
+ deps: {
+ identity: coreServices.identity,
+ logger: coreServices.logger,
+ httpRouter: coreServices.httpRouter,
++ permissions: coreServices.permissions,
+ },
+- async init({ identity, logger, httpRouter }) {
++ async init({ identity, logger, httpRouter, permissions }) {
+ httpRouter.use(
+ await createRouter({
+ identity,
+ logger: loggerToWinstonLogger(logger),
+ permissions,
+ }),
+ );
+ },
+ });
+ },
+ });
+```
+
Now when you run `yarn tsc` you should have no more errors.
diff --git a/docs/permissions/plugin-authors/03-adding-a-resource-permission-check.md b/docs/permissions/plugin-authors/03-adding-a-resource-permission-check.md
index 8913b6d438..b063727c71 100644
--- a/docs/permissions/plugin-authors/03-adding-a-resource-permission-check.md
+++ b/docs/permissions/plugin-authors/03-adding-a-resource-permission-check.md
@@ -76,7 +76,7 @@ This enables decisions based on characteristics of the resource, but it's import
Install the missing module:
```
-$ yarn workspace @internal/plugin-todo-list-backend add @backstage/plugin-permission-node
+$ yarn workspace @internal/plugin-todo-list-backend add @backstage/plugin-permission-node zod
```
Create a new `plugins/todo-list-backend/src/service/rules.ts` file and append the following code:
@@ -89,7 +89,8 @@ import { Todo, TodoFilter } from './todos';
export const createTodoListPermissionRule = makeCreatePermissionRule<
Todo,
- TodoFilter
+ TodoFilter,
+ typeof TODO_LIST_RESOURCE_TYPE
>();
export const isOwner = createTodoListPermissionRule({
@@ -97,8 +98,8 @@ export const isOwner = createTodoListPermissionRule({
description: 'Should allow only if the todo belongs to the user',
resourceType: TODO_LIST_RESOURCE_TYPE,
paramsSchema: z.object({
- userId: z.string().describe('User ID to match on the resource')
- })
+ userId: z.string().describe('User ID to match on the resource'),
+ }),
apply: (resource: Todo, { userId }) => {
return resource.author === userId;
},
@@ -187,6 +188,7 @@ Make sure `todoListConditions` and `createTodoListConditionalDecision` are expor
```diff
export * from './service/router';
+ export * from './conditionExports';
+ export { exampleTodoListPlugin } from './plugin';
```
## Test the authorized update endpoint
@@ -209,7 +211,6 @@ Let's go back to the permission policy's handle function and try to authorize ou
+ import {
+ todoListCreatePermission,
+ todoListUpdatePermission,
-+ TODO_LIST_RESOURCE_TYPE,
+ } from '@internal/plugin-todo-list-common';
+ import {
+ todoListConditions,
@@ -217,7 +218,11 @@ Let's go back to the permission policy's handle function and try to authorize ou
+ } from '@internal/plugin-todo-list-backend';
...
-
+ async handle(
+ request: PolicyQuery,
+- _user?: BackstageIdentityResponse,
++ user?: BackstageIdentityResponse,
+ ): Promise {
if (isPermission(request.permission, todoListCreatePermission)) {
return {
result: AuthorizeResult.ALLOW,
@@ -236,6 +241,7 @@ Let's go back to the permission policy's handle function and try to authorize ou
return {
result: AuthorizeResult.ALLOW,
};
+ }
```
For any incoming update requests, we now return a _Conditional Decision_. We are saying:
diff --git a/docs/permissions/plugin-authors/04-authorizing-access-to-paginated-data.md b/docs/permissions/plugin-authors/04-authorizing-access-to-paginated-data.md
index 8ddcffdcd9..e84f53f176 100644
--- a/docs/permissions/plugin-authors/04-authorizing-access-to-paginated-data.md
+++ b/docs/permissions/plugin-authors/04-authorizing-access-to-paginated-data.md
@@ -15,7 +15,7 @@ One possible solution may leverage the batching functionality to authorize all o
- res.json(getAll())
+ const items = getAll();
+ const decisions = await permissions.authorize(
-+ items.map(({ id }) => ({ permission: todosListRead, resourceRef: id })),
++ items.map(({ id }) => ({ permission: todoListReadPermission, resourceRef: id })),
+ );
+ const filteredItems = decisions.filter(
@@ -53,7 +53,7 @@ Let's add another permission to the plugin.
resourceType: TODO_LIST_RESOURCE_TYPE,
});
+
-+ export const todosListRead = createPermission({
++ export const todoListReadPermission = createPermission({
+ name: 'todos.list.read',
+ attributes: { action: 'read' },
+ resourceType: TODO_LIST_RESOURCE_TYPE,
@@ -81,10 +81,9 @@ So far we've only used the `PermissionEvaluator.authorize` method, which will ev
import {
todosListCreate,
todosListUpdate,
-+ todosListRead,
++ todoListReadPermission,
TODO_LIST_RESOURCE_TYPE,
} from './permissions';
-+ import { rules } from './rules';
+ const transformConditions: ConditionTransformer = createConditionTransformer(Object.values(rules));
@@ -95,7 +94,7 @@ So far we've only used the `PermissionEvaluator.authorize` method, which will ev
+ );
+
+ const decision = (
-+ await permissions.authorizeConditional([{ permission: todosListRead }], {
++ await permissions.authorizeConditional([{ permission: todoListReadPermission }], {
+ token,
+ })
+ )[0];
@@ -110,7 +109,6 @@ So far we've only used the `PermissionEvaluator.authorize` method, which will ev
+ } else {
+ res.json(getAll());
+ }
-+ }
- res.json(getAll());
});
```
@@ -121,7 +119,7 @@ Since `TodoFilter` used in our plugin matches the structure of the conditions ob
## Test the authorized read endpoint
-Let's update our permission policy to return a conditional result whenever a `todosListRead` permission is received. In this case, we can reuse the decision returned for the `todosListCreate` permission.
+Let's update our permission policy to return a conditional result whenever a `todoListReadPermission` permission is received. In this case, we can reuse the decision returned for the `todosListCreate` permission.
```diff
// packages/backend/src/plugins/permission.ts
@@ -132,7 +130,6 @@ import {
todoListCreatePermission,
todoListUpdatePermission,
+ todoListReadPermission,
- TODO_LIST_RESOURCE_TYPE,
} from '@internal/plugin-todo-list-common';
...
diff --git a/docs/permissions/plugin-authors/05-frontend-authorization.md b/docs/permissions/plugin-authors/05-frontend-authorization.md
index d494ea60ba..753ce56461 100644
--- a/docs/permissions/plugin-authors/05-frontend-authorization.md
+++ b/docs/permissions/plugin-authors/05-frontend-authorization.md
@@ -56,7 +56,11 @@ Let's make the following changes in `plugins/todo-list/src/components/TodoListPa
- Add
-
+ {!loadingPermission && (
-+