Skip to content

fix(skill): repair three broken commands in the release skill - #104

Merged
pofallon merged 1 commit into
mainfrom
fix/release-skill-pr-discovery
Jul 27, 2026
Merged

fix(skill): repair three broken commands in the release skill#104
pofallon merged 1 commit into
mainfrom
fix/release-skill-pr-discovery

Conversation

@pofallon

Copy link
Copy Markdown
Contributor

Why

While answering "how do I test a build before cutting a version", I ran the release skill's own commands against the repo. Three of them fail as written. Each failure and each replacement is verified against the live repo, where release-please PR #81 (chore(main): release 3.0.0) is currently open.

1. PR discovery returned zero results while the PR existed

gh pr list --state open --json number,title,headRefName,url \
  --search 'chore(main): release in:title'     # -> 0 results

GitHub's search parser drops the chore(main): prefix. Replaced with a --jq filter matching either signal — the release-please--* head branch or the title prefix — so a change to either still finds the PR.

This bug's failure mode is the dangerous kind. "Filter is broken" and "no release PR exists" are indistinguishable from the caller's side, and the skill's instruction on that branch is to stop. As written it silently strands a real release and reports the opposite. Added a guard clause: sanity-check with a bare gh pr list --state open before concluding nothing is there.

2. gh pr diff has no pathspec support

gh pr diff 81 -- pyproject.toml CHANGELOG.md
# accepts at most 1 arg(s), received 3

Replaced with gh api repos/{owner}/{repo}/pulls/<n>/files filtered by filename (gh expands the {owner}/{repo} placeholders — verified). Added a pointer to read the ⚠ BREAKING CHANGES block, since that is what drove #81 to a major bump.

3. gh run watch needs an explicit run id outside a TTY

gh run watch
# run ID required when not running interactively

The skill runs it non-interactively, so it never worked there. Both occurrences now resolve the run id via gh run list --limit 1 first; the dev-build block reuses that id for the following gh run download instead of leaving a <run-id> placeholder.

Also: tightened the RC lane's revert

Step 5 discarded the version bump with git checkout pyproject.toml uv.lock — a discard-without-looking on two files contributors commonly edit. It was safe only by virtue of the clean-tree precondition four steps upstream, with a full test run in between.

Now it asserts both files are unmodified before the bump, and at revert time prints the diff and requires it to be only the version bump before running git restore --source=HEAD --worktree. If anything else appears, stop — discarding it destroys unrecoverable work.

Verification

  • Both rewritten gh commands run verbatim against chore(main): release 3.0.0 #81 and return the expected output (PR row; version = "2.2.0""3.0.0" plus the changelog patch).
  • gh run watch with no args reproduced as run ID required when not running interactively.
  • The guard and restore were exercised in a throwaway git repo: silent on a clean tree, STOP on a dirty one, and git restore --source=HEAD --worktree returns the file to HEAD and leaves the tree clean.

Skill documentation only — no source, dependency, or CI changes. Nothing here touches the wheel.

🤖 Generated with Claude Code

https://claude.ai/code/session_01ER1fspJAScAo1o4jGdjuJE

All three fail as written; each failure and each replacement was verified
against the live repo, where release-please PR #81 (chore(main): release 3.0.0)
is currently open.

1. PR discovery returned zero results while the PR existed.
   `--search 'chore(main): release in:title'` -> 0 hits: GitHub's search parser
   drops the `chore(main):` prefix. Replaced with a --jq filter matching either
   signal (the release-please--* head branch or the title prefix), so a change
   to either still finds the PR.

   This bug's failure mode is the dangerous kind: "filter is broken" and "no
   release PR exists" are indistinguishable from the caller's side, and the
   skill's instruction on that branch is to STOP -- so it silently strands a
   real release. Added a guard clause to sanity-check with a bare
   `gh pr list --state open` before concluding nothing is there.

2. `gh pr diff <n> -- pyproject.toml CHANGELOG.md` fails outright:
   "accepts at most 1 arg(s), received 3". gh pr diff has no pathspec support.
   Replaced with `gh api repos/{owner}/{repo}/pulls/<n>/files` filtered by
   filename (gh expands the {owner}/{repo} placeholders). Added a pointer to
   read the BREAKING CHANGES block, since that is what drove #81 to 3.0.0.

3. `gh run watch` with no argument fails outside a TTY ("run ID required when
   not running interactively"), and the skill runs it non-interactively. Both
   occurrences now resolve the run id via `gh run list --limit 1` first; the
   dev-build block reuses that id for the following `gh run download` instead
   of a <run-id> placeholder.

Also tightened the RC lane's revert, which used `git checkout pyproject.toml
uv.lock` -- a discard-without-looking on two files contributors commonly edit.
It was safe only by virtue of the clean-tree precondition four steps upstream,
with a full test run in between. Now: assert both files are unmodified before
the bump, and at revert time print the diff and require it to be only the
version bump before `git restore --source=HEAD --worktree`. If anything else
appears, stop -- discarding it destroys unrecoverable work.

Verified: the two rewritten gh commands run verbatim against #81 and return the
expected output; the guard and restore were exercised in a throwaway git repo
(silent on clean, STOP on dirty, restore returns the file to HEAD).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ER1fspJAScAo1o4jGdjuJE
@pofallon
pofallon merged commit 3f5aef2 into main Jul 27, 2026
11 checks passed
@pofallon
pofallon deleted the fix/release-skill-pr-discovery branch July 27, 2026 16:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant