Initial commit
This commit is contained in:
81
skills/github-pr-workflow/SKILL.md
Normal file
81
skills/github-pr-workflow/SKILL.md
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
name: github-pr-workflow
|
||||
description: Working with GitHub Pull Requests using the gh CLI. Use for fetching PR details, review comments, CI status, and understanding the difference between PR-level comments vs inline code review comments.
|
||||
---
|
||||
|
||||
# GitHub PR Workflow
|
||||
|
||||
## Key Concepts
|
||||
|
||||
### Comment Types
|
||||
|
||||
GitHub PRs have **two different types of comments**:
|
||||
|
||||
1. **PR-level comments** - General discussion on the PR (shown via `gh pr view --comments`)
|
||||
2. **Inline code review comments** - Comments attached to specific lines of code (requires API)
|
||||
|
||||
**Important**: `gh pr view --comments` does NOT show inline code review comments!
|
||||
|
||||
## Scripts
|
||||
|
||||
| Script | Purpose |
|
||||
|--------|---------|
|
||||
| `gh-pr-review-comments <PR>` | Get inline code review comments (the ones `gh` misses!) |
|
||||
| `gh-pr-summary <PR>` | PR title, description, state, branches |
|
||||
| `gh-pr-reviews <PR>` | Review decisions (approved/changes requested) |
|
||||
| `gh-pr-checks <PR>` | CI check status |
|
||||
|
||||
All scripts auto-detect the repo from git remote, or accept `[REPO]` as second arg.
|
||||
|
||||
## Common Commands
|
||||
|
||||
```bash
|
||||
# Basic PR info
|
||||
gh pr view <PR> # Overview
|
||||
gh pr view <PR> --comments # PR-level comments only (NOT inline!)
|
||||
gh pr diff <PR> # View the diff
|
||||
|
||||
# Review comments (inline) - USE THE SCRIPT
|
||||
gh-pr-review-comments <PR> # ✅ Gets inline code review comments
|
||||
|
||||
# Or manually via API
|
||||
gh api repos/OWNER/REPO/pulls/PR/comments | jq '.[] | {path, line, body}'
|
||||
|
||||
# Reviews (approve/request changes)
|
||||
gh pr review <PR> --approve
|
||||
gh pr review <PR> --request-changes --body "Please fix X"
|
||||
gh pr review <PR> --comment --body "Looks good overall"
|
||||
|
||||
# Checks
|
||||
gh pr checks <PR> # CI status
|
||||
gh run view <RUN_ID> --log-failed # Failed job logs
|
||||
```
|
||||
|
||||
## API Endpoints Reference
|
||||
|
||||
When `gh` commands don't expose what you need, use the API:
|
||||
|
||||
```bash
|
||||
# Inline review comments
|
||||
gh api repos/OWNER/REPO/pulls/PR/comments
|
||||
|
||||
# PR-level comments (issue comments)
|
||||
gh api repos/OWNER/REPO/issues/PR/comments
|
||||
|
||||
# Review submissions
|
||||
gh api repos/OWNER/REPO/pulls/PR/reviews
|
||||
|
||||
# Commits in PR
|
||||
gh api repos/OWNER/REPO/pulls/PR/commits
|
||||
|
||||
# Files changed
|
||||
gh api repos/OWNER/REPO/pulls/PR/files
|
||||
```
|
||||
|
||||
## Workflow: Addressing Review Comments
|
||||
|
||||
1. **Get the comments**: `gh-pr-review-comments <PR>`
|
||||
2. **Make fixes** in your local branch
|
||||
3. **Push** (if using JJ: `jj git push`)
|
||||
4. **Reply to comments** on GitHub or via API
|
||||
5. **Re-request review** if needed: `gh pr edit <PR> --add-reviewer <USER>`
|
||||
23
skills/github-pr-workflow/scripts/gh-pr-checks
Executable file
23
skills/github-pr-workflow/scripts/gh-pr-checks
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
# Get CI check status for a PR
|
||||
# Usage: gh-pr-checks <PR_NUMBER> [REPO]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
PR_NUMBER="${1:?Usage: gh-pr-checks <PR_NUMBER> [REPO]}"
|
||||
REPO="${2:-}"
|
||||
|
||||
if [[ -z "$REPO" ]]; then
|
||||
REPO=$(gh repo view --json nameWithOwner -q '.nameWithOwner' 2>/dev/null || true)
|
||||
if [[ -z "$REPO" ]]; then
|
||||
echo "Error: Could not detect repo. Provide REPO as second argument" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Get the head SHA first
|
||||
HEAD_SHA=$(gh api "repos/${REPO}/pulls/${PR_NUMBER}" --jq '.head.sha')
|
||||
|
||||
gh api "repos/${REPO}/commits/${HEAD_SHA}/check-runs" | jq -r '
|
||||
.check_runs[] |
|
||||
"\(if .conclusion == "success" then "✓" elif .conclusion == "failure" then "✗" elif .status == "in_progress" then "⋯" else "?" end) \(.name): \(.conclusion // .status)"'
|
||||
28
skills/github-pr-workflow/scripts/gh-pr-review-comments
Executable file
28
skills/github-pr-workflow/scripts/gh-pr-review-comments
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env bash
|
||||
# Get inline code review comments from a GitHub PR
|
||||
# Usage: gh-pr-review-comments <PR_NUMBER> [REPO]
|
||||
#
|
||||
# If REPO is not provided, uses the current git remote origin
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
PR_NUMBER="${1:?Usage: gh-pr-review-comments <PR_NUMBER> [REPO]}"
|
||||
REPO="${2:-}"
|
||||
|
||||
# If no repo provided, try to detect from git remote
|
||||
if [[ -z "$REPO" ]]; then
|
||||
REPO=$(gh repo view --json nameWithOwner -q '.nameWithOwner' 2>/dev/null || true)
|
||||
if [[ -z "$REPO" ]]; then
|
||||
echo "Error: Could not detect repo. Provide REPO as second argument (e.g., owner/repo)" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
gh api "repos/${REPO}/pulls/${PR_NUMBER}/comments" | jq -r '
|
||||
.[] |
|
||||
"───────────────────────────────────────────────────────────────────────
|
||||
File: \(.path):\(.line // .original_line // "N/A")
|
||||
Author: \(.user.login) (\(.created_at | split("T")[0]))
|
||||
───────────────────────────────────────────────────────────────────────
|
||||
\(.body)
|
||||
"'
|
||||
21
skills/github-pr-workflow/scripts/gh-pr-reviews
Executable file
21
skills/github-pr-workflow/scripts/gh-pr-reviews
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
# Get review decisions (approved, changes_requested, commented) for a PR
|
||||
# Usage: gh-pr-reviews <PR_NUMBER> [REPO]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
PR_NUMBER="${1:?Usage: gh-pr-reviews <PR_NUMBER> [REPO]}"
|
||||
REPO="${2:-}"
|
||||
|
||||
if [[ -z "$REPO" ]]; then
|
||||
REPO=$(gh repo view --json nameWithOwner -q '.nameWithOwner' 2>/dev/null || true)
|
||||
if [[ -z "$REPO" ]]; then
|
||||
echo "Error: Could not detect repo. Provide REPO as second argument" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
gh api "repos/${REPO}/pulls/${PR_NUMBER}/reviews" | jq -r '
|
||||
.[] |
|
||||
select(.state != "PENDING") |
|
||||
"\(.user.login): \(.state) (\(.submitted_at | split("T")[0]))\(if .body != "" then "\n \(.body)" else "" end)"'
|
||||
27
skills/github-pr-workflow/scripts/gh-pr-summary
Executable file
27
skills/github-pr-workflow/scripts/gh-pr-summary
Executable file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
# Get a summary of a PR: title, body, state, and review status
|
||||
# Usage: gh-pr-summary <PR_NUMBER> [REPO]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
PR_NUMBER="${1:?Usage: gh-pr-summary <PR_NUMBER> [REPO]}"
|
||||
REPO="${2:-}"
|
||||
|
||||
if [[ -z "$REPO" ]]; then
|
||||
REPO=$(gh repo view --json nameWithOwner -q '.nameWithOwner' 2>/dev/null || true)
|
||||
if [[ -z "$REPO" ]]; then
|
||||
echo "Error: Could not detect repo. Provide REPO as second argument" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
gh api "repos/${REPO}/pulls/${PR_NUMBER}" | jq -r '
|
||||
"PR #\(.number): \(.title)
|
||||
State: \(.state) | Mergeable: \(.mergeable // "unknown") | Draft: \(.draft)
|
||||
Author: \(.user.login)
|
||||
Branch: \(.head.ref) → \(.base.ref)
|
||||
Created: \(.created_at | split("T")[0])
|
||||
URL: \(.html_url)
|
||||
|
||||
─── Description ───
|
||||
\(.body // "(no description)")"'
|
||||
Reference in New Issue
Block a user