Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
:_mod-docs-content-type: ASSEMBLY

[id="assembly-install-third-party-plugins-rhdh"]
= Installing third-party plugins in {product}
= Installing {plugin-type-name} plugins in {product}
:context: assembly-install-third-party-plugins-rhdh

You can install a third-party plugins in {product} without rebuilding the {product-very-short} application.
You can install a {plugin-type-name} plugins in {product} without rebuilding the {product-very-short} application.

The location of the `dynamic-plugin-config.yaml` file depends on the deployment method. For more details, refer to xref:proc-config-dynamic-plugins-rhdh-operator_rhdh-installing-rhdh-plugins[Installing dynamic plugins with the {product} Operator] and xref:con-install-dynamic-plugin-helm_rhdh-installing-rhdh-plugins[Installing dynamic plugins using the Helm chart].

Expand All @@ -30,5 +30,5 @@ include::../modules/dynamic-plugins/proc-load-plugin-tgz-file.adoc[leveloffset=+
include::../modules/dynamic-plugins/proc-load-plugin-js-package.adoc[leveloffset=+2]

//example third-party plugin installation
include::../modules/dynamic-plugins/proc-example-third-party-plugin-installation.adoc[leveloffset=+2]
//include::../modules/dynamic-plugins/proc-example-third-party-plugin-installation.adoc[leveloffset=+2]

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?


Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
:_mod-docs-content-type: ASSEMBLY

[id="assembly-package-publish-third-party-dynamic-plugin"]
= Packaging and publishing third-party plugins as dynamic plugins
= Packaging and publishing {plugin-type-name} plugins as dynamic plugins
:context: assembly-package-publish-third-party-dynamic-plugin

After xref:proc-export-third-party-plugins-rhdh_assembly-third-party-plugins[exporting a third-party plugin], you can package the derived package into one of the following supported formats:
After xref:proc-export-third-party-plugins-rhdh_assembly-third-party-plugins[exporting a {plugin-type-name} plugin], you can package the derived package into one of the following supported formats:

* Open Container Initiative (OCI) image (recommended)
* TGZ file
Expand Down
11 changes: 8 additions & 3 deletions assemblies/dynamic-plugins/assembly-third-party-plugins.adoc
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
:_mod-docs-content-type: ASSEMBLY

[id="assembly-third-party-plugins"]
= Third-party plugins in {product}
= {plugin-type-name-uppercase} plugins in {product}
:context: assembly-third-party-plugins

You can integrate third-party dynamic plugins into {product} to enhance its functionality without modifying its source code or rebuilding it. To add these plugins, export them as derived packages.
You can integrate {plugin-type-name} dynamic plugins into {product} to enhance its functionality without modifying its source code or rebuilding it. To add these plugins, export them as derived packages.

While exporting the plugin package, you must ensure that dependencies are correctly bundled or marked as shared, depending on their relationship to the {product-short} environment.

To integrate a third-party plugin into {product-short}:
To integrate a {plugin-type-name} plugin into {product-short}:

. First, obtain the plugin's source code.
. Export the plugin as a dynamic plugin package. See xref:proc-export-third-party-plugins-rhdh_assembly-third-party-plugins[].
Expand All @@ -24,5 +24,10 @@ include::assembly-package-publish-third-party-dynamic-plugin.adoc[leveloffset=+1
//Install third-party plugin
include::assembly-install-third-party-plugins-rhdh.adoc[leveloffset=+1]

include::../modules/dynamic-plugins/proc-custom-plugin-conversion.adoc[leveloffset=+1]

include::../modules/dynamic-plugins/proc-custom-plugin-add-to-rhdh.adoc[leveloffset=+2]

include::../modules/dynamic-plugins/proc-displaying-frontend-plugin.adoc[leveloffset=+2]


Binary file added images/rhdh/custom-container-images.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/rhdh/custom-entity-view.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/rhdh/custom-extensions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/rhdh/custom-feedback-overlay.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/rhdh/custom-limitations.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions modules/dynamic-plugins/con-custom-plugin-conversion.adoc
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.

Choose a reason for hiding this comment

The 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: {}
----
2 changes: 1 addition & 1 deletion modules/dynamic-plugins/con-rhdh-plugins.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ To install or update a static plugin you must update your {product-very-short} a

To install or update a dynamic plugin, you must restart your {product-very-short} application source code after installing the plugin.

You can also import your own custom-built or third-party plugins or create new features using dynamic plugins.
You can also import your own custom-built or {plugin-type-name} plugins or create new features using dynamic plugins.


Dynamic plugins boost modularity and scalability by enabling more flexible and efficient functionality loading, significantly enhancing the developer experience and customization of your {product-very-short} instance.
Expand Down
2 changes: 1 addition & 1 deletion modules/dynamic-plugins/proc-create-plugin-js-package.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The derived dynamic plugin JavaScript packages must not be published to the publ
====

.Prerequisites
* You have exported a third-party dynamic plugin package. For more information, see xref:proc-export-third-party-plugins-rhdh_assembly-third-party-plugins[].
* You have exported a {plugin-type-name} dynamic plugin package. For more information, see xref:proc-export-third-party-plugins-rhdh_assembly-third-party-plugins[].

.Procedure
. Navigate to the `dist-dynamic` directory.
Expand Down
4 changes: 2 additions & 2 deletions modules/dynamic-plugins/proc-create-plugin-oci-image.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@

.Prerequisites
* You have installed `podman` or `docker`.
* You have exported a third-party dynamic plugin package. For more information, see xref:proc-export-third-party-plugins-rhdh_assembly-third-party-plugins[].
* You have exported a {plugin-type-name} dynamic plugin package. For more information, see xref:proc-export-third-party-plugins-rhdh_assembly-third-party-plugins[].

.Procedure
. Navigate to the plugin's root directory (not the `dist-dynamic` directory).
. Run the following command to package the plugin into an OCI image:
+
--
.Example command to package an exported third-party plugin
.Example command to package an exported {plugin-type-name} plugin
[source,terminal]
----
npx @red-hat-developer-hub/cli@latest plugin package --tag quay.io/example/image:v0.0.1
Expand Down
2 changes: 1 addition & 1 deletion modules/dynamic-plugins/proc-create-plugin-tgz-file.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
= Creating a TGZ file with dynamic packages

.Prerequisites
* You have exported a third-party dynamic plugin package. For more information, see xref:proc-export-third-party-plugins-rhdh_assembly-third-party-plugins[].
* You have exported a {plugin-type-name} dynamic plugin package. For more information, see xref:proc-export-third-party-plugins-rhdh_assembly-third-party-plugins[].

.Procedure
. Navigate to the `dist-dynamic` directory.
Expand Down
22 changes: 22 additions & 0 deletions modules/dynamic-plugins/proc-custom-plugin-add-to-rhdh.adoc
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:

Choose a reason for hiding this comment

The 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

Choose a reason for hiding this comment

The 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.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest linking to pull secret guide in OCP docs or similar.

====
131 changes: 131 additions & 0 deletions modules/dynamic-plugins/proc-custom-plugin-conversion.adoc
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.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is the oc CLI used? I didn't see it

* *Container runtime:* Either podman or docker is required for packaging the plugin into an OCI image and logging into registries.

Choose a reason for hiding this comment

The 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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the git checkout command and text about versions not included for a reason?

----

. 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[]
71 changes: 71 additions & 0 deletions modules/dynamic-plugins/proc-displaying-frontend-plugin.adoc
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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The version 0.5.0 will be incorrect without the git checkout I referred to in another comment

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.
====
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
:_mod-docs-content-type: PROCEDURE

[id="ref-example-third-party-plugin-installation_{context}"]
= Example of installing a third-party plugin in {product}
= Example of installing a {plugin-type-name} plugin in {product}

This section describes the process for integrating the Todo plugin into your {product-short}.

.Procedure
. *Obtain the third-party plugin source code*: Clone the plugins repository and navigate to the link:https://github.com/backstage/community-plugins/tree/main/workspaces/todo/plugins[Todo plugin] directory:
. *Obtain the {plugin-type-name} plugin source code*: Clone the plugins repository and navigate to the link:https://github.com/backstage/community-plugins/tree/main/workspaces/todo/plugins[Todo plugin] directory:
+
--
.Obtain the third-party plugin source code
.Obtain the {plugin-type-name} plugin source code
[source,terminal]
----
$ git clone https://github.com/backstage/community-plugins
Expand Down Expand Up @@ -83,7 +83,7 @@ Saving self-contained config schema in /Users/user/Code/community-plugins/worksp
----
--

. *Package and publish a third-party plugin*: Run the following commands to navigate to the workspace directory and package the dynamic plugin to build the OCI image:
. *Package and publish a {plugin-type-name} plugin*: Run the following commands to navigate to the workspace directory and package the dynamic plugin to build the OCI image:
+
--
.Build an OCI image
Expand Down Expand Up @@ -138,7 +138,7 @@ Writing manifest to image destination
----
--

. *Install and configure the third-party plugin*: Add the following plugin definitions to your `dynamic-plugins.yaml` file:
. *Install and configure the {plugin-type-name} plugin*: Add the following plugin definitions to your `dynamic-plugins.yaml` file:
+
--
.Plugin definitions in `dynamic-plugins.yaml` file
Expand Down
Loading