Skip to content

Commit 8453bd9

Browse files
committed
incorporated review suggestions
1 parent 1661454 commit 8453bd9

File tree

4 files changed

+146
-39
lines changed

4 files changed

+146
-39
lines changed

modules/dynamic-plugins/proc-export-third-party-plugins-rhdh.adoc

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,26 @@
33

44
To use plugins in {product}, the plugins must be exported as derived dynamic plugin package. These packages contain the plugin code and dependencies, ready for dynamic plugin integration into {product-short}.
55

6-
The third-party plugins include:
7-
86
Backend plugins::
97
+
108
--
11-
To ensure compatibility with the dynamic plugin support and enable their use as dynamic plugins, existing backend plugins must be compatible with the plugin instance. Additionally, these plugins must be rebuilt using a dedicated CLI command.
9+
To ensure compatibility with the dynamic plugin support and enable their use as dynamic plugins, existing backend plugins must be compatible with the new backend system. Additionally, these plugins must be rebuilt using a dedicated CLI command.
10+
11+
The new backend system entry point (created using `createBackendPlugin()` or `createBackendModule()`) must be exported as the default export from either the main package or an `alpha` package (if the plugin instance support is still provided using `alpha` APIs). This doesn't add any additional requirement on top of the standard plugin development guidelines of the plugin instance.
1212

13-
The plugin instance is created using `createBackendPlugin()` or `createBackendModule()`. You must export the plugin instance as the default export from either the main package or an `alpha` package (if the plugin instance support is still provided using `alpha` APIs). This doesn't add any additional requirement on top of the standard plugin development guidelines of the plugin instance.
13+
The dynamic export mechanism identifies private dependencies and sets the `bundleDependencies` field in the `package.json` file. This export mechanism ensures that the dynamic plugin package is published as a self-contained package, with its private dependencies bundled in a private `node_modules` folder.
1414

1515
Certain plugin dependencies require specific handling in the derived packages, such as:
1616

1717
* *Shared dependencies* are provided by the {product-very-short} application and listed as `peerDependencies` in `package.json` file, not bundled in the dynamic plugin package. For example, by default, all `@backstage` scoped packages are shared.
1818
+
19-
You can use the `--shared-package` flag to specify shared dependencies. To treat a `@backstage` package as private, use the negation prefix (`!`).
19+
You can use the `--shared-package` flag to specify shared dependencies, that are expected to be provided by {product} application and not bundled in the dynamic plugin package.
20+
+
21+
To treat a `@backstage` package as private, use the negation prefix (`!`). For example, when a plugin depends on the package in `@backstage` that is not provided by the {product} application.
2022

2123
* *Embedded dependencies* are bundled into the dynamic plugin package with their dependencies hoisted to the top level. By default, packages with `-node` or `-common` suffixes are embedded.
2224
+
23-
You can use the `--embed-package` flag to specify additional embedded packages, including those in the same repository that do not follow the default naming convention.
25+
You can use the `--embed-package` flag to specify additional embedded packages. For example, packages from the same workspace that do not follow the default naming convention.
2426

2527
The following is an example of exporting a dynamic plugin with shared and embedded packages:
2628

