# Check if we're in a git repositoryif [ ! -d ".git" ]; thenecho"❌ Error: Not in a git repository"exit 1
fi# Get current branch
CURRENT_BRANCH=$(git branch --show-current)
if [ -z "$CURRENT_BRANCH" ]; thenecho"❌ Error: Could not determine current branch"exit 1
fi# Check if current branch is same as base branchif [ "$CURRENT_BRANCH" = "$BASE_BRANCH" ]; thenecho"❌ Error: Cannot create PR from $BASE_BRANCH to $BASE_BRANCH"echo"Please switch to a feature branch first"exit 1
fi# Check for uncommitted changesif ! git diff --quiet || ! git diff --cached --quiet; thenecho"⚠️ Warning: You have uncommitted changes"echo"Please commit your changes before creating a PR"echo""
git status --short
echo""echo"Run the following commands to commit your changes:"echo" git add ."echo" git commit -m 'Your commit message'"
1
3. Analyze Branch Changes
# Check if base branch existsif ! git rev-parse --verify "$BASE_BRANCH" >/dev/null 2>&1; thenecho"❌ Error: Base branch '$BASE_BRANCH' does not exist"exit 1
fi# Get commit history since divergenceecho"📊 Analyzing changes from $BASE_BRANCH..."# Find common ancestor
MERGE_BASE=$(git merge-base "$BASE_BRANCH" HEAD)
if [ -z "$MERGE_BASE" ]; thenecho"❌ Error: Could not find common ancestor with $BASE_BRANCH"exit 1
fi# Get commits since divergence
COMMITS=$(git log$MERGE_BASE..HEAD --oneline)
COMMIT_COUNT=$(echo"$COMMITS" | wc -l | tr -d ' ')
if [ "$COMMIT_COUNT" -eq 0 ]; thenecho"❌ Error: No commits found since divergence from $BASE_BRANCH"exit 1
fiecho"📝 Found $COMMIT_COUNT commit(s):"echo"$COMMITS"echo
git diff -- ..HEAD
CHANGED_FILES=$(git diff --name-only ..HEAD)
4. Categorize Changes
# Analyze changes to determine type and scopeecho""echo"🔍 Analyzing change categories..."
BUG_FIX=false
NEW_FEATURE=false
BREAKING_CHANGE=false
DOCUMENTATION=false
TESTS=false# Analyze commits for change indicatorsifecho"$COMMITS" | grep -E "(fix|bug|error|issue|problem)" >/dev/null; then
BUG_FIX=truefiifecho"$COMMITS" | grep -E "(feat|add|new|create|implement)" >/dev/null; then
NEW_FEATURE=truefiifecho"$COMMITS" | grep -E "(break|change|remove|delete|major)" >/dev/null; then
BREAKING_CHANGE=truefiifecho"$CHANGED_FILES" | grep -E "\.(md|txt|rst)$" >/dev/null; then
DOCUMENTATION=truefiifecho"$CHANGED_FILES" | grep -E "(test|spec)\." >/dev/null; then
TESTS=truefi
[ = ]; ;
[ = ]; ;
[ = ]; ;
[ = ]; ;
[ = ]; ;
5. Generate PR Title
# Generate PR titleif [ -n "$CUSTOM_TITLE" ]; then
PR_TITLE="$CUSTOM_TITLE"else# Auto-generate title from first commit
FIRST_COMMIT=$(echo"$COMMITS" | tail -1)
# Clean up commit message for PR titleifecho"$FIRST_COMMIT" | grep -E "^(feat|fix|docs|style|refactor|test|chore)(\(.+\))?: " >/dev/null; then# Use conventional commit format
PR_TITLE=$(echo"$FIRST_COMMIT" | sed 's/^[a-f0-9]\+ //')
else# Fallback to simple format
PR_TITLE="$CURRENT_BRANCH"fifiecho"📝 PR Title: $PR_TITLE"
6. Generate PR Description
# Generate comprehensive PR descriptionecho"📋 Generating PR description..."# Generate change summary
CHANGE_SUMMARY=""if [ "$BUG_FIX" = true ]; then
CHANGE_SUMMARY="${CHANGE_SUMMARY}- Bug fixes and error handling improvements\n"fiif [ "$NEW_FEATURE" = true ]; then
CHANGE_SUMMARY="${CHANGE_SUMMARY}- New features and functionality additions\n"fiif [ "$BREAKING_CHANGE" = true ]; then
CHANGE_SUMMARY="${CHANGE_SUMMARY}- Breaking changes requiring attention\n"fiif [ "$DOCUMENTATION" = true ]; then
CHANGE_SUMMARY="${CHANGE_SUMMARY}- Documentation updates and improvements\n"fiif [ "$TESTS" = true ]; then
CHANGE_SUMMARY="${CHANGE_SUMMARY}- Test coverage and quality improvements\n"fi# Generate file change summary
FILE_CHANGES=""for file in$CHANGED_FILES;
FILE_CHANGES=
PR_DESCRIPTION=$( <<
)
[ = ];
PR_DESCRIPTION=
PR_DESCRIPTION=
[ = ];
PR_DESCRIPTION=
PR_DESCRIPTION=
[ = ];
PR_DESCRIPTION=
PR_DESCRIPTION=
[ = ];
PR_DESCRIPTION=
PR_DESCRIPTION=
PR_DESCRIPTION=
[ = ];
PR_DESCRIPTION=
PR_DESCRIPTION=
PR_DESCRIPTION=✅ PR description generated
7. Push Branch and Create PR
# Check if branch exists on remoteif ! git ls-remote --heads origin "$CURRENT_BRANCH" >/dev/null 2>&1; thenecho"📤 Pushing branch to remote..."
git push -u origin "$CURRENT_BRANCH"elseecho"📤 Branch already exists on remote, ensuring it's up to date..."
git push origin "$CURRENT_BRANCH"fi# Create PR using gh CLIecho"📋 Creating pull request..."
PR_OPTIONS="--title '$PR_TITLE' --body '$PR_DESCRIPTION'"if [ "$IS_DRAFT" = true ]; then
PR_OPTIONS="$PR_OPTIONS --draft"fi# Execute gh pr create command
PR_URL=$(eval"gh pr create --base $BASE_BRANCH$PR_OPTIONS")
if [ $? -eq 0 ]; thenecho""echo"✅ Pull request created successfully!"echo"🔗 PR URL: $PR_URL"echo""echo"📋 PR Details:"echo" Title: $PR_TITLE"echo
1
Complete Workflow Summary
Parameter Parsing: Parse base branch, draft mode, and custom title options
Branch Validation: Check current branch status and ensure it's different from base branch
Change Analysis: Analyze commits and file changes since divergence from base branch
Title Generation: Generate appropriate PR title or use custom title
Description Generation: Create comprehensive PR description following project template
Branch Push: Ensure branch is available on remote repository
PR Creation: Create pull request using GitHub CLI with all details
Important Notes
⚠️ Prerequisites:
GitHub CLI (gh): Must be installed and authenticated
Clean working directory: All changes must be committed before PR creation
Remote branch: Current branch must be pushed to remote repository
Base branch: Target branch must exist and be accessible
Best Practices:
Ensure commit messages follow conventional commit format
Test all changes before creating PR
Review auto-generated PR description for accuracy
Add any additional context specific to your changes
Check that all tests pass in CI/CD pipeline
Change Detection Logic:
The command automatically categorizes changes based on:
Commit messages: Keywords like "feat", "fix", "break", "docs", "test"
File patterns: .md/.txt for docs, (test|spec)\. for tests
File extensions: TypeScript, JavaScript, JSON, etc.
Example Outputs:
# Standard PR to main
/zcf-pr
# → Creates PR: "feat: add new feature" with full description# PR to develop branch
/zcf-pr --base develop
# → Creates PR to develop branch instead of main# Draft PR
/zcf-pr --draft
# → Creates draft PR for initial review# Custom title
/zcf-pr --title "Critical bug fix for authentication"# → Uses custom title instead of auto-generated one
Now creating pull request...
"$CUSTOM_TITLE"
then
echo
"📝 Custom title: $CUSTOM_TITLE"
fi
exit
fi
echo
"✅ Branch status OK: $CURRENT_BRANCH"
""
# Analyze file changes
echo
"📁 File change statistics:"
stat
$MERGE_BASE
# Get changed files
$MERGE_BASE
echo
""
echo
"📋 Changed files:"
echo
"$CHANGED_FILES"
# Show analysis results
echo
"📊 Change type analysis:"
if
"$BUG_FIX"
true
then
echo
" ✅ Bug fix detected"
fi
if
"$NEW_FEATURE"
true
then
echo
" ✅ New feature detected"
fi
if
"$BREAKING_CHANGE"
true
then
echo
" ✅ Breaking change detected"
fi
if
"$DOCUMENTATION"
true
then
echo
" ✅ Documentation update detected"
fi
if
"$TESTS"
true
then
echo
" ✅ Test updates detected"
fi
do
"${FILE_CHANGES}- \`$file\`\n"
done
# Build complete PR description
cat
EOF
## Description
This PR includes changes from branch \`$CURRENT_BRANCH\` with $COMMIT_COUNT commit(s) since divergence from \`$BASE_BRANCH\`.
### Key Changes:
$CHANGE_SUMMARY
### Files Modified:
$FILE_CHANGES
## Type of Change
EOF
# Add checkboxes based on analysis
if
"$BUG_FIX"
true
then
"${PR_DESCRIPTION}- [x] Bug fix\n"
else
"${PR_DESCRIPTION}- [ ] Bug fix\n"
fi
if
"$NEW_FEATURE"
true
then
"${PR_DESCRIPTION}- [x] New feature\n"
else
"${PR_DESCRIPTION}- [ ] New feature\n"
fi
if
"$BREAKING_CHANGE"
true
then
"${PR_DESCRIPTION}- [x] Breaking change\n"
else
"${PR_DESCRIPTION}- [ ] Breaking change\n"
fi
if
"$DOCUMENTATION"
true
then
"${PR_DESCRIPTION}- [x] Documentation update\n"
else
"${PR_DESCRIPTION}- [ ] Documentation update\n"
fi
# Add testing section
"${PR_DESCRIPTION}
## Testing
- [x] Code changes tested
- [x] No new warnings introduced
- [x] Code follows style guidelines"