Merge branch 'backstage:master' into master

This commit is contained in:
AmbrishRamachandiran
2023-08-03 10:06:45 +05:30
committed by GitHub
519 changed files with 8101 additions and 1646 deletions
+43
View File
@@ -0,0 +1,43 @@
---
'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch
'@backstage/plugin-catalog-backend-module-bitbucket-server': patch
'@backstage/plugin-catalog-backend-module-bitbucket-cloud': patch
'@backstage/plugin-search-backend-module-elasticsearch': patch
'@backstage/plugin-catalog-backend-module-puppetdb': patch
'@backstage/plugin-catalog-backend-module-msgraph': patch
'@backstage/plugin-search-backend-module-techdocs': patch
'@backstage/plugin-catalog-backend-module-gerrit': patch
'@backstage/plugin-catalog-backend-module-github': patch
'@backstage/plugin-catalog-backend-module-gitlab': patch
'@backstage/plugin-events-backend-module-aws-sqs': patch
'@backstage/plugin-search-backend-module-catalog': patch
'@backstage/plugin-search-backend-module-explore': patch
'@backstage/plugin-catalog-backend-module-azure': patch
'@backstage/plugin-events-backend-module-github': patch
'@backstage/plugin-events-backend-module-gitlab': patch
'@backstage/plugin-catalog-backend-module-aws': patch
'@backstage/plugin-catalog-backend-module-gcp': patch
'@backstage/plugin-search-backend-module-pg': patch
'@backstage/plugin-azure-devops-backend': patch
'@backstage/plugin-kubernetes-backend': patch
'@backstage/plugin-lighthouse-backend': patch
'@backstage/plugin-permission-backend': patch
'@backstage/plugin-scaffolder-backend': patch
'@backstage/backend-defaults': patch
'@backstage/plugin-airbrake-backend': patch
'@backstage/plugin-devtools-backend': patch
'@backstage/plugin-periskop-backend': patch
'@backstage/plugin-techdocs-backend': patch
'@backstage/backend-common': patch
'@backstage/plugin-catalog-backend': patch
'@backstage/plugin-badges-backend': patch
'@backstage/plugin-bazaar-backend': patch
'@backstage/plugin-events-backend': patch
'@backstage/plugin-search-backend': patch
'@backstage/plugin-kafka-backend': patch
'@backstage/plugin-proxy-backend': patch
'@backstage/plugin-todo-backend': patch
'@backstage/plugin-app-backend': patch
---
Use `coreServices.rootConfig` instead of `coreService.config`
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/plugin-search-backend-module-techdocs': patch
'@backstage/plugin-search-backend-module-catalog': patch
'@backstage/plugin-search-backend-module-explore': patch
---
Ensure that all services are dependency injected into the module instead of taken from options
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-kubernetes-backend': patch
---
Fixed a bug where the proxy was not rewriting WebSocket request paths properly.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder': patch
---
Fix the get entities query in the `MyGroupsPicker` to query the `kind=Group` entities.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/create-app': patch
---
Bumped create-app version.
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/config-loader': minor
---
Loading invalid TypeScript configuration schemas will now throw an error rather than silently being ignored.
In particular this includes defining any additional types other than `Config` in the schema file, or use of unsupported types such as `Record` or `Partial`.
+91
View File
@@ -0,0 +1,91 @@
---
'@backstage/plugin-scaffolder-backend-module-confluence-to-markdown': patch
'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch
'@backstage/plugin-events-backend-module-bitbucket-cloud': patch
'@backstage/plugin-search-backend-module-elasticsearch': patch
'@backstage/plugin-catalog-backend-module-unprocessed': patch
'@backstage/plugin-scaffolder-backend-module-sentry': patch
'@backstage/plugin-scaffolder-backend-module-yeoman': patch
'@backstage/plugin-scaffolder-backend-module-rails': patch
'@backstage/plugin-search-backend-module-techdocs': patch
'@backstage/plugin-cicd-statistics-module-gitlab': patch
'@backstage/plugin-events-backend-module-aws-sqs': patch
'@backstage/plugin-search-backend-module-catalog': patch
'@backstage/plugin-search-backend-module-explore': patch
'@backstage/plugin-events-backend-module-gerrit': patch
'@backstage/plugin-events-backend-module-github': patch
'@backstage/plugin-events-backend-module-gitlab': patch
'@backstage/plugin-events-backend-module-azure': patch
'@backstage/plugin-events-backend-test-utils': patch
'@backstage/plugin-search-backend-module-pg': patch
'@backstage/plugin-entity-feedback-backend': patch
'@backstage/backend-openapi-utils': patch
'@backstage/plugin-bitbucket-cloud-common': patch
'@backstage/plugin-entity-feedback-common': patch
'@backstage/plugin-code-coverage-backend': patch
'@backstage/plugin-user-settings-backend': patch
'@backstage/plugin-analytics-module-ga4': patch
'@backstage/plugin-azure-devops-backend': patch
'@backstage/plugin-analytics-module-ga': patch
'@backstage/plugin-git-release-manager': patch
'@backstage/plugin-search-backend-node': patch
'@backstage/integration-react': patch
'@backstage/plugin-github-deployments': patch
'@backstage/plugin-microsoft-calendar': patch
'@backstage/plugin-newrelic-dashboard': patch
'@backstage/plugin-permission-backend': patch
'@backstage/plugin-entity-validation': patch
'@backstage/plugin-sonarqube-backend': patch
'@backstage/plugin-airbrake-backend': patch
'@backstage/plugin-devtools-backend': patch
'@backstage/plugin-linguist-backend': patch
'@backstage/plugin-periskop-backend': patch
'@backstage/plugin-playlist-backend': patch
'@backstage/plugin-apollo-explorer': patch
'@backstage/plugin-devtools-common': patch
'@backstage/plugin-entity-feedback': patch
'@backstage/plugin-explore-backend': patch
'@backstage/plugin-graphql-voyager': patch
'@backstage/plugin-jenkins-backend': patch
'@backstage/plugin-linguist-common': patch
'@backstage/plugin-playlist-common': patch
'@backstage/plugin-scaffolder-node': patch
'@backstage/plugin-apache-airflow': patch
'@backstage/plugin-bazaar-backend': patch
'@backstage/plugin-events-backend': patch
'@backstage/plugin-jenkins-common': patch
'@backstage/plugin-octopus-deploy': patch
'@backstage/plugin-search-backend': patch
'@backstage/plugin-stack-overflow': patch
'@backstage/plugin-catalog-graph': patch
'@backstage/plugin-code-coverage': patch
'@backstage/plugin-config-schema': patch
'@backstage/plugin-github-issues': patch
'@backstage/plugin-nomad-backend': patch
'@backstage/plugin-tech-insights': patch
'@backstage/plugin-catalog-node': patch
'@backstage/plugin-code-climate': patch
'@backstage/plugin-events-node': patch
'@backstage/plugin-firehydrant': patch
'@backstage/cli-node': patch
'@backstage/plugin-auth-node': patch
'@backstage/plugin-codescene': patch
'@backstage/plugin-dynatrace': patch
'@backstage/plugin-gcalendar': patch
'@backstage/plugin-org-react': patch
'@backstage/plugin-shortcuts': patch
'@backstage/plugin-xcmetrics': patch
'@backstage/plugin-airbrake': patch
'@backstage/plugin-periskop': patch
'@backstage/plugin-playlist': patch
'@backstage/plugin-bitrise': patch
'@backstage/plugin-allure': patch
'@backstage/plugin-bazaar': patch
'@backstage/plugin-ilert': patch
'@backstage/plugin-kafka': patch
'@backstage/plugin-nomad': patch
'@backstage/plugin-adr': patch
'@backstage/plugin-org': patch
---
Add package repository and homepage metadata
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend-module-gitlab': patch
---
Added option to skip forked repos in GitlabDiscoveryEntityProvider
+14
View File
@@ -0,0 +1,14 @@
---
'@backstage/plugin-devtools-backend': patch
---
Add DevTools configuration to enable dependency listing to be filtered with custom prefixes. For instance, in your `app-config.yaml`:
```yaml
devTools:
info:
packagePrefixes:
- @backstage/
- @roadiehq/backstage-
- @spotify/backstage-
```
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-sonarqube': patch
---
Remove sonarQube card disable class
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-test-utils': minor
---
**BREAKING**: Renamed `mockServices.config` to `mockServices.rootConfig`.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-app-api': minor
---
**BREAKING**: Renamed `configServiceFactory` to `rootConfigServiceFactory`.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-plugin-api': minor
---
**BREAKING**: Renamed `coreServices.config` to `coreServices.rootConfig`.
+17
View File
@@ -0,0 +1,17 @@
---
'@backstage/plugin-catalog-backend-module-bitbucket-server': patch
'@backstage/plugin-catalog-backend-module-bitbucket-cloud': patch
'@backstage/plugin-catalog-backend-module-puppetdb': patch
'@backstage/plugin-catalog-backend-module-msgraph': patch
'@backstage/plugin-catalog-backend-module-gerrit': patch
'@backstage/plugin-catalog-backend-module-github': patch
'@backstage/plugin-catalog-backend-module-gitlab': patch
'@backstage/plugin-events-backend-module-aws-sqs': patch
'@backstage/plugin-catalog-backend-module-azure': patch
'@backstage/plugin-catalog-backend-module-aws': patch
'@backstage/backend-common': patch
'@backstage/plugin-jenkins-backend': patch
'@backstage/plugin-proxy-backend': patch
---
Fixed invalid configuration schema. The configuration schema may be more strict as a result.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend-module-confluence-to-markdown': patch
---
Use `fetchContents` directly instead of a `fetchPlainAction`
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-auth-backend': patch
---
Updated config schema to match what was being used in code
+29 -2
View File
@@ -229,26 +229,53 @@
"@backstage/plugin-vault": "0.1.14",
"@backstage/plugin-vault-backend": "0.3.3",
"@backstage/plugin-xcmetrics": "0.2.40",
"@backstage/plugin-analytics-module-newrelic-browser": "0.0.0"
"@backstage/plugin-analytics-module-newrelic-browser": "0.0.0",
"@backstage/plugin-catalog-backend-module-gcp": "0.0.0"
},
"changesets": [
"analytics-millenial-whoop",
"angry-beers-relate",
"chatty-foxes-buy",
"chatty-seahorses-juggle",
"chilly-keys-count",
"cold-numbers-sleep",
"create-app-1690284535",
"create-app-1690892926",
"dirty-chefs-listen",
"gorgeous-months-doubt",
"hungry-shrimps-care",
"khaki-flies-draw",
"kind-cougars-allow",
"large-experts-poke",
"large-vans-cross",
"loud-garlics-press",
"mean-squids-relax",
"mighty-lions-search-2",
"mighty-lions-search-3",
"mighty-lions-search",
"neat-coins-raise",
"neat-lamps-press",
"odd-avocados-buy",
"pink-squids-nail",
"popular-fans-camp",
"quiet-starfishes-kick",
"rare-pens-exist",
"rich-zoos-occur",
"rude-feet-sparkle",
"search-donuts-wash",
"selfish-coats-shout",
"serious-bats-repair",
"slimy-kids-jam",
"smart-pandas-applaud",
"stale-wombats-talk",
"strong-bobcats-unite",
"stupid-berries-run",
"ten-otters-appear"
"ten-otters-appear",
"tender-fireants-cheer",
"thin-yaks-hang",
"tidy-cobras-scream",
"tough-dolphins-care",
"tough-lies-float",
"wild-timers-sparkle"
]
}
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/backend-plugin-api': minor
'@backstage/backend-defaults': minor
---
**BREAKING**: Removing shared environments concept from the new experimental backend system.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend': minor
---
Added OpenTelemetry spans for catalog processing
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend-module-aws': patch
---
Added option to configure AWS `accountId` in `AwsS3EntityProvider`
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-test-utils': patch
---
Add needed constants and constructs to support PostgreSQL version 14 as test database
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-devtools': patch
---
Fix readme typo
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-search-backend': patch
---
Add missing `configSchema` to package.json
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/plugin-scaffolder-backend-module-confluence-to-markdown': patch
'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch
'@backstage/plugin-scaffolder-backend-module-rails': patch
---
Import helpers from the node package instead of the backend package
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend-module-gcp': minor
---
Added GCP catalog plugin with GKE provider
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/plugin-scaffolder-backend': patch
'@backstage/plugin-scaffolder-node': patch
---
Deprecated `executeShellCommand`, `RunCommandOptions`, and `fetchContents` from `@backstage/plugin-scaffolder-backend`, since they are useful for Scaffolder modules (who should not be importing from the plugin package itself). You should now import these from `@backstage/plugin-scaffolder-backend-node` instead. `RunCommandOptions` was renamed in the Node package as `ExecuteShellCommandOptions`, for consistency.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-auth-backend': patch
---
Add frontend visibility to provider objects in `auth` config.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-microsoft-calendar': patch
---
README update - example of apiRef definition and fixed component name
+2
View File
@@ -254,3 +254,5 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/
| [Celonis](https://celonis.com) | [@georgeyord](https://github.com/georgeyord), [@LauraMoraB](https://github.com/LauraMoraB), [@mariosant](https://github.com/mariosant), [@Rbillon59](https://github.com/Rbillon59) | Internal developer and product portal implementation. |
| [Rabobank](https://www.rabobank.com) | [Willem Dekker](https://github.com/wdekker), [Sridhar Gnanasekaran](https://github.com/srid99), [Ruben Ernst](https://github.com/Ruben-E) | At Rabobank, our mission is to make life better for engineers. After exploring various options in the market, we've discovered that Backstage provides the perfect foundation for creating a platform that meets our engineers' needs and helps us achieve our goals. We want to make our engineers happy by offering standardized services, freeing them up to focus on delivering value. Our vision is to create a one-stop platform where engineers can find everything related to software and services. In practice, we're excited about using all the cool features in Backstage, and we're even planning to build our own plugins. |
| [JB Hi-Fi](https://www.jbhifi.com.au) | [@bahman](https://github.com/bahman-jb/) | We use Backstage as a central place for all of our components/apis across multiple teams. It helps us to quickly identify the ownership of a component/api, find the related links and have a quick access to CI/CD pipelines. |
| [Zenklub](https://www.zenklub.com.br) | [@zenklub](https://github.com/zenklub), [@gioufop](https://github.com/gioufop) | Developer portal, services catalog and centralization of metrics from Grafana Stack and AWS. Furthermore, centralization of documentation and infra details like Tools, Network services and so on. |
| [Platzi](https://platzi.com/) | [@juancarestre](https://github.com/juancarestre/), [Engineering at Platzi](https://github.com/PlatziDev/) | Backstage allow our developers to get easily engaged with all the internal components, technical documentations and software templates. All new developers reduce its onboarding time via Backstage, and after a couple of integrations it allowed us to create new components with in a couple of clicks. |
+2
View File
@@ -10,6 +10,8 @@
[![Codecov](https://img.shields.io/codecov/c/github/backstage/backstage)](https://codecov.io/gh/backstage/backstage)
[![](https://img.shields.io/github/v/release/backstage/backstage)](https://github.com/backstage/backstage/releases)
[![Uffizzi](https://img.shields.io/endpoint?url=https%3A%2F%2Fapp.uffizzi.com%2Fapi%2Fv1%2Fpublic%2Fshields%2Fgithub.com%2Fbackstage%2Fbackstage)](https://app.uffizzi.com/ephemeral-environments/backstage/backstage)
[![OpenSSF Best Practices](https://bestpractices.coreinfrastructure.org/projects/7678/badge)](https://bestpractices.coreinfrastructure.org/projects/7678)
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/backstage/backstage/badge)](https://securityscorecards.dev/viewer/?uri=github.com/backstage/backstage)
> 🏖️ The week beginning the 26th of June, some of the maintainers will be taking a well earned Summer Holiday break. We will be slower to respond to issues and PRs during this time. Releases will continue to be shipped weekly. Normal service will resume on the 24th of July. 🏝️
+4 -4
View File
@@ -211,7 +211,7 @@ integrations:
# clientEmail: 'example@example.com'
# privateKey: ${GCS_PRIVATE_KEY}
awsS3:
- host: amazonaws.com
- endpoint: ${AWS_S3_ENDPOINT}
accessKeyId: ${AWS_ACCESS_KEY_ID}
secretAccessKey: ${AWS_SECRET_ACCESS_KEY}
@@ -352,8 +352,6 @@ auth:
metadataUrl: ${AUTH_OIDC_METADATA_URL}
clientId: ${AUTH_OIDC_CLIENT_ID}
clientSecret: ${AUTH_OIDC_CLIENT_SECRET}
authorizationUrl: ${AUTH_OIDC_AUTH_URL}
tokenUrl: ${AUTH_OIDC_TOKEN_URL}
tokenEndpointAuthMethod: ${AUTH_OIDC_TOKEN_ENDPOINT_AUTH_METHOD} # default='client_secret_basic'
tokenSignedResponseAlg: ${AUTH_OIDC_TOKEN_SIGNED_RESPONSE_ALG} # default='RS256'
scope: ${AUTH_OIDC_SCOPE} # default='openid profile email'
@@ -434,8 +432,10 @@ costInsights:
kind: 'PINTS_OF_ICE_CREAM'
unit: 'ice cream pint'
rate: 5.5
pagerduty:
pagerDuty:
eventsBaseUrl: 'https://events.pagerduty.com/v2'
jenkins:
instances:
- name: default
+23 -16
View File
@@ -58,6 +58,7 @@ When using ALB authentication Backstage will only be loaded once the user has su
import React from 'react';
import { UserIdentity } from '@backstage/core-components';
import { SignInPageProps } from '@backstage/core-app-api';
import { useApi, configApiRef } from '@backstage/core-plugin-api';
const SampleSignInComponent: any = (props: SignInPageProps) => {
const [error, setError] = React.useState<string | undefined>();
@@ -90,8 +91,8 @@ const SampleSignInComponent: any = (props: SignInPageProps) => {
},
}),
);
} catch (err) {
setError(err.message);
} catch (err: any) {
setError(err.message as string);
}
}
}, [config]);
@@ -135,12 +136,14 @@ export default async function createPlugin({
database,
config,
discovery,
tokenManager,
}: PluginEnvironment): Promise<Router> {
return await createRouter({
logger,
config,
database,
discovery,
tokenManager,
providerFactories: {
awsalb: providers.awsAlb.create({
authHandler: async ({ fullProfile }) => {
@@ -168,25 +171,29 @@ export default async function createPlugin({
};
},
signIn: {
resolver: async ({ profile: { email } }, ctx) => {
const [id] = email?.split('@') ?? '';
// Fetch from an external system that returns entity claims like:
// ['user:default/breanna.davison', ...]
const userEntityRef = stringifyEntityRef({
resolver: async ({ profile }, ctx) => {
if (!profile.email) {
throw new Error('Profile contained no email');
}
const [id] = profile.email.split('@');
if (!id) {
throw new Error('Invalid email format');
}
const userRef = stringifyEntityRef({
kind: 'User',
namespace: DEFAULT_NAMESPACE,
name: id,
namespace: DEFAULT_NAMESPACE,
});
// Resolve group membership from the Backstage catalog
const fullEnt =
await ctx.catalogIdentityClient.resolveCatalogMembership({
entityRefs: [id].concat([userEntityRef]),
logger: ctx.logger,
});
const token = await ctx.tokenIssuer.issueToken({
claims: { sub: userEntityRef, ent: fullEnt },
const { token } = await ctx.issueToken({
claims: {
sub: userRef,
ent: [userRef],
},
});
return { id, token };
},
},
+1 -1
View File
@@ -59,7 +59,7 @@ Just like plugins, modules also have access to services and can depend on their
A detailed explanation of the package architecture can be found in the
[Backstage Architecture
Overview](../../overview/architecture-overview.md#package-architecture). The
Overview](../../overview/architecture-overview/#package-architecture). The
most important packages to consider for this system are the following:
- `plugin-<pluginId>-backend` houses the implementation of the backend plugins
@@ -37,4 +37,4 @@ At a high level, when you call `createBackend`, it will create a new backend ins
Underneath the hood, `createBackend` calls `createSpecializedBackend` from `@backstage/backend-app-api` which is responsible for actually creating the backend instance, but with no services or no features. You can think of `createBackend` more of a 'batteries included' approach, and `createSpecializedBackend` a little more low level.
As mentioned previously there's also the ability to create multiple of these backends in your project so that you can split apart your backend and deploy different backends that can scale independently of each other. For instance you might choose to deploy a backend with only the catalog plugin enabled, and one with just the scaffolder plugin enabled. We've provided some tools to be able to share services and defaults across your backend system, and you can find out more about that in the [shared environments docs](../building-backends/01-index.md#shared-environments).
As mentioned previously there's also the ability to create multiple of these backends in your project so that you can split apart your backend and deploy different backends that can scale independently of each other. For instance you might choose to deploy a backend with only the catalog plugin enabled, and one with just the scaffolder plugin enabled.
@@ -61,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 { configServiceFactory } from '@backstage/backend-app-api';
import { rootConfigServiceFactory } from '@backstage/backend-app-api';
const backend = createBackend({
services: [
configServiceFactory({
rootConfigServiceFactory({
remote: { reloadIntervalSeconds: 60 },
}),
],
@@ -148,35 +148,3 @@ backend.start();
```
We've now split the backend into two separate deployments, but we still need to make sure that they can communicate with each other. This is the hard and somewhat tedious part, as Backstage currently doesn't provide an out of the box solution that solves this. You'll need to manually configure the two backends with custom implementations of the `DiscoveryService` and have them return the correct URLs for each other. Likewise, you'll also need to provide a custom implementation of the `DiscoveryApi` in the frontend, unless you surface the two backends via a proxy that handles the routing instead.
### Shared Environments
To make it a bit easier to manage multiple backends, it's possible to create a shared environment that can be used across multiple backends. You would typically house it in a separate package that can be referenced by backends in your monorepo, or published to a package registry for broader use.
A shared environment contains a set of service implementations that should be used across all backends. These services will override the default ones, but if a service is provided directly to the backend, it will override the one in the shared environment.
A shared environment is defined using `createSharedEnvironment`. In this example we place it in a new and separate package called `backend-env`:
```ts
// packages/backend-env/src/index.ts
import { createSharedEnvironment } from '@backstage/backend-plugin-api';
import { customDiscoveryServiceFactory } from './customDiscoveryServiceFactory';
export const env = createSharedEnvironment({
services: [
customDiscoveryServiceFactory(), // custom DiscoveryService implementation
],
});
```
And passed on to backends using the `env` option:
```ts
// packages/backend-b/src/index.ts, imports omitted
import { env } from '@internal/backend-env';
const backend = createBackend({ env });
backend.add(scaffolderPlugin());
backend.start();
```
@@ -37,7 +37,7 @@ describe('myPlugin', () => {
const { server } = await startTestBackend({
features: [myPlugin()],
services: [mockServices.config.factory({ data: fakeConfig })],
services: [mockServices.rootConfig.factory({ data: fakeConfig })],
});
const response = await request(server).get('/api/example/get-value');
@@ -183,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 { configServiceFactory } from '@backstage/backend-app-api';
import { rootConfigServiceFactory } from '@backstage/backend-app-api';
const backend = createBackend({
services: [
configServiceFactory({
rootConfigServiceFactory({
argv: [
'--config',
'/backstage/app-config.development.yaml',
+3 -3
View File
@@ -51,7 +51,7 @@ The TechDocs plugin has supported integrations to Search, meaning that it
provides a default collator factory ready to be used.
The purpose of this guide is to walk you through how to register the
[DefaultTechDocsCollatorFactory](https://github.com/backstage/backstage/blob/de294ce5c410c9eb56da6870a1fab795268f60e3/plugins/techdocs-backend/src/search/DefaultTechDocsCollatorFactory.ts)
[DefaultTechDocsCollatorFactory](https://github.com/backstage/backstage/blob/1adc2c7/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.ts)
in your App, so that you can get TechDocs documents indexed.
If you have been through the
@@ -61,10 +61,10 @@ so, you can go ahead and follow this guide - if not, start by going through the
getting started guide.
1. Import the `DefaultTechDocsCollatorFactory` from
`@backstage/plugin-techdocs-backend`.
`@backstage/plugin-search-backend-module-techdocs`.
```typescript
import { DefaultTechDocsCollatorFactory } from '@backstage/plugin-techdocs-backend';
import { DefaultTechDocsCollatorFactory } from '@backstage/plugin-search-backend-module-techdocs';
```
2. If there isn't an existing schedule you'd like to run the collator on, be
@@ -64,7 +64,7 @@ The recommended approach would be to represent information in catalog-info files
**Naming strategies:**
- Ldap: Internal ldap usernames as entity names. e.g., owner: user:myuser or user: my-team-name.
- Ldap: Internal ldap usernames as entity names. e.g., owner: user:my-user or user: my-team-name.
**Ownership strategies:**
+1
View File
@@ -23,6 +23,7 @@ catalog:
host: gitlab-host # Identifies one of the hosts set up in the integrations
branch: main # Optional. Used to discover on a specific branch
fallbackBranch: main # Optional. Fallback to be used if there is no default branch configured at the Gitlab repository. It is only used, if `branch` is undefined. Uses `master` as default
skipForkedRepos: false # Optional. If the project is a fork, skip repository
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]*`, which means to not filter anything
+1 -1
View File
@@ -36,7 +36,7 @@ Example:
```yaml
# in app-config.yaml
proxy:
simple-example: http://simple.example.com:8080
/simple-example: http://simple.example.com:8080
'/larger-example/v1':
target: http://larger.example.com:8080/svc.v1
headers:
File diff suppressed because it is too large Load Diff
@@ -26,7 +26,6 @@ When we set out on this project, we had a few primary goals. First, we intended
- Make it easier to create and maintain backend installations.
- Align how plugins provide points of customization and how those customizations are installed.
- Make it much easier to maintain plugins, in particular keeping the API stable.
- Simplify the process of splitting plugins out into separate deployments with shared environments.
- Improve the local development and testing experience.
Prioritizing simplicity is often a guiding principle that we use for designs that span multiple ownership roles. We decide on which parts of the system that we think are the most important to have as simple as possible, or, viewed from the opposite end, where in the system we put necessary complexity. In this case, we optimized for keeping the backend setup as simple as possible, followed by modules and plugins, then libraries, and lastly the framework itself. What this guidance means in practice is that when there is complexity that needs to be added to implement a certain feature, we place as much of it as possible within the framework itself, then libraries, plugins and modules, and if absolutely needed, the backend setup.
@@ -0,0 +1,51 @@
---
# prettier-ignore
title: "Five common traits of successful Backstage adopters"
author: Taras Mankovski, CXO, Frontside
---
![backstage header](assets/2023-07-28/header.png)
At [Frontside](https://frontside.com/), our goal is to help cloud-native teams create cohesive development experiences. We've been at the Backstage party since the beginning helping companies adopt and extend Backstage to fit the needs of their unique ecosystems.
Through our experience, we've uncovered five common traits of organizations that have improved developer experience through successful Backstage implementation and adoption. In this blog, we'll dive into these traits with some thoughts on how you can follow their blueprint.
{/* truncate */}
## **1) They take a product-centric approach**
The biggest factor for successful adopters of Backstage is their approach. There is a high correlation of success within organizations that approach building a developer portal like they're building a product. Some organizations will jump straight into solutioning instead of taking their time to identify what the problems are, how they affect users, and how those issues can be addressed.
The team building out Backstage should assess or work from existing insights on the core challenges that developers are facing in their organization — both qualitative and quantitative data counts here — and connect those issues to a product roadmap with initial use cases and adoption milestones marked. By doing their research in advance, successful orgs have a clear vision of what they want to accomplish with their Backstage instance. They know exactly what goals need to be met and have pressure-tested potential issues and barriers.
If you've already started your Backstage adoption journey but haven't mapped a Product Requirements Document (or PRD), don't panic! There is always time to do the foundational knowledge-building necessary to deploy something successful.
## **2) They tie Backstage to a larger platform journey**
Platform engineering has emerged in response to the growing complexity of cloud-native software architecture. Backstage has a huge role to play in implementing a platform strategy but its part of a larger story. Having buy-in from both higher ups and the teams tasked with platform goals is an essential step in successful Backstage adoption. Without the support at the top, it can be difficult to implement platforming as a priority within your organization.
And by "the top", we don't necessarily mean your CTO needs to rubber stamp your Backstage POC. But it's important that higher-level Platform goals have been set among VPs and directors with the understanding that a well-constructed developer portal can be the catalyst to achieving not only better developer experience but broader cultural shifts.
Having this kind of executive buy-in means more than just getting stakeholders on board with a portal build or clearing pathways towards Backstage adoption; it also means ensuring they understand the realities of your organization's journey.
## **3) They prioritize developer experience**
Having a dedicated developer experience or DevOps team tasked not only with building out a Backstage instance — but with leading adoption — is another big factor to success.
Competing platforms are very common at big companies, with many teams doing different things or serving different parts of a business. But developer experience teams usually have a very clear mandate and are often one of the only commonalities between these competing teams. This team should have the bandwidth available to oversee the adoption process from start to finish, and partner with the right folks (research, design, internal comms and marketing) to create an effective adoption plan tailored specifically for a company's needs.
If you don't have established developer experience resources in place, then the questions the team leading the Backstage work needs to ask are "what are the common problems to be solved at a platform level?" and "once we've proved our initial use cases, how are we internally evangelizing this amongst our competing teams?"
## **4) They collaborate with other platform teams**
A developer experience team can not single-handedly transform an organization's development structures, processes, and culture. It requires collaboration with teams responsible for other aspects of the platform. Successful adopters collaborate with other teams to bring them along on the journey of improving developer experience. They use Backstage as an opportunity to foster their inner-source contribution practice by allowing multiple platform teams to contribute plugins to their portal.
The developer experience team takes on the role of host in that collaborative process. They support other teams in integrating their features into the portal, provide guidance on best practices, and advocate for the needs of developers.
## **5) They engage, learn, and grow with the community**
One of the key benefits of building a developer platform based off an open source framework is leveraging the contributions and best practices from the community. The Backstage community is the largest gathering of developer experience practitioners in the world. There are now [thousands of adopters](https://github.com/backstage/backstage/blob/63aa3a65ec05f638ba76c06878d6635194620b34/ADOPTERS.md#L4) with a wealth of experience and best practices to learn from — and they are excited to share!
By participating in the community, developer experience leaders can learn from their peers at other companies about strategies that work and can keep up with the latest features of the ever-evolving Backstage platform. They're aware of what solutions exist within the open source framework and plugin marketplace as well as what they may need to build in-house.
In short, successful Backstage adopters engage within the Backstage community and their peer group to find solutions that fit their common challenges as well as their unique needs.
Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

+1 -1
View File
@@ -47,7 +47,7 @@
"@types/react": "^17",
"@types/react-dom": "^17"
},
"version": "1.17.0-next.0",
"version": "1.17.0-next.1",
"dependencies": {
"@backstage/errors": "workspace:^",
"@manypkg/get-packages": "^1.1.3"
+75
View File
@@ -1,5 +1,80 @@
# example-app
## 0.2.86-next.1
### Patch Changes
- Updated dependencies
- @backstage/plugin-playlist@0.1.13-next.1
- @backstage/plugin-scaffolder@1.14.2-next.1
- @backstage/integration-react@1.1.16-next.1
- @backstage/plugin-microsoft-calendar@0.1.6-next.1
- @backstage/plugin-newrelic-dashboard@0.2.14-next.1
- @backstage/plugin-entity-feedback@0.2.4-next.1
- @backstage/plugin-linguist-common@0.1.1-next.0
- @backstage/plugin-apache-airflow@0.2.14-next.1
- @backstage/plugin-octopus-deploy@0.2.3-next.1
- @backstage/plugin-stack-overflow@0.1.19-next.1
- @backstage/plugin-catalog-graph@0.2.33-next.1
- @backstage/plugin-code-coverage@0.2.14-next.1
- @backstage/plugin-tech-insights@0.3.13-next.1
- @backstage/plugin-dynatrace@7.0.1-next.1
- @backstage/plugin-gcalendar@0.3.17-next.1
- @backstage/plugin-shortcuts@0.3.13-next.1
- @backstage/plugin-airbrake@0.3.21-next.1
- @backstage/plugin-kafka@0.3.21-next.1
- @backstage/plugin-nomad@0.1.2-next.1
- @backstage/plugin-adr@0.6.4-next.1
- @backstage/plugin-org@0.6.11-next.1
- @backstage/plugin-devtools@0.1.3-next.1
- @backstage/cli@0.22.10-next.1
- @backstage/plugin-catalog-import@0.9.11-next.1
- @backstage/plugin-github-actions@0.6.2-next.1
- @backstage/plugin-techdocs@1.6.6-next.1
- @backstage/plugin-techdocs-module-addons-contrib@1.0.16-next.1
- @backstage/plugin-linguist@0.1.6-next.1
- @backstage/plugin-jenkins@0.8.3-next.1
- @backstage/app-defaults@1.4.2-next.0
- @backstage/catalog-model@1.4.1
- @backstage/config@1.0.8
- @backstage/core-app-api@1.9.1-next.0
- @backstage/core-components@0.13.4-next.0
- @backstage/core-plugin-api@1.5.3
- @backstage/theme@0.4.1
- @backstage/plugin-api-docs@0.9.7-next.1
- @backstage/plugin-azure-devops@0.3.3-next.0
- @backstage/plugin-azure-sites@0.1.10-next.0
- @backstage/plugin-badges@0.2.45-next.0
- @backstage/plugin-catalog-common@1.0.15
- @backstage/plugin-catalog-react@1.8.1-next.0
- @backstage/plugin-catalog-unprocessed-entities@0.1.2-next.0
- @backstage/plugin-circleci@0.3.21-next.0
- @backstage/plugin-cloudbuild@0.3.21-next.0
- @backstage/plugin-cost-insights@0.12.10-next.0
- @backstage/plugin-explore@0.4.7-next.0
- @backstage/plugin-gcp-projects@0.3.40-next.0
- @backstage/plugin-gocd@0.1.27-next.0
- @backstage/plugin-graphiql@0.2.53-next.0
- @backstage/plugin-home@0.5.5-next.0
- @backstage/plugin-kubernetes@0.9.4-next.0
- @backstage/plugin-lighthouse@0.4.6-next.0
- @backstage/plugin-newrelic@0.3.39-next.0
- @backstage/plugin-pagerduty@0.6.2-next.0
- @backstage/plugin-permission-react@0.4.14
- @backstage/plugin-puppetdb@0.1.4-next.0
- @backstage/plugin-rollbar@0.4.21-next.0
- @backstage/plugin-scaffolder-react@1.5.2-next.0
- @backstage/plugin-search@1.3.4-next.0
- @backstage/plugin-search-common@1.2.5
- @backstage/plugin-search-react@1.6.4-next.0
- @backstage/plugin-sentry@0.5.6-next.0
- @backstage/plugin-stackstorm@0.1.5-next.0
- @backstage/plugin-tech-radar@0.6.7-next.0
- @backstage/plugin-techdocs-react@1.1.9-next.0
- @backstage/plugin-todo@0.2.23-next.0
- @backstage/plugin-user-settings@0.7.6-next.0
- @internal/plugin-catalog-customized@0.0.13-next.1
## 0.2.86-next.0
### Patch Changes
+7 -1
View File
@@ -1,11 +1,17 @@
{
"name": "example-app",
"version": "0.2.86-next.0",
"version": "0.2.86-next.1",
"private": true,
"backstage": {
"role": "frontend"
},
"bundled": true,
"homepage": "https://backstage.io",
"repository": {
"type": "git",
"url": "https://github.com/backstage/backstage",
"directory": "packages/app"
},
"dependencies": {
"@backstage/app-defaults": "workspace:^",
"@backstage/catalog-model": "workspace:^",
+20
View File
@@ -1,5 +1,25 @@
# @backstage/backend-app-api
## 0.5.0-next.1
### Minor Changes
- b9c57a4f857e: **BREAKING**: Renamed `configServiceFactory` to `rootConfigServiceFactory`.
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.19.2-next.1
- @backstage/config-loader@1.4.0-next.1
- @backstage/plugin-auth-node@0.2.17-next.1
- @backstage/backend-plugin-api@0.6.0-next.1
- @backstage/backend-tasks@0.5.5-next.1
- @backstage/plugin-permission-node@0.7.11-next.1
- @backstage/cli-common@0.1.12
- @backstage/config@1.0.8
- @backstage/errors@1.2.1
- @backstage/types@1.1.0
## 0.4.6-next.0
### Patch Changes
+14 -14
View File
@@ -9,7 +9,6 @@ import type { AppConfig } from '@backstage/config';
import { BackendFeature } from '@backstage/backend-plugin-api';
import { CacheClient } from '@backstage/backend-common';
import { Config } from '@backstage/config';
import { ConfigService } from '@backstage/backend-plugin-api';
import { CorsOptions } from 'cors';
import { ErrorRequestHandler } from 'express';
import { Express as Express_2 } from 'express';
@@ -30,6 +29,7 @@ import { PluginEndpointDiscovery } from '@backstage/backend-common';
import { RemoteConfigSourceOptions } from '@backstage/config-loader';
import { RequestHandler } from 'express';
import { RequestListener } from 'http';
import { RootConfigService } from '@backstage/backend-plugin-api';
import { RootHttpRouterService } from '@backstage/backend-plugin-api';
import { RootLifecycleService } from '@backstage/backend-plugin-api';
import { RootLoggerService } from '@backstage/backend-plugin-api';
@@ -53,17 +53,6 @@ export interface Backend {
// @public (undocumented)
export const cacheServiceFactory: () => ServiceFactory<CacheClient, 'plugin'>;
// @public (undocumented)
export interface ConfigFactoryOptions {
argv?: string[];
remote?: Pick<RemoteConfigSourceOptions, 'reloadInterval'>;
}
// @public (undocumented)
export const configServiceFactory: (
options?: ConfigFactoryOptions | undefined,
) => ServiceFactory<ConfigService, 'root'>;
// @public (undocumented)
export function createConfigSecretEnumerator(options: {
logger: LoggerService;
@@ -224,7 +213,7 @@ export interface MiddlewareFactoryErrorOptions {
// @public
export interface MiddlewareFactoryOptions {
// (undocumented)
config: ConfigService;
config: RootConfigService;
// (undocumented)
logger: LoggerService;
}
@@ -244,12 +233,23 @@ export function readHelmetOptions(config?: Config): HelmetOptions;
// @public
export function readHttpServerOptions(config?: Config): HttpServerOptions;
// @public (undocumented)
export interface RootConfigFactoryOptions {
argv?: string[];
remote?: Pick<RemoteConfigSourceOptions, 'reloadInterval'>;
}
// @public (undocumented)
export const rootConfigServiceFactory: (
options?: RootConfigFactoryOptions | undefined,
) => ServiceFactory<RootConfigService, 'root'>;
// @public (undocumented)
export interface RootHttpRouterConfigureContext {
// (undocumented)
app: Express_2;
// (undocumented)
config: ConfigService;
config: RootConfigService;
// (undocumented)
lifecycle: LifecycleService;
// (undocumented)
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-app-api",
"description": "Core API used by Backstage backend apps",
"version": "0.4.6-next.0",
"version": "0.5.0-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"publishConfig": {
@@ -14,12 +14,11 @@
* limitations under the License.
*/
import { ConfigService } from '@backstage/backend-plugin-api';
import { ConfigReader } from '@backstage/config';
import { Config, ConfigReader } from '@backstage/config';
import { JsonValue } from '@backstage/types';
export class ObservableConfigProxy implements ConfigService {
private config: ConfigService = new ConfigReader({});
export class ObservableConfigProxy implements Config {
private config: Config = new ConfigReader({});
private readonly subscribers: (() => void)[] = [];
@@ -32,7 +31,7 @@ export class ObservableConfigProxy implements ConfigService {
}
}
setConfig(config: ConfigService) {
setConfig(config: Config) {
if (this.parent) {
throw new Error('immutable');
}
@@ -62,9 +61,9 @@ export class ObservableConfigProxy implements ConfigService {
};
}
private select(required: true): ConfigService;
private select(required: false): ConfigService | undefined;
private select(required: boolean): ConfigService | undefined {
private select(required: true): Config;
private select(required: false): Config | undefined;
private select(required: boolean): Config | undefined {
if (this.parent && this.parentKey) {
if (required) {
return this.parent.select(true).getConfig(this.parentKey);
@@ -87,19 +86,19 @@ export class ObservableConfigProxy implements ConfigService {
getOptional<T = JsonValue>(key?: string): T | undefined {
return this.select(false)?.getOptional(key);
}
getConfig(key: string): ConfigService {
getConfig(key: string): Config {
return new ObservableConfigProxy(this, key);
}
getOptionalConfig(key: string): ConfigService | undefined {
getOptionalConfig(key: string): Config | undefined {
if (this.select(false)?.has(key)) {
return new ObservableConfigProxy(this, key);
}
return undefined;
}
getConfigArray(key: string): ConfigService[] {
getConfigArray(key: string): Config[] {
return this.select(true).getConfigArray(key);
}
getOptionalConfigArray(key: string): ConfigService[] | undefined {
getOptionalConfigArray(key: string): Config[] | undefined {
return this.select(false)?.getOptionalConfigArray(key);
}
getNumber(key: string): number {
@@ -14,7 +14,10 @@
* limitations under the License.
*/
import { ConfigService, LoggerService } from '@backstage/backend-plugin-api';
import {
RootConfigService,
LoggerService,
} from '@backstage/backend-plugin-api';
import {
Request,
Response,
@@ -47,7 +50,7 @@ import { NotImplementedError } from '@backstage/errors';
* @public
*/
export interface MiddlewareFactoryOptions {
config: ConfigService;
config: RootConfigService;
logger: LoggerService;
}
@@ -78,7 +81,7 @@ export interface MiddlewareFactoryErrorOptions {
* @public
*/
export class MiddlewareFactory {
#config: ConfigService;
#config: RootConfigService;
#logger: LoggerService;
/**
@@ -24,7 +24,7 @@ import {
export const cacheServiceFactory = createServiceFactory({
service: coreServices.cache,
deps: {
config: coreServices.config,
config: coreServices.rootConfig,
plugin: coreServices.pluginMetadata,
},
async createRootContext({ config }) {
@@ -14,5 +14,5 @@
* limitations under the License.
*/
export { configServiceFactory } from './configServiceFactory';
export type { ConfigFactoryOptions } from './configServiceFactory';
export { rootConfigServiceFactory } from './rootConfigServiceFactory';
export type { RootConfigFactoryOptions } from './rootConfigServiceFactory';
@@ -24,7 +24,7 @@ import {
} from '@backstage/config-loader';
/** @public */
export interface ConfigFactoryOptions {
export interface RootConfigFactoryOptions {
/**
* Process arguments to use instead of the default `process.argv()`.
*/
@@ -37,9 +37,9 @@ export interface ConfigFactoryOptions {
}
/** @public */
export const configServiceFactory = createServiceFactory(
(options?: ConfigFactoryOptions) => ({
service: coreServices.config,
export const rootConfigServiceFactory = createServiceFactory(
(options?: RootConfigFactoryOptions) => ({
service: coreServices.rootConfig,
deps: {},
async factory() {
const source = ConfigSources.default({
@@ -25,7 +25,7 @@ import { ConfigReader } from '@backstage/config';
export const databaseServiceFactory = createServiceFactory({
service: coreServices.database,
deps: {
config: coreServices.config,
config: coreServices.rootConfig,
lifecycle: coreServices.lifecycle,
pluginMetadata: coreServices.pluginMetadata,
},
@@ -24,7 +24,7 @@ import {
export const discoveryServiceFactory = createServiceFactory({
service: coreServices.discovery,
deps: {
config: coreServices.config,
config: coreServices.rootConfig,
},
async factory({ config }) {
return HostDiscovery.fromConfig(config);
@@ -24,7 +24,7 @@ import { ServerPermissionClient } from '@backstage/plugin-permission-node';
export const permissionsServiceFactory = createServiceFactory({
service: coreServices.permissions,
deps: {
config: coreServices.config,
config: coreServices.rootConfig,
discovery: coreServices.discovery,
tokenManager: coreServices.tokenManager,
},
@@ -15,7 +15,7 @@
*/
import {
ConfigService,
RootConfigService,
coreServices,
createServiceFactory,
LifecycleService,
@@ -36,7 +36,7 @@ export interface RootHttpRouterConfigureContext {
app: Express;
middleware: MiddlewareFactory;
routes: RequestHandler;
config: ConfigService;
config: RootConfigService;
logger: LoggerService;
lifecycle: LifecycleService;
}
@@ -70,7 +70,7 @@ export const rootHttpRouterServiceFactory = createServiceFactory(
(options?: RootHttpRouterFactoryOptions) => ({
service: coreServices.rootHttpRouter,
deps: {
config: coreServices.config,
config: coreServices.rootConfig,
rootLogger: coreServices.rootLogger,
lifecycle: coreServices.rootLifecycle,
},
@@ -26,7 +26,7 @@ import { createConfigSecretEnumerator } from '../../../config';
export const rootLoggerServiceFactory = createServiceFactory({
service: coreServices.rootLogger,
deps: {
config: coreServices.config,
config: coreServices.rootConfig,
},
async factory({ config }) {
const logger = WinstonLogger.create({
@@ -24,7 +24,7 @@ import { ServerTokenManager } from '@backstage/backend-common';
export const tokenManagerServiceFactory = createServiceFactory({
service: coreServices.tokenManager,
deps: {
config: coreServices.config,
config: coreServices.rootConfig,
logger: coreServices.rootLogger,
},
createRootContext({ config, logger }) {
@@ -24,7 +24,7 @@ import {
export const urlReaderServiceFactory = createServiceFactory({
service: coreServices.urlReader,
deps: {
config: coreServices.config,
config: coreServices.rootConfig,
logger: coreServices.logger,
},
async factory({ config, logger }) {
+18
View File
@@ -1,5 +1,23 @@
# @backstage/backend-common
## 0.19.2-next.1
### Patch Changes
- 629cbd194a87: Use `coreServices.rootConfig` instead of `coreService.config`
- 4b82382ed8c2: Fixed invalid configuration schema. The configuration schema may be more strict as a result.
- Updated dependencies
- @backstage/config-loader@1.4.0-next.1
- @backstage/backend-app-api@0.5.0-next.1
- @backstage/backend-plugin-api@0.6.0-next.1
- @backstage/integration@1.5.1
- @backstage/integration-aws-node@0.1.5
- @backstage/backend-dev-utils@0.1.1
- @backstage/cli-common@0.1.12
- @backstage/config@1.0.8
- @backstage/errors@1.2.1
- @backstage/types@1.1.0
## 0.19.2-next.0
### Patch Changes
+2 -2
View File
@@ -18,7 +18,6 @@ import { CacheService as CacheClient } from '@backstage/backend-plugin-api';
import { CacheServiceOptions as CacheClientOptions } from '@backstage/backend-plugin-api';
import { CacheServiceSetOptions as CacheClientSetOptions } from '@backstage/backend-plugin-api';
import { Config } from '@backstage/config';
import { ConfigService } from '@backstage/backend-plugin-api';
import cors from 'cors';
import Docker from 'dockerode';
import { ErrorRequestHandler } from 'express';
@@ -51,6 +50,7 @@ import { ReadTreeResponseFile } from '@backstage/backend-plugin-api';
import { ReadUrlOptions } from '@backstage/backend-plugin-api';
import { ReadUrlResponse } from '@backstage/backend-plugin-api';
import { RequestHandler } from 'express';
import { RootConfigService } from '@backstage/backend-plugin-api';
import { Router } from 'express';
import { SchedulerService } from '@backstage/backend-plugin-api';
import { SearchOptions } from '@backstage/backend-plugin-api';
@@ -525,7 +525,7 @@ export const legacyPlugin: (
TransformedEnv<
{
cache: CacheClient;
config: ConfigService;
config: RootConfigService;
database: PluginDatabaseManager;
discovery: PluginEndpointDiscovery;
logger: LoggerService;
+3 -3
View File
@@ -77,17 +77,17 @@ export interface Config {
*/
connection:
| string
| Partial<{
| {
/**
* Password that belongs to the client User
* @visibility secret
*/
password: string;
password?: string;
/**
* Other connection settings
*/
[key: string]: unknown;
}>;
};
/** Database name prefix override */
prefix?: string;
/**
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-common",
"description": "Common functionality library for Backstage backends",
"version": "0.19.2-next.0",
"version": "0.19.2-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"publishConfig": {
+1 -1
View File
@@ -108,7 +108,7 @@ export function makeLegacyPlugin<
export const legacyPlugin = makeLegacyPlugin(
{
cache: coreServices.cache,
config: coreServices.config,
config: coreServices.rootConfig,
database: coreServices.database,
discovery: coreServices.discovery,
logger: coreServices.logger,
+14
View File
@@ -1,5 +1,19 @@
# @backstage/backend-defaults
## 0.2.0-next.1
### Minor Changes
- d008aefef808: **BREAKING**: Removing shared environments concept from the new experimental backend system.
### Patch Changes
- 629cbd194a87: Use `coreServices.rootConfig` instead of `coreService.config`
- Updated dependencies
- @backstage/backend-common@0.19.2-next.1
- @backstage/backend-app-api@0.5.0-next.1
- @backstage/backend-plugin-api@0.6.0-next.1
## 0.1.13-next.0
### Patch Changes
-3
View File
@@ -5,15 +5,12 @@
```ts
import { Backend } from '@backstage/backend-app-api';
import { ServiceFactoryOrFunction } from '@backstage/backend-plugin-api';
import { SharedBackendEnvironment } from '@backstage/backend-plugin-api';
// @public (undocumented)
export function createBackend(options?: CreateBackendOptions): Backend;
// @public (undocumented)
export interface CreateBackendOptions {
// (undocumented)
env?: SharedBackendEnvironment;
// (undocumented)
services?: ServiceFactoryOrFunction[];
}
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-defaults",
"description": "Backend defaults used by Backstage backend apps",
"version": "0.1.13-next.0",
"version": "0.2.0-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"publishConfig": {
@@ -16,17 +16,10 @@
import {
coreServices,
createBackendPlugin,
createServiceFactory,
createServiceRef,
createSharedEnvironment,
} from '@backstage/backend-plugin-api';
import { mockServices } from '@backstage/backend-test-utils';
import { createBackend } from './CreateBackend';
const fooServiceRef = createServiceRef<string>({ id: 'foo', scope: 'root' });
const barServiceRef = createServiceRef<string>({ id: 'bar', scope: 'root' });
describe('createBackend', () => {
it('should not throw when overriding a default service implementation', () => {
expect(() =>
@@ -85,91 +78,4 @@ describe('createBackend', () => {
}),
).toThrow('The core.pluginMetadata service cannot be overridden');
});
it('should throw if an unsupported InternalSharedEnvironment version is passed in', () => {
expect(() =>
createBackend({
env: {} as any,
}),
).toThrow(
"Shared environment version 'undefined' is invalid or not supported",
);
expect(() =>
createBackend({
env: { version: {} } as any,
}),
).toThrow(
"Shared environment version '[object Object]' is invalid or not supported",
);
expect(() =>
createBackend({
env: { version: 'v2' } as any,
}),
).toThrow("Shared environment version 'v2' is invalid or not supported");
});
it('should prioritize services correctly', async () => {
const backend = createBackend({
env: createSharedEnvironment({
services: [
createServiceFactory({
service: coreServices.rootHttpRouter,
deps: {},
async factory() {
return {
use() {},
};
},
}),
mockServices.config.factory({
data: { root: 'root-env' },
}),
createServiceFactory({
service: fooServiceRef,
deps: {},
async factory() {
return 'foo-env';
},
}),
createServiceFactory({
service: barServiceRef,
deps: {},
async factory() {
return 'bar-env';
},
}),
],
})(),
services: [
createServiceFactory({
service: fooServiceRef,
deps: {},
factory: async () => 'foo-backend',
}),
],
});
expect.assertions(3);
backend.add(
createBackendPlugin({
pluginId: 'test',
register(reg) {
reg.registerInit({
deps: {
config: coreServices.config,
foo: fooServiceRef,
bar: barServiceRef,
},
async init({ config, foo, bar }) {
expect(config.get('root')).toBe('root-env');
expect(foo).toBe('foo-backend');
expect(bar).toBe('bar-env');
},
});
},
})(),
);
await backend.start();
});
});
+2 -24
View File
@@ -17,7 +17,7 @@
import {
Backend,
cacheServiceFactory,
configServiceFactory,
rootConfigServiceFactory,
createSpecializedBackend,
databaseServiceFactory,
discoveryServiceFactory,
@@ -36,16 +36,11 @@ import {
import {
ServiceFactory,
ServiceFactoryOrFunction,
SharedBackendEnvironment,
} from '@backstage/backend-plugin-api';
// Internal import of the type to avoid needing to export this.
// eslint-disable-next-line @backstage/no-forbidden-package-imports
import type { InternalSharedBackendEnvironment } from '@backstage/backend-plugin-api/src/wiring/createSharedEnvironment';
export const defaultServiceFactories = [
cacheServiceFactory(),
configServiceFactory(),
rootConfigServiceFactory(),
databaseServiceFactory(),
discoveryServiceFactory(),
httpRouterServiceFactory(),
@@ -65,7 +60,6 @@ export const defaultServiceFactories = [
* @public
*/
export interface CreateBackendOptions {
env?: SharedBackendEnvironment;
services?: ServiceFactoryOrFunction[];
}
@@ -81,22 +75,6 @@ export function createBackend(options?: CreateBackendOptions): Backend {
);
services.push(...providedServices);
// Middle priority: Services from the shared environment
if (options?.env) {
const env = options.env as unknown as InternalSharedBackendEnvironment;
if (env.version !== 'v1') {
throw new Error(
`Shared environment version '${env.version}' is invalid or not supported`,
);
}
const environmentServices =
env.services?.filter(
sf => !services.some(({ service }) => sf.service.id === service.id),
) ?? [];
services.push(...environmentServices);
}
// Lowest priority: Default services that are not already provided by environment or directly to createBackend
const defaultServices = defaultServiceFactories.filter(
sf => !services.some(({ service }) => service.id === sf.service.id),
+31
View File
@@ -1,5 +1,36 @@
# example-backend-next
## 0.0.14-next.1
### Patch Changes
- Updated dependencies
- @backstage/plugin-search-backend-module-techdocs@0.1.4-next.1
- @backstage/plugin-search-backend-module-catalog@0.1.4-next.1
- @backstage/plugin-search-backend-module-explore@0.1.4-next.1
- @backstage/plugin-azure-devops-backend@0.3.27-next.1
- @backstage/plugin-kubernetes-backend@0.11.3-next.1
- @backstage/plugin-lighthouse-backend@0.2.4-next.1
- @backstage/plugin-permission-backend@0.5.23-next.1
- @backstage/plugin-scaffolder-backend@1.15.2-next.1
- @backstage/backend-defaults@0.2.0-next.1
- @backstage/plugin-devtools-backend@0.1.3-next.1
- @backstage/plugin-techdocs-backend@1.6.5-next.1
- @backstage/plugin-catalog-backend@1.12.0-next.1
- @backstage/plugin-badges-backend@0.2.3-next.1
- @backstage/plugin-search-backend@1.4.0-next.1
- @backstage/plugin-todo-backend@0.2.0-next.1
- @backstage/plugin-app-backend@0.3.48-next.1
- @backstage/plugin-catalog-backend-module-unprocessed@0.2.0-next.1
- @backstage/plugin-entity-feedback-backend@0.1.6-next.1
- @backstage/plugin-search-backend-node@1.2.4-next.1
- @backstage/plugin-linguist-backend@0.3.2-next.1
- @backstage/plugin-auth-node@0.2.17-next.1
- @backstage/backend-tasks@0.5.5-next.1
- @backstage/plugin-adr-backend@0.3.6-next.1
- @backstage/plugin-permission-node@0.7.11-next.1
- @backstage/plugin-permission-common@0.7.7
## 0.0.14-next.0
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "example-backend-next",
"version": "0.0.14-next.0",
"version": "0.0.14-next.1",
"main": "dist/index.cjs.js",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -1,5 +1,13 @@
# @backstage/backend-openapi-utils
## 0.0.3-next.1
### Patch Changes
- 12a8c94eda8d: Add package repository and homepage metadata
- Updated dependencies
- @backstage/errors@1.2.1
## 0.0.3-next.0
### Patch Changes
+7 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-openapi-utils",
"description": "OpenAPI typescript support.",
"version": "0.0.3-next.0",
"version": "0.0.3-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -11,6 +11,12 @@
"module": "dist/index.esm.js",
"types": "dist/index.d.ts"
},
"homepage": "https://backstage.io",
"repository": {
"type": "git",
"url": "https://github.com/backstage/backstage",
"directory": "packages/backend-openapi-utils"
},
"backstage": {
"role": "node-library"
},
+16
View File
@@ -1,5 +1,21 @@
# @backstage/backend-plugin-api
## 0.6.0-next.1
### Minor Changes
- 629cbd194a87: **BREAKING**: Renamed `coreServices.config` to `coreServices.rootConfig`.
- d008aefef808: **BREAKING**: Removing shared environments concept from the new experimental backend system.
### Patch Changes
- Updated dependencies
- @backstage/plugin-auth-node@0.2.17-next.1
- @backstage/backend-tasks@0.5.5-next.1
- @backstage/config@1.0.8
- @backstage/types@1.1.0
- @backstage/plugin-permission-common@0.7.7
## 0.5.5-next.0
### Patch Changes
+4 -25
View File
@@ -93,13 +93,10 @@ export type CacheServiceSetOptions = {
ttl?: number;
};
// @public (undocumented)
export interface ConfigService extends Config {}
// @public
export namespace coreServices {
const cache: ServiceRef<CacheService, 'plugin'>;
const config: ServiceRef<ConfigService, 'root'>;
const rootConfig: ServiceRef<RootConfigService, 'root'>;
const database: ServiceRef<DatabaseService, 'plugin'>;
const discovery: ServiceRef<DiscoveryService, 'plugin'>;
const httpRouter: ServiceRef<HttpRouterService, 'plugin'>;
@@ -222,15 +219,6 @@ export function createServiceRef<TService>(
config: ServiceRefConfig<TService, 'root'>,
): ServiceRef<TService, 'root'>;
// @public
export function createSharedEnvironment<
TOptions extends [options?: object] = [],
>(
config:
| SharedBackendEnvironmentConfig
| ((...params: TOptions) => SharedBackendEnvironmentConfig),
): (...options: TOptions) => SharedBackendEnvironment;
// @public
export interface DatabaseService {
getClient(): Promise<Knex>;
@@ -389,6 +377,9 @@ export type ReadUrlResponse = {
lastModifiedAt?: Date;
};
// @public (undocumented)
export interface RootConfigService extends Config {}
// @public (undocumented)
export interface RootHttpRouterService {
use(path: string, handler: Handler): void;
@@ -476,18 +467,6 @@ export interface ServiceRefConfig<TService, TScope extends 'root' | 'plugin'> {
scope?: TScope;
}
// @public
export interface SharedBackendEnvironment {
// (undocumented)
$$type: '@backstage/SharedBackendEnvironment';
}
// @public
export interface SharedBackendEnvironmentConfig {
// (undocumented)
services?: ServiceFactoryOrFunction[];
}
// @public
export interface TokenManagerService {
authenticate(token: string): Promise<void>;
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-plugin-api",
"description": "Core API used by Backstage backend plugins",
"version": "0.5.5-next.0",
"version": "0.6.0-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"publishConfig": {
@@ -19,4 +19,4 @@ import { Config } from '@backstage/config';
/**
* @public
*/
export interface ConfigService extends Config {}
export interface RootConfigService extends Config {}
@@ -32,13 +32,13 @@ export namespace coreServices {
});
/**
* The service reference for the root scoped {@link ConfigService}.
* The service reference for the root scoped {@link RootConfigService}.
*
* @public
*/
export const config = createServiceRef<
import('./ConfigService').ConfigService
>({ id: 'core.config', scope: 'root' });
export const rootConfig = createServiceRef<
import('./RootConfigService').RootConfigService
>({ id: 'core.rootConfig', scope: 'root' });
/**
* The service reference for the plugin scoped {@link DatabaseService}.
@@ -20,7 +20,7 @@ export type {
CacheServiceOptions,
CacheServiceSetOptions,
} from './CacheService';
export type { ConfigService } from './ConfigService';
export type { RootConfigService } from './RootConfigService';
export type { DatabaseService } from './DatabaseService';
export type { DiscoveryService } from './DiscoveryService';
export type { HttpRouterService } from './HttpRouterService';
@@ -1,100 +0,0 @@
/*
* Copyright 2023 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.
*/
import {
createServiceFactory,
createServiceRef,
ServiceFactoryOrFunction,
} from '../services';
import {
createSharedEnvironment,
InternalSharedBackendEnvironment,
} from './createSharedEnvironment';
const fooService = createServiceRef<string>({ id: 'foo', scope: 'root' });
const fooFactory = createServiceFactory({
service: fooService,
deps: {},
async factory() {
return 'foo';
},
});
const barService = createServiceRef<number>({ id: 'bar', scope: 'root' });
const barFactory = createServiceFactory({
service: barService,
deps: {},
async factory() {
return 0xba5;
},
});
describe('createSharedEnvironment', () => {
it('should create an empty shared environment', () => {
const env = createSharedEnvironment({});
expect(env).toBeDefined();
const internalEnv = env() as unknown as InternalSharedBackendEnvironment;
expect(internalEnv).toEqual({
$$type: '@backstage/SharedBackendEnvironment',
version: 'v1',
services: undefined,
});
});
it('should create a shared environment with services', () => {
const env = createSharedEnvironment({
services: [fooFactory, barFactory()],
});
const internalEnv = env() as unknown as InternalSharedBackendEnvironment;
expect(internalEnv.version).toBe('v1');
expect(internalEnv.services?.length).toBe(2);
expect(internalEnv.services?.[0]?.service.id).toBe('foo');
expect(internalEnv.services?.[1]?.service.id).toBe('bar');
});
it('should create a shared environment with options', () => {
const env = createSharedEnvironment((options?: { withFoo?: boolean }) => {
const services = new Array<ServiceFactoryOrFunction>();
if (options?.withFoo) {
services.push(fooFactory());
}
services.push(barFactory);
return { services };
});
const internalEnv1 = env() as unknown as InternalSharedBackendEnvironment;
expect(internalEnv1.version).toBe('v1');
expect(internalEnv1.services?.length).toBe(1);
expect(internalEnv1.services?.[0]?.service.id).toBe('bar');
const internalEnv2 = env({
withFoo: true,
}) as unknown as InternalSharedBackendEnvironment;
expect(internalEnv2.version).toBe('v1');
expect(internalEnv2.services?.length).toBe(2);
expect(internalEnv2.services?.[0]?.service.id).toBe('foo');
expect(internalEnv2.services?.[1]?.service.id).toBe('bar');
});
it('should not allow duplicate service factories', () => {
expect(() =>
createSharedEnvironment({
services: [fooFactory, fooFactory()],
})(),
).toThrow(
"Duplicate service implementations provided in shared environment for 'foo'",
);
});
});
@@ -1,102 +0,0 @@
/*
* Copyright 2023 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.
*/
import { ServiceFactory, ServiceFactoryOrFunction } from '../services';
/**
* The configuration options passed to {@link createSharedEnvironment}.
*
* @public
*/
export interface SharedBackendEnvironmentConfig {
services?: ServiceFactoryOrFunction[];
}
/**
* An opaque type that represents the contents of a shared backend environment.
*
* @public
*/
export interface SharedBackendEnvironment {
$$type: '@backstage/SharedBackendEnvironment';
// NOTE: This type is opaque in order to allow for future API evolution without
// cluttering the external API. For example we might want to add support
// for more powerful callback based backend modifications.
//
// By making this opaque we also ensure that the type doesn't become an input
// type that we need to care about, as it would otherwise be possible to pass
// a custom environment definition to `createBackend`, which we don't want.
}
/**
* This type is NOT supposed to be used by anyone except internally by the
* backend-app-api package.
*
* @internal
*/
export interface InternalSharedBackendEnvironment {
version: 'v1';
services?: ServiceFactory[];
}
/**
* Creates a shared backend environment which can be used to create multiple
* backends.
*
* @public
*/
export function createSharedEnvironment<
TOptions extends [options?: object] = [],
>(
config:
| SharedBackendEnvironmentConfig
| ((...params: TOptions) => SharedBackendEnvironmentConfig),
): (...options: TOptions) => SharedBackendEnvironment {
const configCallback = typeof config === 'function' ? config : () => config;
return (...options) => {
const actualConfig = configCallback(...options);
const services = actualConfig?.services?.map(sf =>
typeof sf === 'function' ? sf() : sf,
);
const exists = new Set<string>();
const duplicates = new Set<string>();
for (const { service } of services ?? []) {
if (exists.has(service.id)) {
duplicates.add(service.id);
} else {
exists.add(service.id);
}
}
if (duplicates.size > 0) {
const dupStr = [...duplicates].map(id => `'${id}'`).join(', ');
throw new Error(
`Duplicate service implementations provided in shared environment for ${dupStr}`,
);
}
// Here to ensure type safety in this internal implementation.
const env: SharedBackendEnvironment & InternalSharedBackendEnvironment = {
$$type: '@backstage/SharedBackendEnvironment',
version: 'v1',
services,
};
return env;
};
}
@@ -14,11 +14,6 @@
* limitations under the License.
*/
export { createSharedEnvironment } from './createSharedEnvironment';
export type {
SharedBackendEnvironment,
SharedBackendEnvironmentConfig,
} from './createSharedEnvironment';
export type {
BackendModuleConfig,
BackendPluginConfig,
+10
View File
@@ -1,5 +1,15 @@
# @backstage/backend-tasks
## 0.5.5-next.1
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.19.2-next.1
- @backstage/config@1.0.8
- @backstage/errors@1.2.1
- @backstage/types@1.1.0
## 0.5.5-next.0
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-tasks",
"description": "Common distributed task management library for Backstage backends",
"version": "0.5.5-next.0",
"version": "0.5.5-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"publishConfig": {
+17
View File
@@ -1,5 +1,22 @@
# @backstage/backend-test-utils
## 0.2.0-next.1
### Minor Changes
- b9c57a4f857e: **BREAKING**: Renamed `mockServices.config` to `mockServices.rootConfig`.
### Patch Changes
- ae9304818136: Add needed constants and constructs to support PostgreSQL version 14 as test database
- Updated dependencies
- @backstage/backend-common@0.19.2-next.1
- @backstage/plugin-auth-node@0.2.17-next.1
- @backstage/backend-app-api@0.5.0-next.1
- @backstage/backend-plugin-api@0.6.0-next.1
- @backstage/config@1.0.8
- @backstage/types@1.1.0
## 0.1.40-next.0
### Patch Changes
+15 -14
View File
@@ -6,7 +6,6 @@
import { Backend } from '@backstage/backend-app-api';
import { BackendFeature } from '@backstage/backend-plugin-api';
import { CacheService } from '@backstage/backend-plugin-api';
import { ConfigService } from '@backstage/backend-plugin-api';
import { DatabaseService } from '@backstage/backend-plugin-api';
import { ExtendedHttpServer } from '@backstage/backend-app-api';
import { ExtensionPoint } from '@backstage/backend-plugin-api';
@@ -18,6 +17,7 @@ import { Knex } from 'knex';
import { LifecycleService } from '@backstage/backend-plugin-api';
import { LoggerService } from '@backstage/backend-plugin-api';
import { PermissionsService } from '@backstage/backend-plugin-api';
import { RootConfigService } from '@backstage/backend-plugin-api';
import { RootLifecycleService } from '@backstage/backend-plugin-api';
import { SchedulerService } from '@backstage/backend-plugin-api';
import { ServiceFactory } from '@backstage/backend-plugin-api';
@@ -36,19 +36,6 @@ export namespace mockServices {
factory: () => ServiceFactory<CacheService, 'plugin'>;
}
// (undocumented)
export function config(options?: config.Options): ConfigService;
// (undocumented)
export namespace config {
// (undocumented)
export type Options = {
data?: JsonObject;
};
const // (undocumented)
factory: (
options?: Options | undefined,
) => ServiceFactory<ConfigService, 'root'>;
}
// (undocumented)
export namespace database {
const // (undocumented)
factory: () => ServiceFactory<DatabaseService, 'plugin'>;
@@ -83,6 +70,19 @@ export namespace mockServices {
factory: () => ServiceFactory<PermissionsService, 'plugin'>;
}
// (undocumented)
export function rootConfig(options?: rootConfig.Options): RootConfigService;
// (undocumented)
export namespace rootConfig {
// (undocumented)
export type Options = {
data?: JsonObject;
};
const // (undocumented)
factory: (
options?: Options | undefined,
) => ServiceFactory<RootConfigService, 'root'>;
}
// (undocumented)
export namespace rootLifecycle {
const // (undocumented)
factory: () => ServiceFactory<RootLifecycleService, 'root'>;
@@ -168,6 +168,7 @@ export interface TestBackendOptions<
// @public
export type TestDatabaseId =
| 'POSTGRES_14'
| 'POSTGRES_13'
| 'POSTGRES_12'
| 'POSTGRES_11'
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-test-utils",
"description": "Test helpers library for Backstage backends",
"version": "0.1.40-next.0",
"version": "0.2.0-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"publishConfig": {
@@ -59,6 +59,37 @@ describe('TestDatabases', () => {
describe('each connect', () => {
const dbs = TestDatabases.create();
itIfDocker(
'obeys a provided connection string for postgres 14',
async () => {
const { host, port, user, password, stop } =
await startPostgresContainer('postgres:14');
try {
// Leave a mark
process.env.BACKSTAGE_TEST_DATABASE_POSTGRES14_CONNECTION_STRING = `postgresql://${user}:${password}@${host}:${port}`;
const input = await dbs.init('POSTGRES_14');
await input.schema.createTable('a', table =>
table.string('x').primary(),
);
await input.insert({ x: 'y' }).into('a');
// Look for the mark
const database = input.client.config.connection.database;
const output = knexFactory({
client: 'pg',
connection: { host, port, user, password, database },
});
// eslint-disable-next-line jest/no-standalone-expect
await expect(output.select('x').from('a')).resolves.toEqual([
{ x: 'y' },
]);
} finally {
await stop();
}
},
);
itIfDocker(
'obeys a provided connection string for postgres 13',
async () => {
@@ -24,6 +24,7 @@ import { getDockerImageForName } from '../util/getDockerImageForName';
* @public
*/
export type TestDatabaseId =
| 'POSTGRES_14'
| 'POSTGRES_13'
| 'POSTGRES_12'
| 'POSTGRES_11'
@@ -46,6 +47,13 @@ export type Instance = {
export const allDatabases: Record<TestDatabaseId, TestDatabaseProperties> =
Object.freeze({
POSTGRES_14: {
name: 'Postgres 14.x',
driver: 'pg',
dockerImageName: getDockerImageForName('postgres:14'),
connectionStringEnvironmentVariableName:
'BACKSTAGE_TEST_DATABASE_POSTGRES14_CONNECTION_STRING',
},
POSTGRES_13: {
name: 'Postgres 13.x',
driver: 'pg',
@@ -15,7 +15,7 @@
*/
import {
ConfigService,
RootConfigService,
coreServices,
createServiceFactory,
IdentityService,
@@ -61,13 +61,13 @@ function simpleFactory<
* @public
*/
export namespace mockServices {
export function config(options?: config.Options): ConfigService {
export function rootConfig(options?: rootConfig.Options): RootConfigService {
return new ConfigReader(options?.data, 'mock-config');
}
export namespace config {
export namespace rootConfig {
export type Options = { data?: JsonObject };
export const factory = simpleFactory(coreServices.config, config);
export const factory = simpleFactory(coreServices.rootConfig, rootConfig);
}
export function rootLogger(options?: rootLogger.Options): LoggerService {
@@ -168,7 +168,7 @@ describe('TestBackend', () => {
env.registerInit({
deps: {
cache: coreServices.cache,
config: coreServices.config,
config: coreServices.rootConfig,
database: coreServices.database,
discovery: coreServices.discovery,
httpRouter: coreServices.httpRouter,
@@ -73,7 +73,7 @@ export interface TestBackend extends Backend {
const defaultServiceFactories = [
mockServices.cache.factory(),
mockServices.config.factory(),
mockServices.rootConfig.factory(),
mockServices.database.factory(),
mockServices.httpRouter.factory(),
mockServices.identity.factory(),
@@ -108,7 +108,7 @@ export async function startTestBackend<
const rootHttpRouterFactory = createServiceFactory({
service: coreServices.rootHttpRouter,
deps: {
config: coreServices.config,
config: coreServices.rootConfig,
lifecycle: coreServices.rootLifecycle,
rootLogger: coreServices.rootLogger,
},
+55
View File
@@ -1,5 +1,60 @@
# example-backend
## 0.2.86-next.1
### Patch Changes
- Updated dependencies
- @backstage/plugin-search-backend-module-elasticsearch@1.3.3-next.1
- @backstage/plugin-search-backend-module-pg@0.5.9-next.1
- @backstage/plugin-azure-devops-backend@0.3.27-next.1
- @backstage/plugin-kubernetes-backend@0.11.3-next.1
- @backstage/plugin-lighthouse-backend@0.2.4-next.1
- @backstage/plugin-permission-backend@0.5.23-next.1
- @backstage/plugin-scaffolder-backend@1.15.2-next.1
- @backstage/plugin-devtools-backend@0.1.3-next.1
- @backstage/plugin-techdocs-backend@1.6.5-next.1
- @backstage/backend-common@0.19.2-next.1
- @backstage/plugin-catalog-backend@1.12.0-next.1
- @backstage/plugin-badges-backend@0.2.3-next.1
- @backstage/plugin-events-backend@0.2.9-next.1
- @backstage/plugin-search-backend@1.4.0-next.1
- @backstage/plugin-kafka-backend@0.2.41-next.1
- @backstage/plugin-proxy-backend@0.2.42-next.1
- @backstage/plugin-todo-backend@0.2.0-next.1
- @backstage/plugin-app-backend@0.3.48-next.1
- @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.1-next.1
- @backstage/plugin-catalog-backend-module-unprocessed@0.2.0-next.1
- @backstage/plugin-scaffolder-backend-module-rails@0.4.17-next.1
- @backstage/plugin-entity-feedback-backend@0.1.6-next.1
- @backstage/plugin-code-coverage-backend@0.2.14-next.1
- @backstage/plugin-search-backend-node@1.2.4-next.1
- @backstage/plugin-linguist-backend@0.3.2-next.1
- @backstage/plugin-playlist-backend@0.3.4-next.1
- @backstage/plugin-explore-backend@0.0.10-next.1
- @backstage/plugin-jenkins-backend@0.2.3-next.1
- @backstage/plugin-nomad-backend@0.1.2-next.1
- @backstage/plugin-catalog-node@1.4.1-next.1
- @backstage/plugin-events-node@0.2.9-next.1
- @backstage/plugin-auth-node@0.2.17-next.1
- @backstage/plugin-auth-backend@0.18.6-next.1
- @backstage/backend-tasks@0.5.5-next.1
- @backstage/plugin-adr-backend@0.3.6-next.1
- @backstage/plugin-azure-sites-backend@0.1.10-next.1
- @backstage/plugin-graphql-backend@0.1.38-next.1
- @backstage/plugin-permission-node@0.7.11-next.1
- @backstage/plugin-rollbar-backend@0.1.45-next.1
- @backstage/plugin-tech-insights-backend@0.5.14-next.1
- @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.32-next.1
- @backstage/plugin-tech-insights-node@0.4.6-next.1
- example-app@0.2.86-next.1
- @backstage/integration@1.5.1
- @backstage/catalog-client@1.4.3
- @backstage/catalog-model@1.4.1
- @backstage/config@1.0.8
- @backstage/plugin-permission-common@0.7.7
- @backstage/plugin-search-common@1.2.5
## 0.2.86-next.0
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "example-backend",
"version": "0.2.86-next.0",
"version": "0.2.86-next.1",
"main": "dist/index.cjs.js",
"types": "src/index.ts",
"license": "Apache-2.0",
+10
View File
@@ -1,5 +1,15 @@
# @backstage/cli-node
## 0.1.3-next.0
### Patch Changes
- 12a8c94eda8d: Add package repository and homepage metadata
- Updated dependencies
- @backstage/cli-common@0.1.12
- @backstage/errors@1.2.1
- @backstage/types@1.1.0
## 0.1.2
### Patch Changes
+7 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/cli-node",
"description": "Node.js library for Backstage CLIs",
"version": "0.1.2",
"version": "0.1.3-next.0",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -13,6 +13,12 @@
"backstage": {
"role": "node-library"
},
"homepage": "https://backstage.io",
"repository": {
"type": "git",
"url": "https://github.com/backstage/backstage",
"directory": "packages/cli-node"
},
"scripts": {
"build": "backstage-cli package build",
"lint": "backstage-cli package lint",

Some files were not shown because too many files have changed in this diff Show More