Skip to content
Open
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
13 changes: 12 additions & 1 deletion skills/overlay/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
---
name: overlay
description: Manages the rhdh-plugin-export-overlays repository — onboards plugins to the Extensions Catalog, updates plugin versions, fixes overlay build failures, triages and analyzes PRs, triggers publishes, and manages plugin workspaces. Use when working with overlays, importing plugins, debugging CI, checking PRs, or bumping versions.
description: Manages the rhdh-plugin-export-overlays repository — onboards plugins to the Extensions Catalog, updates plugin versions, generates and audits Package metadata, fixes overlay build failures, triages and analyzes PRs, triggers publishes, and manages plugin workspaces. Use when working with overlays, importing plugins, generating metadata, auditing metadata, fixing metadata inconsistencies, debugging CI, checking PRs, or bumping versions.
---

<path_resolution>
All relative paths in this skill (`scripts/`, `references/`, `workflows/`, `templates/`) are relative to **this SKILL.md file's directory**. Derive the skill root from the absolute path used to read this file. For example, if this file was read from `/Users/me/.agents/skills/overlay/SKILL.md`, then `scripts/derive-metadata.py` resolves to `/Users/me/.agents/skills/overlay/scripts/derive-metadata.py`. Always use absolute paths when invoking scripts or reading reference files.
</path_resolution>

<shell_permissions>
Prefer running `gh api` and `gh search code` as **direct shell commands** rather than via Python subprocess. Direct `gh` calls go through the user's command allowlist without triggering permission prompts. Python scripts that only do local work (file I/O, JSON processing, field derivation) also need no extra permissions. Only request `full_network` for Python scripts that internally spawn `gh` as a subprocess — the sandbox blocks network access from child processes.
</shell_permissions>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This directive says "prefer direct gh shell commands over Python subprocess" but derive-metadata.py's fetch-and-derive subcommand does exactly the opposite — it calls gh api via subprocess.run.

Either:

  • Remove fetch-and-derive from the script (recommended — see my comment on the script), or
  • Rewrite this to explain that the script handles gh calls internally and agents should use the script's subcommands rather than calling gh directly for metadata tasks


<cli_setup>
This skill uses the orchestrator CLI. **Set up first:**

Expand Down Expand Up @@ -63,6 +71,7 @@ What overlay task would you like to do?
2. **Update plugin version** — Bump to newer upstream commit/tag
3. **Check plugin status** — Verify health and compatibility
4. **Fix build failure** — Debug CI/publish issues
8. **Generate or audit metadata** — Add missing Package metadata or fix inconsistencies in existing metadata
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: jumps from option 4 to option 8 in the user-facing menu. Should be 5 (or renumber the Core Team section to leave room).


### Core Team Tasks

Expand All @@ -84,6 +93,7 @@ What overlay task would you like to do?
| 2, "update", "bump", "upgrade", "version" | `workflows/update-plugin.md` |
| 3, "status", "check", "health" | Run inline status checks |
| 4, "fix", "debug", "failure", "error" | `workflows/fix-build.md` |
| 8, "metadata", "generate metadata", "add metadata", "audit", "audit metadata", "fix metadata", "check metadata", "validate metadata" | `workflows/generate-metadata.md` |

### Core Team Routes

Expand Down Expand Up @@ -158,6 +168,7 @@ See `../rhdh/references/github-reference.md` for full patterns.
| onboard-plugin.md | Full 6-phase process to add new plugin |
| update-plugin.md | Bump to newer upstream version |
| fix-build.md | Debug and resolve CI failures |
| generate-metadata.md | Generate missing Package metadata and audit existing metadata for consistency |

### Core Team Workflows

Expand Down
171 changes: 127 additions & 44 deletions skills/overlay/references/metadata-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,61 +11,153 @@ Two entity kinds work together:
<package_entity>
**Location:** `workspaces/<name>/metadata/<package>.yaml`

**Purpose:** Defines a single exportable package with its configuration.
**Purpose:** Defines a single exportable package with its OCI artifact reference and configuration.

**Frontend plugin example:**

```yaml
apiVersion: extensions.backstage.io/v1alpha1
kind: Package
metadata:
name: backstage-community-plugin-dynatrace
namespace: rhdh
title: "Dynatrace"
links:
- url: https://red.ht/rhdh
title: Homepage
- url: https://github.com/backstage/community-plugins/issues
title: Bugs
- title: Source Code
url: https://github.com/backstage/community-plugins/tree/main/workspaces/dynatrace/plugins/dynatrace
annotations:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

supportedVersions: 1.45.3 but the dynamicArtifact tag above uses bs_1.49.4. These should match — this is the reference doc that agents will follow when generating metadata.

Same issue with the backend example below (supportedVersions: 1.48.3 vs bs_1.49.4 in the tag).

backstage.io/source-location: url:https://github.com/backstage/community-plugins/tree/main/workspaces/dynatrace/plugins/dynatrace
tags: []
spec:
packageName: "@backstage-community/plugin-dynatrace"
dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-dynatrace:bs_1.49.4__10.17.0!backstage-community-plugin-dynatrace
version: 10.17.0
backstage:
role: frontend-plugin
supportedVersions: 1.45.3
author: Dynatrace
support: community
lifecycle: active
partOf:
- dynatrace-community
appConfigExamples:
- title: Default configuration
content:
dynamicPlugins:
frontend:
backstage-community.plugin-dynatrace:
mountPoints:
- mountPoint: entity.page.monitoring/cards
importName: DynatraceTab
config:
layout:
gridColumn: 1 / -1
if:
allOf:
- isDynatraceAvailable
```

**Backend plugin example (with config):**