@@ -99,7 +101,6 @@ export const DynamicEntityTechdocsContent = {
99101
* The `@janus-idp/cli` package is installed. Use the latest version (`@latest` tag) for compatibility with the most recent features and fixes.
100102
* The third-party plugin must have a valid package.json file in its root directory, containing all required metadata and dependencies.
101103
* Node.js and NPM is installed and configured.
102-
* You have access to a private NPM registry for publishing and distributing the exported plugin package.
103104
* The third-party plugin is compatible with your {product} version. For more information, see link:https://github.com/janus-idp/backstage-showcase/blob/main/docs/dynamic-plugins/versions.md[Version compatibility matrix].
104105

105106
.Procedure
@@ -113,4 +114,11 @@ npx @janus-idp/cli@latest package export-dynamic-plugin
113114

114115
Ensure that you execute the previous command in the root directory of the plugin's JavaScript package (containing `package.json` file).
115116

117+
The resulting derived package will be located in the `dist-dynamic` subfolder. The exported package name consists of the original plugin name with `-dynamic` appended.
118+
119+
[WARNING]
120+
====
121+
The derived dynamic plugin JavaScript packages must not be published to the public NPM registry. For more appropriate packaging options, see xref:proc-package-third-party-dynamic-plugin_{context}[]. If you must publish to the NPM registry, use a private registry.
122+
====
123+
116124

modules/dynamic-plugins/proc-install-third-party-plugins-rhdh.adoc

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@
33

44
You can install a third-party plugins in {product} without rebuilding the {product-very-short} application.
55

6+
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_{context}[] and xref:con-install-dynamic-plugin-helm_{context}[].
7+
8+
Plugins are defined in the `plugins` array within the `dynamic-plugin-config.yaml` file. Each plugin is represented as an object with the following properties:
9+
10+
* `package`: The plugin's package definition, which can be an OCI image, a TGZ file, a JavaScript package, or a directory path
11+
* `disabled`: A boolean value indicating whether the plugin is enabled or disabled.
12+
* `integrity`: The integrity hash of the package, required for TGZ file and JavaScript packages.
13+
* `pluginConfig`: The plugin's configuration. For backend plugins, this is optional; for frontend plugins, it is required. The `pluginConfig` is a fragment of the `app-config.yaml` file, and any added properties are merged with the {product-very-short} `app-config.yaml` file.
14+
615
.Prerequisites
716
* The third-party plugin is packaged as a dynamic plugin in one of the following formats:
817
** OCI image
@@ -20,11 +29,11 @@ You can also load dynamic plugins from a plain directory, though this is intende
2029
Load a plugin packaged as an OCI image::
2130
+
2231
--
23-
. Define the plugin with the `oci://` prefix in the following format in `dynamic-plugins.default.yaml` file:
32+
. Define the plugin with the `oci://` prefix in the following format in `dynamic-plugins.yaml` file:
2433
+
2534
`oci://<image-name>:<tag>!<plugin-name>`
2635
+
27-
.Example configuration in `dynamic-plugins.default.yaml` file
36+
.Example configuration in `dynamic-plugins.yaml` file
2837
[source,yaml]
2938
----
3039
plugins:
@@ -34,9 +43,9 @@ plugins:
3443

3544
. Configure authentication for private registries by setting the `REGISTRY_AUTH_FILE` environment variable to the path of the registry configuration file. For example, `~/.config/containers/auth.json` or `~/.docker/config.json`.
3645

37-
. To perform an integrity check, use the image digest in place of the tag in `dynamic-plugins.default.yaml` file as follows:
46+
. To perform an integrity check, use the image digest in place of the tag in `dynamic-plugins.yaml` file as follows:
3847
+
39-
.Example configuration in `dynamic-plugins.default.yaml` file
48+
.Example configuration in `dynamic-plugins.yaml` file
4049
[source,yaml]
4150
----
4251
plugins:
@@ -50,9 +59,9 @@ plugins:
5059
Load a plugin packaged as a TGZ file::
5160
+
5261
--
53-
. Specify the archive URL and its integrity hash in the `dynamic-plugins.default.yaml` file using the following example:
62+
. Specify the archive URL and its integrity hash in the `dynamic-plugins.yaml` file using the following example:
5463
+
55-
.Example configuration in `dynamic-plugins.default.yaml` file
64+
.Example configuration in `dynamic-plugins.yaml` file
5665
[source,yaml]
5766
----
5867
plugins:
@@ -74,9 +83,9 @@ Load a plugin packaged as a JavaScript package::
7483
npm view --registry <registry-url> <npm package>@<version> dist.integrity
7584
----
7685

77-
. Specify the package name, version, and its integrity hash in the `dynamic-plugins.default.yaml` file as follows:
86+
. Specify the package name, version, and its integrity hash in the `dynamic-plugins.yaml` file as follows:
7887
+
79-
.Example configuration in `dynamic-plugins.default.yaml` file
88+
.Example configuration in `dynamic-plugins.yaml` file
8089
[source,yaml]
8190
----
8291
plugins:

modules/dynamic-plugins/proc-package-third-party-dynamic-plugin.adoc

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ After exporting a third-party plugin, you can package the derived package into o
1414
Exported dynamic plugin packages must only be published to private NPM registries.
1515
====
1616

17-
[#convert-to-oci-image]
18-
== Converting a dynamic plugin package to an OCI image
17+
[#create-oci-image]
18+
== Creating an OCI image with dynamic packages
1919

2020
.Prerequisites
2121
* You have installed `podman` or `docker`.
2222
* You have exported a third-party dynamic plugin package. For more information, see xref:proc-export-third-party-plugins-rhdh_{context}[].
2323

2424
.Procedure
25-
. Navigate to the exported plugin's root directory (not the `dist-dynamic` directory).
25+
. Navigate to the plugin's root directory (not the `dist-dynamic` directory).
2626
. Run the following command to package the plugin into an OCI image:
2727
+
2828
--
@@ -49,11 +49,11 @@ podman push quay.io/example/image:v0.0.1
4949
docker push quay.io/example/image:v0.0.1
5050
----
5151

52-
The output of the previous commands provides the plugin's path for use in the `dynamic-plugin-config.yaml` file.
52+
The output of the `package-dynamic-plugins` command provides the plugin's path for use in the `dynamic-plugin-config.yaml` file.
5353
--
5454

55-
[#convert-to-tgz]
56-
== Converting a dynamic plugin package to a TGZ file
55+
[#create-tgz-file]
56+
== Creating a TGZ file with dynamic packages
5757

5858
.Prerequisites
5959
* You have exported a third-party dynamic plugin package. For more information, see xref:proc-export-third-party-plugins-rhdh_{context}[].
@@ -68,16 +68,15 @@ The output of the previous commands provides the plugin's path for use in the `d
6868
----
6969
npm pack
7070
----
71-
--
72-
. To retrieve the integrity hash of the archive, run the following command:
73-
+
74-
--
75-
.Example command to retrieve the integrity hash of a `tgz` archive
71+
You can obtain the integrity hash from the output of the `npm pack` command by using the `--json` flag as follows:
72+
73+
.Example command to obtain the integrity hash of a `tgz` archive
7674
[source,bash]
7775
----
78-
npm pack --json | jq -r '.[0].integrity'
76+
npm pack --json | head -n 10
7977
----
8078
--
79+
8180
. Host the archive on a web server accessible to your {product-very-short} instance, and reference its URL in the `dynamic-plugin-config.yaml` file as follows:
8281
+
8382
--
@@ -97,10 +96,11 @@ plugins:
9796
----
9897
npm pack --pack-destination ~/test/dynamic-plugins-root/
9998
----
100-
--
101-
. Build and deploy an HTTP server in {ocp-short}:
102-
+
103-
--
99+
100+
[TIP]
101+
====
102+
To create a plugin registry using HTTP server on {ocp-short}, run the following commands:
103+
104104
.Example commands to build and deploy an HTTP server in {ocp-short}
105105
[source,bash]
106106
----
@@ -109,7 +109,9 @@ oc new-build httpd --name=plugin-registry --binary
109109
oc start-build plugin-registry --from-dir=dynamic-plugins-root --wait
110110
oc new-app --image-stream=plugin-registry
111111
----
112+
====
112113
--
114+
113115
. Configure your {product-very-short} to use plugins from the HTTP server by editing the `dynamic-plugin-config.yaml` file:
114116
+
115117
--
@@ -121,8 +123,13 @@ plugins:
121123
----
122124
--
123125

124-
[#convert-to-jsp]
125-
== Converting a dynamic plugin to a JavaScript package
126+
[#create-js-package]
127+
== Creating a JavaScript package with dynamic packages
128+
129+
[WARNING]
130+
====
131+
The derived dynamic plugin JavaScript packages must not be published to the public NPM registry. If you must publish to the NPM registry, use a private registry.
132+
====
126133

127134
.Prerequisites
128135
* You have exported a third-party dynamic plugin package. For more information, see xref:proc-export-third-party-plugins-rhdh_{context}[].

modules/dynamic-plugins/ref-example-third-party-plugin-installation.adoc

Lines changed: 89 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This section provides step-by-step instructions for integrating the link:https:/
66
. *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:
77
+
88
--
9-
.Example commands to obtain the third-party plugin source code
9+
.Obtain the third-party plugin source code
1010
[source,bash]
1111
----
1212
$ git clone https://github.com/backstage/community-plugins
@@ -18,44 +18,127 @@ $ yarn install
1818
. *Export backend and front-end plugins*: Run the following commands to build the backend plugin, adjust package dependencies for dynamic loading, and generate self-contained configuration schema:
1919
+
2020
--
21-
.Example commands to export a backend plugin
21+
.Export a backend plugin
2222
[source,bash]
2323
----
2424
$ cd todo-backend
2525
$ npx @janus-idp/cli@latest package export-dynamic-plugin
2626
----
2727

28+
.Output of exporting a backend plugin commands
29+
[source,bash]
30+
----
31+
Building main package
32+
executing yarn build ✔
33+
Packing main package to dist-dynamic/package.json
34+
Customizing main package in dist-dynamic/package.json for dynamic loading
35+
moving @backstage/backend-common to peerDependencies
36+
moving @backstage/backend-openapi-utils to peerDependencies
37+
moving @backstage/backend-plugin-api to peerDependencies
38+
moving @backstage/catalog-client to peerDependencies
39+
moving @backstage/catalog-model to peerDependencies
40+
moving @backstage/config to peerDependencies
41+
moving @backstage/errors to peerDependencies
42+
moving @backstage/integration to peerDependencies
43+
moving @backstage/plugin-catalog-node to peerDependencies
44+
Installing private dependencies of the main package
45+
executing yarn install --no-immutable ✔
46+
Validating private dependencies
47+
Validating plugin entry points
48+
Saving self-contained config schema in /Users/user/Code/community-plugins/workspaces/todo/plugins/todo-backend/dist-dynamic/dist/configSchema.json
49+
----
50+
2851
You can run the following commands to set default dynamic UI configurations, create front-end plugin assets, and to generate a configuration schema for a front-end plugin:
2952

30-
.Example command to export a front-end plugin
53+
.Export a front-end plugin
3154
[source,bash]
3255
----
3356
$ cd ../todo
3457
$ npx @janus-idp/cli@latest package export-dynamic-plugin
3558
----
59+
60+
.Output of exporting a front-end plugin commands
61+
[source,bash]
62+
----
63+
No scalprum config. Using default dynamic UI configuration:
64+
{
65+
"name": "backstage-community.plugin-todo",
66+
"exposedModules": {
67+
"PluginRoot": "./src/index.ts"
68+
}
69+
}
70+
If you wish to change the defaults, add "scalprum" configuration to plugin "package.json" file, or use the '--scalprum-config' option to specify an external config.
71+
Packing main package to dist-dynamic/package.json
72+
Customizing main package in dist-dynamic/package.json for dynamic loading
73+
Generating dynamic frontend plugin assets in /Users/user/Code/community-plugins/workspaces/todo/plugins/todo/dist-dynamic/dist-scalprum
74+
263.46 kB dist-scalprum/static/1417.d5271413.chunk.js
75+
...
76+
...
77+
...
78+
250 B dist-scalprum/static/react-syntax-highlighter_languages_highlight_plaintext.0b7d6592.chunk.js
79+
Saving self-contained config schema in /Users/user/Code/community-plugins/workspaces/todo/plugins/todo/dist-dynamic/dist-scalprum/configSchema.json
80+
----
3681
--
3782

3883
. *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:
3984
+
4085
--
41-
.Example commands to build an OCI image
86+
.Build an OCI image
4287
[source,bash]
4388
----
4489
$ cd ../..
4590
$ npx @janus-idp/cli@latest package package-dynamic-plugins --tag quay.io/user/backstage-community-plugin-todo:v0.1.1
4691
----
4792

48-
.Example command to push the OCI image to a container registry:
93+
.Output of building an OCI image commands
94+
[source,bash]
95+
----
96+
executing podman --version ✔
97+
Using existing 'dist-dynamic' directory at plugins/todo
98+
Using existing 'dist-dynamic' directory at plugins/todo-backend
99+
Copying 'plugins/todo/dist-dynamic' to '/var/folders/5c/67drc33d0018j6qgtzqpcsbw0000gn/T/package-dynamic-pluginsmcP4mU/backstage-community-plugin-todo
100+
No plugin configuration found at undefined create this file as needed if this plugin requires configuration
101+
Copying 'plugins/todo-backend/dist-dynamic' to '/var/folders/5c/67drc33d0018j6qgtzqpcsbw0000gn/T/package-dynamic-pluginsmcP4mU/backstage-community-plugin-todo-backend-dynamic
102+
No plugin configuration found at undefined create this file as needed if this plugin requires configuration
103+
Writing plugin registry metadata to '/var/folders/5c/67drc33d0018j6qgtzqpcsbw0000gn/T/package-dynamic-pluginsmcP4mU/index.json'
104+
Creating image using podman
105+
executing echo "from scratch
106+
COPY . .
107+
" | podman build --annotation com.redhat.rhdh.plugins='[{"backstage-community-plugin-todo":{"name":"@backstage-community/plugin-todo","version":"0.2.40","description":"A Backstage plugin that lets you browse TODO comments in your source code","backstage":{"role":"frontend-plugin","pluginId":"todo","pluginPackages":["@backstage-community/plugin-todo","@backstage-community/plugin-todo-backend"]},"homepage":"https://backstage.io","repository":{"type":"git","url":"https://github.com/backstage/community-plugins","directory":"workspaces/todo/plugins/todo"},"license":"Apache-2.0"}},{"backstage-community-plugin-todo-backend-dynamic":{"name":"@backstage-community/plugin-todo-backend","version":"0.3.19","description":"A Backstage backend plugin that lets you browse TODO comments in your source code","backstage":{"role":"backend-plugin","pluginId":"todo","pluginPackages":["@backstage-community/plugin-todo","@backstage-community/plugin-todo-backend"]},"homepage":"https://backstage.io","repository":{"type":"git","url":"https://github.com/backstage/community-plugins","directory":"workspaces/todo/plugins/todo-backend"},"license":"Apache-2.0"}}]' -t 'quay.io/user/backstage-community-plugin-todo:v0.1.1' -f - .
108+
109+
Successfully built image quay.io/user/backstage-community-plugin-todo:v0.1.1 with following plugins:
110+
backstage-community-plugin-todo
111+
backstage-community-plugin-todo-backend-dynamic
112+
113+
Here is an example dynamic-plugins.yaml for these plugins:
114+
115+
plugins:
116+
- package: oci://quay.io/user/backstage-community-plugin-todo:v0.1.1!backstage-community-plugin-todo
117+
disabled: false
118+
- package: oci://quay.io/user/backstage-community-plugin-todo:v0.1.1!backstage-community-plugin-todo-backend-dynamic
119+
disabled: false
120+
----
121+
122+
.Push the OCI image to a container registry:
49123
[source,bash]
50124
----
51125
$ podman push quay.io/user/backstage-community-plugin-todo:v0.1.1
52126
----
127+
128+
.Output of pushing the OCI image command
129+
[source,bash]
130+
----
131+
Getting image source signatures
132+
Copying blob sha256:86a372c456ae6a7a305cd464d194aaf03660932efd53691998ab3403f87cacb5
133+
Copying config sha256:3b7f074856ecfbba95a77fa87cfad341e8a30c7069447de8144aea0edfcb603e
134+
Writing manifest to image destination
135+
----
53136
--
54137

55138
. *Install and configure the third-party plugin*: Add the following plugin definitions to your `dynamic-plugins.yaml` file:
56139
+
57140
--
58-
.Example plugin definitions in `dynamic-plugins.yaml` file
141+
.Plugin definitions in `dynamic-plugins.yaml` file
59142
[source,yaml]
60143
----
61144
packages:

0 commit comments

Comments
 (0)