Merge branch 'backstage:master' into update-custom-permission-rule-doc

This commit is contained in:
Stanley Nicholl
2023-12-01 17:00:18 +00:00
committed by GitHub
1018 changed files with 20775 additions and 5101 deletions
+6
View File
@@ -236,6 +236,12 @@ export default async function createPlugin(
// an entity you will need to replace this step as well.
//
// You might also replace it if you for example want to filter out certain groups.
//
// Note that `getDefaultOwnershipEntityRefs` only includes groups to which the
// user has a direct MEMBER_OF relationship. It's perfectly fine to include
// groups that the user is transitively part of in the claims array, but the
// catalog doesn't currently provide a direct way of accessing this list of
// groups.
const ownershipRefs = getDefaultOwnershipEntityRefs(entity);
// The last step is to issue the token, where we might provide more options in the future.
@@ -25,8 +25,8 @@ import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'
import { MyCustomProcessor } from './MyCustomProcessor';
export const catalogModuleExampleCustomProcessor = createBackendModule({
moduleId: 'exampleCustomProcessor',
pluginId: 'catalog',
moduleId: 'example-custom-processor',
register(env) {
env.registerInit({
deps: {
@@ -10,18 +10,20 @@ description: Naming patterns in the backend system
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.
As a rule, all names should be camel case, with the exceptions of plugin and module IDs, which should be kebab case.
### Plugins
| Description | Pattern | Examples |
| ----------- | ------------ | ----------------------------------- |
| export | `<id>Plugin` | `catalogPlugin`, `scaffolderPlugin` |
| ID | `'<id>'` | `'catalog'`, `'scaffolder'` |
| Description | Pattern | Examples |
| ----------- | ----------------- | ------------------------------------- |
| export | `<camelId>Plugin` | `catalogPlugin`, `userSettingsPlugin` |
| ID | `'<kebab-id>'` | `'catalog'`, `'user-settings'` |
Example:
```ts
export const catalogPlugin = createBackendPlugin({
pluginId: 'catalog',
export const userSettingsPlugin = createBackendPlugin({
pluginId: 'user-settings',
...
})
```
@@ -31,14 +33,14 @@ export const catalogPlugin = createBackendPlugin({
| Description | Pattern | Examples |
| ----------- | ---------------------------- | ----------------------------------- |
| export | `<pluginId>Module<ModuleId>` | `catalogModuleGithubEntityProvider` |
| ID | `'<moduleId>'` | `'githubEntityProvider'` |
| ID | `'<module-id>'` | `'github-entity-provider'` |
Example:
```ts
export const catalogModuleGithubEntityProvider = createBackendModule({
pluginId: 'catalog',
moduleId: 'githubEntityProvider',
moduleId: 'github-entity-provider',
...
})
```
@@ -297,7 +297,7 @@ import { microsoftGraphOrgEntityProviderTransformExtensionPoint } from '@backsta
backend.add(
createBackendModule({
pluginId: 'catalog',
moduleId: 'microsoftGraphExtensions',
moduleId: 'microsoft-graph-extensions',
register(env) {
env.registerInit({
deps: {
@@ -337,7 +337,7 @@ import { createBackendModule } from '@backstage/backend-plugin-api';
/* highlight-add-start */
const catalogModuleCustomExtensions = createBackendModule({
pluginId: 'catalog', // name of the plugin that the module is targeting
moduleId: 'customExtensions',
moduleId: 'custom-extensions',
register(env) {
env.registerInit({
deps: {
@@ -406,7 +406,7 @@ import { createBackendModule } from '@backstage/backend-plugin-api';
/* highlight-add-start */
const eventsModuleCustomExtensions = createBackendModule({
pluginId: 'events', // name of the plugin that the module is targeting
moduleId: 'customExtensions',
moduleId: 'custom-extensions',
register(env) {
env.registerInit({
deps: {
@@ -471,7 +471,7 @@ import { createBackendModule } from '@backstage/backend-plugin-api';
/* highlight-add-start */
const scaffolderModuleCustomExtensions = createBackendModule({
pluginId: 'scaffolder', // name of the plugin that the module is targeting
moduleId: 'customExtensions',
moduleId: 'custom-extensions',
register(env) {
env.registerInit({
deps: {
@@ -104,8 +104,8 @@ import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'
import { MyCustomProcessor } from './MyCustomProcessor';
export const catalogModuleExampleCustomProcessor = createBackendModule({
moduleId: 'exampleCustomProcessor',
pluginId: 'catalog',
moduleId: 'example-custom-processor',
register(env) {
env.registerInit({
deps: {
@@ -196,7 +196,7 @@ import { GoogleContainerEngineSupplier } from './GoogleContainerEngineSupplier';
export default createBackendModule({
pluginId: 'kubernetes',
moduleId: 'gke.supplier',
moduleId: 'gke-supplier',
register(env) {
env.registerInit({
deps: {
+2 -2
View File
@@ -31,8 +31,8 @@ with a `Bearer` token, which should then be the Backstage token returned by the
These are the endpoints that deal with reading of entities directly. What it
exposes are final entities - i.e. the output of all processing and the stitching
process, not the raw originally ingested entity data. See [The Life of an
Entity](life-of-an-entity.md) for more details about this process and
process, not the raw originally ingested entity data. See
[The Life of an Entity](./life-of-an-entity.md) for more details about this process and
distinction.
### `GET /entities`
+3
View File
@@ -91,6 +91,9 @@ Options:
--docker-option <DOCKER_OPTION...> Extra options to pass to the docker run command, e.g. "--add-host=internal.host:192.168.11.12"
(can be added multiple times).
--no-docker Do not use Docker, use MkDocs executable in current user environment.
--mkdocs-parameter-clean Pass "--clean" parameter to mkdocs server running in containerized environment.
--mkdocs-parameter-dirtyreload Pass "--dirtyreload" parameter to mkdocs server running in containerized environment.
--mkdocs-parameter-strict Pass "--strict" parameter to mkdocs server running in containerized environment.
--mkdocs-port <PORT> Port for MkDocs server to use (default: "8000")
--preview-app-bundle-path <PATH_TO_BUNDLE> Preview documentation using a web app other than the included one.
--preview-app-port <PORT> Port where the preview will be served.
+4
View File
@@ -484,3 +484,7 @@ You can see more ways to use this in the [Storybook Sidebar examples](https://ba
In addition to a custom theme, a custom logo, you can also customize the
homepage of your app. Read the full guide on the [next page](homepage.md).
## Migrating to Material UI v5
We now support Material UI v5 in Backstage. Check out our [migration guide](../tutorials/migrate-to-mui5.md) to get started.
+5
View File
@@ -290,6 +290,11 @@ otherwise something went terribly wrong.
## Create a new component using a software template
> Note: if you're running Backstage with Node 20 or later, you'll need to pass the flag `--no-node-snapshot` to Node in order to
> use the templates feature.
> One way to do this is to specify the `NODE_OPTIONS` environment variable before starting Backstage:
> `export NODE_OPTIONS=--no-node-snapshot`
- Go to `create` and choose to create a website with the `Example Node.js Template`
- Type in a name, let's use `tutorial` and click `Next Step`
@@ -15,7 +15,7 @@ The following steps assume that you have
to it.
We are using the
[CircleCI](https://github.com/backstage/backstage/blob/master/plugins/circleci/README.md)
[CircleCI](https://github.com/CircleCI-Public/backstage-plugin/tree/main/plugins/circleci)
plugin in this example, which is designed to show CI/CD pipeline information attached
to an entity in the software catalog.
@@ -23,7 +23,7 @@ to an entity in the software catalog.
```bash
# From your Backstage root directory
yarn add --cwd packages/app @backstage/plugin-circleci
yarn add --cwd packages/app @circleci/backstage-plugin
```
Note the plugin is added to the `app` package, rather than the root
@@ -38,7 +38,7 @@ to an entity in the software catalog.
import {
EntityCircleCIContent,
isCircleCIAvailable,
} from '@backstage/plugin-circleci';
} from '@circleci/backstage-plugin';
/* highlight-add-end */
const cicdContent = (
+2 -3
View File
@@ -57,6 +57,7 @@ In your `launch.json`, add a new entry with the following,
```jsonc
{
"name": "Start Backend",
"type": "node",
"request": "launch",
"args": [
"package",
@@ -67,8 +68,6 @@ In your `launch.json`, add a new entry with the following,
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
"console": "integratedTerminal"
},
```
You may notice that the normal logs mentioned above do not get logged, this is an issue with the logging library we're using, `winston`, and is not easily solved. See [this thread](https://github.com/winstonjs/winston/issues/1544) for more information.
+25
View File
@@ -0,0 +1,25 @@
## How to generate a client with `repo-tools schema openapi generate-client`?
### Prerequisites
1. Add your plugin ID as the last `servers` item, like this,
```yaml
servers:
# first value, used for OpenAPI router validation.
- url: /
# final value, pluginId.
- url: catalog
```
2. Find or create a new plugin to house your new generated client. Currently, we do not support generating an entirely new plugin and instead just generate client files.
### Generating your client
1. Run `yarn backstage-repo-tools schema openapi generate-client --input-spec <file> --output-directory <directory>`. This will create a new folder in `<directory>/src/generated` to house the generated content.
2. You should use the generated files as follows,
- `apis/DefaultApi.client.ts` - this is the client that you should use. It has types for all of the various operations on your API.
- `models/*` - These are the types generated from your OpenAPI file, ideally you should not need to use these directly and can instead use the inferred types from `apis/DefaultApi.client.ts`.
- everything else is directory specific and shouldn't be touched.
+12 -1
View File
@@ -21,7 +21,18 @@ description: A brief description of the plugin. # Max 170 characters
documentation: # A link to your documentation E.g. Your github README
iconUrl: # Used as the src attribute for your logo.
# You can provide an external url or add your logo under static/img and provide a path
# relative to static/ e.g. img/my-logo.png
# relative to static/ e.g. /img/my-logo.png
npmPackageName: # Your npm package name E.g. '@backstage/plugin-<etc>' quotes are required
addedDate: # The date plugin added to directory E.g. '2022-10-01' quotes are required
```
## Submission Tips
Here are a few tips to help speed up the review process when you submit your plugin:
- For any icon that you use make sure you have the proper rights to use it.
- Make sure that your package had been published on the NPM registry and that it's public.
- Make sure your package on NPM has a link back to your code repo, this helps provide confidence that it's the right package.
- Where possible, please use an [NPM scope](https://docs.npmjs.com/about-scopes) that matches either your Organization name or user name, this provides trust in the plugin
- If your plugin has both a frontend and backend link the documentation to the frontend package but make sure it mentioned needing to install the backend package.
- Where possible include a screenshot of the features in you plugin documentation, it really does help when deciding to use a plugin.
+11 -6
View File
@@ -10,7 +10,7 @@ The Backstage core function provides internationalization for plugins
## For a plugin developer
When you are creating your plugin, you have the possibility to use `createTranslationRef` to define all messages for your plugin. For example
When you are creating your plugin, you have the possibility to use `createTranslationRef` to define all messages for your plugin. For example:
```ts
import { createTranslationRef } from '@backstage/core-plugin-api/alpha';
@@ -19,8 +19,13 @@ import { createTranslationRef } from '@backstage/core-plugin-api/alpha';
export const myPluginTranslationRef = createTranslationRef({
id: 'plugin.my-plugin',
messages: {
index_page_title: 'All your components',
create_component_button_label: 'Create new component',
indexPage: {
title: 'All your components',
createButtonTitle: 'Create new component',
},
entityPage: {
notFound: 'Entity not found',
},
},
});
```
@@ -33,9 +38,9 @@ import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
const { t } = useTranslationRef(myPluginTranslationRef);
return (
<PageHeader title={t('index_page_title')}>
<PageHeader title={t('indexPage.title')}>
<Button onClick={handleCreateComponent}>
{t('create_component_button_label')}
{t('indexPage.createButtonTitle')}
</Button>
</PageHeader>
);
@@ -53,7 +58,7 @@ In an app you can both override the default messages, as well as register transl
+ createTranslationMessages({
+ ref: myPluginTranslationRef,
+ messages: {
+ create_component_button_label: 'Create new entity',
+ 'indexPage.createButtonTitle': 'Create new entity',
+ },
+ }),
+ createTranslationResource({
+1 -1
View File
@@ -147,8 +147,8 @@ import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'
import { MyCustomProcessor } from './processor';
export const exampleCustomProcessorCatalogModule = createBackendModule({
moduleId: 'exampleCustomProcessor',
pluginId: 'catalog',
moduleId: 'example-custom-processor',
register(env) {
env.registerInit({
deps: {
File diff suppressed because it is too large Load Diff
+65
View File
@@ -0,0 +1,65 @@
---
id: migrate-to-mui5
title: Migrating from Material UI v4 to v5
description: Additional resources for the Material UI v5 migration guide specifically for Backstage
---
Backstage supports developing new plugins or components using Material UI v5. At the same time, large parts of the application as well as existing plugins will still be using Material UI v4. To support Material UI v4 and v5 at the same time, we have introduced a new concept called the `UnifiedTheme`. The goal of the `UnifiedTheme` is to allow gradual migration by running both versions in parallel, applying theme options similarly & supporting potential future versions of Material UI.
By default, the `UnifiedThemeProvider` is already used. If you add a custom theme in your `createApp` function, you would need to replace the Material UI `ThemeProvider` with the `UnifiedThemeProvider`:
```diff ts
+ import import {
+ UnifiedThemeProvider,
+ themes as builtinThemes,
+ } from '@backstage/theme';
const app = createApp({
// ...
themes: [
{
// ...
provider: ({ children }) => (
- <ThemeProvider theme={lightTheme}>.
- <CssBaseline>{children}</CssBaseline>.
- </ThemeProvider
+ <UnifiedThemeProvider theme={builtinThemes.light} children={children} />
),
}
]
});
```
Before making specific changes to your Backstage instance, it might be helpful to take a look at the [Migration Guide provided by Material UI](https://mui.com/material-ui/migration/migration-v4/) first. It breaks down the differences between v4 and v5, and will make it easier to understand the impact on your Backstage instance & plugins.
It is worth noting that we are still using `@mui/styles` & `jss`. You may stumble upon documentation for migrating to `emotion` when using `makeStyles` or `withStyles`. It is not necessary to switch to `emotion`.
Important to keep in mind is that Material UI v5 is meant to be used with React Version 17 or higher. This means if you intend to use the Material UI v5 components in your plugins, you have to enforce React Version to be at least 17 for these plugins:
```json
...
"peerDependencies": {
"react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0",
"react-router-dom": "6.0.0-beta.0 || ^6.3.0"
},
...
```
To comply with Material UI recommendations, we are enforcing a new linting rule that favors standard imports over named imports and also restricts 3rd-level imports as they are considered private ([Guide: Minimizing Bundle Size](https://mui.com/material-ui/guides/minimizing-bundle-size)).
There are `core-components` as well as components exported from Backstage `*-react` plugins written in Material UI v4, which expect Material UI components as props. In these cases you will still be forced to use Material UI v4.
For current known issues with the Material UI v5 migration, follow our [Milestone on GitHub](https://github.com/backstage/backstage/milestone/40). Please open a new issue if you run into different problems.
### Plugins
To migrate your plugin to Material UI v5, you can build on the resources available.
1. Manually fix the imports from named to default imports to match the new [linting rules for minimizing bundle size](https://mui.com/material-ui/guides/minimizing-bundle-size).
2. Run the migration `codemod` for the path of the specific plugin: `npx @mui/codemod v5.0.0/preset-safe plugins/<path>`.
3. Take a look at possible `TODO:` items the `codemod` could not fix.
4. Remove types & methods from `@backstage/theme` which are marked as `@deprecated`.
5. Ensure you are using `"react": "^17.0.0"` (or newer) as a peer dependency
You can follow the [migration of the GraphiQL plugin](https://github.com/backstage/backstage/pull/17696) as an example of a plugin migration.