Chapter 2. Third-party plugins in Red Hat Developer Hub You can integrate third-party dynamic plugins into Red Hat Developer Hub 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 Developer Hub environment. To integrate a third-party plugin into Developer Hub: First, obtain the plugin's source code. Export the plugin as a dynamic plugin package. See Section 2.1, "Exporting third-party plugins in Red Hat Developer Hub" . Package and publish the dynamic plugin. See Section 2.2, "Packaging and publishing third-party plugins as dynamic plugins" . Install the plugin in the Developer Hub environment. See Section 2.3, "Installing third-party plugins in Red Hat Developer Hub" . 2.1. Exporting third-party plugins in Red Hat Developer Hub To use plugins in Red Hat Developer Hub, you can export plugins as derived dynamic plugin packages. These packages contain the plugin code and dependencies, ready for dynamic plugin integration into Developer Hub. Prerequisites The @janus-idp/cli package is installed. Use the latest version ( @latest tag) for compatibility with the most recent features and fixes. Node.js and NPM is installed and configured. The third-party plugin is compatible with your Red Hat Developer Hub version. For more information, see Version compatibility matrix . The third-party plugin must have a valid package.json file in its root directory, containing all required metadata and dependencies. Backend plugins To ensure compatibility with the dynamic plugin support and enable their use as dynamic plugins, existing backend plugins must be compatible with the new Backstage backend system. Additionally, these plugins must be rebuilt using a dedicated CLI command. The new Backstage 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. 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. Certain plugin dependencies require specific handling in the derived packages, such as: Shared dependencies are provided by the RHDH 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. You can use the --shared-package flag to specify shared dependencies, that are expected to be provided by Red Hat Developer Hub application and not bundled in the dynamic plugin package. 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 Red Hat Developer Hub application. 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. 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. The following is an example of exporting a dynamic plugin with shared and embedded packages: Example dynamic plugin export with shared and embedded packages npx @janus-idp/cli@latest export-dynamic-plugin --shared-package '!/@backstage/plugin-notifications/' --embed-package @backstage/plugin-notifications-backend In the example: @backstage/plugin-notifications package is treated as a private dependency and is bundled in the dynamic plugin package, despite being in the @backstage scope. @backstage/plugin-notifications-backend package is marked as an embedded dependency and is bundled in the dynamic plugin package. Front-end plugins Front-end plugins can use scalprum for configuration, which the CLI can generate automatically during the export process. The generated default configuration is logged when running the following command: Example command to log the default configuration npx @janus-idp/cli@latest export-dynamic The following is an example of default scalprum configuration: Default scalprum configuration "scalprum": { "name": "<package_name>", // The Webpack container name matches the NPM package name, with "@" replaced by "." and "/" removed. "exposedModules": { "PluginRoot": "./src/index.ts" // The default module name is "PluginRoot" and doesn't need explicit specification in the app-config.yaml file. } } You can add a scalprum section to the package.json file. For example: Example scalprum customization "scalprum": { "name": "custom-package-name", "exposedModules": { "FooModuleName": "./src/foo.ts", "BarModuleName": "./src/bar.ts" // Define multiple modules here, with each exposed as a separate entry point in the Webpack container. } } Dynamic plugins might need adjustments for Developer Hub needs, such as static JSX for mountpoints or dynamic routes. These changes are optional but might be incompatible with static plugins. To include static JSX, define an additional export and use it as the dynamic plugin's importName . For example: Example static and dynamic plugin export // For a static plugin export const EntityTechdocsContent = () => {...} // For a dynamic plugin export const DynamicEntityTechdocsContent = { element: EntityTechdocsContent, staticJSXContent: ( <TechDocsAddons> <ReportIssue /> </TechDocsAddons> ), }; Procedure Use the package export-dynamic-plugin command from the @janus-idp/cli package to export the plugin: Example command to export a third-party plugin npx @janus-idp/cli@latest package export-dynamic-plugin Ensure that you execute the command in the root directory of the plugin's JavaScript package (containing package.json file). 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. Warning The derived dynamic plugin JavaScript packages must not be published to the public NPM registry. For more appropriate packaging options, see Section 2.2, "Packaging and publishing third-party plugins as dynamic plugins" . If you must publish to the NPM registry, use a private registry. 2.2. Packaging and publishing third-party plugins as dynamic plugins After exporting a third-party plugin , you can package the derived package into one of the following supported formats: Open Container Initiative (OCI) image (recommended) TGZ file JavaScript package Important Exported dynamic plugin packages must only be published to private NPM registries. 2.2.1. Creating an OCI image with dynamic packages Prerequisites You have installed podman or docker . You have exported a third-party dynamic plugin package. For more information, see Section 2.1, "Exporting third-party plugins in Red Hat Developer Hub" . 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 npx @janus-idp/cli@latest package package-dynamic-plugins --tag quay.io/example/image:v0.0.1 In the command, the --tag argument specifies the image name and tag. Run one of the following commands to push the image to a registry: Example command to push an image to a registry using podman podman push quay.io/example/image:v0.0.1 Example command to push an image to a registry using docker docker push quay.io/example/image:v0.0.1 The output of the package-dynamic-plugins command provides the plugin's path for use in the dynamic-plugin-config.yaml file. 2.2.2. Creating a TGZ file with dynamic packages Prerequisites You have exported a third-party dynamic plugin package. For more information, see Section 2.1, "Exporting third-party plugins in Red Hat Developer Hub" . Procedure Navigate to the dist-dynamic directory. Run the following command to create a tgz archive: Example command to create a tgz archive npm pack You can obtain the integrity hash from the output of the npm pack command by using the --json flag as follows: Example command to obtain the integrity hash of a tgz archive npm pack --json | head -n 10 Host the archive on a web server accessible to your RHDH instance, and reference its URL in the dynamic-plugin-config.yaml file as follows: Example dynamic-plugin-config.yaml file plugins: - package: https://example.com/backstage-plugin-myplugin-1.0.0.tgz integrity: sha512-<hash> Run the following command to package the plugins: Example command to package a dynamic plugin npm pack --pack-destination ~/test/dynamic-plugins-root/ Tip To create a plugin registry using HTTP server on OpenShift Container Platform, run the following commands: Example commands to build and deploy an HTTP server in OpenShift Container Platform oc project my-rhdh-project oc new-build httpd --name=plugin-registry --binary oc start-build plugin-registry --from-dir=dynamic-plugins-root --wait oc new-app --image-stream=plugin-registry Configure your RHDH to use plugins from the HTTP server by editing the dynamic-plugin-config.yaml file: Example configuration to use packaged plugins in RHDH plugins: - package: http://plugin-registry:8080/backstage-plugin-myplugin-1.9.6.tgz 2.2.3. Creating a JavaScript package with dynamic packages Warning 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. Prerequisites You have exported a third-party dynamic plugin package. For more information, see Section 2.1, "Exporting third-party plugins in Red Hat Developer Hub" . Procedure Navigate to the dist-dynamic directory. Run the following command to publish the package to your private NPM registry: Example command to publish a plugin package to an NPM registry npm publish --registry <npm_registry_url> Tip You can add the following to your package.json file before running the export command: Example package.json file { "publishConfig": { "registry": "<npm_registry_url>" } } If you modify publishConfig after exporting the dynamic plugin, re-run the export-dynamic-plugin command to ensure the correct configuration is included. 2.3. Installing third-party plugins in Red Hat Developer Hub You can install a third-party plugins in Red Hat Developer Hub without rebuilding the RHDH application. The location of the dynamic-plugin-config.yaml file depends on the deployment method. For more details, refer to Installing dynamic plugins with the Red Hat Developer Hub Operator and Installing dynamic plugins using the Helm chart . 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: package : The plugin's package definition, which can be an OCI image, a TGZ file, a JavaScript package, or a directory path. disabled : A boolean value indicating whether the plugin is enabled or disabled. integrity : The integrity hash of the package, required for TGZ file and JavaScript packages. 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 RHDH app-config.yaml file. Note You can also load dynamic plugins from another directory, though this is intended for development or testing purposes and is not recommended for production, except for plugins included in the RHDH container image. For more information, see Chapter 3, Enabling plugins added in the RHDH container image . 2.3.1. Loading a plugin packaged as an OCI image Prerequisites The third-party plugin is packaged as a dynamic plugin in an OCI image. For more information about packaging a third-party plugin, see Section 2.2, "Packaging and publishing third-party plugins as dynamic plugins" . Procedure Define the plugin with the oci:// prefix in the following format in dynamic-plugins.yaml file: oci://<image-name>:<tag>!<plugin-name> Example configuration in dynamic-plugins.yaml file plugins: - disabled: false package: oci://quay.io/example/image:v0.0.1!backstage-plugin-myplugin 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 . To perform an integrity check, use the image digest in place of the tag in the dynamic-plugins.yaml file as follows: Example configuration in dynamic-plugins.yaml file plugins: - disabled: false package: oci://quay.io/example/image@sha256:28036abec4dffc714394e4ee433f16a59493db8017795049c831be41c02eb5dc!backstage-plugin-myplugin To apply the changes, restart the RHDH application. 2.3.2. Loading a plugin packaged as a TGZ file Prerequisites The third-party plugin is packaged as a dynamic plugin in a TGZ file. For more information about packaging a third-party plugin, see Section 2.2, "Packaging and publishing third-party plugins as dynamic plugins" . Procedure Specify the archive URL and its integrity hash in the dynamic-plugins.yaml file using the following example: Example configuration in dynamic-plugins.yaml file plugins: - disabled: false package: https://example.com/backstage-plugin-myplugin-1.0.0.tgz integrity: sha512-9WlbgEdadJNeQxdn1973r5E4kNFvnT9GjLD627GWgrhCaxjCmxqdNW08cj+Bf47mwAtZMt1Ttyo+ZhDRDj9PoA== To apply the changes, restart the RHDH application. 2.3.3. Loading a plugin packaged as a JavaScript package Prerequisites The third-party plugin is packaged as a dynamic plugin in a JavaScript package. For more information about packaging a third-party plugin, see Section 2.2, "Packaging and publishing third-party plugins as dynamic plugins" . Procedure Run the following command to obtain the integrity hash from the NPM registry: npm view --registry <registry-url> <npm package>@<version> dist.integrity Specify the package name, version, and its integrity hash in the dynamic-plugins.yaml file as follows: Example configuration in dynamic-plugins.yaml file plugins: - disabled: false package: @example/backstage-plugin-myplugin@1.0.0 integrity: sha512-9WlbgEdadJNeQxdn1973r5E4kNFvnT9GjLD627GWgrhCaxjCmxqdNW08cj+Bf47mwAtZMt1Ttyo+ZhDRDj9PoA== If you are using a custom NPM registry, create a .npmrc file with the registry URL and authentication details: Example code for .npmrc file registry=<registry-url> //<registry-url>:_authToken=<auth-token> When using OpenShift Container Platform or Kubernetes: Use the Helm chart to add the .npmrc file by creating a secret. For example: Example secret configuration apiVersion: v1 kind: Secret metadata: name: <release_name> -dynamic-plugins-npmrc 1 type: Opaque stringData: .npmrc: | registry=<registry-url> //<registry-url>:_authToken=<auth-token> 1 Replace <release_name> with your Helm release name. This name is a unique identifier for each chart installation in the Kubernetes cluster. For RHDH Helm chart, name the secret using the following format for automatic mounting: <release_name> -dynamic-plugins-npmrc To apply the changes, restart the RHDH application. 2.3.4. Example of installing a third-party plugin in Red Hat Developer Hub This section describes the process for integrating the Todo plugin into your Developer Hub. Obtain the third-party plugin source code : Clone the plugins repository and navigate to the Todo plugin directory: Obtain the third-party plugin source code USD git clone https://github.com/backstage/community-plugins USD cd community-plugins/workspaces/todo USD yarn install 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: Export the backend plugin USD cd todo-backend USD npx @janus-idp/cli@latest package export-dynamic-plugin Output of exporting the backend plugin commands Building main package executing yarn build ✔ Packing main package to dist-dynamic/package.json Customizing main package in dist-dynamic/package.json for dynamic loading moving @backstage/backend-common to peerDependencies moving @backstage/backend-openapi-utils to peerDependencies moving @backstage/backend-plugin-api to peerDependencies moving @backstage/catalog-client to peerDependencies moving @backstage/catalog-model to peerDependencies moving @backstage/config to peerDependencies moving @backstage/errors to peerDependencies moving @backstage/integration to peerDependencies moving @backstage/plugin-catalog-node to peerDependencies Installing private dependencies of the main package executing yarn install --no-immutable ✔ Validating private dependencies Validating plugin entry points Saving self-contained config schema in /Users/user/Code/community-plugins/workspaces/todo/plugins/todo-backend/dist-dynamic/dist/configSchema.json 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: Export the front-end plugin USD cd ../todo USD npx @janus-idp/cli@latest package export-dynamic-plugin Output of exporting the front-end plugin commands No scalprum config. Using default dynamic UI configuration: { "name": "backstage-community.plugin-todo", "exposedModules": { "PluginRoot": "./src/index.ts" } } 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. Packing main package to dist-dynamic/package.json Customizing main package in dist-dynamic/package.json for dynamic loading Generating dynamic frontend plugin assets in /Users/user/Code/community-plugins/workspaces/todo/plugins/todo/dist-dynamic/dist-scalprum 263.46 kB dist-scalprum/static/1417.d5271413.chunk.js ... ... ... 250 B dist-scalprum/static/react-syntax-highlighter_languages_highlight_plaintext.0b7d6592.chunk.js Saving self-contained config schema in /Users/user/Code/community-plugins/workspaces/todo/plugins/todo/dist-dynamic/dist-scalprum/configSchema.json 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: Build an OCI image USD cd ../.. USD npx @janus-idp/cli@latest package package-dynamic-plugins --tag quay.io/user/backstage-community-plugin-todo:v0.1.1 Output of building an OCI image commands executing podman --version ✔ Using existing 'dist-dynamic' directory at plugins/todo Using existing 'dist-dynamic' directory at plugins/todo-backend Copying 'plugins/todo/dist-dynamic' to '/var/folders/5c/67drc33d0018j6qgtzqpcsbw0000gn/T/package-dynamic-pluginsmcP4mU/backstage-community-plugin-todo No plugin configuration found at undefined create this file as needed if this plugin requires configuration Copying 'plugins/todo-backend/dist-dynamic' to '/var/folders/5c/67drc33d0018j6qgtzqpcsbw0000gn/T/package-dynamic-pluginsmcP4mU/backstage-community-plugin-todo-backend-dynamic No plugin configuration found at undefined create this file as needed if this plugin requires configuration Writing plugin registry metadata to '/var/folders/5c/67drc33d0018j6qgtzqpcsbw0000gn/T/package-dynamic-pluginsmcP4mU/index.json' Creating image using podman executing echo "from scratch COPY . . " | 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 - . ✔ Successfully built image quay.io/user/backstage-community-plugin-todo:v0.1.1 with following plugins: backstage-community-plugin-todo backstage-community-plugin-todo-backend-dynamic Here is an example dynamic-plugins.yaml for these plugins: plugins: - package: oci://quay.io/user/backstage-community-plugin-todo:v0.1.1!backstage-community-plugin-todo disabled: false - package: oci://quay.io/user/backstage-community-plugin-todo:v0.1.1!backstage-community-plugin-todo-backend-dynamic disabled: false Push the OCI image to a container registry: USD podman push quay.io/user/backstage-community-plugin-todo:v0.1.1 Output of pushing the OCI image command Getting image source signatures Copying blob sha256:86a372c456ae6a7a305cd464d194aaf03660932efd53691998ab3403f87cacb5 Copying config sha256:3b7f074856ecfbba95a77fa87cfad341e8a30c7069447de8144aea0edfcb603e Writing manifest to image destination Install and configure the third-party plugin : Add the following plugin definitions to your dynamic-plugins.yaml file: Plugin definitions in dynamic-plugins.yaml file packages: - package: oci://quay.io/user/backstage-community-plugin-todo:v0.1.1!backstage-community-plugin-todo pluginConfig: dynamicPlugins: frontend: backstage-community.plugin-todo: mountPoints: - mountPoint: entity.page.todo/cards importName: EntityTodoContent entityTabs: - path: /todo title: Todo mountPoint: entity.page.todo - package: oci://quay.io/user/backstage-community-plugin-todo:v0.1.1!backstage-community-plugin-todo-backend-dynamic disabled: false

Commands:
npx @janus-idp/cli@latest export-dynamic-plugin --shared-package '!/@backstage/plugin-notifications/' --embed-package @backstage/plugin-notifications-backend
npx @janus-idp/cli@latest export-dynamic
"scalprum": { "name": "<package_name>", // The Webpack container name matches the NPM package name, with "@" replaced by "." and "/" removed. "exposedModules": { "PluginRoot": "./src/index.ts" // The default module name is "PluginRoot" and doesn't need explicit specification in the app-config.yaml file. } }
"scalprum": { "name": "custom-package-name", "exposedModules": { "FooModuleName": "./src/foo.ts", "BarModuleName": "./src/bar.ts" // Define multiple modules here, with each exposed as a separate entry point in the Webpack container. } }
// For a static plugin export const EntityTechdocsContent = () => {...} // For a dynamic plugin export const DynamicEntityTechdocsContent = { element: EntityTechdocsContent, staticJSXContent: ( <TechDocsAddons> <ReportIssue /> </TechDocsAddons> ), };
npx @janus-idp/cli@latest package export-dynamic-plugin
npx @janus-idp/cli@latest package package-dynamic-plugins --tag quay.io/example/image:v0.0.1
push quay.io/example/image:v0.0.1
docker push quay.io/example/image:v0.0.1
npm pack
npm pack --json | head -n 10
plugins: - package: https://example.com/backstage-plugin-myplugin-1.0.0.tgz integrity: sha512-<hash>
npm pack --pack-destination ~/test/dynamic-plugins-root/
project my-rhdh-project new-build httpd --name=plugin-registry --binary start-build plugin-registry --from-dir=dynamic-plugins-root --wait new-app --image-stream=plugin-registry
plugins: - package: http://plugin-registry:8080/backstage-plugin-myplugin-1.9.6.tgz
npm publish --registry <npm_registry_url>
{ "publishConfig": { "registry": "<npm_registry_url>" } }
plugins: - disabled: false package: oci://quay.io/example/image:v0.0.1!backstage-plugin-myplugin
plugins: - disabled: false package: oci://quay.io/example/image@sha256:28036abec4dffc714394e4ee433f16a59493db8017795049c831be41c02eb5dc!backstage-plugin-myplugin
plugins: - disabled: false package: https://example.com/backstage-plugin-myplugin-1.0.0.tgz integrity: sha512-9WlbgEdadJNeQxdn1973r5E4kNFvnT9GjLD627GWgrhCaxjCmxqdNW08cj+Bf47mwAtZMt1Ttyo+ZhDRDj9PoA==
npm view --registry <registry-url> <npm package>@<version> dist.integrity
plugins: - disabled: false package: @example/backstage-plugin-myplugin@1.0.0 integrity: sha512-9WlbgEdadJNeQxdn1973r5E4kNFvnT9GjLD627GWgrhCaxjCmxqdNW08cj+Bf47mwAtZMt1Ttyo+ZhDRDj9PoA==
registry=<registry-url> //<registry-url>:_authToken=<auth-token>
apiVersion: v1 kind: Secret metadata: name: <release_name> -dynamic-plugins-npmrc 1 type: Opaque stringData: .npmrc: | registry=<registry-url> //<registry-url>:_authToken=<auth-token>
git clone https://github.com/backstage/community-plugins cd community-plugins/workspaces/todo yarn install
cd todo-backend npx @janus-idp/cli@latest package export-dynamic-plugin
Building main package executing yarn build ✔ Packing main package to dist-dynamic/package.json Customizing main package in dist-dynamic/package.json for dynamic loading moving @backstage/backend-common to peerDependencies moving @backstage/backend-openapi-utils to peerDependencies moving @backstage/backend-plugin-api to peerDependencies moving @backstage/catalog-client to peerDependencies moving @backstage/catalog-model to peerDependencies moving @backstage/config to peerDependencies moving @backstage/errors to peerDependencies moving @backstage/integration to peerDependencies moving @backstage/plugin-catalog-node to peerDependencies Installing private dependencies of the main package executing yarn install --no-immutable ✔ Validating private dependencies Validating plugin entry points Saving self-contained config schema in /Users/user/Code/community-plugins/workspaces/todo/plugins/todo-backend/dist-dynamic/dist/configSchema.json
cd ../todo npx @janus-idp/cli@latest package export-dynamic-plugin
No scalprum config. Using default dynamic UI configuration: { "name": "backstage-community.plugin-todo", "exposedModules": { "PluginRoot": "./src/index.ts" } } 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. Packing main package to dist-dynamic/package.json Customizing main package in dist-dynamic/package.json for dynamic loading Generating dynamic frontend plugin assets in /Users/user/Code/community-plugins/workspaces/todo/plugins/todo/dist-dynamic/dist-scalprum 263.46 kB dist-scalprum/static/1417.d5271413.chunk.js 250 B dist-scalprum/static/react-syntax-highlighter_languages_highlight_plaintext.0b7d6592.chunk.js Saving self-contained config schema in /Users/user/Code/community-plugins/workspaces/todo/plugins/todo/dist-dynamic/dist-scalprum/configSchema.json
cd ../.. npx @janus-idp/cli@latest package package-dynamic-plugins --tag quay.io/user/backstage-community-plugin-todo:v0.1.1
executing podman --version ✔ Using existing 'dist-dynamic' directory at plugins/todo Using existing 'dist-dynamic' directory at plugins/todo-backend Copying 'plugins/todo/dist-dynamic' to '/var/folders/5c/67drc33d0018j6qgtzqpcsbw0000gn/T/package-dynamic-pluginsmcP4mU/backstage-community-plugin-todo No plugin configuration found at undefined create this file as needed if this plugin requires configuration Copying 'plugins/todo-backend/dist-dynamic' to '/var/folders/5c/67drc33d0018j6qgtzqpcsbw0000gn/T/package-dynamic-pluginsmcP4mU/backstage-community-plugin-todo-backend-dynamic No plugin configuration found at undefined create this file as needed if this plugin requires configuration Writing plugin registry metadata to '/var/folders/5c/67drc33d0018j6qgtzqpcsbw0000gn/T/package-dynamic-pluginsmcP4mU/index.json' Creating image using podman executing echo "from scratch COPY . . " | 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 - . ✔ Successfully built image quay.io/user/backstage-community-plugin-todo:v0.1.1 with following plugins: backstage-community-plugin-todo backstage-community-plugin-todo-backend-dynamic Here is an example dynamic-plugins.yaml for these plugins: plugins: - package: oci://quay.io/user/backstage-community-plugin-todo:v0.1.1!backstage-community-plugin-todo disabled: false - package: oci://quay.io/user/backstage-community-plugin-todo:v0.1.1!backstage-community-plugin-todo-backend-dynamic disabled: false
podman push quay.io/user/backstage-community-plugin-todo:v0.1.1
Getting image source signatures Copying blob sha256:86a372c456ae6a7a305cd464d194aaf03660932efd53691998ab3403f87cacb5 Copying config sha256:3b7f074856ecfbba95a77fa87cfad341e8a30c7069447de8144aea0edfcb603e Writing manifest to image destination
packages: - package: oci://quay.io/user/backstage-community-plugin-todo:v0.1.1!backstage-community-plugin-todo pluginConfig: dynamicPlugins: frontend: backstage-community.plugin-todo: mountPoints: - mountPoint: entity.page.todo/cards importName: EntityTodoContent entityTabs: - path: /todo title: Todo mountPoint: entity.page.todo - package: oci://quay.io/user/backstage-community-plugin-todo:v0.1.1!backstage-community-plugin-todo-backend-dynamic disabled: false