From d2975216f2f5cd93c9b1cedbb5f9685e7c09b23b Mon Sep 17 00:00:00 2001 From: Tomas Kral Date: Tue, 3 Mar 2026 14:26:47 +0100 Subject: [PATCH 1/2] Add Claude Code skills and project instructions Co-Authored-By: Claude Opus 4.6 --- .claude/skills/deploy/SKILL.md | 455 +++++++++++++++++++++++++++++++++ CLAUDE.md | 114 +++++++++ 2 files changed, 569 insertions(+) create mode 100644 .claude/skills/deploy/SKILL.md create mode 100644 CLAUDE.md diff --git a/.claude/skills/deploy/SKILL.md b/.claude/skills/deploy/SKILL.md new file mode 100644 index 0000000..d026362 --- /dev/null +++ b/.claude/skills/deploy/SKILL.md @@ -0,0 +1,455 @@ +--- +name: deploy +description: This skill should be used when the user asks to "deploy a test instance", "create a test deployment", "deploy RHDH", "spin up a test instance", "deploy with helm", "deploy with operator", "set up a test environment", "create a PR deployment", "use /test deploy", "enable a plugin", "disable a plugin", "add a plugin", "configure a plugin", "list available plugins", "show plugins", "install plugin", "remove plugin", "configure dynamic plugins", "add dynamic plugin", or mentions deploying an RHDH instance or enabling, disabling, or configuring dynamic plugins. +allowed-tools: Bash(gh *), Bash(git *), Bash(oc *), Bash(kubectl *), Bash(*vault*), Bash(curl *), Bash(ls *), Read, Edit, Write, WebFetch +--- + +# Deploy & Configure RHDH Test Instance + +This skill guides users through deploying an RHDH test instance and configuring its dynamic plugins. It covers the full workflow: configuring plugins, deploying via PR, and troubleshooting. + +## Part 1: Plugin Configuration + +This section helps users enable, disable, and configure dynamic plugins. It uses the [rhdh-plugin-export-overlays](https://github.com/redhat-developer/rhdh-plugin-export-overlays) repository as the authoritative source for available plugins, their packages, and configuration. + +### Data Sources + +All plugin information comes from the `rhdh-plugin-export-overlays` repo on the `main` branch: + +- **Available plugins catalog**: `https://raw.githubusercontent.com/redhat-developer/rhdh-plugin-export-overlays/refs/heads/main/catalog-entities/extensions/plugins/all.yaml` +- **Package metadata (OCI artifact + config examples)**: `https://raw.githubusercontent.com/redhat-developer/rhdh-plugin-export-overlays/main/workspaces//metadata/.yaml` + +To list all available plugin names: +```bash +curl -s https://api.github.com/repos/redhat-developer/rhdh-plugin-export-overlays/contents/catalog-entities/extensions/plugins | jq -r '.[].name' | sed 's/\.yaml$//' +``` + +### Workflow: Enabling a Plugin + +#### Step 1: Identify the Plugin + +- Ask the user which plugin to enable. List all plugins available in the plugins catalog. +- Validate that the plugin name is valid and exists in the plugins catalog. If not try to fetch information for similar plugin names and ask user to select the correct plugin. + +#### Step 2: Fetch Plugin Definition + +Fetch the plugin definition YAML: +``` +curl -s https://raw.githubusercontent.com/redhat-developer/rhdh-plugin-export-overlays/main/catalog-entities/extensions/plugins/.yaml +``` + +From this file, extract: +- `metadata.name` — canonical plugin name +- `metadata.title` — display name +- `spec.packages` — the list of package names that make up this plugin +- `spec.categories` — plugin category + +#### Step 3: Fetch Package Metadata + +For each package listed in `spec.packages`, fetch its metadata. The metadata files live under `workspaces//metadata/`: +``` +curl -s https://raw.githubusercontent.com/redhat-developer/rhdh-plugin-export-overlays/main/workspaces//metadata/.yaml +``` + +From each package metadata file, extract: +- `spec.dynamicArtifact` — the OCI image reference (e.g., `oci://ghcr.io/...`) +- `spec.backstage.role` — `frontend-plugin`, `backend-plugin`, or `backend-plugin-module` +- `spec.appConfigExamples` — example configuration snippets +- `spec.partOf` — which plugin(s) this package belongs to + +**Important**: Some packages may belong to a different workspace than the plugin name. If a package metadata file is not found under the plugin's workspace, check the package's own workspace (derived from the package name pattern). For example, `backstage-plugin-kubernetes-backend` lives under `workspaces/kubernetes/metadata/`. + +#### Step 4: Add Packages to dynamic-plugins.yaml + +Edit `config/dynamic-plugins.yaml` to add each package. Three package reference formats exist: + +**OCI-based from rhdh-plugin-export-overlays** (most common — use `spec.dynamicArtifact` value): +```yaml +plugins: + - package: 'oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-argocd:bs_1.45.3__2.4.3!backstage-community-plugin-argocd' + disabled: false +``` + +**OCI-based from Red Hat registry** (for Red Hat-shipped plugins): +```yaml +plugins: + - package: 'oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator:{{inherit}}' + disabled: false +``` + +**Local path** (built-in plugins already bundled): +```yaml +plugins: + - package: ./dynamic-plugins/dist/backstage-community-plugin-catalog-backend-module-keycloak-dynamic + disabled: false +``` + +**For packages with frontend plugin configuration** (mount points, translation resources, etc.): +```yaml +plugins: + - package: 'oci://ghcr.io/...' + disabled: false + pluginConfig: + dynamicPlugins: + frontend: + : + mountPoints: + - mountPoint: entity.page.overview/cards + importName: ComponentName + config: + layout: + gridColumnEnd: + lg: span 8 + xs: span 12 + if: + allOf: + - conditionName + translationResources: + - importName: translationImport + module: ModuleName + ref: translationRef +``` + +The `pluginConfig` content comes directly from `spec.appConfigExamples[].content.dynamicPlugins` in the package metadata. Include it exactly as specified. This works only for Operator deployments. + +**For packages with dependencies** on other plugins: +```yaml +plugins: + - package: 'oci://...' + disabled: false + dependencies: + - ref: sonataflow +``` + +**Common mount points:** + +| Mount Point | Location | +|---|---| +| `entity.page.overview/cards` | Entity overview page cards | +| `entity.page.ci/cards` | Entity CI tab cards | +| `entity.page.cd/cards` | Entity CD tab cards | +| `entity.page.kubernetes/cards` | Entity Kubernetes tab cards | +| `entity.page.topology/cards` | Entity Topology tab cards | +| `entity.page.api/cards` | Entity API tab cards | + +#### Step 5: Add Backend Configuration (if needed) + +If any package metadata includes `spec.appConfigExamples` with backend configuration (anything outside the `dynamicPlugins` key), add that configuration to `config/app-config-rhdh.yaml`. + +**Service integration example (ArgoCD):** +```yaml +argocd: + username: ${ARGOCD_USERNAME} + password: ${ARGOCD_PASSWORD} + appLocatorMethods: + - type: config + instances: + - name: argoInstance1 + url: ${ARGOCD_INSTANCE1_URL} + token: ${ARGOCD_AUTH_TOKEN} +``` + +**Kubernetes plugin example:** +```yaml +kubernetes: + serviceLocatorMethod: + type: multiTenant + clusterLocatorMethods: + - type: config + clusters: + - url: ${K8S_CLUSTER_URL} + name: cluster-name + authProvider: serviceAccount + serviceAccountToken: ${K8S_SA_TOKEN} +``` + +#### Step 6: Add Required Secrets/Environment Variables + +If the backend configuration references environment variables (e.g., `${ARGOCD_USERNAME}`), inform the user they need to: +1. Add the actual values to `config/rhdh-secrets.yaml` under `stringData` +2. For PR-based deployments, store secrets in Vault at `vault.ci.openshift.org` under `selfservice/rhdh-test-instance/` +3. For local deployments, add `export MY_NEW_SECRET="value"` to `.env` + +#### Step 7: Present Summary + +After making changes, present a summary: +- Which packages were added to `dynamic-plugins.yaml` +- What app-config was added (if any) +- What environment variables/secrets need to be set (if any) +- Remind the user to deploy or redeploy the instance for changes to take effect + +### Workflow: Disabling a Plugin + +1. Read `config/dynamic-plugins.yaml` +2. Find the package entries for the plugin +3. Either set `disabled: true` or remove the entries entirely +4. If removing, also clean up any related configuration from `config/app-config-rhdh.yaml` + +### Workflow: Checking Current Plugin Configuration + +1. Read `config/dynamic-plugins.yaml` to show currently enabled plugins +2. Cross-reference with the plugin catalog to identify plugin names + +### Plugin Configuration Notes + +- **Package names vs plugin names**: A single plugin (e.g., `argocd`) consists of multiple packages (e.g., `backstage-community-plugin-redhat-argocd` frontend + `backstage-community-plugin-redhat-argocd-backend`). ALL packages for a plugin must be enabled together. +- **OCI references**: Always use the `spec.dynamicArtifact` value from the package metadata as the package reference. Do not construct OCI references manually. +- **Frontend plugin config**: Frontend plugins typically require `pluginConfig` with mount points and other UI wiring. Always include the config from `appConfigExamples`. +- **`{{inherit}}`**: Some older plugins use `{{inherit}}` in their OCI reference — this is a special marker for the Red Hat registry. For plugins from the export-overlays repo, always use the full OCI reference from `spec.dynamicArtifact`. +- **Order matters**: Backend plugins should generally be listed before their corresponding frontend plugins in `dynamic-plugins.yaml`. + +--- + +## Part 2: Deployment + +This section guides users through deploying an RHDH test instance via the GitHub PR workflow. The primary deployment method is opening a PR on the `rhdh-test-instance` repo and using the `/test deploy` slash command in PR comments. Prow CI handles provisioning, Keycloak auth setup, and RHDH installation automatically. + +### Configuration Files + +| File | Purpose | +|---|---| +| `config/app-config-rhdh.yaml` | RHDH app config (auth, catalog, providers, backend plugin config). Applied as a ConfigMap. | +| `config/dynamic-plugins.yaml` | Plugin enablement — lists packages to load and their configuration. Includes `dynamic-plugins.default.yaml` for defaults. | +| `config/rhdh-secrets.yaml` | Kubernetes Secret template with env vars. Variables substituted at deploy time. | +| `config/orchestrator-dynamic-plugins.yaml` | Orchestrator plugins, auto-merged when `ORCH=true`. Do not manually merge. | +| `helm/value_file.yaml` | Helm chart value overrides (resource limits, replicas, etc.) | +| `operator/subscription.yaml` | Backstage CR for operator deployments | + +#### app-config-rhdh.yaml Structure + +```yaml +app: + baseUrl: "${RHDH_BASE_URL}" # Auto-set by deploy scripts +auth: + environment: production + providers: + oidc: # Keycloak OIDC provider (auto-configured) + production: + metadataUrl: "${KEYCLOAK_METADATA_URL}" + clientId: "${KEYCLOAK_CLIENT_ID}" + clientSecret: "${KEYCLOAK_CLIENT_SECRET}" +catalog: + locations: # Entity sources — most common customization + - type: url + target: https://github.com/redhat-developer/rhdh/blob/main/catalog-entities/all.yaml + providers: + keycloakOrg: # Syncs users/groups from Keycloak (auto-configured) + default: + baseUrl: "${KEYCLOAK_BASE_URL}" + realm: "${KEYCLOAK_REALM}" +``` + +All `${VAR}` placeholders are substituted at runtime. Variables come from: Keycloak deploy script (auto-set: `KEYCLOAK_*`, `RHDH_BASE_URL`), Vault secrets (PR deployments), or `.env` file (local deployments). To add a new variable: define it in `config/rhdh-secrets.yaml`, then reference it in app-config as `${VAR_NAME}`. + +#### Common app-config Modifications + +**Add a catalog location** (most common): +```yaml +catalog: + locations: + - type: url + target: https://github.com/my-org/my-repo/blob/main/catalog-info.yaml +``` + +**Add a new auth provider alongside OIDC:** +```yaml +auth: + providers: + oidc: ... # existing + github: + production: + clientId: "${GITHUB_CLIENT_ID}" + clientSecret: "${GITHUB_CLIENT_SECRET}" +``` + +**Add a new catalog provider:** +```yaml +catalog: + providers: + github: + myOrg: + organization: my-org + schedule: + frequency: { minutes: 30 } + timeout: { minutes: 3 } +``` + +#### helm/value_file.yaml Structure + +Minimal by default — most configuration goes through `app-config-rhdh.yaml` via the ConfigMap. + +```yaml +upstream: + backstage: + extraAppConfig: + - configMapRef: app-config-rhdh + filename: app-config-rhdh.yaml + extraEnvVarsSecrets: + - rhdh-secrets +``` + +To customize Helm-specific values (resource limits, replicas, etc.), add under the `upstream` key following the RHDH Helm chart schema. + +#### operator/subscription.yaml Key Fields + +- `spec.application.appConfig.configMapRef` — references the app-config ConfigMap +- `spec.application.dynamicPluginsConfigMapName` — references the dynamic plugins ConfigMap +- `spec.database.enableLocalDb` — uses a local PostgreSQL database +- `spec.application.route.enabled` — creates an OpenShift Route + +### Deployment Workflow + +#### Step 1: Determine Configuration Needs + +Ask the user: + +1. **Install type** — `helm` or `operator` +2. **RHDH version** — semantic (e.g. `1.9`), CI build (e.g. `1.9-190-CI`), or `next` +3. **Duration** — how long the instance should stay up (default: `3h`, e.g. `4h`, `2.5h`) +4. **Custom configuration** — whether they need non-default app-config, plugins, or secrets + +If the user does not need custom configuration, skip to Step 3. + +#### Step 2: Prepare Custom Configuration (if needed) + +If the user needs custom configuration, create a new branch and make changes to the relevant files listed in the Configuration Files table above. + +Common customizations: + +- **Adding catalog locations** — add entries under `catalog.locations` in `app-config-rhdh.yaml` +- **Enabling plugins** — use the Plugin Configuration workflow in Part 1 +- **Adding secrets/env vars** — add to `config/rhdh-secrets.yaml` and reference in app-config via `${VAR_NAME}`; for PR deployments, the actual secret values must be stored in Vault at `vault.ci.openshift.org` under `selfservice/rhdh-test-instance/` + +After making changes, commit and push the branch, then open a PR. + +#### Step 3: Create the PR + +If no custom config is needed, create a minimal PR (e.g. an empty commit or a small README change) to get a PR number for the `/test` command. + +Use `gh` CLI to create the PR: + +```bash +git checkout -b +git commit --allow-empty -m "Deploy test instance" +git push -u origin +gh pr create --title "Deploy RHDH test instance" --body "Deploying RHDH test instance for testing." +``` + +#### Step 4: Trigger Deployment + +Post a comment on the PR with the deploy command: + +``` +/test deploy [duration] +``` + +Examples: +``` +/test deploy helm 1.9 4h +/test deploy operator 1.7 2.5h +/test deploy helm 1.9-190-CI +/test deploy helm next +``` + +Parameters: +- `install-type`: `helm` or `operator` +- `version`: `1.9`, `1.9-190-CI`, `next`, etc. +- `duration`: optional cleanup timer (default `3h`) + +#### Step 5: Monitor and Share Results + +After posting the deploy command, poll for the `@rhdh-test-bot` comment. Deployments typically take 10–20 minutes. + +Run a background polling loop with `run_in_background: true` and `timeout: 600000` (10 min). If it times out without a bot comment, start a second polling loop (another 10 min) to cover the full 20-minute window. + +```bash +while true; do + comment=$(gh pr view --comments --json comments \ + --jq '.comments[] | select(.author.login == "rhdh-test-bot") | .body' 2>/dev/null) + if [ -n "$comment" ]; then + echo "$comment" + break + fi + sleep 30 +done +``` + +Once the bot comments: + +1. On success, the comment contains the RHDH URL, OpenShift Console link, cluster credentials (from Vault), and instance availability window +2. Present the deployment details to the user +3. Share the RHDH URL and credentials from the bot's PR comment with anyone who needs access + +### Constraints + +- Maximum **two concurrent** test instances +- Default duration is **3 hours** if not specified +- Test users for login: `test1` / `test1@123` or `test2` / `test2@123` + +--- + +## Troubleshooting + +If the deployed RHDH instance is not starting (readiness probe failing, pod not becoming ready), log in to the OpenShift cluster and inspect logs. + +### Handling Secrets + +**CRITICAL: Never let secret values appear in tool outputs.** When running commands that involve credentials from Vault, always use bash subshells or piping so that secret values are passed directly between commands and never printed or captured in the response. The LLM model must not see secret values. + +**Correct** — secrets stay inside the shell, never visible to the model: +```bash +oc login https://api.:6443 \ + -u $(VAULT_ADDR=https://vault.ci.openshift.org vault kv get -field=CLUSTER_ADMIN_USERNAME kv/selfservice/rhdh-test-instance/ocp-cluster-creds) \ + -p $(VAULT_ADDR=https://vault.ci.openshift.org vault kv get -field=CLUSTER_ADMIN_PASSWORD kv/selfservice/rhdh-test-instance/ocp-cluster-creds) \ + --insecure-skip-tls-verify +``` + +**Wrong** — fetching credentials into a variable or printing them exposes secrets to the model: +```bash +# DO NOT do this — secrets will appear in the tool output +PASSWORD=$(vault kv get -field=CLUSTER_ADMIN_PASSWORD ...) +echo $PASSWORD +oc login -u admin -p "$PASSWORD" ... +``` + +### Logging in to the Cluster + +Use `oc` if available, otherwise fall back to `kubectl`. Check with `which oc || which kubectl`. + +The cluster API URL can be derived from the bot comment's OpenShift Console URL by replacing `console-openshift-console.apps.` with `api.` and appending port `:6443`. + +Example: if the console URL is `https://console-openshift-console.apps.rhdh-4-18-us-east-2-q5h5x.rhdh-qe.devcluster.openshift.com`, the API URL is `https://api.rhdh-4-18-us-east-2-q5h5x.rhdh-qe.devcluster.openshift.com:6443`. + +Credentials are stored in Vault at `kv/selfservice/rhdh-test-instance/ocp-cluster-creds` with keys `CLUSTER_ADMIN_USERNAME` and `CLUSTER_ADMIN_PASSWORD`. + +**With `oc`:** +```bash +oc login https://api.:6443 \ + -u $(VAULT_ADDR=https://vault.ci.openshift.org vault kv get -field=CLUSTER_ADMIN_USERNAME kv/selfservice/rhdh-test-instance/ocp-cluster-creds) \ + -p $(VAULT_ADDR=https://vault.ci.openshift.org vault kv get -field=CLUSTER_ADMIN_PASSWORD kv/selfservice/rhdh-test-instance/ocp-cluster-creds) \ + --insecure-skip-tls-verify +``` + +**With `kubectl`** (when `oc` is not available): +```bash +kubectl config set-cluster rhdh-test --server=https://api.:6443 --insecure-skip-tls-verify=true && \ +kubectl config set-credentials rhdh-test \ + --username=$(VAULT_ADDR=https://vault.ci.openshift.org vault kv get -field=CLUSTER_ADMIN_USERNAME kv/selfservice/rhdh-test-instance/ocp-cluster-creds) \ + --password=$(VAULT_ADDR=https://vault.ci.openshift.org vault kv get -field=CLUSTER_ADMIN_PASSWORD kv/selfservice/rhdh-test-instance/ocp-cluster-creds) && \ +kubectl config set-context rhdh-test --cluster=rhdh-test --user=rhdh-test && \ +kubectl config use-context rhdh-test +``` + +### Debugging Steps + +Use `oc` or `kubectl` interchangeably in all commands below. + +1. **Check pod status**: `oc get pods -n rhdh` +2. **Check events**: `oc get events -n rhdh --sort-by='.lastTimestamp' | tail -30` +3. **Check init container logs** (plugin installation): `oc logs -n rhdh -c install-dynamic-plugins --tail=50` +4. **Check backend logs for errors**: `oc logs -n rhdh -c backstage-backend 2>&1 | grep -i -E 'error|fail|exception' | head -40` + +### Common Issues + +- **Missing environment variables**: Backend plugin modules may require config values (e.g., `jira.baseUrl`) backed by env vars that aren't set. Fix: either add the secrets to Vault and `rhdh-secrets.yaml`, or disable the module that requires them. +- **Plugin initialization failure**: One failing plugin module can block the entire RHDH startup. Check logs for `threw an error during startup` messages to identify which module is failing. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..67fec8c --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,114 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +This repository provides **PR-driven deployment of Red Hat Developer Hub (RHDH) test instances** on OpenShift clusters. Users open a PR (optionally with custom configuration changes) and use the `/test deploy` slash command in PR comments to trigger automated deployment via Prow CI. The system handles cluster provisioning, Keycloak auth setup, RHDH installation, and posts deployment URLs and credentials back to the PR. + +Two installation methods are supported (Helm and Operator), with optional Orchestrator components. Local deployment is also possible as a secondary use case. The codebase is entirely Bash scripts and YAML configuration. + +## GitHub PR Workflow (Primary Use Case) + +Users deploy test instances by commenting on PRs: + +``` +/test deploy [duration] +``` + +- `install-type`: `helm` or `operator` +- `version`: `1.9`, `1.9-190-CI`, `next` +- `duration`: optional cleanup timer (e.g., `4h`, `2.5h`; default `3h`) + +Examples: +``` +/test deploy helm 1.7 4h +/test deploy operator 1.6 2.5h +``` + +The bot responds with RHDH URL, OpenShift console link, and cluster credentials (from Vault). Users can test custom configurations by modifying config files in the PR branch before deploying. Max two concurrent instances. + +Prow job status: https://prow.ci.openshift.org/?repo=redhat-developer%2Frhdh-test-instance&type=presubmit&job=pull-ci-redhat-developer-rhdh-test-instance-main-deploy + +## Local Deployment Commands + +### Deploy + +```bash +# Helm deployment (primary method) +make deploy-helm VERSION=1.9 NAMESPACE=rhdh + +# Helm with orchestrator +make deploy-helm VERSION=1.9 ORCH=true + +# Operator deployment (requires install-operator first) +make install-operator VERSION=1.9 +make deploy-operator VERSION=1.9 +``` + +### Teardown + +```bash +make undeploy-helm # Remove Helm-deployed RHDH +make undeploy-operator # Remove Operator-deployed RHDH +make undeploy-infra # Remove Keycloak +make clean # Remove everything (RHDH + Keycloak) +``` + +### Debugging + +```bash +make status # Show pod status in namespace +make logs # Tail RHDH pod logs +make url # Print the RHDH portal URL +``` + +### Makefile Variables + +| Variable | Default | Description | +|---|---|---| +| `NAMESPACE` | `rhdh` | OpenShift namespace for RHDH | +| `VERSION` | `1.9` | RHDH version (supports `1.9`, `1.9-190-CI`, `next`) | +| `ORCH` | `false` | Enable Orchestrator components | +| `CATALOG_INDEX_TAG` | auto-detected | Plugin catalog index tag | + +## Architecture + +``` +deploy.sh (entry point) +├── Parses args: method (helm/operator), version, namespace, --with-orchestrator +├── Sources secrets from .env (local) or Vault (CI) +├── Deploys Keycloak via utils/keycloak/keycloak-deploy.sh +├── Creates namespace and app-config ConfigMap from config/ +└── Delegates to: + ├── helm/deploy.sh — Resolves version from Quay API, installs RHDH Helm chart + └── operator/deploy.sh — Applies Backstage CR after optional operator install +``` + +### Key directories + +- **config/** — RHDH application config (app-config-rhdh.yaml), dynamic plugin definitions, and Kubernetes Secret templates. These are applied as ConfigMaps/Secrets to the cluster. +- **helm/** — Helm-specific deployment: `deploy.sh` resolves chart versions from Quay, `value_file.yaml` provides Helm overrides. +- **operator/** — Operator-based deployment: `install-operator.sh` installs the RHDH operator CRD, `deploy.sh` applies the Backstage CR from `subscription.yaml`. +- **utils/keycloak/** — Full Keycloak deployment automation: Helm install, realm/client/user/group creation via Keycloak REST API. Test users defined in `users.json`, groups in `groups.json`. + +### Deployment flow + +1. Keycloak is deployed first (Bitnami Helm chart) with an OIDC client (`rhdh-client`) and test users (`test1`/`test2`, password: `test1@123`/`test2@123`). +2. Environment variables (Keycloak URLs, credentials) are exported and substituted into `config/rhdh-secrets.yaml`. +3. `config/app-config-rhdh.yaml` configures RHDH with OIDC auth pointing to Keycloak and catalog entity locations from GitHub. +4. For Helm: the RHDH chart is installed with dynamic plugins config. For Operator: a Backstage CR is applied referencing the ConfigMaps. +5. When `ORCH=true`, orchestrator plugins are merged into `dynamic-plugins.yaml` and serverless operators are installed. + +### Secrets + +- **PR deployments (primary):** secrets pulled automatically from Vault at `vault.ci.openshift.org` under `selfservice/rhdh-test-instance/` +- **Local deployments:** secrets loaded from `.env` file (copy `.env.example` to `.env`); Vault is used when `.env` is absent + +## Required CLI Tools + +`oc`, `helm`, `jq`, `curl`, `podman` (or `docker` for container-based operator install) + +## Version Resolution + +Helm deploy resolves semantic versions (e.g., `1.9`) to the latest patch by querying the Quay.io API for available chart tags. CI versions like `1.9-190-CI` and `next` are passed through directly. From 06b6fb556eff9198c1f2bf76feb5c45a9bf1b2ac Mon Sep 17 00:00:00 2001 From: Tomas Kral Date: Tue, 3 Mar 2026 15:00:10 +0100 Subject: [PATCH 2/2] Enable Scorecard plugin with GitHub module - Add scorecard-backend, scorecard-backend-module-github, and scorecard frontend plugins - Configure frontend plugin with Scorecard tab on entity pages - Add GitHub open_prs threshold configuration (success: <10, warning: 10-50, error: >50) - Add commented GitHub integration templates for future configuration Signed-off-by: Tomas Kral Assisted-by: Cursor Made-with: Cursor --- config/app-config-rhdh.yaml | 34 +++++++++++++++++++++++++++++++++- config/dynamic-plugins.yaml | 30 +++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/config/app-config-rhdh.yaml b/config/app-config-rhdh.yaml index c4e9986..e4f7384 100644 --- a/config/app-config-rhdh.yaml +++ b/config/app-config-rhdh.yaml @@ -45,4 +45,36 @@ catalog: schedule: frequency: { minutes: 20 } initialDelay: { seconds: 15 } - timeout: { minutes: 5 } \ No newline at end of file + timeout: { minutes: 5 } + +# GitHub integration for Scorecard plugin (configure one of the options below) +# Option 1: Token-based authentication +# integrations: +# github: +# - host: github.com +# token: ${GITHUB_TOKEN} + +# Option 2: GitHub App authentication (recommended for organizations) +# integrations: +# github: +# - host: github.com +# apps: +# - appId: ${GITHUB_APP_ID} +# clientId: ${GITHUB_CLIENT_ID} +# clientSecret: ${GITHUB_CLIENT_SECRET} +# privateKey: | +# ${GITHUB_PRIVATE_KEY} + +# Scorecard GitHub metrics thresholds +scorecard: + plugins: + github: + open_prs: + thresholds: + rules: + - key: success + expression: '<10' + - key: warning + expression: '10-50' + - key: error + expression: '>50' \ No newline at end of file diff --git a/config/dynamic-plugins.yaml b/config/dynamic-plugins.yaml index 1707b52..9cdf8b9 100644 --- a/config/dynamic-plugins.yaml +++ b/config/dynamic-plugins.yaml @@ -3,4 +3,32 @@ includes: plugins: - package: ./dynamic-plugins/dist/backstage-community-plugin-catalog-backend-module-keycloak-dynamic disabled: false - \ No newline at end of file + + # Scorecard plugin - backend + - package: 'oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard-backend:bs_1.45.3__2.3.5!red-hat-developer-hub-backstage-plugin-scorecard-backend' + disabled: false + + # Scorecard plugin - GitHub module (requires GitHub integration in app-config) + - package: 'oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard-backend-module-github:bs_1.45.3__2.3.5!red-hat-developer-hub-backstage-plugin-scorecard-backend-module-github' + disabled: false + + # Scorecard plugin - frontend + - package: 'oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard:bs_1.45.3__2.3.5!red-hat-developer-hub-backstage-plugin-scorecard' + disabled: false + pluginConfig: + dynamicPlugins: + frontend: + red-hat-developer-hub.backstage-plugin-scorecard: + entityTabs: + - path: '/scorecard' + title: Scorecard + mountPoint: entity.page.scorecard + mountPoints: + - mountPoint: entity.page.scorecard/cards + importName: EntityScorecardContent + config: + layout: + gridColumn: 1 / -1 + if: + allOf: + - isKind: component