{"id":50980011,"url":"https://github.com/shineii86/pullshark","last_synced_at":"2026-06-19T13:02:07.102Z","repository":{"id":351592123,"uuid":"1211685161","full_name":"Shineii86/PullShark","owner":"Shineii86","description":"Automated GitHub Pull Shark achievement unlocker. Creates and merges pull requests in your repo — runs in Google Colab with zero setup.","archived":false,"fork":false,"pushed_at":"2026-05-09T04:09:18.000Z","size":3314,"stargazers_count":20,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-09T04:28:02.008Z","etag":null,"topics":["achievement","achievement-unlocker","achivements","automation","pull-request-template","pull-requests","pull-shark"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Shineii86.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-15T16:37:05.000Z","updated_at":"2026-05-09T04:09:22.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Shineii86/PullShark","commit_stats":null,"previous_names":["shineii86/pullshark"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Shineii86/PullShark","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shineii86%2FPullShark","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shineii86%2FPullShark/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shineii86%2FPullShark/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shineii86%2FPullShark/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Shineii86","download_url":"https://codeload.github.com/Shineii86/PullShark/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shineii86%2FPullShark/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34532260,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-19T02:00:06.005Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["achievement","achievement-unlocker","achivements","automation","pull-request-template","pull-requests","pull-shark"],"created_at":"2026-06-19T13:02:02.120Z","updated_at":"2026-06-19T13:02:07.096Z","avatar_url":"https://github.com/Shineii86.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n[![Pull Shark Automator Banner](https://raw.githubusercontent.com/Shineii86/PullShark/refs/heads/main/images/PullShark.png)](https://github.com/Shineii86/PullShark)\n\n[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Shineii86/PullShark/blob/main/notebooks/PullShark.ipynb)\n[![CI](https://github.com/Shineii86/PullShark/actions/workflows/ci.yml/badge.svg)](https://github.com/Shineii86/PullShark/actions/workflows/ci.yml)\n[![PyPI](https://img.shields.io/pypi/v/pullshark.svg?style=flat-square)](https://pypi.org/project/pullshark/)\n[![Python 3.8+](https://img.shields.io/badge/python-3.8%2B-blue.svg)](https://www.python.org/downloads/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n[![GitHub Stars](https://img.shields.io/github/stars/Shineii86/PullShark?style=for-the-badge)](https://github.com/Shineii86/PullShark/stargazers)\n[![GitHub Forks](https://img.shields.io/github/forks/Shineii86/PullShark?style=for-the-badge)](https://github.com/Shineii86/PullShark/fork)\n\nA **fully automated** Python tool that creates and merges multiple pull requests in your GitHub repository — helping you earn the coveted **Pull Shark** achievement. Runs in **Google Colab** or directly from your **terminal**.\n\n\u003c/div\u003e\n\n---\n\n\u003e [!WARNING]\n\u003e **This script creates real pull requests on your GitHub account.**\n\u003e - Never share your **Personal Access Token** — treat it like a password.\n\u003e - Use a **dedicated repository** to avoid cluttering important projects.\n\u003e - GitHub may rate‑limit excessive API calls; the built‑in delay helps prevent this.\n\n---\n\n## 📖 Table of Contents\n\n- [What is Pull Shark?](#-what-is-pull-shark)\n- [Features](#-features)\n- [Prerequisites](#-prerequisites)\n- [Project Structure](#-project-structure)\n- [Installation](#-installation)\n- [Usage](#-usage)\n  - [Google Colab](#1️⃣-google-colab)\n  - [Command Line (CLI)](#2️⃣-command-line-cli)\n  - [As a Python Package](#3️⃣-as-a-python-package)\n- [Configuration Options](#-configuration-options)\n- [How It Works](#-how-it-works-technical-overview)\n- [Merge Methods](#-merge-methods)\n- [Testing \u0026 Contributing](#-testing--contributing)\n- [Troubleshooting](#-troubleshooting)\n- [Changelog](#-changelog)\n- [License \u0026 Disclaimer](#-license--disclaimer)\n\n---\n\n## 🎯 What is Pull Shark?\n\n**Pull Shark** is a GitHub achievement awarded when you have **at least 2 pull requests merged** into any repository. It's one of the most popular achievements and a fun way to show off your open-source contributions.\n\nThis script automates the creation and merging of pull requests, so you can unlock the achievement in **under 5 minutes** — from your browser or terminal.\n\n| Base | Bronze | Silver | Gold |\n| :--: | :----: | :----: | :--: |\n| [![Base](https://github.com/Shineii86/PullShark/blob/main/images/pull-shark-default.png)](https://github.com/Shineii86/PullShark) | [![Bronze](https://github.com/Shineii86/PullShark/blob/main/images/pull-shark-bronze.png)](https://github.com/Shineii86/PullShark) | [![Silver](https://github.com/Shineii86/PullShark/blob/main/images/pull-shark-silver.png)](https://github.com/Shineii86/PullShark) | [![Gold](https://github.com/Shineii86/PullShark/blob/main/images/pull-shark-gold.png)](https://github.com/Shineii86/PullShark) |\n\n\n\u003e To earn the \"**Pull Shark**\" achievement on GitHub, you need to have your pull requests (PRs) merged. The badge has four tiers, each requiring a specific number of merged PRs.\n\n### 🦈 Pull Shark Achievement Tiers\n\n| Tier | Badge Name | Required Merged Pull Requests |\n| :--- | :--- | :--- |\n| 1 | **Default / x1** | **2** merged PRs |\n| 2 | **Bronze / x2** | **16** merged PRs |\n| 3 | **Silver / x3** | **128** merged PRs |\n| 4 | **Gold / x4** | **1024** merged PRs |\n\n\u003e [!IMPORTANT]\n\u003e Only merged PRs count toward this achievement. PRs that are closed without being merged do not contribute to your progress.\n\n---\n\n## ✨ Features\n\n| Feature | Description |\n|:--------|:------------|\n| ☁️ **Google Colab** | One-click notebook with 5-step guided flow — no install needed |\n| 🎨 **Dark Mode** | Colab notebook auto-adapts to light and dark themes |\n| 🖥️ **CLI** | Full terminal interface with `run` and `clean` subcommands |\n| 🔍 **Dry Run** | Preview branches, commits, and PRs without making any changes |\n| 🧹 **Branch Cleanup** | Bulk-delete auto-created branches after a run |\n| 📊 **Rate Limit Check** | View your API quota before starting — prevents mid-run failures |\n| 🔀 **Merge Strategies** | Choose between `merge`, `squash`, or `rebase` methods |\n| 🔄 **Retry Logic** | Automatically retries failed merges with configurable attempts |\n| 📝 **Logging** | `--log file.log` saves timestamped debug output for auditing |\n| 📄 **JSON Reports** | `--output report.json` saves structured run results |\n| 🏷️ **Custom Prefix** | `--prefix mybot` to customize branch names |\n| 📦 **Python Package** | Import into your own scripts for custom workflows |\n| 🐍 **`python -m`** | Run as `python -m pullshark` without installing |\n| ✅ **Validation** | Catches config errors before making any API calls |\n| 🧪 **Tested** | 35+ pytest tests with CI on Python 3.9–3.12 |\n| 📦 **PyPI** | `pip install pullshark` — install from PyPI |\n| 🔧 **Pre-Commit** | Ruff lint/format + pytest hooks for contributors |\n\n---\n\n## 🧰 Prerequisites\n\nBefore you begin, make sure you have:\n\n1. **A GitHub account** — obviously 😄  \n2. **A repository** where you have **write access** (you can create a new one just for this).  \n3. **A GitHub Personal Access Token** with `repo` scope.\n\n### 🔐 How to Get a Personal Access Token\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eClassic Token (Recommended for beginners)\u003c/b\u003e\u003c/summary\u003e\n\n1. Go to **Settings** → **Developer settings** → **Personal access tokens** → **Tokens (classic)**.\n2. Click **Generate new token (classic)**.\n3. Give it a name (e.g., `Pull Shark Bot`).\n4. Under **Select scopes**, check **`repo`**.\n5. Click **Generate token** and **copy it immediately**.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eFine-Grained Token (More secure, recommended)\u003c/b\u003e\u003c/summary\u003e\n\n1. Go to **Settings** → **Developer settings** → **Personal access tokens** → **Fine-grained tokens**.\n2. Click **Generate new token**.\n3. Set **Resource owner** to your username.\n4. Under **Repository access**, select **Only select repositories** → pick your target repo.\n5. Under **Permissions** → **Repository permissions**, set:\n   - **Contents**: `Read and write`\n   - **Metadata**: `Read-only`\n   - **Pull requests**: `Read and write`\n6. Click **Generate token** and copy it.\n\n\u003c/details\u003e\n\n---\n\n## 📁 Project Structure\n\n```\nPullShark/\n├── pullshark/                  # Python package\n│   ├── __init__.py             # Package init \u0026 version\n│   ├── __main__.py             # python -m pullshark support\n│   ├── config.py               # Configuration dataclass with validation\n│   ├── core.py                 # PullSharkBot — main automation logic\n│   ├── utils.py                # Helpers (random strings, mergeability, reports)\n│   └── cli.py                  # Command-line interface (run \u0026 clean subcommands)\n├── tests/\n│   └── test_pullshark.py       # pytest test suite (35+ tests)\n├── notebooks/\n│   └── PullShark.ipynb         # Google Colab notebook (5-step guided flow)\n├── .github/\n│   ├── workflows/\n│   │   ├── ci.yml              # CI on push/PR (Python 3.9–3.12)\n│   │   └── publish.yml         # PyPI publish on tag\n│   └── dependabot.yml          # Auto dependency updates\n├── images/                     # Achievement badge images\n├── pyproject.toml              # Python packaging + pytest + ruff config\n├── requirements.txt            # Dependencies\n├── .pre-commit-config.yaml     # Pre-commit hooks (ruff, pytest, linting)\n├── CONTRIBUTING.md             # Contribution guidelines\n├── CHANGELOG.md                # Version history\n├── LICENSE                     # MIT License\n└── README.md                   # This file\n```\n\n---\n\n## 📥 Installation\n\n### From PyPI (Easiest)\n\n```bash\npip install pullshark\n```\n\n### From Source (Recommended for Contributors)\n\n```bash\ngit clone https://github.com/Shineii86/PullShark.git\ncd PullShark\npip install -e .\n```\n\nThis installs the `pullshark` CLI command and makes the package importable.\n\n### With Dev Dependencies (For Contributors)\n\n```bash\npip install -e \".[dev]\"\npip install pre-commit \u0026\u0026 pre-commit install\n```\n\nInstalls pytest, pytest-cov, ruff, and sets up pre-commit hooks.\n\n### Dependencies Only\n\n```bash\npip install PyGithub\u003e=2.1.0\n```\n\n---\n\n## 🚀 Usage\n\n### 1️⃣ Google Colab\n\n\u003ca href=\"https://colab.research.google.com/github/Shineii86/PullShark/blob/main/notebooks/PullShark.ipynb\"\u003e\n  \u003cimg src=\"https://user-images.githubusercontent.com/125879861/255389999-a0d261cf-893a-46a7-9a3d-2bb52811b997.png\" alt=\"Open In Colab\" width=\"200px\"\u003e\n\u003c/a\u003e\n\nThe notebook walks you through **5 steps**:\n\n| Step | Name | What it does |\n|:----:|:-----|:-------------|\n| 1 | 📦 **Install \u0026 Load** | Installs PyGithub and loads the package |\n| 2 | 🔌 **Test Connection** | Validates token, repo access, write permissions, API rate limit, and existing branches |\n| 3 | 🔍 **Dry Run** | Preview what the bot will do — no changes made *(auto-fills from Step 2)* |\n| 4 | 🚀 **Run for Real** | Create and merge PRs with full configuration *(auto-fills from Step 3)* |\n| 5 | 🧹 **Cleanup** | Delete all auto-created branches *(auto-fills from Step 4)* |\n\n\u003e 💡 **Tip:** Enter your credentials once in Step 2 — they flow through to Steps 3, 4, and 5 automatically. Run the styling cell first to enable dark/light mode support.\n\n### 2️⃣ Command Line (CLI)\n\nAfter installing with `pip install -e .`, use the `pullshark` command:\n\n```bash\n# Create and merge PRs\npullshark run --token ghp_xxx --username YourUsername --repo YourRepo --prs 4\n\n# Preview what would happen (no changes made)\npullshark run --token ghp_xxx --username YourUsername --repo YourRepo --dry-run\n\n# Check API quota first\npullshark run --token ghp_xxx --username YourUsername --repo YourRepo --check-rate\n\n# Use squash merge with custom branch prefix\npullshark run --token ghp_xxx --username YourUsername --repo YourRepo --merge-method squash --prefix mybot\n\n# Save logs and JSON report\npullshark run --token ghp_xxx --username YourUsername --repo YourRepo --log run.log --output report.json\n\n# Clean up auto-created branches\npullshark clean --token ghp_xxx --username YourUsername --repo YourRepo\n\n# Preview cleanup without deleting\npullshark clean --token ghp_xxx --username YourUsername --repo YourRepo --dry-run\n\n# Clean with custom prefix\npullshark clean --token ghp_xxx --username YourUsername --repo YourRepo --prefix mybot\n\n# Run without installing\npython -m pullshark run --token ghp_xxx --username YourUsername --repo YourRepo\n```\n\n\u003e 💡 The `run` subcommand is optional — `pullshark --token ... --repo ...` still works as a shortcut.\n\n#### CLI Arguments — `run`\n\n| Flag | Short | Required | Default | Description |\n|------|-------|:--------:|---------|-------------|\n| `--token` | `-t` | ✅ | — | GitHub Personal Access Token |\n| `--username` | `-u` | ✅ | — | Your GitHub username |\n| `--repo` | `-r` | ✅ | — | Target repository name |\n| `--prs` | `-n` | | `4` | Number of PRs to create |\n| `--branch` | `-b` | | `main` | Base branch to target |\n| `--delay` | `-d` | | `10` | Delay (seconds) between PRs |\n| `--max-retries` | | | `3` | Max merge retry attempts |\n| `--merge-method` | | | `merge` | Merge strategy: `merge`, `squash`, `rebase` |\n| `--prefix` | | | `auto-pr` | Branch name prefix |\n| `--dry-run` | | | off | Preview mode — no changes made |\n| `--check-rate` | | | off | Show API quota before running |\n| `--log` | | | — | Save detailed logs to a file |\n| `--output` | | | — | Save run report as JSON |\n\n#### CLI Arguments — `clean`\n\n| Flag | Short | Required | Description |\n|------|-------|:--------:|-------------|\n| `--token` | `-t` | ✅ | GitHub Personal Access Token |\n| `--username` | `-u` | ✅ | Your GitHub username |\n| `--repo` | `-r` | ✅ | Target repository name |\n| `--prefix` | | Branch prefix to clean (default: `auto-pr`) |\n| `--dry-run` | | | Show branches that would be deleted without deleting |\n| `--log` | | | Save detailed logs to a file |\n\n#### CLI Output Example\n\n```\nConfiguration: user='Shineii86' repo='PullShark'\nBase branch: main\nWill create 4 PR(s) with 10s delay.\nMerge method: squash\nBranch prefix: mybot\n\n--- 📦 PR #1 of 4 ---\n  Latest main commit: a1b2c3d\n  ✅ Created branch: mybot-xyz123-1234567890\n  📝 Updated README.md\n  🔗 Created PR: https://github.com/Shineii86/PullShark/pull/178\n  ⏳ Waiting for GitHub to calculate mergeability...\n  🎉 Merged PR #178\n  ⏸️  Pausing 10s for GitHub to process...\n\n🏁 Finished. 4 out of 4 pull requests merged.\n🦈 Congratulations! You've met the requirements for Pull Shark!\n\n📄 Report saved to report.json\n```\n\n#### JSON Report Format\n\nWhen using `--output report.json`, the file contains:\n\n```json\n{\n  \"version\": \"2.4.6\",\n  \"timestamp\": \"2026-05-09T02:37:00+00:00\",\n  \"config\": {\n    \"username\": \"Shineii86\",\n    \"repo\": \"PullShark\",\n    \"base_branch\": \"main\",\n    \"num_prs\": 4,\n    \"merge_method\": \"squash\",\n    \"branch_prefix\": \"mybot\"\n  },\n  \"summary\": {\n    \"total\": 4,\n    \"successful\": 4,\n    \"failed\": 0,\n    \"pull_shark_tier\": \"Default\"\n  },\n  \"pull_requests\": [\n    {\"index\": 1, \"merged\": true, \"branch\": \"mybot-abc123\", \"pr_number\": 178, \"pr_url\": \"...\"}\n  ]\n}\n```\n\n### 3️⃣ As a Python Package\n\nImport the bot into your own scripts for custom workflows:\n\n```python\nfrom pullshark.config import Config\nfrom pullshark.core import PullSharkBot\n\nconfig = Config(\n    github_username=\"YourUsername\",\n    github_token=\"ghp_xxx\",\n    repo_name=\"YourRepo\",\n    num_prs=6,\n    delay_seconds=15,\n    merge_method=\"squash\",\n    branch_prefix=\"mybot\",\n    output_file=\"report.json\",  # Save JSON report\n)\n\nbot = PullSharkBot(config)\nmerged = bot.run()\nprint(f\"Merged {merged} PRs\")\n\n# Clean up branches when done\nbot.clean()\n\n# Check API quota\ninfo = bot.check_rate_limit()\nprint(f\"API: {info['remaining']}/{info['limit']} remaining\")\n```\n\n---\n\n## ⚙️ Configuration Options\n\n| Parameter | Default | Description |\n|:----------|:--------|:------------|\n| `num_prs` | `4` | Total number of pull requests to create and merge. Minimum `2` for the badge. |\n| `base_branch` | `\"main\"` | Target branch for PRs (e.g., `master`, `develop`). |\n| `delay_seconds` | `10` | Wait time (in seconds) between PRs and between merge retries. |\n| `max_retries` | `3` | Number of times to retry a failed merge before stopping. |\n| `merge_method` | `\"merge\"` | Merge strategy: `\"merge\"`, `\"squash\"`, or `\"rebase\"`. |\n| `branch_prefix` | `\"auto-pr\"` | Prefix for auto-generated branch names. |\n| `dry_run` | `False` | If `True`, previews actions without making changes. |\n| `log_file` | `\"\"` | Path to save detailed debug logs. |\n| `output_file` | `\"\"` | Path to save JSON run report. |\n\n### Advanced Customization\n\n- **File Modified**: By default, the script updates or creates `README.md`. To change this, edit `_make_commit()` in `pullshark/core.py`.\n- **Repository**: Use any repo you own or have write access to — just update the repo name.\n\n---\n\n## 🔬 How It Works (Technical Overview)\n\nThe script performs the following steps for **each** pull request:\n\n1. **Fetch the latest commit SHA** from the specified base branch to ensure we branch from the most up‑to‑date state.  \n2. **Create a new branch** with a unique name (e.g., `auto-pr-abc123-1234567890`).  \n3. **Make a commit** on that branch — either appending a line to `README.md` or creating it if it doesn't exist.  \n4. **Open a pull request** from the new branch to the base branch.  \n5. **Wait for GitHub's mergeability check** (polling the PR status every 3 seconds).  \n6. **Merge the pull request** using the configured merge method.  \n7. **Pause for `DELAY_SECONDS`** to let GitHub fully update the base branch before starting the next iteration.\n\n**Retry Logic**: If a merge fails (e.g., due to a temporary GitHub hiccup), the script will wait `DELAY_SECONDS` and retry up to `MAX_RETRIES` times before giving up.\n\n**Rate Limit Check**: With `--check-rate`, the bot inspects your remaining API quota before starting. Each PR cycle uses ~4 API calls, so the bot estimates whether you have enough.\n\n---\n\n## 🔀 Merge Methods\n\nPullShark supports three merge strategies. Choose based on your preference:\n\n| Method | Flag | What It Does | History |\n|:-------|:-----|:-------------|:--------|\n| **Merge** | `--merge-method merge` | Creates a merge commit joining the branch to base | Preserves all commits |\n| **Squash** | `--merge-method squash` | Combines all branch commits into a single commit | Clean, linear history |\n| **Rebase** | `--merge-method rebase` | Replays branch commits on top of base | Linear, no merge commit |\n\n\u003e 💡 For Pull Shark achievement purposes, all three methods count equally. Use `squash` for cleaner history.\n\n---\n\n## 🧪 Testing \u0026 Contributing\n\n### Running Tests\n\n```bash\n# Install dev dependencies\npip install -e \".[dev]\"\n\n# Run all tests\npytest tests/ -v\n\n# Run with coverage\npytest tests/ -v --cov=pullshark --cov-report=term-missing\n\n# Lint\nruff check pullshark/ tests/\n```\n\n### Pre-Commit Hooks\n\nFor contributors, pre-commit hooks run automatically before each commit:\n\n```bash\npip install pre-commit\npre-commit install\n```\n\nHooks include:\n- **ruff** — lint and auto-format Python code\n- **trailing-whitespace** — remove trailing spaces\n- **end-of-file-fixer** — ensure files end with newline\n- **check-yaml / check-json** — validate config files\n- **pytest** — run the test suite\n\n### CI Pipeline\n\nEvery push and PR triggers the GitHub Actions workflow which:\n- Runs the test suite across Python 3.9, 3.10, 3.11, and 3.12\n- Lints code with ruff\n- Validates notebook JSON structure\n\n### Publishing (Maintainers)\n\nTag a release to auto-publish to PyPI:\n\n```bash\ngit tag v2.4.6\ngit push origin v2.4.6\n```\n\nThe `publish.yml` workflow builds and publishes automatically via trusted publishing.\n\n### Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, branch naming conventions, and PR guidelines.\n\n---\n\n## 🆘 Troubleshooting\n\n| Issue | Solution |\n|:------|:---------|\n| `BadCredentialsException` | Token is wrong or expired. Generate a new one with `repo` scope. |\n| `405 Not mergeable` | Enable **Allow auto-merge** in repo Settings → General → Pull Requests. |\n| Hangs at \"Waiting for mergeability\" | PR may have a conflict. Delete the branch manually and retry. |\n| `RateLimitExceededException` | Wait an hour or increase `DELAY_SECONDS`. Use `--check-rate` to check beforehand. |\n| No badge after success | Wait a few minutes and refresh your profile. Achievement updates are not always instant. |\n| Leftover branches | Run `pullshark clean` to delete all auto-created branches. |\n\n---\n\n## 📋 Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md) for a full history of changes.\n\n---\n\n## 📄 License \u0026 Disclaimer\n\nThis project is licensed under the **MIT License** – see the [LICENSE](LICENSE) file for details.\n\n\u003e [!WARNING]\n\u003e **This script is intended for educational purposes and to help users unlock a harmless GitHub achievement**. Please use responsibly and do not abuse automation to spam repositories. The author is not responsible for any consequences arising from misuse of this tool.\n\n---\n\n### 🔗 Quick Links\n\n- [PyPI Package](https://pypi.org/project/pullshark/)\n- [Google Colab](https://colab.research.google.com/)\n- [GitHub Personal Access Tokens](https://github.com/settings/tokens)\n- [Fine-Grained Tokens](https://github.com/settings/personal-access-tokens/new)\n- [Pull Shark Achievement Details](https://github.com/Schweinepriester/github-profile-achievements#pull-shark-)\n- [Contributing Guide](CONTRIBUTING.md)\n\n---\n\n## 💕 Loved My Work?\n\n🚨 [Follow me on GitHub](https://github.com/Shineii86)\n\n⭐ [Give a star to this project](https://github.com/Shineii86/PullShark)\n\n\u003cdiv align=\"center\"\u003e\n\n\u003ca href=\"https://github.com/Shineii86/PullShark\"\u003e\n\u003cimg src=\"https://github.com/Shineii86/AniPay/blob/main/Source/Banner6.png\" alt=\"Banner\"\u003e\n\u003c/a\u003e\n  \n  *For inquiries or collaborations*\n     \n[![Telegram Badge](https://img.shields.io/badge/-Telegram-2CA5E0?style=flat\u0026logo=Telegram\u0026logoColor=white)](https://telegram.me/Shineii86 \"Contact on Telegram\")\n[![Instagram Badge](https://img.shields.io/badge/-Instagram-C13584?style=flat\u0026logo=Instagram\u0026logoColor=white)](https://instagram.com/ikx7.a \"Follow on Instagram\")\n[![Pinterest Badge](https://img.shields.io/badge/-Pinterest-E60023?style=flat\u0026logo=Pinterest\u0026logoColor=white)](https://pinterest.com/ikx7a \"Follow on Pinterest\")\n[![Gmail Badge](https://img.shields.io/badge/-Gmail-D14836?style=flat\u0026logo=Gmail\u0026logoColor=white)](mailto:ikx7a@hotmail.com \"Send an Email\")\n\n  \u003csup\u003e\u003cb\u003eCopyright © 2026 \u003ca href=\"https://telegram.me/Shineii86\"\u003eShinei Nouzen\u003c/a\u003e All Rights Reserved\u003c/b\u003e\u003c/sup\u003e\n\n![Last Commit](https://img.shields.io/github/last-commit/Shineii86/PullShark?style=for-the-badge)\n\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshineii86%2Fpullshark","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshineii86%2Fpullshark","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshineii86%2Fpullshark/lists"}