Skip to content

itxashancode/Pair-Extraordinaire-Automation

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🤝 Pair Extraordinaire Automation

Header

Typing Animation

Features Install Usage Contribute

Python GitHub CLI License Platform


⚠️ Educational Purpose Only

Educational

This tool is designed for educational purposes to understand GitHub automation, co-authoring workflows, and API integration. Use responsibly and in accordance with GitHub's Terms of Service.


🏆 Earn Your Pair Extraordinaire Badge

Pair Extraordinaire Badge

Default 1 PR Bronze 10 PRs Silver 24 PRs Gold 48 PRs

Automate co-authored PR creation and merging to unlock all achievement tiers!


🎯 What Is Pair Extraordinaire Automation?

A powerful Python automation framework that streamlines GitHub co-authored Pull Request workflows at scale. Perfect for developers who want to:

🎯 Use Case 📊 Benefit
Co-authored Commits Automatic Co-authored-by trailers on every commit
Badge Hunting Earn GitHub Pair Extraordinaire badge efficiently
Batch Documentation Update files across multiple branches with a collaborator
CI/CD Testing Stress-test co-authoring automation pipelines
Learning & Research Study GitHub automation patterns and workflows

📑 Table of Contents

🌟 Features 🏗️ Architecture 📦 Installation ⚙️ Configuration
🚀 Usage 🔧 Components 🔐 Security 🐛 Troubleshooting
📈 Optimization 🤝 Contributing 📄 License 📞 Support

🌟 Features

🎯 Core Capabilities Core 🔧 Advanced Features Advanced
✅ Automated Co-authored PRs └─ Auto Co-authored-by trailer ✅ Smart Auto-Merge └─ Intelligent PR merging ✅ Dual Execution Modes └─ Sequential & Parallel ✅ State Management └─ Resume from interruptions ✅ Dry Run Mode └─ Test without real commits ✅ Multi-Token Rotation └─ Automatic token switching ✅ Discord/Slack Webhooks └─ Real-time notifications ✅ Rate Limit Handling └─ Smart API throttling ✅ Exponential Backoff └─ Intelligent retry logic ✅ Template-based Commits └─ Customizable messages

🎬 How It Works

graph TB
    Start([🚀 Start Automation]) --> Config[📋 Load Config & .env]
    Config --> Mode{🔀 Choose Mode}
    Mode -->|Sequential| Seq[📝 run.py]
    Mode -->|Parallel| Par[⚡ Parallel Workers]
    Seq --> Git[🔧 Git Operations]
    Par --> Git
    Git --> Branch[🌿 Create Branch]
    Branch --> Commit[💾 Co-authored Commit]
    Commit --> Push[📤 Push to Remote]
    Push --> PR[🎯 Create PR]
    PR --> AutoMerge{🤖 Auto-merge?}
    AutoMerge -->|Yes| Merge[✅ Merge PR]
    AutoMerge -->|No| Next{📊 More PRs?}
    Merge --> Next
    Next -->|Yes| Git
    Next -->|No| Notify[📢 Send Notifications]
    Notify --> End([🎉 Complete!])

🏗️ Architecture

System Design Overview

Architecture

┌─────────────────────────────────────────────────────────────────┐
│               🤝 Pair Extraordinaire Automation                  │
│                     Core Orchestration Layer                     │
└─────────────────────────────────────────────────────────────────┘
                                │
                ┌───────────────┴───────────────┐
                │                               │
        ┌───────▼────────┐            ┌────────▼───────┐
        │  📝 Sequential │            │  ⚡ Parallel   │
        │    run.py      │            │   src/async    │
        │   Reliable     │            │   Fast Mode    │
        └───────┬────────┘            └────────┬───────┘
                │                              │
                └──────────────┬───────────────┘
                               │
        ┌──────────────────────┼──────────────────────┐
        │                      │                      │
   ┌────▼─────┐         ┌─────▼────┐         ┌──────▼──────┐
   │ 🔧 src/  │         │ ⚙️ config│         │ 📄 templates│
   │ Core Bot │         │ Settings │         │  Commit Msg │
   └────┬─────┘         └─────┬────┘         └──────┬──────┘
        │                     │                      │
        └─────────────────────┼──────────────────────┘
                              │
              ┌───────────────┼───────────────┐
              │               │               │
        ┌─────▼─────┐  ┌─────▼─────┐  ┌─────▼─────┐
        │ 🔑 Token  │  │ 📢 Notify │  │ 📝 Logger │
        │ Manager   │  │ Webhooks  │  │  System   │
        └───────────┘  └───────────┘  └───────────┘

🔑 Component Matrix

Component Role Features
run.py 📝 Entry Point Bootstraps automation, loads config
src/ 🔧 Core Logic Branch, commit, push, PR, merge
config/ ⚙️ Settings JSON/env-based configuration
templates/ 📄 Templates Commit messages & PR body templates
.env 🔑 Secrets GitHub tokens & co-author credentials

📦 Installation

🚀 Quick Start Guide

Setup Time

Prerequisites Checklist

✅ Python 3.8 or higher
✅ Git 2.0 or higher
✅ GitHub CLI (gh)
✅ Active GitHub account
✅ A collaborator account (for co-authoring)
✅ Write access to target repository

Step 1️⃣: Clone Repository

📥 Download the Code

# Clone via HTTPS
git clone https://github.com/itxashancode/Pair-Extraordinaire.git

# Or clone via SSH
git clone git@github.com:itxashancode/Pair-Extraordinaire.git

# Navigate to directory
cd Pair-Extraordinaire

Step 2️⃣: Install Dependencies

🐍 Python Packages

# Install all required packages
pip install -r requirements.txt

# Or use pip3 on some systems
pip3 install -r requirements.txt

📦 What Gets Installed:

Package Purpose
requests HTTP/API calls
gitpython Git automation
python-dotenv Load .env variables
colorama Terminal colors
aiohttp Async HTTP (parallel mode)

Step 3️⃣: Install GitHub CLI

🍎 macOS

brew install gh && gh --version

🐧 Linux (Debian/Ubuntu)

curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | \
  sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] \
  https://cli.github.com/packages stable main" | \
  sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null

sudo apt update && sudo apt install gh -y
gh --version

🪟 Windows

winget install --id GitHub.cli
# Or: choco install gh
gh --version

Step 4️⃣: Authenticate GitHub

🔐 Login to GitHub

# Start authentication
gh auth login

# Follow the interactive prompts:
# 1. Choose: GitHub.com
# 2. Protocol: HTTPS
# 3. Authenticate Git: Yes
# 4. Method: Login with a web browser

# Verify authentication
gh auth status

Expected Output:

✓ Logged in to github.com as YourUsername
✓ Git operations for github.com configured to use https protocol.
✓ Token: *******************

✅ Installation Complete!

Ready to configure? Proceed to ⚙️ Configuration


⚙️ Configuration

🎛️ Setup Your Automation

Config


📋 File 1: Environment Variables (.env)

cp .env.example .env
# GitHub credentials
GITHUB_TOKEN=your_personal_access_token_here

# Repository details
REPO_OWNER=your_github_username
REPO_NAME=your_repository_name

# Co-author details (required for Pair Extraordinaire)
CO_AUTHOR_NAME=Collaborator Name
CO_AUTHOR_EMAIL=collaborator@email.com
CO_AUTHOR_TOKEN=collaborator_github_token

# Notification webhooks (optional)
DISCORD_WEBHOOK=https://discord.com/api/webhooks/YOUR_WEBHOOK_HERE
SLACK_WEBHOOK=https://hooks.slack.com/services/YOUR_WEBHOOK_HERE

📖 Configuration Reference:

