-
Notifications
You must be signed in to change notification settings - Fork 55
Metadata Synchronization
This guide covers the process of keeping your plugin metadata synchronized between the source repository and the overlay repository.
The overlay repository doesn't store your plugin's source code—it stores references and metadata. When these drift from the actual source, problems occur:
| Drift Type | Symptom | Impact |
|---|---|---|
| Version mismatch | Build uses wrong tag | Old bugs, missing features |
| Backstage version wrong | Compatibility check fails | PR blocked, build failures |
| Package name changed | OCI tagging fails | Plugin not found at runtime |
| Description outdated | Catalog shows wrong info | User confusion |
| source.json Field | Must Match |
|---|---|
repo |
Repository URL where plugin lives |
repo-ref |
Exact tag or commit SHA for the version you want |
repo-backstage-version |
Backstage version declared in source's root package.json
|
| Metadata Field | Source Field |
|---|---|
spec.packageName |
package.json:name |
spec.version |
package.json:version |
spec.backstage.role |
Derived from plugin type |
spec.backstage.supportedVersions |
Backstage deps in package.json
|
Note: For most plugins under supported scopes, the automated discovery workflow handles synchronization automatically. The manual steps below are for cases where automation does not apply or when you need to verify/override what automation produced.
How you identify the correct repo-ref depends on the source repository model:
Single-plugin repositories (e.g., backstage/backstage) use version tags:
git ls-remote --tags https://github.com/backstage/backstage | tail -20
# repo-ref example: "v1.45.3"Multi-plugin monorepos (e.g., backstage/community-plugins, redhat-developer/rhdh-plugins) typically use per-package tags. However, these tags point to individual plugin releases and there is no common workspace-level tag. When a workspace contains multiple plugins that may release independently, the preferred reference is often a commit SHA rather than a single package tag:
# Per-package tag (works when the workspace has a single plugin or all plugins share the same tag)
git ls-remote --tags https://github.com/backstage/community-plugins | grep "plugin-your-plugin"
# repo-ref example: "@backstage-community/plugin-your-plugin@1.2.3"
# Commit SHA (preferred for multi-plugin workspaces where plugins release independently)
# Use the commit that contains the versions you need for all plugins in the workspace
# repo-ref example: "abc123def456..."# Using a tag
curl -s "https://raw.githubusercontent.com/backstage/community-plugins/@backstage-community/plugin-your-plugin@1.2.3/workspaces/your-workspace/plugins/your-plugin/package.json" | jq '{name, version, backstage}'
# Using a commit SHA
curl -s "https://raw.githubusercontent.com/backstage/community-plugins/abc123def456/workspaces/your-workspace/plugins/your-plugin/package.json" | jq '{name, version, backstage}'Check the workspace's backstage.json:
curl -s "https://raw.githubusercontent.com/backstage/community-plugins/[ref]/workspaces/your-workspace/backstage.json" | jq '.version'Tag-based reference (single-plugin workspace or shared tag):
{
"repo": "https://github.com/backstage/community-plugins",
"repo-ref": "@backstage-community/plugin-your-plugin@1.2.3",
"repo-flat": false,
"repo-backstage-version": "1.45.0"
}Commit-based reference (multi-plugin workspace):
{
"repo": "https://github.com/redhat-developer/rhdh-plugins",
"repo-ref": "abc123def456789...",
"repo-flat": false,
"repo-backstage-version": "1.45.2"
}Update each file in metadata/*.yaml to match the source package.json at the ref you chose:
spec:
packageName: "@backstage-community/plugin-your-plugin" # Must match package.json:name
version: 1.2.3 # Must match package.json:version
backstage:
role: backend-plugin # Must match package.json:backstage.role
supportedVersions: 1.45.0 # Backstage version from backstage.jsonThe repository has automated workflows that create PRs for plugin updates.
Runs twice daily for scopes defined in workspace-discovery-include:
@backstage-community/@red-hat-developer-hub/@roadiehq/
Workspaces matching patterns in workspace-discovery-exclude are skipped.
You can trigger the discovery workflow on demand. Wrap the value in single quotes to target an exact package name rather than a regex pattern (see Option 2: Trigger Workflow Manually for a full explanation of quoting behavior).
# Exact package name (single quotes = literal match)
gh workflow run update-plugins-repo-refs.yaml \
-f regexps="'@backstage-community/plugin-your-plugin'" \
-f single-branch="main"
# Regex pattern (no quotes = pattern match)
gh workflow run update-plugins-repo-refs.yaml \
-f regexps="@backstage-community/plugin-your-plugin" \
-f single-branch="main"| File | Fields Updated |
|---|---|
source.json |
repo-ref, repo-backstage-version
|
metadata/*.yaml |
spec.version, spec.backstage.supportedVersions
|
Note: Automation does not update descriptions, links, or custom fields.
Before submitting your PR, verify:
## Sync Validation Checklist
### source.json
- [ ] `repo-ref` points to a valid tag or commit
- [ ] Tag/commit actually contains the plugin
- [ ] `repo-backstage-version` matches source Backstage version
### metadata/*.yaml (for each plugin)
- [ ] `spec.packageName` exactly matches source `package.json:name`
- [ ] `spec.version` exactly matches source `package.json:version`
- [ ] `spec.backstage.role` matches (frontend-plugin, backend-plugin, etc.)
- [ ] `spec.backstage.supportedVersions` is reasonable for source
### plugins-list.yaml
- [ ] Plugin path is correct for the source structure
- [ ] Any `--embed-package` args reference valid packagesCause: spec.version doesn't match source package.json:version
Fix:
# Get correct version
curl -s "https://raw.githubusercontent.com/[repo]/[ref]/path/to/package.json" | jq '.version'
# Update metadata fileCause: Plugin path in plugins-list.yaml doesn't exist in source at repo-ref
Fix:
-
Verify the plugin exists at the ref:
git ls-tree -r --name-only [ref] | grep "plugin-name"
-
Update path or
repo-refaccordingly
Cause: The repo-backstage-version declared in source.json is higher than the target Backstage version in versions.json. The automated workflow rejects updates where the source was built against a newer Backstage than the platform currently targets.
Fix:
- Find a plugin version whose source Backstage version is less than or equal to the target version in
versions.json - Update
repo-refto point to that version - Update
repo-backstage-versionto match the source's actual Backstage version
This check runs during the discovery/update workflow, not during the export build itself. It prevents the overlay from referencing a plugin version that is known to be incompatible with the target platform.
During the export build, the process verifies that the source package.json fields (name, version) match the metadata declared in the overlay. This catches cases where source.json:repo-ref and metadata/*.yaml:spec.version have drifted apart.
-
Verify you have the correct ref:
git ls-remote --refs https://github.com/[repo] | grep "[your-ref]"
-
Compare the source version with your metadata:
- Check
package.json:versionat the ref you are targeting - Confirm it matches
spec.versionin your metadata YAML
- Check
-
If the mismatch is intentional (e.g., a patch modifies the version), document the reason in your PR description
- ✅ Update metadata immediately when releasing new plugin versions
- ✅ Use exact tags (e.g.,
@backstage-community/plugin-x@1.2.3) not branches - ✅ Test with
/publishand/smoketestbefore merging - ✅ Keep descriptions and links current
- ❌ Point
repo-reftomainormasterbranches - ❌ Update
spec.versionwithout updatingrepo-ref - ❌ Use a per-package tag as
repo-refwhen the workspace contains other plugins at different versions (use a commit SHA instead)
- 05 - Version Updates – Backstage version update procedures
- 06 - Patch Management – When source needs modification
- 66 workspaces
- 6 with patches