-
Notifications
You must be signed in to change notification settings - Fork 55
RHIDP-8634-2-1-8 - Improve the documentation to help developers convert plugins to dynamic plugins CP #1514
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| :_mod-docs-content-type: CONCEPT | ||
|
|
||
| [id="con-converting-custom-plugins"] | ||
| = Dynamic Plugins | ||
| {product} implements a dynamic plugin system. You can install, configure, and load plugins at runtime without changing or rebuilding the application. You only need a restart. You can load these plugins from NPM, tarballs, or OCI compliant container images. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think npm should be lowercase - nodejs/nodejs.org#6917 |
||
|
|
||
| With dynamic plugins, instead of modifying the {backstage} application itself, you create a `dynamic-plugins.yaml` file to specify the plugins that {product} will install and enable at startup. For example, the following configuration loads a plugin named `plugin-name`, which is stored in a `Quay.io` container image at `quay.io/account-name/image-name`: | ||
|
|
||
| .`dynamic-plugins.yaml` fragment | ||
| [source,yaml] | ||
| ---- | ||
| plugins: | ||
| - package: oci://quay.io/account-name/image-name:tag!plugin-name | ||
| disabled: false | ||
| pluginConfig: {} | ||
| ---- | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| :_mod-docs-content-type: PROCEDURE | ||
|
|
||
| [id="proc-adding-a-custom-dynamic-plugin"] | ||
| = Adding a custom dynamic plugin to {product} | ||
|
|
||
| .Procedure | ||
| . To add your custom dynamic plugins to {product}. you must update the `dynamic-plugins.yaml` file by using the following configuration that is generated from the `npx @red-hat-developer-hub/cli@latest plugin package` command: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this official doc might want to link to the specific instructions for "adding a plugin for helm installs" and the same for operators. Maybe I should add to the blog too There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just in case someone is wondering where this file is, since it's not super clear. It's a file, but stored in a ConfigMap |
||
| + | ||
| [source,yaml] | ||
| ---- | ||
| plugins: | ||
| - package: oci://quay.io/_<user_name>_/entity-feedback-plugin:0.5.0!backstage-community-plugin-entity-feedback | ||
| disabled: false | ||
| - package: oci://quay.io/_<user_name>_/entity-feedback-plugin-backend:0.6.0!backstage-community-plugin-entity-feedback-backend | ||
| disabled: false | ||
| ---- | ||
|
|
||
| [NOTE] | ||
| ==== | ||
| Ensure that your container images are publicly accessible, or that you have configured a pull secret in your environment. A pull secret provides {product} with credentials to authenticate pulling your plugin container images from a container registry. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggest linking to pull secret guide in OCP docs or similar. |
||
| ==== | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,131 @@ | ||
| :_mod-docs-content-type: PROCEDURE | ||
|
|
||
| [id="proc-example-custom-plugin-installation_{context}"] | ||
| = Example of installing a custom plugin in {product} | ||
| This example demonstrates how to package and install dynamic plugins using the {product-custom-resource-type} *Entity Feedback* community plugin that is not included in {product} pre-installed dynamic plugins. | ||
|
|
||
| .Limitations | ||
| * You need to ensure that your custom plugin is built with a compatible version of {product-custom-resource-type}. In {product-short}, click *Settings*. Your custom plugin must be compatible with the *Backstage Version* (or the closest previous version) that is displayed in the *Metadata* section of {product}. | ||
| + | ||
| For example, if you view the link:https://github.com/backstage/community-plugins/commits/main/workspaces/entity-feedback/backstage.json[history] of the `backstage.json` file for the *Entity Feedback* plugin, the `1fc87de` commit is closest previous version to {product-custom-resource-type} version of 1.39.1. | ||
| + | ||
| .`backstage.json` file history in Github | ||
| image::rhdh/custom-limitations.png[] | ||
|
|
||
|
|
||
| .Prerequisites | ||
| * Your local environment meets the following requirements: | ||
|
|
||
| * *Node.js:* Version 22.x | ||
| * *Yarn:* Version 4.x | ||
| * *git CLI* | ||
| * *jq CLI:* Command-line JSON processor | ||
| * *OpenShift CLI (oc):* The client for interacting with your OpenShift cluster. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where is the |
||
| * *Container runtime:* Either podman or docker is required for packaging the plugin into an OCI image and logging into registries. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think container runtime is the correct term for this. "Container tooling" might be better |
||
| * *Container registry access:* Access to an OCI-compliant container registry (such as the internal OpenShift registry or a public registry like Quay.io). | ||
| //* *Command-line tool to build and package plugins:* The `@red-hat-developer-hub/cli` package. For compatibility with the most recent features and fixes, use the latest version (`@latest` tag) version of the `@red-hat-developer-hub/cli` package. | ||
|
|
||
| .Procedure | ||
| . Clone the source code for the *Entity Feedback* plugin, as follows: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| git clone https://github.com/backstage/community-plugins.git | ||
| cd community-plugins | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is the |
||
| ---- | ||
|
|
||
| . Prepare your environment to build the plugin by enabling Yarn for your Node.js installation, as follows: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| corepack enable yarn | ||
| ---- | ||
|
|
||
| . Install the dependencies, compile the code, and build the plugins, as follows: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| cd workspaces/entity-feedback | ||
| yarn install | ||
| yarn tsc | ||
| yarn build:all | ||
| ---- | ||
| + | ||
| [NOTE] | ||
| ==== | ||
| At this point, with {product-custom-resource-type}, you need to publish the built plugins to a NPM or NPM-compatible registry. However, as you are building this plugin to support it being loaded dynamically by {product}, you do not need to publish the plugin to a NPM registry. Instead, you can package the plugin for dynamic loading and publish it as a container image on `Quay.io` or your preferred container registry. | ||
| ==== | ||
|
|
||
| . Prepare the *Entity Feedback* frontend plugin by using the {product} CLI. The following command uses the plugin files in the `dist` folder that was generated by the `yarn build:all` command, and creates a new `dist-scalprum` folder that contains the necessary configuration and source files to enable dynamic loading: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| cd plugins/entity-feedback | ||
| npx @red-hat-developer-hub/cli@latest plugin export | ||
| ---- | ||
| + | ||
| When this command packages a frontend plugin, it uses a default Scalprum configuration if one is not found. The Scalprum configuration is used to specify the plugin entry point and exports, and then to build a `dist-scalprum` folder that contains the dynamic plugin. The default Scalprum configuration is shown below, however a `scalprum` key can be added to the `package.json` file used by your plugin to set custom values, if necessary: | ||
| + | ||
| [source,json] | ||
| ---- | ||
| { | ||
| "name": "backstage-community.plugin-entity-feedback", | ||
| "exposedModules": { | ||
| "PluginRoot": "./src/index.ts" | ||
| } | ||
| } | ||
| ---- | ||
| + | ||
| The following `plugin-manifest.json` file, which {product} uses to load the plugin, is located in the `dist-dynamic/dist-scalprum` folder: | ||
| + | ||
| [source,json] | ||
| ---- | ||
| { | ||
| "name": "backstage-community.plugin-entity-feedback", | ||
| "version": "0.6.0", | ||
| "extensions": [], | ||
| "registrationMethod": "callback", | ||
| "baseURL": "auto", | ||
| "loadScripts": [ | ||
| "backstage-community.plugin-entity-feedback.fd691533c03cb52c30ac.js" | ||
| ], | ||
| "buildHash": "fd691533c03cb52c30acbb5a80197c9d" | ||
| } | ||
| ---- | ||
|
|
||
| . Package the plugin into a container image and publish it to Quay.io or your preferred container registry: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| export QUAY_USER=replace-with-your-username | ||
| export PLUGIN_NAME=entity-feedback-plugin | ||
| export VERSION=$(cat package.json | jq .version -r) | ||
| npx @red-hat-developer-hub/cli@latest plugin package \ | ||
| --tag quay.io/$QUAY_USER/$PLUGIN_NAME:$VERSION | ||
| podman login quay.io | ||
| podman push quay.io/$QUAY_USER/$PLUGIN_NAME:$VERSION | ||
| ---- | ||
|
|
||
| . Repeat the same steps for the backend plugin. Scalprum is not required for backend plugins, and a `dist-dynamic` folder is generated instead of a `dist-scalprum` folder: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| cd ../entity-feedback-backend/ | ||
| npx @red-hat-developer-hub/cli@latest plugin export | ||
| export QUAY_USER=replace-with-your-username | ||
| export PLUGIN_NAME=entity-feedback-plugin-backend | ||
| export VERSION=$(cat package.json | jq .version -r) | ||
| npx @red-hat-developer-hub/cli@latest plugin package \ | ||
| --tag quay.io/$QUAY_USER/$PLUGIN_NAME:$VERSION | ||
| podman push quay.io/$QUAY_USER/$PLUGIN_NAME:$VERSION | ||
| ---- | ||
| + | ||
| Those commands result in two container images being published to your container registry. | ||
| + | ||
| .Container images published to Quay.io | ||
| image::rhdh/custom-container-images.png[] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| :_mod-docs-content-type: PROCEDURE | ||
|
|
||
| [id="proc-displaying-frontend-plugin"] | ||
| = Displaying the frontend plugin | ||
|
|
||
| .Procedure | ||
| . You need to update the `pluginConfig` section of your `dynamic-plugins.yaml` file to specify how the *Entity Feedback* should be added to the {product} UI. | ||
| + | ||
| .`dynamic-plugins.yaml` file fragment | ||
| [source,yaml] | ||
| ---- | ||
| - package: oci://quay.io/_<user_name>_/entity-feedback-plugin:0.5.0!backstage-community-plugin-entity-feedback | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The version 0.5.0 will be incorrect without the |
||
| disabled: false | ||
| pluginConfig: | ||
| dynamicPlugins: | ||
| frontend: | ||
| backstage-community.plugin-entity-feedback: | ||
| entityTabs: | ||
| - mountPoint: entity.page.feedback | ||
| path: /feedback | ||
| title: Feedback | ||
| mountPoints: | ||
| - config: | ||
| layout: | ||
| gridColumn: 1 / -1 | ||
| importName: StarredRatingButtons | ||
| mountPoint: entity.page.feedback/cards | ||
| - config: | ||
| layout: | ||
| gridColumn: 1 / -1 | ||
| importName: EntityFeedbackResponseContent | ||
| mountPoint: entity.page.feedback/cards | ||
| - config: | ||
| layout: | ||
| gridColumnEnd: | ||
| lg: span 6 | ||
| md: span 6 | ||
| xs: span 6 | ||
| importName: StarredRatingButtons | ||
| mountPoint: entity.page.overview/cards | ||
| ---- | ||
| + | ||
| where: | ||
| + | ||
| `backstage-community.plugin-entity-feedback:entityTabs`:: Enter the `entityTabs` array to define a new tab, named “Feedback” on the *Entity Overview* screen in {product}. | ||
| `frontend:mountPoints`:: This array defines the following configurations to mount React components exposed by the plugin: | ||
| + | ||
| * The `StarredRatingButtons` component is added to the new *Feedback* tab defined in entityTabs. | ||
| * Similar to the `StarredRatingButtons`, the `EntityFeedbackResponseContent` is mounted on the *Feedback* tab. | ||
| * The `StarredRatingButtons` is added to the default *Overview* tab for each entity. | ||
|
|
||
| . To complete installing the *Entity Feedback* plugins, you must redeploy your {product} instance. | ||
|
|
||
|
|
||
| .Verification | ||
| When your new instance of {product} has started, you can check that your plugins are installed and enabled by visiting the *Administration > Extensions* screen and searching for “entity” on the *Installed* tab. | ||
|
|
||
| image::rhdh/custom-extensions.png[] | ||
|
|
||
| When you click *Catalog*, you should see the new *Feedback* tab, and the *StarredRatingButtons* displayed, as follows: | ||
|
|
||
| image::rhdh/custom-entity-view.png[] | ||
|
|
||
| Selecting a low star rating prompts the user to provide feedback, as follows: | ||
|
|
||
| image::rhdh/custom-feedback-overlay.png[] | ||
|
|
||
| [NOTE] | ||
| ==== | ||
| The user provided feedback is not saved if you are logged in as the Guest user. | ||
| ==== | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commented out for a reason?