Variable Required Description
GITHUB_TOKEN ✅ Yes Your GitHub Personal Access Token
REPO_OWNER ✅ Yes GitHub username or org of the target repo
REPO_NAME ✅ Yes Name of the target repository
CO_AUTHOR_NAME ✅ Yes Display name of your co-author
CO_AUTHOR_EMAIL ✅ Yes Email used by co-author on GitHub
CO_AUTHOR_TOKEN ⚠️ Optional Co-author token for mutual achievements
DISCORD_WEBHOOK ❌ Optional Discord channel webhook URL
SLACK_WEBHOOK ❌ Optional Slack channel webhook URL

📋 File 2: Main Config (config/)

{
  "repo_path": ".",
  "base_branch": "main",
  "target_file": "README.md",
  "pr_count": 50,
  "delay_seconds": 15,
  "auto_merge": true,
  "dry_run": false,
  "max_retries": 3
}

📖 Configuration Reference:

Parameter Type Default Description
repo_path string "." Path to your Git repository
base_branch string "main" Target branch for PRs
target_file string "README.md" File modified in each commit
pr_count integer 50 Total co-authored PRs to create
delay_seconds integer 15 Wait time between PRs
auto_merge boolean true Automatically merge created PRs
dry_run boolean false Test mode — no actual changes
max_retries integer 3 Retry attempts on failure

📋 File 3: Commit Templates (templates/)

The templates/ directory contains message templates for commits and PR bodies. Every co-authored commit automatically appends the required trailer:

feat: automated update #{pr_number}

This is an automated co-authored commit.

Co-authored-by: {co_author_name} <{co_author_email}>

GitHub detects the Co-authored-by trailer and awards the badge to both users upon merge.


🔔 Optional: Webhook Setup

💬 Discord Webhook

  1. Discord Server → Settings → Integrations → Webhooks → New Webhook
  2. Name it, select a channel, copy the URL
  3. Paste into .env as DISCORD_WEBHOOK
# Test your webhook
curl -X POST "YOUR_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{"content": "Test from Pair Extraordinaire!"}'

💼 Slack Webhook

  1. Visit api.slack.com/apps → New App → Incoming Webhooks
  2. Activate, add to workspace, select channel, copy URL
  3. Paste into .env as SLACK_WEBHOOK

✅ Configuration Complete!

Ready

Next: 🚀 Usage Guide


🚀 Usage

🎮 Command Center


🏁 Quick Start Commands

# 1️⃣ Basic sequential run
python run.py

# 2️⃣ Test without creating PRs
python run.py --dry-run

# 3️⃣ Custom PR count
python run.py --count 50

# 4️⃣ Resume after interruption
python run.py  # Auto-resumes from state file

📘 Sequential Mode (run.py)

python run.py [OPTIONS]

Sequential

⭐ Best For: Reliability, debugging, smaller PR counts

Option Description Example
--count N Override PR count python run.py --count 50
--delay N Seconds between PRs python run.py --delay 30
--dry-run Test mode (no commits) python run.py --dry-run
--no-merge Disable auto-merge python run.py --no-merge
--reset Start from PR #1 python run.py --reset

📊 Example Output:

🚀 Starting Pair Extraordinaire Automation from PR #1
⏱️  Delay: 15 seconds

🔹 Processing PR #1
  ├─ 🌿 Created branch: pair-auto-1-a1b2c3d4
  ├─ 💾 Committed with Co-authored-by trailer
  ├─ 📤 Pushed to remote
  └─ ✅ PR #101 created successfully

✅ PR #101 merged — both users credited
⏱️  Waiting 15 seconds...

🔹 Processing PR #2
...

📚 Usage Examples

Example 1: Default Badge (1 PR)

Goal: Earn the default Pair Extraordinaire badge

# Test with dry run first
python run.py --count 2 --dry-run

# Run actual automation
python run.py --count 2 --delay 10

Output:

🚀 Starting from PR #1

