Installation (vanilla Backstage)

This guide adds the X2A plugins to a stock Backstage app created with the upstream wizard, not Red Hat Developer Hub on OpenShift. For RHDH deployment, use Installation instead.

Reference implementation and deeper notes live in the Red Hat plugin workspace: rhdh-plugins/workspaces/x2a (packages/app, packages/backend).

The plugins are currently tested against Backstage 1.45.3 (conforms RHDH 1.9). Other Backstage versions may work but are not guaranteed.

Prerequisites

Follow Standalone Installation, but create the app with the legacy stack so the X2A plugins work with the current APIs:

npx @backstage/create-app@latest --legacy

The X2A plugins are not yet adapted to Backstage’s new frontend system - that migration is in progress. Until it lands, you must use --legacy when generating the app.

Additionally, for X2A you need:

  • A Kubernetes API the backend can reach (local ~/.kube/config or in-cluster config) so migration jobs can run.
  • LLM credentials and optional Ansible Automation Platform settings (see the X2A backend plugin README for x2a.credentials and related environment variables).

Install packages

From the repository root of your generated app (where packages/app and packages/backend live):

yarn --cwd packages/app add @red-hat-developer-hub/backstage-plugin-x2a
yarn --cwd packages/backend add @red-hat-developer-hub/backstage-plugin-x2a-backend
yarn --cwd packages/backend add @red-hat-developer-hub/backstage-plugin-scaffolder-backend-module-x2a

Published packages (verify versions before pinning in production):

Optional components

Only if you need OAuth Dynamic Client Registration UI and/or MCP tool wiring similar to production RHDH overlays:

yarn --cwd packages/app add @red-hat-developer-hub/backstage-plugin-x2a-dcr
yarn --cwd packages/backend add @backstage/plugin-mcp-actions-backend
yarn --cwd packages/backend add @red-hat-developer-hub/backstage-plugin-x2a-mcp-extras

For mcpActions and related app-config fragments, see MCP tools - Advanced configuration. Core X2A conversion flows do not require these packages.

Register backend plugins

In packages/backend/src/index.ts, register the scaffolder module and X2A backend after the base scaffolder backend (reference index.ts):

// ... existing backend.add(...) calls ...
backend.add(import('@backstage/plugin-scaffolder-backend'));
// Add GitHub / GitLab / Bitbucket scaffolder modules to match the auth providers you enable.
backend.add(import('@backstage/plugin-scaffolder-backend-module-github'));
backend.add(import('@backstage/plugin-scaffolder-backend-module-gitlab'));
backend.add(import('@backstage/plugin-scaffolder-backend-module-bitbucket'));
backend.add(
  import('@red-hat-developer-hub/backstage-plugin-scaffolder-backend-module-x2a'),
);
backend.add(import('@red-hat-developer-hub/backstage-plugin-x2a-backend'));

If you added the optional MCP packages:

backend.add(import('@backstage/plugin-mcp-actions-backend'));
backend.add(import('@red-hat-developer-hub/backstage-plugin-x2a-mcp-extras'));

Register frontend routes and scaffolder extension

In packages/app/src/App.tsx (adjust imports to match your existing create-app layout):

  1. Import the X2A page, translations, and repo field extension:
import {
  X2APage,
  x2aPluginTranslations,
  RepoAuthenticationExtension,
} from '@red-hat-developer-hub/backstage-plugin-x2a';
  1. If you use OAuth DCR and installed backstage-plugin-x2a-dcr:
import { DcrConsentPage } from '@red-hat-developer-hub/backstage-plugin-x2a-dcr';
  1. Pass plugin strings into createApp:
const app = createApp({
  // ...apis, bindRoutes, components, etc.
  __experimentalTranslations: {
    availableLanguages: ['en'], // add more if you use them elsewhere
    resources: [x2aPluginTranslations],
  },
});
  1. Add a route for the portal (path is /x2a, not /x2a/):
<Route path="/x2a" element={<X2APage />} />
  1. Wrap the scaffolder page so the conversion template can use the Repo authentication custom field (same pattern as the reference App.tsx):
import { ScaffolderPage } from '@backstage/plugin-scaffolder';
import { ScaffolderFieldExtensions } from '@backstage/plugin-scaffolder-react';

<Route path="/create" element={<ScaffolderPage />}>
  <ScaffolderFieldExtensions>
    <RepoAuthenticationExtension />
  </ScaffolderFieldExtensions>
</Route>
  1. Optional DCR consent route:
<Route path="/oauth2/*" element={<DcrConsentPage />} />

If repository OAuth behaves oddly, compare packages/app/src/apis.ts with the reference apis.ts (ScmIntegrationsApi, ScmAuth).

Static routes do not add a sidebar label by themselves (RHDH injects menu text via dynamic plugin metadata). In packages/app/src/components/Root.tsx, add an item next to your other SidebarItem entries (adjust the icon import if your app uses @mui/icons-material instead of @material-ui/icons):

import { SidebarItem } from '@backstage/core-components';
import ExtensionIcon from '@material-ui/icons/Extension';

// Inside the main <SidebarGroup label="Menu" ...> (or equivalent).
<SidebarItem icon={ExtensionIcon} to="x2a" text="Conversion Hub" />

to="x2a" matches the /x2a route registered in App.tsx.

Catalog: register the conversion template

In the root app-config.yaml (next to packages/), register the template shipped inside the scaffolder module. Paths are relative to this file. After yarn install, confirm the file exists under node_modules.

catalog:
  locations:
    - type: file
      # Tweak following path based on your actual directory structure. It's relative from the perspective of `packages/backend`.
      target: ../../node_modules/@red-hat-developer-hub/backstage-plugin-scaffolder-backend-module-x2a/templates/conversion-project-template.yaml
      rules:
        - allow: [Template]

CSV-driven bulk flows and the RepoAuthentication extension are described in CSV Bulk Import.

Configuration (pointers only)

Topic Where it is documented
OAuth providers, env vars, sign-in Authentication
RBAC / permissions for the x2a plugin Authorization
x2a: Kubernetes image, job resources, LLM and AAP credentials X2A backend plugin README and reference app-config.yaml
SCM host detection (GitHub Enterprise, self-hosted GitLab, etc.) Workspace README — SCM Provider Detection (integrations: host entries; tokens there are not used for X2A repo auth; OAuth applies.)

If the backend API base URL seen by clients or integrations is not the default, you may need x2a.callbackBaseUrl (see in-cluster example in deploy/app.yaml); local yarn start often works without it.

Run and verify

yarn start

Open http://localhost:3000/x2a for the Conversion Hub. In the catalog, confirm the conversion project template appears (might take some time to load after start-up).

API exploration

Use API Reference for the REST surface once the backend plugin is running.


Back to top