--- name: github version: 4.0.0 description: Execute GitHub operations (PRs, issues, milestones, labels, comments, merges) using Python scripts with structured output and error handling. Use when working with pull requests, issues, review comments, CI checks, or milestones instead of raw gh. Use when you say "create a PR", "add label to issue", or "check CI status". Do NOT use to read a pasted github.com URL (use github-url-intercept). license: MIT metadata: domains: - github - pr - issue - labels - milestones - comments - reactions capability: kind: specialized-implementation status: active complexity: intermediate generator: keep_headings: - Decision Tree - Offline Invocation - Script Reference - Output Format - See Also routing: role: front-door invoker: autoplan trigger: autoplan routes PR, issue, label, and milestone operations to github user-facing: true --- # GitHub Skill Use these scripts instead of raw `gh` commands for consistent error handling and structured output. --- ## Triggers | Phrase | Operation | |--------|-----------| | `create a PR` | new_pr.py | | `respond to review comments` | post_pr_comment_reply.py | | `check CI status` | get_pr_checks.py / get_pr_check_logs.py | | `close issue` | close_issue.py | | `add label to issue` | set_issue_labels.py | --- ## Transport Preflight `gh` can be installed, hold a token, and still be refused for a whole session (agent sandboxes that proxy egress do this). Decide the transport once, before the first GitHub call: ```bash # CLAUDE_PLUGIN_ROOT is set in a vendored install; falls back to .claude in-repo. SCRIPTS_DIR="${COPILOT_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT:-.claude}}/skills/github/scripts/utils" python3 "$SCRIPTS_DIR/check_github_transport.py" ``` Non-POSIX hosts do not run the block above. The authoritative, per-harness launcher for this one command is `check_transport` in the `scripts` map of `pr-review-config.yaml`: the `copilot` entry runs it under PowerShell and resolves the interpreter (`python3`, then `py -3`, then `python`), because a Windows host may expose only the launcher. Read it from the map for the harness you are on rather than transcribing a second copy here, which would drift. - `Transport: gh` (exit 0). Use the scripts below. This is CI and a normal developer machine. - `Transport: gh_unusable` (exit 0). `gh` cannot reach GitHub here. Route the work through the GitHub MCP operations and do not re-try the scripts to confirm. The verdict names only what was measured: confirm the operations you need are exposed before relying on them. Tool spelling differs by harness (`mcp__github__` in Claude Code, `github/` in Copilot CLI). - Exit 3 or 4. Not a transport problem: a quota window or a fixable token. Script-to-tool mapping, the operations with no MCP equivalent, and the rules for reporting one: `references/transport-routing.md`. A transport failure is an unknown, never a verdict. Do not report a PR as blocked, red, or unmergeable because the API was unreachable. --- ## Decision Tree ```text Which transport? → check_github_transport.py (run once, before the rest) Need GitHub data? ├─ List PRs (filtered) → get_pull_requests.py ├─ PR info/diff → get_pr_context.py ├─ CI check status → get_pr_checks.py ├─ Failing check also red on main? → triage_red_check.py ├─ CI failure logs → get_pr_check_logs.py ├─ Review comments → get_pr_review_comments.py ├─ Review threads → get_pr_review_threads.py ├─ Review verdicts (approved / changes requested) → get_pr_reviews.py ├─ Bot CHANGES_REQUESTED blocking after threads resolve → detect_stale_bot_review.py ├─ Unique reviewers → get_pr_reviewers.py ├─ Unaddressed bot comments → get_unaddressed_comments.py ├─ PR merged check → test_pr_merged.py ├─ Copilot follow-up PRs → detect_copilot_followup_pr.py ├─ Validate PR description → validate_pr_description.py ├─ Issue info → get_issue_context.py ├─ Issue parent, sub-issues, blockers, related → get_issue_relationships.py ├─ Merge readiness check → test_pr_merge_ready.py ├─ PR reports blocked/dirty and cause is unclear → why_pr_blocked.py ├─ Latest milestone → get_latest_semantic_milestone.py ├─ Actionable backlog → get_actionable_items.py └─ Need to take action? ├─ Create issue → new_issue.py ├─ Create PR → new_pr.py ├─ Reply to review → post_pr_comment_reply.py ├─ Reply to thread (GraphQL) → add_pr_review_thread_reply.py ├─ Comment on issue → post_issue_comment.py ├─ Add reaction → add_comment_reaction.py ├─ Apply labels → set_issue_labels.py ├─ Set issue milestone → set_issue_milestone.py ├─ Set PR/issue milestone (auto-detect) → set_item_milestone.py ├─ Assign issue → set_issue_assignee.py ├─ Link issues (parent, sub-issue, blocked-by, blocking, relates-to) → set_issue_relationship.py ├─ Resolve threads → resolve_pr_review_thread.py ├─ Unresolve threads → unresolve_pr_review_thread.py ├─ Process AI triage → invoke_pr_comment_processing.py ├─ Assign Copilot → invoke_copilot_assignment.py ├─ Enable/disable auto-merge → set_pr_auto_merge.py ├─ Update PR branch with its base (server side) → update_pr_branch.py ├─ Close PR → close_pr.py └─ Merge PR → merge_pr.py ``` --- ## Offline Invocation In a network-restricted sandbox (triage, PR status checks), run read-only PR scripts under `scripts/pr/` with bare `python3`, not `uv run`. `uv run