Pull Request Creator
Creates a comprehensive GitHub Pull Request with authentication validation and structured documentation.
Usage
/skill:ac-git-pull-request [target_branch] [gh_user]
Arguments:
target_branch: Base branch for PR (default:main)gh_user: Expected GitHub username (default:$GH_USERenv var)
Examples:
/skill:ac-git-pull-request # Uses main, $GH_USER
/skill:ac-git-pull-request master # Target master branch
/skill:ac-git-pull-request main my-username # Explicit user override
Workflow Steps
Step 1: Authentication Verification (CRITICAL - DO FIRST)
INSTRUCTION: Verify GitHub CLI authentication before any other operation.
ROOT=$(git rev-parse --show-toplevel)
BRANCH=$(git rev-parse --abbrev-ref HEAD)
# Get authenticated user
echo "Checking GitHub authentication..."
GH_AUTH_OUTPUT=$(gh auth status 2>&1)
echo "$GH_AUTH_OUTPUT"
# Extract authenticated username
AUTH_USER=$(echo "$GH_AUTH_OUTPUT" | grep -oE "Logged in to github.com account [^ ]+ " | sed 's/Logged in to github.com account //' | tr -d ' ' || echo "")
# Alternative extraction if format differs
if [ -z "$AUTH_USER" ]; then
AUTH_USER=$(echo "$GH_AUTH_OUTPUT" | grep -oE "account [^(]+" | head -1 | sed 's/account //' | tr -d ' ')
fi
echo "Authenticated as: $AUTH_USER"
Validation Logic:
- Extract
AUTH_USERfromgh auth statusoutput - Determine expected user:
- If
gh_userargument provided -> use it - Else if
$GH_USERenv var set -> use it - Else -> skip user validation (proceed with warning)
- If
- Compare
AUTH_USERwith expected user - If mismatch: STOP immediately with error:
ERROR: GitHub authentication mismatch - Authenticated as: <AUTH_USER> - Expected user: <EXPECTED_USER> Please run: gh auth login Or switch accounts: gh auth switch - If match: Proceed with success message
Step 2: Pre-Flight Validation
# Check not on protected branch
if [ "$BRANCH" = "master" ] || [ "$BRANCH" = "main" ]; then
echo "ERROR: Cannot create PR from protected branch: $BRANCH"
exit 1
fi
# Determine target branch
TARGET="${1:-main}" # Default to main
# Verify target exists on remote
if ! git -C "$ROOT" show-ref --verify --quiet "refs/remotes/origin/$TARGET"; then
echo "ERROR: Target branch 'origin/$TARGET' does not exist"
echo "Available remote branches:"
git -C "$ROOT" branch -r | grep -v HEAD
exit 1
fi
# Check for uncommitted changes
if [ -n "$(git -C "$ROOT" status --porcelain)" ]; then
echo "WARNING: Uncommitted changes detected"
git -C "$ROOT" status --short
fi
Step 3: Context Gathering
3.1 Fetch Latest Target
echo "Fetching latest $TARGET from origin..."
git -C "$ROOT" fetch origin "$TARGET"
3.2 Gather Commit Information
echo "Commits on this branch (since $TARGET):"
echo "========================================"
git -C "$ROOT" log "origin/$TARGET..HEAD" --oneline
echo ""
COMMITS_AHEAD=$(git -C "$ROOT" rev-list --count "origin/$TARGET..HEAD")
echo "Total commits: $COMMITS_AHEAD"
3.3 Gather File Changes
echo ""
echo "Files changed (summary):"
echo "========================"
git -C "$ROOT" diff "origin/$TARGET...HEAD" --stat
echo ""
echo "Detailed diff:"
echo "=============="
git -C "$ROOT" diff "origin/$TARGET...HEAD"
3.4 Check for CHANGELOG
CWD_FROM_ROOT=${PWD#$ROOT/}
# Search for CHANGELOG files
for changelog in "CHANGELOG.md" "changelog.md" "CHANGES.md"; do
CHANGELOG_PATH="$CWD_FROM_ROOT/$changelog"
if git -C "$ROOT" ls-files "$CHANGELOG_PATH" | grep -q .; then
echo ""
echo "CHANGELOG found: $CHANGELOG_PATH"
echo "Recent entries:"
git -C "$ROOT" show "HEAD:$CHANGELOG_PATH" | head -80
break
fi
done
3.5 Check Remote Status
echo ""
echo "Remote tracking status:"
git -C "$ROOT" status -sb
Step 4: Analyze & Draft PR
INSTRUCTION: Analyze all gathered context to create a comprehensive PR.
4.1 Analysis Checklist
- Review all commits since target branch
- Identify version bumps (CHANGELOG, package.json, pyproject.toml)
- Identify spec files modified/added
- Categorize changes by type (features, fixes, refactors, docs)
- Identify affected components/modules
- Detect breaking changes
- Extract ticket/issue references from commit messages or branch name
4.2 PR Title Generation
Format: <type>(<scope>): <concise description>
Type Classification (from changes):
| Type | When to Use |
|---|---|
feat |
New functionality |
fix |
Bug fixes |
refactor |
Code restructuring |
docs |
Documentation only |
test |
Test additions/fixes |
chore |
Maintenance tasks |
perf |
Performance improvements |
Scope: Derive scope from primary modified paths. Use consistent naming (e.g., component/subcomponent). Omit scope if changes span unrelated areas.
4.3 PR Body Template
CRITICAL: Use this EXACT structure for the PR body.
## Summary
<1-3 sentence overview explaining WHAT this PR does and WHY>
<Bulleted list of key changes/improvements>
### Root Cause (if applicable)
<What problem was being solved - include error traces, user reports, or investigation findings>
### Key Changes
<Detailed breakdown organized by component/area>
**Component 1:**
- Change description with context
**Component 2:**
- Change description with context
## Test Plan
- [ ] <Specific test case 1>
- [ ] <Specific test case 2>
- [ ] Run existing test suite: `pytest <path>`
- [ ] Deploy to staging environment
- [ ] Verify in staging with sample data
## Files Changed
**Category 1 (e.g., Core Logic):**
- `path/to/file.py` - Brief description of changes
**Category 2 (e.g., Configuration):**
- `path/to/config.json` - Brief description of changes
**Category 3 (e.g., Documentation):**
- `path/to/spec.md` - Brief description of changes
## Related
- **Spec**: `path/to/spec.md` (if applicable)
- **Ticket**: [TICKET-123](link) (if applicable)
- **Trace**: `trace-id` (if applicable)
- **Previous PR**: `#123` (if applicable)
Generated with pi
Step 5: Create Pull Request
5.1 Push Branch if Needed
# Check if branch needs to be pushed
UPSTREAM=$(git -C "$ROOT" rev-parse --abbrev-ref --symbolic-full-name @{upstream} || true)
if [ -z "$UPSTREAM" ]; then
echo "Pushing branch to origin with upstream tracking..."
git -C "$ROOT" push -u origin "$BRANCH"
else
# Check if local is ahead of remote
LOCAL_SHA=$(git -C "$ROOT" rev-parse HEAD)
REMOTE_SHA=$(git -C "$ROOT" rev-parse "@{upstream}" || echo "")
if [ "$LOCAL_SHA" != "$REMOTE_SHA" ]; then
echo "Pushing latest commits to origin..."
git -C "$ROOT" push origin "$BRANCH"
else
echo "Branch is up-to-date with remote"
fi
fi
5.2 Create PR with gh CLI
CRITICAL FORMATTING RULES:
- Use HEREDOC for body to preserve multi-line formatting
- Escape or backtick-wrap
#characters that could be interpreted as issue references- Headers (
## Summary) are OK - GitHub interprets these correctly - Standalone
#123without context MUST be escaped:\#123or wrapped:`#123`
- Headers (
- Wrap code paths in backticks to prevent interpretation
gh pr create \
--base "$TARGET" \
--title "<GENERATED_TITLE>" \
--body "$(cat <<'EOF'
<GENERATED_PR_BODY>
EOF
)"
Step 6: Report Results
After PR creation, output:
========================================
PR CREATED
========================================
PR URL: <URL from gh pr create>
Branch: <BRANCH> -> <TARGET>
Title: <PR_TITLE>
Summary:
- <Key point 1>
- <Key point 2>
- <Key point 3>
Files included: <N> files changed
Next steps:
1. Review PR: <URL>
2. Request reviewers if needed: gh pr edit --add-reviewer <user>
3. Monitor CI checks
========================================
Design Decisions
Authentication-First Approach
- Validates GitHub auth BEFORE any other operation
- Prevents wasted effort if credentials are wrong
- Supports both argument override and env var default
Default to
main(notmaster)- Modern GitHub default is
main - Override available via argument for legacy repos
- Modern GitHub default is
HEREDOC for PR Body
- Preserves markdown formatting correctly
- Handles multi-line content without escaping issues
- Single-quoted
'EOF'prevents variable expansion in body
Comprehensive Context Gathering
- Analyzes full diff, not just commit messages
- Checks CHANGELOG for version context
- Reviews specs for documentation links
Structured PR Template
- Consistent format for all PRs
- Sections optimized for reviewer experience
- Test plan with actionable checkboxes
AI Attribution
- Footer indicates AI-assisted PR creation
- Links to the generating tool for transparency
Edge Cases
No Commits Ahead of Target
WARNING: No commits ahead of $TARGET
Branch may already be merged or rebased.
Prompt user to verify before proceeding.
Branch Already Has Open PR
Check with gh pr list --head $BRANCH and warn if PR exists:
WARNING: Open PR already exists for this branch
PR #123: <title>
URL: <url>
Would you like to update the existing PR instead?
Target Branch Not Found
ERROR: Target branch 'origin/$TARGET' not found
Available branches:
- origin/main
- origin/master
- origin/develop
Please specify correct target: /skill:ac-git-pull-request <branch>
Safety Checks Summary
- Verify GitHub authentication matches expected user
- Confirm not on protected branch
- Verify target branch exists
- Check for uncommitted changes (warn, don't block)
- Push branch before PR creation
- Use HEREDOC for safe body formatting