agentleFS
redhat-developerredhat-developer/rhdh/.claude/skills/patch-backstage/SKILL.md

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
  1. Very specific:

    Stop and ask: when RHDH_VERSION, COMMITS, clone paths, or workspace ownership is missing or ambiguous—not for a second confirmation when …

    line 65
  2. Very specific:

    RHDH: Remove stale .patch + resolutions for targets.

    line 79
  3. Distinctive:

    Ask: if intent is vague (“sync Backstage” only) or they may want a maintenance PR for traceability despite identical source.

    line 118
  4. Very specific:

    Remove prior .patch files and matching resolutions entries for the packages you are refreshing.

    line 136
  5. Very specific:

    Run from RHDH root.

    line 141
  6. Very specific:

    Do not invent patch/release-* if missing on redhat-developer/backstage.

    line 181
  7. Distinctive:

    No blind conflict resolution on cherry-picks.

    line 182

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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 on master (merged fixes). Fetch master from BACKSTAGE_UPSTREAM_REMOTE so those objects exist in the maintenance clone for git 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

RepoRole
redhat-developer/rhdhPatches live here. Sync release-<VERSION>; run yarn patch here.
redhat-developer/backstageMaintenance fork: patch/release-<VERSION>, optional cherry-pick, yarn build per package cd, copy dist/ into RHDH patch temps. PRs from your fork.
backstage/backstageUpstream 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

NameRequiredNotes
RHDH_VERSIONYese.g. 1.9 → release-1.9, patch/release-1.9. Do not infer from the current branch.
RHDH_ROOTNoAbsolute path to the RHDH repo root (appears as <RHDH_ROOT> in examples). Inferred from context if omitted.
COMMITSTypicalUpstream SHAs (oldest first for cherry-pick). If no SHAs, manual dist / patch only.
PACKAGESIf 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 as origin.
  • Upstream Backstage (fetch COMMITS only): 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 && and cd <RHDH_ROOT>; cwd may not persist between tool calls. Use network / git_write / all as needed (all for rm/cp into 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 patch overlays dist/ on the version RHDH already resolves (lockfile), so PACKAGE_VERSION must come from yarn 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)

  1. Pre-flight: Clean trees and remotes (Step 1 opening + Git remotes); set RHDH_CORE_REMOTE, BACKSTAGE_UPSTREAM_REMOTE, optional FORK_REMOTE (your Backstage fork for PRs).
  2. RHDH: HUSKY=0 fetch/checkout/pull release-<RHDH_VERSION>.
  3. Maintenance: Fetch patch/release-* from redhat-developer; HUSKY=0 checkout -B; git fetch <BACKSTAGE_UPSTREAM_REMOTE> master (upstream integration branch for COMMITS); pre-check; cherry-pick or patch-only path; yarn build per PACKAGES (cd + yarn build, not root yarn workspace … build).
  4. RHDH: Remove stale .patch + resolutions for targets; yarn why → versions; yarn patch / replace dist / patch-commit; clean up resolutions; yarn install.
  5. Verify: @patch: in each relevant yarn.lock; yarn why shows via 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.

  1. git remote -v → RHDH_CORE_REMOTE = remote for redhat-developer/rhdh.
  2. HUSKY=0 git fetch … release-<RHDH_VERSION> && HUSKY=0 git checkout … && HUSKY=0 git pull …. Fail if the branch is missing.
  3. 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_HEAD

Then 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):

  1. git show --name-only --pretty=format: <SHA>
  2. Drop bookkeeping-only paths: root package.json, CHANGELOG.md, package package.json version-only edits, .changeset/, docs/, lockfiles, etc. Keep src/, tests, fixtures tied to the fix.
  3. 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 COMMITS on this release-*: 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

  1. Remove prior .patch files and matching resolutions entries for the packages you are refreshing.
  2. 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:

  1. yarn patch <package>@npm:<PACKAGE_VERSION>
  2. rm -rf <PATCH_TEMP>/dist && cp -r <backstage-clone>/<plugins|packages>/.../dist <PATCH_TEMP>/dist
  3. yarn patch-commit -s <PATCH_TEMP> in that workspace.

After yarn patch-commit (cleanup — required)

  1. Replace any bare "@backstage/foo": "1.2.3" in resolutions with the single patch: locator Yarn printed—do not leave bare semver beside new patch keys (patch may not apply; Step 5 will show plain @npm:).
  2. Delete spurious range keys patch-commit added (e.g. @backstage/foo@^1.6.0 → patch built from @npm:1.5.0).
  3. Install: yarn install.

Step 5: Verify (required)

Incomplete until every patched package shows a patch locator in yarn.lock and yarn why.

  1. yarn install in each touched project.
  2. grep '@backstage/<pkg>@patch' yarn.lock.
  3. yarn why @backstage/<pkg> in the same directory: must include via patch: / @…@patch:, not only via 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

  1. Links: https://github.com/backstage/backstage/commit/<SHA> for each COMMITS entry.
  2. PACKAGES, patch locations, notable resolutions keys.
  3. Cherry-pick skipped vs applied; conflicts/aborts if any.
  4. MAINTENANCE_BRANCH, optional Backstage PR link; RHDH PR intent.
  5. 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)

SymptomWhat to do
Wrong maintenance tipFetch https://github.com/redhat-developer/backstage.git patch/release-<V>, checkout -B … FETCH_HEAD
bad object on cherry-pick / showgit fetch <BACKSTAGE_UPSTREAM_REMOTE> master
Checkout/pull fails after Yarn / HuskyHUSKY=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 versionUse yarn why version, not RHDH meta-version
Skill not in Cursor.rulesync/skills/ may not sync to .cursor/—see Rulesync / Cursor

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.