An open-source Python toolchain for learning GitHub API integrations. This project demonstrates how to interact with GitHub's REST API v3 and GraphQL API v4 to analyze contribution activity and generate backdated contributions programmatically.
Purpose: Educational tool for understanding GitHub API authentication, GraphQL queries, repository management, and git operations automation.
This tool is intended for demo and educational use only. It demonstrates GitHub API integration patterns and is designed for use on repositories you own. Using this tool to misrepresent your contributions or deceive others violates GitHub's Terms of Service and the spirit of open source collaboration. Use responsibly.
- Python 3.11+
- Git installed locally
- GitHub account with at least one repository
- GitHub Personal Access Token (PAT) with appropriate scopes
git clone <repository-url>
cd gh-contrib-filler
pip install -r requirements.txtCopy .env.example to .env and fill in your credentials:
cp .env.example .envEdit .env:
GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxx
GITHUB_USERNAME=your_username
COMMIT_AUTHOR_NAME=Your Name
COMMIT_AUTHOR_EMAIL=your@email.com
LOCAL_REPOS_BASE_DIR=./repos- Go to GitHub Settings β Developer settings β Personal access tokens β Fine-grained tokens
- Click Generate new token
- Set the token name and expiration
- Select All repositories or specific repositories
- Grant the following permissions:
- Repository permissions:
- Contents: Read and write
- Issues: Read and write
- Pull requests: Read and write
- Metadata: Read (mandatory)
- Account permissions:
- Read user profile data
- Repository permissions:
Copy the generated token to your .env file.
Find all days in the past year with zero contributions:
python main.py analyzeAnalyze a specific year:
python main.py analyze --year 2024Output as JSON:
python main.py analyze --output jsonPreview what activities would be created without making changes:
python main.py fill --year 2024 --dry-runGenerate activities for all blank days in a year:
python main.py fill --year 2024Fill specific dates only:
python main.py fill --dates 2024-03-15,2024-04-02Limit to specific activity types:
python main.py fill --activity commits,issues --max-days 10Verify how many days are still blank:
python main.py statusgh-contrib-filler/
βββ main.py # CLI entrypoint
βββ analyzer.py # GraphQL contribution analyzer
βββ filler.py # Activity orchestrator
βββ repo_manager.py # Auto repo discovery and cloning
βββ config.py # Configuration management
βββ activities/
β βββ commits.py # Backdated commit generator
β βββ issues.py # Issue creator
β βββ pull_requests.py # PR creator
β βββ reviews.py # PR review submitter
βββ utils/
β βββ date_utils.py # Date/time helpers
β βββ git_utils.py # GitPython wrappers
βββ logs/ # Operation logs
βββ requirements.txt
βββ .env.example
βββ README.md
All configuration is managed via environment variables in .env:
| Variable | Description | Default |
|---|---|---|
GITHUB_TOKEN |
Fine-grained PAT | Required |
GITHUB_USERNAME |
Your GitHub username | Required |
COMMIT_AUTHOR_NAME |
Git author name | Required |
COMMIT_AUTHOR_EMAIL |
Git author email | Required |
LOCAL_REPOS_BASE_DIR |
Local repo storage | ./repos |
MIN_COMMITS_PER_DAY |
Min commits per day | 3 |
MAX_COMMITS_PER_DAY |
Max commits per day | 6 |
ACTIVITY_WEIGHTS |
Activity distribution | commits:50,issues:20,pull_requests:20,reviews:10 |
INCLUDE_FORKS |
Include forked repos | false |
GitHub's contribution graph counts various activities:
| Activity | Counts as Contribution | Notes |
|---|---|---|
| Commits | β Yes | On default branch or gh-pages |
| Issues | β Yes | Created or assigned |
| Pull Requests | β Yes | Opened, merged, or reviewed |
| PR Reviews | β Yes | Comments, approvals |
The tool implements several safety measures:
- Rate limit checking: Monitors
X-RateLimit-Remainingand sleeps when low - Graceful failures: API errors are logged but don't crash the tool
- Configurable delays: Random sleeps between operations (0.5-2s)
- Dry-run mode: Preview all actions without making changes
- Future date protection: Automatically skips dates in the future
- Repository limits: Max 2 commits per repo per day to avoid spam patterns
The analyzer uses this GraphQL query to fetch contribution data:
query($username: String!, $from: DateTime!, $to: DateTime!) {
user(login: $username) {
contributionsCollection(from: $from, to: $to) {
contributionCalendar {
weeks {
contributionDays {
date
contributionCount
}
}
}
}
}
}GET /user/repos- List all repositoriesPOST /repos/{owner}/{repo}/issues- Create issuesPOST /repos/{owner}/{repo}/pulls- Create PRsPUT /repos/{owner}/{repo}/pulls/{number}/merge- Merge PRsPOST /repos/{owner}/{repo}/pulls/{number}/reviews- Submit reviews
Fetching contributions for username from 2023-03-22 to 2024-03-22...
==================================================
CONTRIBUTION ANALYSIS SUMMARY
==================================================
+----------------------+------------------------+
| Metric | Value |
+----------------------+------------------------+
| Date Range | 2023-03-22 to 2024-03-22
| Total Days Scanned | 366 |
| Active Days | 298 |
| Blank Days Found | 68 |
| Total Contributions | 1247 |
| Contribution Rate | 81.4% |
+----------------------+------------------------+
Filling 68 blank contribution days...
*** DRY RUN MODE - No actual changes will be made ***
[1/68] Processing 2024-01-15 (Monday)
Creating 3 commits...
[DRY RUN] Would commit to owner/repo1 at 2024-01-15 14:32:00+00:00
...
- Ensure your token has access to the repository
- Check if the repository is private (needs
reposcope)
- Some repositories may have issues disabled
- The tool will skip these automatically
- Some repos may have protected default branches
- PR creation will fail gracefully, commits may still work
- The tool will automatically sleep when rate limits are approached
- For large operations, consider running over multiple sessions
This project demonstrates:
- GitHub GraphQL API - Querying user contribution data
- GitHub REST API - Creating issues, PRs, and reviews
- GitPython - Programmatic git operations
- Backdated commits - Using
GIT_AUTHOR_DATEandGIT_COMMITTER_DATE - API rate limiting - Handling HTTP 429 responses
- Configuration management - Environment-based config
- CLI design - argparse with subcommands
This is an educational project. Feel free to fork and experiment with the code to learn more about GitHub APIs and git automation.
MIT License - See LICENSE file for details.
- Token Security: Never commit your
.envfile or expose your PAT - Repository Ownership: Only use on repositories you own
- Rate Limits: GitHub API has hourly rate limits - the tool respects these
- Contribution Graph Updates: Changes may take a few minutes to appear on your profile
- Git History: Backdated commits will appear in git history with the specified dates