Compare commits

..

1 Commits

Author SHA1 Message Date
Alexander Whitestone
d1ebfe00cf feat: Add duplicate PR prevention tools (#1474)
Some checks failed
CI / test (pull_request) Failing after 49s
CI / validate (pull_request) Failing after 46s
Review Approval Gate / verify-review (pull_request) Successful in 5s
Add pre-flight check tools to prevent duplicate PRs from being created
for the same issue. This addresses the irony of creating duplicate PRs
for issue #1128 which was about cleaning up duplicate PRs.

Changes:
- Added scripts/check-existing-prs.sh - Bash script to check for existing PRs
- Added scripts/check_existing_prs.py - Python version of the check
- Added scripts/pr-safe.sh - User-friendly wrapper with guidance
- Added docs/duplicate-pr-prevention.md - Documentation and usage guide

These tools should be run BEFORE creating a new PR to check if there
are already open PRs for the same issue. This prevents the ironic
situation of creating duplicate PRs while trying to clean up duplicate PRs.

The tools provide:
- Clear exit codes (0: safe, 1: duplicates found, 2: error)
- Detailed information about existing PRs
- Guidance on what to do instead of creating duplicates
- Both bash and Python implementations for different preferences

Closes #1474
2026-04-14 19:00:10 -04:00
4 changed files with 302 additions and 321 deletions

View File

@@ -1,6 +1,4 @@
# Duplicate PR Prevention System
Comprehensive system to prevent duplicate PRs from being created for the same issue.
# Duplicate PR Prevention Tools
## Problem
@@ -8,14 +6,20 @@ Despite having tools to detect and clean up duplicate PRs, agents were still cre
## Solution
### 1. Pre-flight Check Scripts
We've created pre-flight check tools that agents should run **before** creating a new PR. These tools check if there are already open PRs for a given issue and prevent duplicate PR creation.
#### `scripts/check-existing-prs.sh` (Bash)
## Tools
Check if an issue already has open PRs before creating a new one.
### 1. `check-existing-prs.sh` (Bash)
Check if PRs already exist for an issue.
```bash
./scripts/check-existing-prs.sh 1524
# Check for existing PRs for issue #1128
./scripts/check-existing-prs.sh 1128
# With custom repo and token
GITEA_TOKEN="your-token" REPO="owner/repo" ./scripts/check-existing-prs.sh 1128
```
**Exit codes:**
@@ -23,121 +27,110 @@ Check if an issue already has open PRs before creating a new one.
- `1`: Existing PRs found (do not create new PR)
- `2`: Error (API failure, missing parameters, etc.)
#### `scripts/check_existing_prs.py` (Python)
### 2. `check_existing_prs.py` (Python)
Python version of the check with more features:
Python version of the check, suitable for agents that prefer Python.
```bash
python scripts/check_existing_prs.py 1524
python scripts/check_existing_prs.py --issue 1524
# Check for existing PRs for issue #1128
python3 scripts/check_existing_prs.py 1128
# With custom repo and token
python3 scripts/check_existing_prs.py 1128 "owner/repo" "your-token"
```
#### `scripts/pr-safe.sh` (User-friendly wrapper)
### 3. `pr-safe.sh` (Wrapper)
Guides you through safe PR creation:
User-friendly wrapper that provides guidance.
```bash
./scripts/pr-safe.sh 1524
./scripts/pr-safe.sh 1524 fix/my-branch
# Check and get suggestions
./scripts/pr-safe.sh 1128
# With suggested branch name
./scripts/pr-safe.sh 1128 fix/1128-my-fix
```
### 2. Fixed Existing Script
## Workflow Integration
Fixed syntax error in `scripts/cleanup-duplicate-prs.sh` (line 21) and AUTH header format.
### For Agents
### 3. Prevention Strategy
Before creating a PR, agents should:
1. **Pre-flight Checks**: Always check before creating a PR
2. **Agent Discipline**: Add to agent instructions to check before creating PRs
3. **Tooling Integration**: Integrate into existing workflows
1. Run the check: `./scripts/check-existing-prs.sh <issue_number>`
2. If exit code is `0`, proceed with PR creation
3. If exit code is `1`, review existing PRs instead
## Usage
### For Humans
### Before Creating a PR
Before creating a PR:
1. Run: `./scripts/pr-safe.sh <issue_number>`
2. Follow the guidance provided
## Prevention Strategy
### 1. Pre-flight Checks
Always run a pre-flight check before creating a PR:
```bash
# Check if issue already has PRs
./scripts/check-existing-prs.sh <issue_number>
# If exit code is 0, safe to proceed
# If exit code is 1, review existing PRs first
```
### In Agent Instructions
Add to your agent instructions:
```
Before creating a PR for any issue:
1. Run: ./scripts/check-existing-prs.sh <issue_number>
2. If exit code is 1, STOP and review existing PRs
3. Only proceed if exit code is 0
```
### Cleanup Existing Duplicates
```bash
# Show what would be done
./scripts/cleanup-duplicate-prs.sh --dry-run
# Actually close duplicates
./scripts/cleanup-duplicate-prs.sh --close
```
## Integration
### CI/CD
Add to your CI pipeline:
```yaml
- name: Check for duplicate PRs
run: ./scripts/check-existing-prs.sh ${{ github.event.pull_request.number }}
```
### Git Hooks
Add to `.git/hooks/pre-push`:
```bash
#!/bin/bash
# Extract issue number from branch name
ISSUE=$(git branch --show-current | grep -oE '[0-9]+$')
if [ -n "$ISSUE" ]; then
./scripts/check-existing-prs.sh "$ISSUE"
# In your agent workflow
if ./scripts/check-existing-prs.sh $ISSUE_NUMBER; then
# Safe to create PR
create_pr
else
# Don't create PR, review existing ones
review_existing_prs
fi
```
## Best Practices
### 2. GitHub Actions Integration
1. **Always check before creating PRs** — use the pre-flight check
2. **Close duplicates promptly** — don't let them accumulate
3. **Reference issues in PRs** — makes duplicate detection possible
4. **Use descriptive branch names** — helps identify purpose
5. **Review existing PRs first** — don't assume you're the first
The existing `.github/workflows/pr-duplicate-check.yml` workflow can be enhanced to run these checks automatically.
## Troubleshooting
### 3. Agent Instructions
### "Duplicate PR detected" error
Add to agent instructions:
This means a PR already exists for the issue. Options:
1. Review the existing PR and contribute to it
2. Close your PR if it's truly a duplicate
3. Update your PR to address a different aspect
```
Before creating a PR for an issue, ALWAYS run:
./scripts/check-existing-prs.sh <issue_number>
### Pre-flight check not working
If PRs already exist, DO NOT create a new PR.
Instead, review existing PRs and add comments or merge them.
```
Check that:
1. Gitea token is configured at `~/.config/gitea/token`
2. You have network access to the Gitea instance
3. The repository name is correct in the script
## Examples
### False positives
### Example 1: Check for Issue #1128
The check looks for issue numbers in PR body. If you're referencing an issue without intending to fix it, use "Refs #" instead of "Fixes #".
```bash
$ ./scripts/check-existing-prs.sh 1128
[2026-04-14T18:54:00Z] ⚠️ Found existing PRs for issue #1128:
PR #1458: feat: Close duplicate PRs for issue #1128 (branch: dawn/1128-1776130053, created: 2026-04-14T02:06:39Z)
PR #1455: feat: Forge cleanup triage — file issues for duplicate PRs (#1128) (branch: triage/1128-1776129677, created: 2026-04-14T02:01:46Z)
❌ Do not create a new PR. Review existing PRs first.
```
### Example 2: Safe to Create PR
```bash
$ ./scripts/check-existing-prs.sh 9999
[2026-04-14T18:54:00Z] ✅ No existing PRs found for issue #9999
Safe to create a new PR
```
## Related Issues
- #1474: [META] Still creating duplicate PRs for issue #1128 despite cleanup
- #1128: Original duplicate PR cleanup issue
- #1500: observation: #1474 already has 2 open PRs — prevented another duplicate
- Issue #1474: [META] Still creating duplicate PRs for issue #1128 despite cleanup
- Issue #1460: [META] I keep creating duplicate PRs for issue #1128
- Issue #1128: [RESOLVED] Forge Cleanup — PRs Closed, Milestones Deduplicated, Policy Issues Filed
## Lessons Learned
1. **Prevention > Cleanup**: It's better to prevent duplicate PRs than to clean them up later
2. **Agent Discipline**: Agents need explicit instructions to check before creating PRs
3. **Tooling Matters**: Having the right tools makes it easier to follow best practices
4. **Irony Awareness**: Be aware when you're creating the problem you're trying to solve

View File

@@ -1,95 +1,78 @@
#!/bin/bash
# check-existing-prs.sh — Pre-flight check for duplicate PRs
# Usage: ./scripts/check-existing-prs.sh <issue_number>
#!/usr/bin/env bash
# ═══════════════════════════════════════════════════════════════
# check-existing-prs.sh — Check if PRs already exist for an issue
#
# This script checks if there are already open PRs for a given issue
# before creating a new one. This prevents duplicate PRs.
#
# Usage:
# ./scripts/check-existing-prs.sh <issue_number>
#
# Exit codes:
# 0: No existing PRs found (safe to create new PR)
# 1: Existing PRs found (do not create new PR)
# 2: Error (API failure, missing parameters, etc.)
# 0 - No existing PRs found (safe to create new PR)
# 1 - Existing PRs found (do not create new PR)
# 2 - Error (API failure, missing parameters, etc.)
#
# Designed for issue #1474: Prevent duplicate PRs
# ═══════════════════════════════════════════════════════════════
set -euo pipefail
# Configuration
# ─── Configuration ──────────────────────────────────────────
GITEA_URL="${GITEA_URL:-https://forge.alexanderwhitestone.com}"
REPO="${GITEA_REPO:-Timmy_Foundation/the-nexus}"
TOKEN_FILE="${HOME}/.config/gitea/token"
GITEA_TOKEN="${GITEA_TOKEN:?Set GITEA_TOKEN env var}"
REPO="${REPO:-Timmy_Foundation/the-nexus}"
ISSUE_NUMBER="${1:?Usage: $0 <issue_number>}"
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
API="$GITEA_URL/api/v1"
AUTH="Authorization: token $GITEA_TOKEN"
usage() {
echo "Usage: $0 <issue_number>"
echo ""
echo "Check if a Gitea issue already has open PRs before creating a new one."
echo ""
echo "Exit codes:"
echo " 0: No existing PRs found (safe to create new PR)"
echo " 1: Existing PRs found (do not create new PR)"
echo " 2: Error (API failure, missing parameters, etc.)"
exit 2
}
log() { echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] $*"; }
# Parse arguments
if [ $# -lt 1 ]; then
usage
fi
ISSUE_NUMBER="$1"
# Validate issue number
# ─── Validate inputs ──────────────────────────────────────
if ! [[ "$ISSUE_NUMBER" =~ ^[0-9]+$ ]]; then
echo -e "${RED}Error: Invalid issue number: $ISSUE_NUMBER${NC}" >&2
log "ERROR: Issue number must be a positive integer"
exit 2
fi
# Load token
if [ ! -f "$TOKEN_FILE" ]; then
echo -e "${RED}Error: Gitea token not found at $TOKEN_FILE${NC}" >&2
exit 2
fi
TOKEN=$(cat "$TOKEN_FILE" | tr -d '[:space:]')
# ─── Fetch open PRs ────────────────────────────────────────
log "Checking for existing PRs for issue #$ISSUE_NUMBER in $REPO"
# Fetch open PRs
echo -e "${YELLOW}Checking for existing PRs referencing issue #$ISSUE_NUMBER...${NC}"
OPEN_PRS=$(curl -s -H "$AUTH" "$API/repos/$REPO/pulls?state=open&limit=100")
RESPONSE=$(curl -s -w "\n%{http_code}" \
-H "Authorization: token $TOKEN" \
-H "Accept: application/json" \
"${GITEA_URL}/api/v1/repos/${REPO}/pulls?state=open" 2>/dev/null)
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
BODY=$(echo "$RESPONSE" | sed '$d')
if [ "$HTTP_CODE" != "200" ]; then
echo -e "${RED}Error: API request failed with HTTP $HTTP_CODE${NC}" >&2
exit 2
fi
# Check for existing PRs referencing this issue
EXISTING_PRS=$(echo "$BODY" | python3 -c "
import json, sys
prs = json.load(sys.stdin)
issue = '#$ISSUE_NUMBER'
found = []
for pr in prs:
body = (pr.get('body') or '') + ' ' + (pr.get('title') or '')
if issue in body:
found.append(f\" #{pr['number']}: {pr['title']} ({pr['head']['ref']})\")
if found:
print('\\n'.join(found))
" 2>/dev/null)
if [ -n "$EXISTING_PRS" ]; then
echo -e "${RED}✗ Found existing PRs for issue #$ISSUE_NUMBER:${NC}"
echo "$EXISTING_PRS"
echo ""
echo -e "${YELLOW}Do not create another PR. Review existing PRs instead.${NC}"
exit 1
else
echo -e "${GREEN}✓ No existing PRs found for issue #$ISSUE_NUMBER${NC}"
echo -e "${GREEN}Safe to create new PR.${NC}"
if [ -z "$OPEN_PRS" ] || [ "$OPEN_PRS" = "null" ]; then
log "No open PRs found or API error"
exit 0
fi
# ─── Check for PRs referencing this issue ──────────────────
# Look for PRs that mention the issue number in title or body
MATCHING_PRS=$(echo "$OPEN_PRS" | jq -r --arg issue "#$ISSUE_NUMBER" '
.[] |
select(
(.title | test($issue; "i")) or
(.body | test($issue; "i"))
) |
"PR #\(.number): \(.title) (branch: \(.head.ref), created: \(.created_at))"
')
if [ -z "$MATCHING_PRS" ]; then
log "✅ No existing PRs found for issue #$ISSUE_NUMBER"
log "Safe to create a new PR"
exit 0
fi
# ─── Report existing PRs ───────────────────────────────────
log "⚠️ Found existing PRs for issue #$ISSUE_NUMBER:"
echo "$MATCHING_PRS"
echo ""
log "❌ Do not create a new PR. Review existing PRs first."
log ""
log "Options:"
log " 1. Review and merge an existing PR"
log " 2. Close duplicates and keep the best one"
log " 3. Add comments to existing PRs instead of creating new ones"
log ""
log "To see details of existing PRs:"
log " curl -H \"Authorization: token \$GITEA_TOKEN\" \"$API/repos/$REPO/pulls?state=open\" | jq '.[] | select(.title | test(\"#$ISSUE_NUMBER\"; \"i\"))'"
exit 1

195
scripts/check_existing_prs.py Normal file → Executable file
View File

@@ -1,111 +1,148 @@
#!/usr/bin/env python3
"""
check_existing_prs.py — Pre-flight check for duplicate PRs (Python version)
Check if PRs already exist for an issue before creating a new one.
This script prevents duplicate PRs by checking if there are already
open PRs for a given issue.
Usage:
python scripts/check_existing_prs.py <issue_number>
python scripts/check_existing_prs.py --issue 1524
python3 scripts/check_existing_prs.py <issue_number>
Exit codes:
0: No existing PRs found (safe to create new PR)
1: Existing PRs found (do not create new PR)
2: Error (API failure, missing parameters, etc.)
0 - No existing PRs found (safe to create new PR)
1 - Existing PRs found (do not create new PR)
2 - Error (API failure, missing parameters, etc.)
Designed for issue #1474: Prevent duplicate PRs
"""
import argparse
import json
import os
import sys
import urllib.request
import urllib.error
from pathlib import Path
# Configuration
GITEA_URL = os.environ.get("GITEA_URL", "https://forge.alexanderwhitestone.com")
REPO = os.environ.get("GITEA_REPO", "Timmy_Foundation/the-nexus")
TOKEN_PATH = Path.home() / ".config" / "gitea" / "token"
# ANSI colors
RED = "\033[0;31m"
GREEN = "\033[0;32m"
YELLOW = "\033[1;33m"
NC = "\033[0m"
from datetime import datetime
def load_token() -> str:
"""Load Gitea API token."""
if TOKEN_PATH.exists():
return TOKEN_PATH.read_text().strip()
return os.environ.get("GITEA_TOKEN", "")
def check_existing_prs(issue_number: int, token: str) -> list:
"""Check if issue already has open PRs.
Returns list of existing PR dicts, or empty list if none found.
def check_existing_prs(issue_number: int, repo: str = None, token: str = None) -> int:
"""
url = f"{GITEA_URL}/api/v1/repos/{REPO}/pulls?state=open"
headers = {
"Authorization": f"token {token}",
"Accept": "application/json",
}
Check if PRs already exist for an issue.
Args:
issue_number: The issue number to check
repo: Repository in format "owner/repo" (default: from env or "Timmy_Foundation/the-nexus")
token: Gitea API token (default: from GITEA_TOKEN env var)
Returns:
0: No existing PRs found (safe to create new PR)
1: Existing PRs found (do not create new PR)
2: Error (API failure, missing parameters, etc.)
"""
# Get configuration from environment
gitea_url = os.environ.get('GITEA_URL', 'https://forge.alexanderwhitestone.com')
token = token or os.environ.get('GITEA_TOKEN')
repo = repo or os.environ.get('REPO', 'Timmy_Foundation/the-nexus')
if not token:
print("ERROR: GITEA_TOKEN environment variable not set", file=sys.stderr)
return 2
# Validate issue number
if not isinstance(issue_number, int) or issue_number <= 0:
print("ERROR: Issue number must be a positive integer", file=sys.stderr)
return 2
# Build API URL
api_url = f"{gitea_url}/api/v1/repos/{repo}/pulls?state=open&limit=100"
# Make API request
try:
req = urllib.request.Request(url, headers=headers)
req = urllib.request.Request(api_url, headers={
'Authorization': f'token {token}',
'Content-Type': 'application/json'
})
with urllib.request.urlopen(req, timeout=30) as resp:
prs = json.loads(resp.read())
except urllib.error.HTTPError as e:
print(f"{RED}Error: API request failed with HTTP {e.code}{NC}", file=sys.stderr)
return []
except urllib.error.URLError as e:
print(f"ERROR: Failed to fetch PRs: {e}", file=sys.stderr)
return 2
except json.JSONDecodeError as e:
print(f"ERROR: Failed to parse API response: {e}", file=sys.stderr)
return 2
except Exception as e:
print(f"{RED}Error: {e}{NC}", file=sys.stderr)
return []
print(f"ERROR: Unexpected error: {e}", file=sys.stderr)
return 2
# Find PRs referencing this issue
# Check for PRs referencing this issue
issue_ref = f"#{issue_number}"
existing = []
for pr in prs:
body = (pr.get("body") or "") + " " + (pr.get("title") or "")
if issue_ref in body:
existing.append(pr)
matching_prs = []
return existing
for pr in prs:
title = pr.get('title', '')
body = pr.get('body', '') or ''
# Check if issue is referenced in title or body
if issue_ref in title or issue_ref in body:
matching_prs.append(pr)
# Report results
timestamp = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ")
if not matching_prs:
print(f"[{timestamp}] ✅ No existing PRs found for issue #{issue_number}")
print("Safe to create a new PR")
return 0
# Found existing PRs
print(f"[{timestamp}] ⚠️ Found existing PRs for issue #{issue_number}:")
print()
for pr in matching_prs:
pr_number = pr.get('number')
pr_title = pr.get('title')
pr_branch = pr.get('head', {}).get('ref', 'unknown')
pr_created = pr.get('created_at', 'unknown')
pr_url = pr.get('html_url', 'unknown')
print(f" PR #{pr_number}: {pr_title}")
print(f" Branch: {pr_branch}")
print(f" Created: {pr_created}")
print(f" URL: {pr_url}")
print()
print("❌ Do not create a new PR. Review existing PRs first.")
print()
print("Options:")
print(" 1. Review and merge an existing PR")
print(" 2. Close duplicates and keep the best one")
print(" 3. Add comments to existing PRs instead of creating new ones")
print()
print("To see details of existing PRs:")
print(f' curl -H "Authorization: token $GITEA_TOKEN" "{gitea_url}/api/v1/repos/{repo}/pulls?state=open" | jq \'.[] | select(.title | test("#{issue_number}"; "i"))\'')
return 1
def main():
parser = argparse.ArgumentParser(description="Check for existing PRs before creating new one")
parser.add_argument("issue_number", nargs="?", type=int, help="Issue number to check")
parser.add_argument("--issue", "-i", type=int, help="Issue number (alternative syntax)")
args = parser.parse_args()
"""Main entry point."""
if len(sys.argv) < 2:
print("Usage: python3 check_existing_prs.py <issue_number>", file=sys.stderr)
print(" python3 check_existing_prs.py <issue_number> [repo] [token]", file=sys.stderr)
return 2
issue_number = args.issue_number or args.issue
if not issue_number:
print(f"{RED}Error: Issue number required{NC}", file=sys.stderr)
print("Usage: python check_existing_prs.py <issue_number>", file=sys.stderr)
sys.exit(2)
try:
issue_number = int(sys.argv[1])
except ValueError:
print("ERROR: Issue number must be an integer", file=sys.stderr)
return 2
# Load token
token = load_token()
if not token:
print(f"{RED}Error: Gitea token not found{NC}", file=sys.stderr)
sys.exit(2)
repo = sys.argv[2] if len(sys.argv) > 2 else None
token = sys.argv[3] if len(sys.argv) > 3 else None
# Check for existing PRs
print(f"{YELLOW}Checking for existing PRs referencing issue #{issue_number}...{NC}")
existing = check_existing_prs(issue_number, token)
if existing:
print(f"{RED}✗ Found existing PRs for issue #{issue_number}:{NC}")
for pr in existing:
print(f" #{pr['number']}: {pr['title']} ({pr['head']['ref']})")
print()
print(f"{YELLOW}Do not create another PR. Review existing PRs instead.{NC}")
sys.exit(1)
else:
print(f"{GREEN}✓ No existing PRs found for issue #{issue_number}{NC}")
print(f"{GREEN}Safe to create new PR.{NC}")
sys.exit(0)
return check_existing_prs(issue_number, repo, token)
if __name__ == "__main__":
main()
if __name__ == '__main__':
sys.exit(main())

View File

@@ -1,80 +1,48 @@
#!/bin/bash
# pr-safe.sh — User-friendly wrapper for PR creation with duplicate prevention
# Usage: ./scripts/pr-safe.sh <issue_number> [branch_name]
#!/usr/bin/env bash
# ═══════════════════════════════════════════════════════════════
# pr-safe.sh — Safe PR creation wrapper
#
# This script:
# 1. Checks for existing PRs
# 2. Guides you through safe PR creation
# 3. Prevents duplicate PRs
# This script checks for existing PRs before creating a new one.
# It's a wrapper around check-existing-prs.sh that provides
# a user-friendly interface.
#
# Usage:
# ./scripts/pr-safe.sh <issue_number> [branch_name]
#
# If branch_name is not provided, it will suggest one based on
# the issue number and current timestamp.
# ═══════════════════════════════════════════════════════════════
set -euo pipefail
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
ISSUE_NUMBER="${1:?Usage: $0 <issue_number> [branch_name]}"
BRANCH_NAME="${2:-}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
usage() {
echo "Usage: $0 <issue_number> [branch_name]"
echo ""
echo "Safe PR creation with duplicate prevention."
echo ""
echo "Examples:"
echo " $0 1524 # Create PR for issue #1524"
echo " $0 1524 fix/my-branch # Create PR with specific branch name"
echo ""
exit 1
}
# Parse arguments
if [ $# -lt 1 ]; then
usage
fi
ISSUE_NUMBER="$1"
BRANCH_NAME="${2:-fix/issue-${ISSUE_NUMBER}-$(date +%s)}"
echo -e "${BLUE}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║ Safe PR Creation for Issue #${ISSUE_NUMBER}${NC}"
echo -e "${BLUE}╚════════════════════════════════════════════════════════════╝${NC}"
echo "🔍 Checking for existing PRs for issue #$ISSUE_NUMBER..."
echo ""
# Step 1: Check for existing PRs
echo -e "${YELLOW}Step 1: Checking for existing PRs...${NC}"
if ! "${SCRIPT_DIR}/check-existing-prs.sh" "$ISSUE_NUMBER"; then
# Run the check
if "$SCRIPT_DIR/check-existing-prs.sh" "$ISSUE_NUMBER"; then
echo ""
echo -e "${RED}Cannot create PR — existing PRs found.${NC}"
echo -e "${YELLOW}Options:${NC}"
echo " 1. Review and contribute to existing PRs"
echo " 2. Close your local changes if truly duplicate"
echo " 3. Update your PR to address a different aspect"
echo "✅ Safe to create a new PR for issue #$ISSUE_NUMBER"
if [ -z "$BRANCH_NAME" ]; then
TIMESTAMP=$(date +%s)
BRANCH_NAME="fix/$ISSUE_NUMBER-$TIMESTAMP"
echo "📝 Suggested branch name: $BRANCH_NAME"
fi
echo ""
echo "To create a PR:"
echo " 1. Create branch: git checkout -b $BRANCH_NAME"
echo " 2. Make your changes"
echo " 3. Commit: git commit -m 'fix: Description (#$ISSUE_NUMBER)'"
echo " 4. Push: git push -u origin $BRANCH_NAME"
echo " 5. Create PR via API or web interface"
else
echo ""
echo "❌ Cannot create new PR for issue #$ISSUE_NUMBER"
echo " Existing PRs found. Review them first."
exit 1
fi
echo ""
# Step 2: Create branch
echo -e "${YELLOW}Step 2: Creating branch ${BRANCH_NAME}...${NC}"
git checkout -b "$BRANCH_NAME" 2>/dev/null || {
echo -e "${YELLOW}Branch already exists, switching to it.${NC}"
git checkout "$BRANCH_NAME"
}
echo ""
# Step 3: Guide through commit
echo -e "${YELLOW}Step 3: Make your changes and commit.${NC}"
echo " git add -A"
echo " git commit -m 'fix: implementation for #${ISSUE_NUMBER}'"
echo ""
# Step 4: Push and create PR
echo -e "${YELLOW}Step 4: Push and create PR.${NC}"
echo " git push -u origin ${BRANCH_NAME}"
echo ""
echo -e "${GREEN}✓ Ready to create PR safely!${NC}"