✅ PR #1-2 created and merged successfully
🎉 Default Pair Extraordinaire Badge unlocked!

Example 2: Bronze Badge (10 PRs)

Goal: Earn Bronze Pair Extraordinaire Badge

python run.py --count 12 --delay 15
# Expected time: ~3 minutes

Output:

🚀 Starting automation

📈 12/12 PRs complete

🎉 Bronze Pair Extraordinaire Badge unlocked!
⏱️ Completed in 3 minutes 1 second

Example 3: Gold Badge (48 PRs)

Goal: Earn Gold Pair Extraordinaire Badge

python run.py --count 50 --delay 10
# Expected time: ~8-10 minutes

Output:

🚀 Starting automation

📈 50/50 PRs complete ✓ 48 merged ✗ 2 retried

🎉🎉🎉 GOLD PAIR EXTRAORDINAIRE UNLOCKED! 🎉🎉🎉
⏱️ Completed in 8 minutes 45 seconds

Example 4: Resume After Interruption

Scenario: Process interrupted at PR #22

# Check current state
cat state.json
# Output: {"last_completed_pr": 22}

# Resume automatically
python run.py --count 50
# Continues from PR #23

Example 5: Dry Run Testing

Goal: Test configuration without creating real PRs

python run.py --count 5 --dry-run

Output:

🔍 DRY RUN MODE - No actual commits

🔹 PR #1 Simulation
  📝 Would create branch: pair-auto-1-abc123
  📝 Would modify: README.md
  📝 Would commit with Co-authored-by trailer
  📝 Would push to: origin/pair-auto-1-abc123
  📝 Would create PR: "Automated Co-authored PR #1"
  ✅ Simulation successful

✅ All 5 PRs simulated successfully

💡 Pro Tips

🎯 Tip 1 Always start with --dry-run to validate your config
🤝 Tip 2 Make sure your co-author's email matches their GitHub account
🔄 Tip 3 State files allow safe resuming after any interruption
📊 Tip 4 Monitor rate limits with gh api rate_limit
Tip 5 Lower delay_seconds for faster runs (minimum ~10s recommended)

🔧 Components Deep Dive

🏗️ System Architecture Breakdown


1️⃣ Entry Point (run.py)

🎯 Purpose: Bootstrap the automation, load configuration, and invoke the core pipeline

🔑 Responsibilities:

# run.py high-level flow
def main():
    config = load_config()            # Load config/ and .env
    state  = load_state()             # Resume support

    for pr_num in range(start, total):
        branch = create_branch(pr_num)
        commit_with_coauthor(branch)   # Appends Co-authored-by
        push(branch)
        pr_id = create_pr(branch)
        if config.auto_merge:
            merge_pr(pr_id)
        save_state(pr_num)
        notify(pr_num)
        sleep(config.delay_seconds)

2️⃣ Source Modules (src/)

🎯 Purpose: Core bot logic — Git operations, GitHub API calls, PR management

✨ Key Features:

Module Role
Git Manager Branch creation, co-authored commits, push
GitHub Tool PR create, merge, rate-limit handling
Token Manager Token rotation for higher throughput
State Manager Persist progress for resumable runs

🔑 Co-authored Commit Format:

git commit -m "Automated update #1

Co-authored-by: Collaborator Name <collaborator@email.com>"

GitHub detects the Co-authored-by trailer and credits both users, triggering the Pair Extraordinaire badge upon merge.

✨ Features:

⏱️ Exponential Backoff Retry delays: 5s → 10s → 20s
🌐 Internet Check Validates connection before operations
🔁 Auto-Retry Configurable attempts (default: 3)
⏲️ Timeout Protection 30-second command timeout

3️⃣ Configuration (config/)

🎯 Purpose: Centralize all settings, making the bot easy to tune without editing source code

Key responsibilities:

  • Load and validate JSON settings
  • Merge with environment variables from .env
  • Provide defaults for all optional values