```yaml
apiVersion: extensions.backstage.io/v1alpha1
kind: Package
metadata:
name: <package-name> # e.g., backstage-plugin-aws-codebuild
title: <Display Name>
description: <Brief description>
name: backstage-community-plugin-redhat-argocd-backend
namespace: rhdh
title: "ArgoCD Backend"
links:
- url: https://red.ht/rhdh
title: Homepage
- url: https://github.com/backstage/community-plugins/issues
title: Bugs
- title: Source Code
url: https://github.com/backstage/community-plugins/tree/main/workspaces/argocd/plugins/argocd-backend
annotations:
backstage.io/source-location: url:https://github.com/backstage/community-plugins/tree/main/workspaces/argocd/plugins/argocd-backend
tags: []
spec:
packageName: <npm-package-name> # e.g., @aws/backstage-plugin-aws-codebuild

# Dynamic plugin configuration
dynamicPluginConfig:
frontend:
# or backend: for backend plugins
mountPoints:
- id: entity-card
importName: AwsCodeBuildCard
config:
layout:
gridColumnEnd: span 4

# Example app-config.yaml snippets
packageName: "@backstage-community/plugin-argocd-backend"
dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-argocd-backend:bs_1.49.4__1.4.0!backstage-community-plugin-argocd-backend
version: 1.4.0
backstage:
role: backend-plugin
supportedVersions: 1.48.3
author: Red Hat
support: community
lifecycle: active
partOf:
- redhat-argocd
appConfigExamples:
- title: Basic Configuration
content: |
aws:
codebuild:
accountId: '123456789012'
region: us-east-1
- title: Default configuration
content:
argocd:
username: ${ARGOCD_USERNAME}
password: ${ARGOCD_PASSWORD}
appLocatorMethods:
- type: config
instances:
- name: argoInstance1
url: ${ARGOCD_INSTANCE1_URL}
token: ${ARGOCD_AUTH_TOKEN}
```

**Key sections:**
**Backend plugin example (no config):**

```yaml
spec:
# ... other fields ...
backstage:
role: backend-plugin
supportedVersions: 1.48.3
appConfigNotRequired: true
appConfigExamples: []
```

- `dynamicPluginConfig` — how the plugin mounts in RHDH
- `appConfigExamples` — configuration snippets for users
**Key fields:**

| Field | Source | Required |
|-------|--------|----------|
| `metadata.name` | Derived from `packageName`: strip `@`, replace `/` with `-`. Shorten if >63 chars. | Yes |
| `metadata.namespace` | Always `rhdh` | Yes |
| `spec.packageName` | npm package name from upstream `package.json` | Yes |
| `spec.dynamicArtifact` | OCI URL: `oci://ghcr.io/.../name:bs_<bsVer>__<ver>!name` | Yes |
| `spec.version` | From upstream `package.json` | Yes |
| `spec.backstage.role` | `frontend-plugin` or `backend-plugin` from upstream `package.json` | Yes |
| `spec.backstage.supportedVersions` | From overlay `backstage.json` override, or `source.json` `repo-backstage-version` | Yes |
| `spec.author` | From upstream `package.json` or copy from existing workspace metadata | Yes |
| `spec.support` | Typically `community` for new plugins | Yes |
| `spec.lifecycle` | Typically `active` | Yes |
| `spec.partOf` | References the Plugin entity `metadata.name` | Yes |
| `spec.appConfigNotRequired` | `true` when no config schema exists (backend only) | Conditional |
| `spec.appConfigExamples` | Config examples derived from `config.d.ts` + frontend wiring | Yes |

**Name shortening (when >63 chars):**

Apply rules from [shorten-component-name.sh](https://github.com/redhat-developer/rhdh-plugin-export-utils/blob/main/common/scripts/shorten-component-name.sh):
`backstage-community-plugin` → `bcp`, `backstage-plugin` → `bsp`, `red-hat-developer-hub-` → `rhdh-`, `catalog` → `ctlg`, `module` → `mod`, `kubernetes` → `k8s`, `bitbucket` → `bbckt`
</package_entity>

<plugin_entity>
**Location:** `catalog-entities/marketplace/plugins/<name>.yaml`
**Location:** `catalog-entities/extensions/plugins/<name>.yaml`

**Purpose:** User-facing catalog entry that groups related packages.

```yaml
apiVersion: extensions.backstage.io/v1alpha1
kind: Plugin
metadata:
name: <plugin-name> # e.g., aws-codebuild
name: <plugin-name>
namespace: rhdh
title: <Display Title>
description: <Brief description for listing>
annotations:
extensions.backstage.io/icon: <icon-url>
spec:
# Full markdown documentation
description: |
## Overview
<What the plugin does>
Expand All @@ -76,32 +168,23 @@ spec:

## Configuration
<How to configure>

# Packages included in this plugin
packages:
- backstage-plugin-aws-codebuild
- backstage-plugin-aws-codebuild-backend

# For filtering in catalog
- <package-metadata-name-1>
- <package-metadata-name-2>
categories:
- CI/CD
- Cloud

# Feature highlights
highlights:
- Build status visibility
- Project history
- Start/stop builds

# Support level
developer: AWS
developer: <Author>
supportLevel: community
```

**Registration:**
Add to `catalog-entities/marketplace/plugins/all.yaml` (alphabetical order).
Add to `catalog-entities/extensions/plugins/all.yaml` (alphabetical order).
</plugin_entity>

<documentation_link>
Full annotated example: [catalog-entities/marketplace/README.md](https://github.com/redhat-developer/rhdh-plugin-export-overlays/blob/main/catalog-entities/marketplace/README.md)
Full annotated example: [catalog-entities/extensions/README.md](https://github.com/redhat-developer/rhdh-plugin-export-overlays/blob/main/catalog-entities/extensions/README.md)
</documentation_link>
Loading
Loading