patch-backstage
Skill171 starsChanged 20 days agoApache-2.0View on GitHub
Workflow to backport Backstage changes into RHDH by syncing a downstream maintenance branch and generating yarn patches.
- Deletes or force-pushes
We split this skill into the rules it gives an agent
7 rules. About 0 are common, 2 are distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 63
Stop and ask: when RHDH_VERSION, COMMITS, clone paths, or workspace ownership is missing or ambiguous—not for a second confirmation when …
- Very specific: line 77
RHDH: Remove stale .patch + resolutions for targets.
- Distinctive: line 116
Ask: if intent is vague (“sync Backstage” only) or they may want a maintenance PR for traceability despite identical source.
- Very specific: line 134
Remove prior .patch files and matching resolutions entries for the packages you are refreshing.
- Very specific: line 139
Run from RHDH root.
- Very specific: line 179
Do not invent patch/release-* if missing on redhat-developer/backstage.
- Distinctive: line 180
No blind conflict resolution on cherry-picks.
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
RHDH Patch Generator
Purpose
Ship a fix on an RHDH release-* line without bumping published Backstage versions by adding Yarn patches (.yarn/patches/, package.json resolutions, lockfiles).
COMMITS: SHAs on backstage/backstage that are onmaster(merged fixes). FetchmasterfromBACKSTAGE_UPSTREAM_REMOTEso those objects exist in the maintenance clone forgit show/ cherry-pick.- Build source: redhat-developer/backstage at
patch/release-<VERSION>only (not a separate upstream checkout). - Cherry-pick those SHAs onto maintenance only if the pre-check shows maintenance source still differs; otherwise build + patch RHDH only.
Repos
| Repo | Role |
| redhat-developer/rhdh | Patches live here. Sync release-<VERSION>; run yarn patch here. |
| redhat-developer/backstage | Maintenance fork: patch/release-<VERSION>, optional cherry-pick, yarn build per package cd, copy dist/ into RHDH patch temps. PRs from your fork. |
| backstage/backstage | Upstream object source only: remote on the same maintenance clone, git fetch for COMMITS. Do not use a second upstream checkout as the build tree. |
Parameters
| Name | Required | Notes |
RHDH_VERSION | Yes | e.g. 1.9 → release-1.9, patch/release-1.9. Do not infer from the current branch. |
RHDH_ROOT | No | Absolute path to the RHDH repo root (appears as <RHDH_ROOT> in examples). Inferred from context if omitted. |
COMMITS | Typical | Upstream SHAs (oldest first for cherry-pick). If no SHAs, manual dist / patch only. |
PACKAGES | If unclear | @backstage/... names. Derive from COMMITS (below) when paths map cleanly. |
Path map: @backstage/plugin-<id> → plugins/<id>/; other @backstage/<id> → packages/<id>/.
Deriving PACKAGES from COMMITS
In the maintenance clone, after git fetch <BACKSTAGE_UPSTREAM_REMOTE> master so COMMITS exist locally: git show --name-only --pretty=format: <SHA> (union for multiple SHAs). Map plugins/* and packages/* roots; read each package.json name; dedupe. Ignore-only changes (root lockfile, .changeset/, docs/, version-only package.json) → ask which packages to patch.
Example: 66e08b08f94a31cbf28b416c89b61549bc3b64a2 → @backstage/cli-common, @backstage/backend-plugin-api, @backstage/plugin-techdocs-node.
Git remotes, hooks, and where this skill file lives
Map remotes by URL in each clone (git remote -v); never assume upstream means a given org.
- RHDH core (
release-*): URL redhat-developer/rhdh →RHDH_CORE_REMOTE. - Maintenance Backstage (
patch/release-*, fork push): URL redhat-developer/backstage + usually your fork asorigin. - Upstream Backstage (fetch
COMMITSonly): URL backstage/backstage →BACKSTAGE_UPSTREAM_REMOTE.
Exact maintenance tip:git fetch https://github.com/redhat-developer/backstage.git patch/release-<RHDH_VERSION>
then HUSKY=0 git checkout -B patch/release-<RHDH_VERSION> FETCH_HEAD when Husky would otherwise run on checkout.
Silencing hooks: For branch sync only (Steps 1–2: fetch/checkout/pull/checkout -B, and git cherry-pick when you are not relying on hook side effects), prefix with HUSKY=0. Omit HUSKY=0 on git commit if you want lint-staged locally.
cd <RHDH_ROOT> && HUSKY=0 git fetch <RHDH_CORE_REMOTE> release-<V> && HUSKY=0 git checkout release-<V> && HUSKY=0 git pull <RHDH_CORE_REMOTE> release-<V>Rulesync: Edit SKILL.md only under .rulesync/skills/patch-backstage/ (rulesync expects one directory per skill with SKILL.md inside; a flat *.md at skills/ root is ignored). With "skills" and "simulateSkills": true in rulesync.jsonc, yarn rulesync:generate writes both .claude/skills/ and .cursor/skills/ from that tree (rulesync treats Cursor skill output as “simulated”). Stage and commit generated paths with .rulesync/ after edits.
Agent execution
- Batch related shell commands with
&&andcd <RHDH_ROOT>; cwd may not persist between tool calls. Usenetwork/git_write/allas needed (allforrm/cpinto Yarn patch temps or stubborn sandboxes). - Stop and ask when
RHDH_VERSION,COMMITS, clone paths, or workspace ownership is missing or ambiguous—not for a second confirmation when the user already asked for yarn patches for given SHAs (see Pre-check → patch-only). - Do not invent remotes or wander with speculative
find; do run steps this doc names (git remote -v,yarn why, etc.).
Dist baseline
yarn patchoverlaysdist/on the version RHDH already resolves (lockfile), soPACKAGE_VERSIONmust come fromyarn why, not from “what Backstage released.”- Compile only on redhat-developer/backstage
patch/release-<RHDH_VERSION>after fetching that ref from redhat-developer (local/fork tips can diverge by name). - Do not build from backstage/backstage release tags or other upstream checkouts to “match” versions unless this workflow is explicitly extended.
Workflow (overview)
- Pre-flight: Clean trees and remotes (Step 1 opening + Git remotes); set
RHDH_CORE_REMOTE,BACKSTAGE_UPSTREAM_REMOTE, optionalFORK_REMOTE(your Backstage fork for PRs). - RHDH:
HUSKY=0fetch/checkout/pullrelease-<RHDH_VERSION>. - Maintenance: Fetch
patch/release-*from redhat-developer;HUSKY=0 checkout -B;git fetch <BACKSTAGE_UPSTREAM_REMOTE> master(upstream integration branch forCOMMITS); pre-check; cherry-pick or patch-only path;yarn buildperPACKAGES(cd+yarn build, not rootyarn workspace … build). - RHDH: Remove stale
.patch+resolutionsfor targets;yarn why→ versions;yarn patch/ replacedist/patch-commit; clean upresolutions;yarn install. - Verify:
@patch:in each relevantyarn.lock;yarn whyshowsvia patch:; commit artifacts.
Step 1: Sync RHDH
Pre-flight (both repos): git status clean in RHDH and the maintenance Backstage clone (stash WIP or git merge --abort / git rebase --abort as needed). Do not run the workflow mid-conflict.
git remote -v→RHDH_CORE_REMOTE= remote for redhat-developer/rhdh.HUSKY=0 git fetch … release-<RHDH_VERSION>&&HUSKY=0 git checkout …&&HUSKY=0 git pull …. Fail if the branch is missing.- Set
MAINTENANCE_BRANCH=patch/release-<RHDH_VERSION>(used when opening a Backstage PR).
Step 2: Maintenance clone
One clone with redhat-developer/backstage + backstage/backstage remotes.
2.1 Sync patch/release-*
git fetch https://github.com/redhat-developer/backstage.git patch/release-<RHDH_VERSION> \
&& HUSKY=0 git checkout -B patch/release-<RHDH_VERSION> FETCH_HEADThen git fetch <BACKSTAGE_UPSTREAM_REMOTE> master. backstage/backstage lands merged work on master; COMMITS should be reachable from master. Do not check out upstream as the build tree.
2.2 Pre-check (skip cherry-pick when source already matches)
For each SHA in COMMITS (oldest first):
git show --name-only --pretty=format: <SHA>- Drop bookkeeping-only paths: root
package.json,CHANGELOG.md, packagepackage.jsonversion-only edits,.changeset/,docs/, lockfiles, etc. Keepsrc/, tests, fixtures tied to the fix. git diff <SHA> HEAD -- <kept paths>(union paths if multiple SHAs).
Empty diff → maintenance already has the functional fix; do not cherry-pick (avoids changelog/version noise).
2.3 Patch-only vs ask
- Proceed without extra confirmation if the user already asked for yarn patches for
COMMITSon thisrelease-*: empty pre-check → go to 2.6 Build and RHDH Steps 3–5; note in the Final summary that cherry-pick was skipped. - Ask if intent is vague (“sync Backstage” only) or they may want a maintenance PR for traceability despite identical source.
2.4 Cherry-pick (when pre-check was non-empty)
git cherry-pick <SHA> (oldest first) onto patch/release-*.
Conflicts: Prefer the cherry-picked commit’s content for conflicted src/ (during cherry-pick, git checkout --theirs -- <path> refers to that commit). If fixing conflicts would drop the functional fix, or conflicts are only changelog/version noise you should not merge, git cherry-pick --abort, note it in the Final summary, and coordinate with the user. Do not push a broken maintenance branch.
2.5 Push maintenance (optional)
Push to FORK_REMOTE and open a PR to redhat-developer/backstage base MAINTENANCE_BRANCH (no direct push to redhat-developer).
2.6 Build PACKAGES
For each package: cd plugins/<id>/ or packages/<id>/ → yarn build. If dist-types or build fails: maintenance repo root yarn install / yarn tsc, then retry per-package yarn build.
Step 3: Prepare RHDH
- Remove prior
.patchfiles and matchingresolutionsentries for the packages you are refreshing. yarn why @backstage/<pkg>from RHDH root. Record PACKAGE_VERSION for Step 4.
Step 4: Generate patches
Run from RHDH root.
Temp folder: Each yarn patch … prints a new path—use it immediately for rm, cp, yarn patch-commit -s (same shell or paste path). Do not reuse an old temp. Sandboxes may need all for cp into system temp.
Per package:
yarn patch <package>@npm:<PACKAGE_VERSION>rm -rf <PATCH_TEMP>/dist&&cp -r <backstage-clone>/<plugins|packages>/.../dist <PATCH_TEMP>/distyarn patch-commit -s <PATCH_TEMP>in that workspace.
After yarn patch-commit (cleanup — required)
- Replace any bare
"@backstage/foo": "1.2.3"inresolutionswith the singlepatch:locator Yarn printed—do not leave bare semver beside new patch keys (patch may not apply; Step 5 will show plain@npm:). - Delete spurious range keys
patch-commitadded (e.g.@backstage/foo@^1.6.0→ patch built from@npm:1.5.0). - Install:
yarn install.
Step 5: Verify (required)
Incomplete until every patched package shows a patch locator in yarn.lock and yarn why.
yarn installin each touched project.grep '@backstage/<pkg>@patch' yarn.lock.yarn why @backstage/<pkg>in the same directory: must includevia patch:/@…@patch:, not onlyvia npm:<version>.
Optional: Spot-check node_modules/@backstage/<pkg>/dist/.
Commit: .yarn/patches/*.patch, package.json resolutions, yarn.lock; PR to RHDH.
PR CI: a change under .yarn/patches/ makes PR CI build and test every package (not --affected) and run the Backstage bump checks job. See scripts/backstage-bump-check/README.md. It exercises the patched code only where existing tests reach it; E2E remains the integration gate.
Final summary
- Links:
https://github.com/backstage/backstage/commit/<SHA>for eachCOMMITSentry. PACKAGES, patch locations, notableresolutionskeys.- Cherry-pick skipped vs applied; conflicts/aborts if any.
MAINTENANCE_BRANCH, optional Backstage PR link; RHDH PR intent.RHDH_VERSION.
Safety
- Do not invent
patch/release-*if missing on redhat-developer/backstage. - No blind conflict resolution on cherry-picks; no direct push to redhat-developer remotes without process.
Common issues (quick reference)
| Symptom | What to do |
| Wrong maintenance tip | Fetch https://github.com/redhat-developer/backstage.git patch/release-<V>, checkout -B … FETCH_HEAD |
bad object on cherry-pick / show | git fetch <BACKSTAGE_UPSTREAM_REMOTE> master |
| Checkout/pull fails after Yarn / Husky | HUSKY=0 on those git commands |
yarn why / lockfile: no @patch: | Remove bare semver resolutions for that pkg; use one patch: locator; drop wrong range keys; reinstall |
| Build fails (missing types) | Maintenance root yarn install / yarn tsc, then cd package yarn build |
| Patch wrong version | Use yarn why version, not RHDH meta-version |
| Skill not in Cursor | .rulesync/skills/ may not sync to .cursor/—see Rulesync / Cursor |
In this repository20 other files it gives its agents.
- .cursor/rules/add_extension_metadata.mdcCursor rule
- .cursor/rules/ci-e2e-testing.mdcCursor rule
- .cursor/rules/e2e-coverage-imports.mdcCursor rule
- .cursor/rules/e2e-fix-workflow.mdcCursor rule
- .cursor/rules/github-workflows-security.mdcCursor rule
- .cursor/rules/managing-ai-rules.mdcCursor rule
- .cursor/rules/playwright-locators.mdcCursor rule
- e2e-deploy-rhdhSkill
- e2e-diagnose-and-fixSkill
- e2e-parse-ci-failureSkill
- e2e-reproduce-failureSkill
- e2e-submit-and-reviewSkill
- e2e-verify-fixSkill
- patch-backstageSkill
- e2e-deploy-rhdhSkill
- e2e-diagnose-and-fixSkill
- e2e-parse-ci-failureSkill
- e2e-reproduce-failureSkill
- e2e-submit-and-reviewSkill
- e2e-verify-fixSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