4️⃣ Templates (templates/)

🎯 Purpose: Store reusable commit message and PR body templates

Example Template:

feat: automated update #{pr_number}

This is an automated co-authored commit for demonstration purposes.

Co-authored-by: {co_author_name} <{co_author_email}>

Templates make it easy to customize the message format without touching core code.


5️⃣ Notifications

🎯 Purpose: Send real-time updates to Discord or Slack on automation progress

🎨 Notification Types:

Level Color Use Case
info 🔵 Blue Progress updates
success 🟢 Green PR created/merged
warning 🟡 Yellow Non-critical errors
error 🔴 Red Critical failures

📨 Example Notification:

✅ PR #25 created and merged successfully
Branch: pair-auto-25-xyz
Co-author: CollaboratorName
Speed: 3.8 PRs/min

🔐 Security & Best Practices

🛡️ Keep Your Tokens Safe


🔒 Token Security Checklist

Never commit .env to Git .env is in .gitignore by default
Use environment variables export GITHUB_TOKEN="ghp_xxx"
Rotate tokens regularly Every 30–90 days
Use fine-grained tokens Limit scope to specific repos
Enable 2FA Extra security layer on your account
Monitor token usage gh api rate_limit

🔑 How to Generate GitHub Tokens

Step-by-Step Guide:

  1. GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic)
  2. Click "Generate new token (classic)"
    • Name: Pair Extraordinaire Automation
    • Expiration: 90 days
  3. Select required scopes:repoworkflow
  4. Click "Generate token" — copy immediately (shown only once!)
  5. Add to .env as GITHUB_TOKEN

📊 Rate Limits:

Authentication Requests/Hour Notes
Unauthenticated 60 Very limited
OAuth Token 5,000 Per token
Multiple Tokens (rotated) 10,000+ Automatic rotation

🐛 Troubleshooting

🔧 Common Issues & Solutions


❌ Issue 1: "gh: command not found"

📋 Problem: GitHub CLI is not installed or not in PATH.

✅ Solution:

# macOS
brew install gh

# Linux
sudo apt update && sudo apt install gh -y

# Windows
winget install --id GitHub.cli

# Verify
gh --version

❌ Issue 2: "Authentication failed"

📋 Problem: GitHub CLI not authenticated or token expired.

✅ Solution:

gh auth login
# Or use token directly
echo "YOUR_TOKEN" | gh auth login --with-token
gh auth status

❌ Issue 3: "API rate limit exceeded"

📋 Problem: Too many API requests in a short time.

✅ Solutions:

# Check current rate limit
gh api rate_limit

# Increase delay in config
"delay_seconds": 60

# Add a second token to .env or config

❌ Issue 4: "Failed to push branch"

📋 Problem: Git push fails due to network or permissions.

✅ Solutions:

# Check connection
ping github.com

# Verify repository permissions
gh repo view --web

# Re-authenticate
gh auth refresh

❌ Issue 5: "Co-authored-by not recognized"

📋 Problem: Badge not awarded — co-author email doesn't match a GitHub account.

✅ Solution:

  • Ensure CO_AUTHOR_EMAIL exactly matches the email in the co-author's GitHub account settings
  • The email must be associated with their GitHub profile (set as public or verified)

❌ Issue 6: "No changes to commit"

📋 Problem: File already contains identical content.

✅ Solutions:

# Reset state and start fresh
python run.py --reset

# Or change the target file in config
"target_file": "CONTRIBUTING.md"

🔍 Enable Debug Mode

export LOG_LEVEL=DEBUG
python run.py

Debug Output Example:

DEBUG - Loaded config: pr_count=50, delay=15s
DEBUG - Co-author: CollaboratorName <email@example.com>
DEBUG - Executing: git push origin pair-auto-1-abc123
DEBUG - Command output: [SUCCESS]
DEBUG - PR created: #101
DEBUG - Merged PR #101 successfully

