This document describes the automatic repository collaboration invitation acceptance feature.
The auto-accept invitations feature automatically processes GitHub repository collaboration invitations based on configurable criteria. It uses a cron-based polling approach to check for pending invitations and accept/decline them according to your specified rules.
- Polling: Script runs periodically (via cron) to check for pending invitations
- Evaluation: Each invitation is evaluated against configured criteria
- Action: Invitations are automatically accepted, declined, or skipped
- Post-Acceptance Setup: When accepted, automatically:
- Clones the repository locally
- Updates webhook handler configuration
- Registers webhook in the new repository
- Restarts the webhook service
- Logging: All actions are logged for monitoring and debugging
Add the following to your config/settings.yaml:
auto_accept_invitations:
enabled: true
check_interval_minutes: 10
log_level: "INFO"
criteria:
repository_patterns: ["*"] # Accept all repositories by default
# Post-acceptance actions
post_acceptance:
clone_repository: true
clone_base_dir: "/home/clide"
update_config: true
register_webhook: true
webhook_url: "https://clidecoder.com/hooks/github-webhook"
webhook_events: ["issues", "pull_request", "pull_request_review"]auto_accept_invitations:
enabled: true
check_interval_minutes: 10
log_level: "INFO"
criteria:
# Repository patterns to accept (glob patterns)
repository_patterns:
- "my-org/*" # Accept any repo in my-org
- "*/project-*" # Accept any repo starting with project-
- "specific-repo" # Accept specific repository
# Only accept invitations from these organizations
from_organizations:
- "trusted-company"
- "partner-org"
# Only accept invitations from these specific users
from_users:
- "trusted-user"
- "automation-bot"
# Exclude repositories matching these patterns
exclude_patterns:
- "*/private-*" # Exclude private repositories
- "test-*" # Exclude test repositories
- "experimental/*" # Exclude experimental reposThe feature is included with the standard HLS webhook handler installation:
# If not already done
pip install -r requirements.txtEnsure your GitHub token has the necessary permissions:
# In .env file
GITHUB_TOKEN=your_github_personal_access_tokenRequired token scopes:
repo- To accept repository invitationsuser- To read user invitation data
Add to your crontab to run every 10 minutes:
crontab -e
# Add this line:
*/10 * * * * /home/clide/hls/scripts/cron_auto_accept_invitations.shTest with a dry run first:
cd /home/clide/hls
python scripts/auto_accept_invitations.py --dry-run# Dry run (shows what would happen)
python scripts/auto_accept_invitations.py --dry-run
# Process invitations
python scripts/auto_accept_invitations.py
# Custom configuration file
python scripts/auto_accept_invitations.py --config /path/to/settings.yaml
# Custom log level
python scripts/auto_accept_invitations.py --log-level DEBUGFor manual repository onboarding:
# Set up a specific repository
python scripts/setup_new_repository.py owner/repo-name
# Dry run to see what would happen
python scripts/setup_new_repository.py owner/repo-name --dry-run
# Use custom configuration
python scripts/setup_new_repository.py owner/repo-name --config path/to/settings.yamlThe cron wrapper script handles:
- Environment setup
- Lock file management (prevents concurrent runs)
- Error handling and logging
- Virtual environment activation
For each invitation, the system evaluates:
- Exclude Patterns: If repository matches any exclude pattern → DECLINE
- Repository Patterns: Must match at least one repository pattern
- Organization Filter: If specified, inviter must be from allowed organization
- User Filter: If specified, inviter must be in allowed users list
Final Decision:
- All criteria match → ACCEPT
- Any criteria fails → SKIP (no action)
- Matches exclude pattern → DECLINE
- Main Log:
logs/auto_accept_invitations.log - Cron Log:
logs/cron_auto_accept_invitations.log - Results:
logs/invitation_results_<timestamp>.json
- ERROR: Critical failures, API errors
- WARNING: Non-critical issues, missing configurations
- INFO: Normal operations, decisions made
- DEBUG: Detailed processing information
# View recent activity
tail -f logs/auto_accept_invitations.log
# Check cron execution
tail -f logs/cron_auto_accept_invitations.log
# View recent results
ls -la logs/invitation_results_*.json | tail -5- Store GitHub token in
.envfile (not in repository) - Use tokens with minimal required permissions
- Rotate tokens regularly
- Review invitation criteria regularly
- Monitor acceptance activity via logs
- Consider setting up organization/user allowlists
- All actions are logged with details
- Results saved to JSON files for analysis
- Failed operations logged with error details
-
No Invitations Processed
- Check if feature is enabled in configuration
- Verify GitHub token has correct permissions
- Check if criteria are too restrictive
-
API Rate Limiting
- GitHub API has rate limits (5000 requests/hour)
- Script respects rate limits and logs warnings
- Consider reducing check frequency if needed
-
Permission Errors
- Ensure GitHub token has
repoanduserscopes - Check if token is valid and not expired
- Verify repository access permissions
- Ensure GitHub token has
Run with debug logging for detailed information:
python scripts/auto_accept_invitations.py --log-level DEBUG --dry-runCheck pending invitations manually:
# Using GitHub CLI (if installed)
gh api user/repository_invitations
# Or check via GitHub web interface
# https://github.com/settings/repositoriesauto_accept_invitations:
enabled: true
check_interval_minutes: 10
criteria:
repository_patterns: ["*"]auto_accept_invitations:
enabled: true
check_interval_minutes: 15
criteria:
repository_patterns: ["*"]
from_organizations: ["my-company", "trusted-partner"]auto_accept_invitations:
enabled: true
check_interval_minutes: 10
criteria:
repository_patterns:
- "company/*"
- "*/public-*"
from_organizations: ["trusted-org"]
exclude_patterns:
- "*/test-*"
- "experimental/*"auto_accept_invitations:
enabled: true
check_interval_minutes: 5
criteria:
repository_patterns: ["*"]
from_users: ["github-actions[bot]", "dependabot[bot]"]You can extend the InvitationHandler class to implement custom filtering logic:
# In handlers.py
def _evaluate_invitation(self, invitation: Dict[str, Any]) -> str:
# Add custom logic here
repo_name = invitation["repository"]["full_name"]
# Example: Only accept during business hours
import datetime
now = datetime.datetime.now()
if now.hour < 9 or now.hour > 17:
return "outside business hours"
# Call parent method for standard criteria
return super()._evaluate_invitation(invitation)The invitation processor can be integrated with:
- Slack notifications for accepted invitations
- Database logging for audit purposes
- Custom approval workflows
- Each run makes ~2-3 GitHub API calls
- Rate limit: 5000 requests/hour per token
- Running every 10 minutes ≈ 144 calls/day (well within limits)
- Script runs for <10 seconds typically
- Minimal memory usage (~50MB)
- Log files grow slowly (rotate if needed)
- Adjust check interval based on invitation frequency
- Use exclude patterns to reduce processing
- Monitor logs for performance issues
When an invitation is accepted, the following automated sequence occurs:
- Invitation Acceptance - Repository invitation is accepted via GitHub API
- Repository Cloning - Repository is cloned to
{clone_base_dir}/{repo_name} - Configuration Update -
config/settings.yamlis automatically updated with:- name: "owner/repo-name" enabled: true local_path: "/home/clide/repo-name" events: ["issues", "pull_request", "pull_request_review"] labels: auto_apply: true comments: auto_post: true
- Webhook Registration - Webhook is registered in the new repository with:
- URL:
https://clidecoder.com/hooks/github-webhook - Events: Issues, Pull Requests, Reviews
- Secret: From
GITHUB_WEBHOOK_SECRET
- URL:
- Service Restart -
github-webhooksystemd service is restarted to load new configuration - Immediate Availability - Repository is immediately ready to receive webhooks and be processed
You can also manually set up repositories without going through the invitation process:
# Set up any repository you have access to
python scripts/setup_new_repository.py owner/repo-name
# This performs the same steps 2-6 from the automation workflowAfter accepting an invitation for owner/repo-name, the following structure is created:
/home/clide/
├── hls/ # Main webhook handler
│ ├── config/settings.yaml # Updated with new repo config
│ └── logs/
│ ├── auto_accept_invitations.log # Invitation processing logs
│ ├── repository_setup_*.json # Setup results
│ └── invitation_results_*.json # Invitation results
└── repo-name/ # Cloned repository
├── .git/
├── CLAUDE.md # Project-specific instructions (if exists)
└── ... # Repository contents
This feature provides automated, configurable, and secure handling of repository collaboration invitations while maintaining full audit trails and monitoring capabilities.