From 0b56e8fd9d59df27ee35fe938d7f85a826a7bfcd Mon Sep 17 00:00:00 2001 From: Noah Talerman <47070608+noahtalerman@users.noreply.github.com> Date: Wed, 24 Jun 2026 18:13:04 -0400 Subject: [PATCH] New Claude skill: `/push-reference-docs` (#48172) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Example usage: Screenshot 2026-06-24 at 9 18 32 AM Output: - https://github.com/fleetdm/fleet/pull/48170 - https://github.com/fleetdm/fleet/pull/48171 --------- Co-authored-by: melpike <79950145+melpike@users.noreply.github.com> --- .claude/skills/push-reference-docs/SKILL.md | 154 ++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 .claude/skills/push-reference-docs/SKILL.md diff --git a/.claude/skills/push-reference-docs/SKILL.md b/.claude/skills/push-reference-docs/SKILL.md new file mode 100644 index 0000000000..d83470cd41 --- /dev/null +++ b/.claude/skills/push-reference-docs/SKILL.md @@ -0,0 +1,154 @@ +--- +name: push-reference-docs +description: Move reference doc updates from one release docs branch to another (e.g., 4.89 → 4.90) when a feature is pushed to a later release. Handles three PR states — open (retarget), closed-without-merge (apply-only), merged (revert + apply). +allowed-tools: Bash(git *), Bash(gh pr *), Bash(gh api *), Read, Grep, Glob +effort: medium +--- + +Move reference doc changes from one release docs branch to another. Use when a feature was documented for release X but is being pushed to release Y — the doc changes need to be reverted from X's docs branch and applied to Y's docs branch. + +Arguments: $ARGUMENTS + +Usage: `/push-reference-docs ` + +- `PR_NUMBER` (required): The docs PR number that was (or will be) merged into the source docs branch. +- `TARGET_DOCS_BRANCH` (required): The docs branch for the release the feature is moving to (e.g., `docs-v4.90.0`). + +The source docs branch is auto-detected from the PR's base branch. + +## Step 1: Fetch and get PR details + +1. Fetch upstream. The upstream remote is often SSH (`git@github.com:...`), which can fail silently and leave a stale cached ref — a stale ref causes branches to be based on an old snapshot, producing extra files in the PR diff. Always verify the fetch succeeded: + ``` + git fetch upstream 2>&1 + ``` + If it fails (e.g. "Permission denied (publickey)"), switch to HTTPS and retry: + ``` + git remote set-url upstream https://github.com/.git + git fetch upstream + ``` + +2. Get PR details (include `state` to detect closed-without-merge): + ``` + gh pr view --json title,baseRefName,headRefName,mergeCommit,commits,url,state + ``` +3. Extract: + - `SOURCE_DOCS_BRANCH` = the PR's `baseRefName` (e.g., `docs-v4.89.0`) + - `PR_STATE` = `state` — one of `OPEN`, `MERGED`, `CLOSED` + - `MERGE_COMMIT` = `mergeCommit.oid` — null if the PR is not yet merged or was closed without merging + - `ALL_COMMITS` = all commit SHAs in `commits[].oid`, in order (oldest first) + - `HEAD_COMMIT` = the last commit SHA in `commits[].oid` + - `PR_TITLE` = the PR title + - `UPSTREAM_REPO` = the org/repo from the PR URL (e.g., `fleetdm/fleet`): + ``` + gh pr view --json url --jq '.url | split("/")[3:5] | join("/")' + ``` +4. Get your GitHub username: `gh api user --jq .login` + +## Step 2: Branch based on PR state + +There are three cases. Check `PR_STATE` first, then `MERGE_COMMIT`. + +### If the PR is OPEN and not yet merged (`PR_STATE == "OPEN"`) — retarget path + +The simplest and correct approach: retarget the original PR from the source docs branch to the target docs branch. This avoids creating a revert branch with an empty diff (a git revert against a branch that doesn't have the changes yet is always a no-op). + +1. Retarget the original PR. Always use the REST API — `gh pr edit --base` fails on fleetdm/fleet with a GraphQL "Projects (classic)" deprecation error: + ``` + gh api repos//pulls/ --method PATCH --field base= --jq '.base.ref' + ``` +2. Report to the user: "PR #N has been retargeted from `` to ``. No separate revert or apply PR is needed — the existing PR now targets the correct branch." +3. **Stop here.** Steps 3 and 4 are not needed for the open/unmerged case. + +### If the PR is CLOSED without merging (`PR_STATE == "CLOSED"` and `MERGE_COMMIT` is null) — apply-only path + +The changes were never applied to the source branch, so no revert is needed. Only create the apply PR. + +**Check for an existing apply PR first:** search for any open PR against `` that references ``: +``` +gh pr list --repo --state open --base --search "" --json number,title,url +``` +If one exists, **verify its diff before reusing it**: +``` +gh pr diff --stat +``` +Compare the file count and line count to the original PR's diff stat (`gh pr diff --stat`). If they match, retarget or use as-is. If the existing PR has significantly more files or lines, its branch was based on a stale upstream ref — discard it (let the user close it) and create a fresh branch below. + +- `WORKING_COMMITS = ALL_COMMITS` (cherry-pick all commits in order, not just HEAD_COMMIT — the first commit usually contains the bulk of the changes) +- Skip Step 3 entirely. +- Proceed to Step 4, cherry-picking all commits in `ALL_COMMITS` order. + +Note: You cannot retarget a closed PR via the API — GitHub returns a 422 error. A new PR must be created. + +### If the PR IS merged (`PR_STATE == "MERGED"` / `MERGE_COMMIT` is non-null) — revert + apply path + +- `WORKING_COMMIT = MERGE_COMMIT` +- Proceed to Steps 3 and 4. + +## Step 3: Create the revert PR (from source docs branch) + +This PR removes the doc changes from the source release's docs branch. + +1. Create the revert branch from the tip of the source docs branch (which already contains the merge commit in its history): + ``` + git checkout -b /revert-pr-from- upstream/ + ``` +2. Revert the merge commit. Check if it has multiple parents: + ``` + git rev-list --parents -n 1 + ``` + - Multiple parents → `git revert -m 1 --no-edit ` + - Single parent → `git revert --no-edit ` +3. If there are conflicts, stop and tell the user which files conflict. +4. Push: `git push -u origin HEAD` +5. Open the PR: + ``` + gh pr create --repo --base \ + --title "Revert \"\" from " \ + --body "$(cat <<'EOF' + Reverts # from ``. Feature is moving to ``. + + **Related:** # + EOF + )" + ``` + +## Step 4: Create the apply PR (to target docs branch) + +This PR adds the doc changes to the new release's docs branch. + +1. Create a branch from the target docs branch: + ``` + git checkout -b /pr-docs-to- upstream/ + ``` +2. Cherry-pick commits: + - **CLOSED path (multiple commits):** cherry-pick all commits in `ALL_COMMITS` order: + ``` + git cherry-pick ... + ``` + - **MERGED path (merge commit):** check parent count first: + - Multiple parents → `git cherry-pick -m 1 ` + - Single parent → `git cherry-pick ` +3. If there are conflicts, resolve them manually — the target branch may have received commits since the cherry-picked commit was authored. Keep all content: the new additions from the cherry-pick plus any new sections added by later commits on the target branch. After resolving: `git add && git cherry-pick --continue --no-edit`. +4. **Verify the diff before pushing.** Run `git diff upstream/...HEAD --stat` and confirm the file count and line count match the original PR's diff stat. If they don't, something went wrong with the cherry-pick or the upstream ref is stale. +5. Push: `git push -u origin HEAD` + - If you previously pushed this branch with a different base (e.g., after correcting a stale upstream ref), force-push: `git push --force origin HEAD` +6. Open the PR: + ``` + gh pr create --repo --base \ + --title "" \ + --body "$(cat <<'EOF' + Moves reference doc changes from # to ``. + + Originally documented for `` — feature pushed to this release. + + **Related:** # + EOF + )" + ``` + +## Step 5: Report to user + +- **Open/unmerged path**: report that the original PR was retargeted and include its URL. +- **Closed-without-merge path**: report the apply PR URL. Note that no revert was needed since the changes were never merged. +- **Merged path**: report the revert PR URL and the apply PR URL.