📈 Performance Tips

⚡ Maximize Your Speed


🚀 Speed Optimization Matrix

Strategy Impact Difficulty Implementation
Reduce delay ⭐⭐⭐⭐ 🟢 Easy --delay 10
Multiple tokens ⭐⭐⭐⭐ 🟢 Easy Add tokens to config
Stable network ⭐⭐⭐ 🟡 Medium Use wired connection
SSD storage ⭐⭐ 🔴 Hard Run on SSD drive

📊 Benchmarks

Test 1: Default Badge (2 PRs)

⏱️  Time: ~30 seconds
✅ Success: 2/2 PRs
📈 Speed: ~4 PRs/min

Test 2: Bronze Badge (10 PRs)

⏱️  Time: ~3 minutes
✅ Success: 10/10 PRs
📈 Speed: ~3.5 PRs/min

Test 3: Gold Badge (48 PRs)

⏱️  Time: ~10 minutes
✅ Success: 46/48 PRs
🔁 Retries: 3 operations
📈 Speed: ~4.8 PRs/min

🤝 Contributing

💪 Join the Community


🚀 How to Contribute

# 1️⃣ Fork the repository
gh repo fork itxashancode/Pair-Extraordinaire

# 2️⃣ Clone your fork
git clone https://github.com/YOUR_USERNAME/Pair-Extraordinaire.git
cd Pair-Extraordinaire

# 3️⃣ Create feature branch
git checkout -b feature/amazing-feature

# 4️⃣ Make your changes

# 5️⃣ Commit with conventional commits
git commit -m "feat: add amazing feature"

# 6️⃣ Push to your fork
git push origin feature/amazing-feature

# 7️⃣ Create Pull Request
gh pr create --title "Add amazing feature" --body "Description..."

📝 Code Style Guide

# ✅ Good — Clear, documented, typed
def commit_with_coauthor(branch: str, pr_number: int) -> bool:
    """
    Create a co-authored commit on the given branch.

    Args:
        branch: Branch name to commit on
        pr_number: PR sequence number for the commit message

    Returns:
        True if successful, False otherwise
    """
    try:
        message = build_commit_message(pr_number)
        return git.commit(branch, message)
    except Exception as e:
        logger.error(f"Commit failed: {e}")
        return False

# ❌ Bad — Unclear, no types, no docs
def doCommit(b, n):
    return git.commit(b, buildMsg(n))

🎨 Formatting Tools:

# Auto-format with black
black *.py

# Check style with flake8
flake8 *.py

# Type checking with mypy
mypy *.py

🐛 Reporting Bugs

Found a bug? Help us fix it!

Steps:

  1. Check existing issues
  2. Create a new issue with the template
  3. Include: OS & Python version, full error message, steps to reproduce, expected vs actual behavior

📄 License

MIT License

MIT License

MIT License

Copyright (c) 2026 Pair Extraordinaire Automation

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.

🙏 Acknowledgments

🌟 Built With Amazing Tools

Python GitHub CLI Git Discord Slack

💖 Special Thanks

  • GitHub — For excellent CLI and API tooling
  • Python Community — For amazing open-source libraries
  • Contributors — Everyone who improved this project
  • You — For using Pair Extraordinaire Automation!

📞 Support & Community

📖 Docs 🐛 Issues
💬 Discussions 👤 Profile

🎉 Final Words

Footer

🤝 Unleash the Pair Extraordinaire! 🤝

Co-author smarter. Earn your badge. Ship together.


Made with ❤️ by itxashancode · linktr.ee/itxashanvibes

⭐ Star this repo if you found it helpful!

About

Automate GitHub co-authored Pull Requests with Python. Earn the Pair Extraordinaire badge using sequential or parallel modes, multi-token rotation, Discord/Slack webhooks, and smart rate-limit handling. Supports dry-run, auto-merge & state resumption.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages