Skip to content

Instantly share code, notes, and snippets.

@monperrus
Last active March 21, 2026 06:45
Show Gist options
  • Select an option

  • Save monperrus/e2fd9910348b8ccbe23dc85a41c565c7 to your computer and use it in GitHub Desktop.

Select an option

Save monperrus/e2fd9910348b8ccbe23dc85a41c565c7 to your computer and use it in GitHub Desktop.
Python script to enable GitHub sponsorships for all repositories in an organization using the GraphQL mutation API.
#! /usr/bin/env python3
"""Enable GitHub sponsorships for all repositories in an organization.
This script:
- Reads a GitHub personal access token from the local keyring
- Lists all repositories in the configured organization
- Skips archived repositories
- Enables the sponsorship button on each remaining repository via the GitHub API
Requirements:
- A valid GitHub token stored in keyring under service "login2" and key "github_token"
- Permissions to read organization repositories and update repository settings
url: https://gist.github.com/monperrus/e2fd9910348b8ccbe23dc85a41c565c7
License: public domain
"""
import requests
import json
import keyring
# --- CONFIGURATION ---
GITHUB_TOKEN = keyring.get_password("login2", "github_token")
ORG_NAME = "SpoonLabs"
# ---------------------
BASE_URL = "https://api.github.com"
HEADERS = {
"Authorization": f"Bearer {GITHUB_TOKEN}",
"Accept": "application/vnd.github+json",
}
def get_all_repos(org):
"""Fetches all repositories for the organization using the REST API."""
repos = []
page = 1
while True:
url = f"{BASE_URL}/orgs/{org}/repos?per_page=100&page={page}"
response = requests.get(url, headers=HEADERS)
if response.status_code != 200:
print(f"Error fetching repos: {response.text}")
break
data = response.json()
if not data:
break
repos.extend(data)
page += 1
return repos
def enable_sponsorship(node_id, repo_name):
"""Enables the sponsorship button via GraphQL mutation."""
query = """
mutation($input: UpdateRepositoryInput!) {
updateRepository(input: $input) {
repository {
name
hasSponsorshipsEnabled
}
}
}
"""
variables = {
"input": {
"repositoryId": node_id,
"hasSponsorshipsEnabled": True
}
}
response = requests.post(
f"{BASE_URL}/graphql",
headers=HEADERS,
json={"query": query, "variables": variables}
)
if response.status_code == 200:
res_data = response.json()
if "errors" in res_data:
print(f"❌ Failed to update {repo_name}: {res_data['errors'][0]['message']}")
else:
print(f"✅ Enabled sponsorship for: {repo_name}")
else:
print(f"❌ HTTP Error for {repo_name}: {response.status_code}")
def main():
print(f"Fetching repositories for organization: {ORG_NAME}...")
repos = get_all_repos(ORG_NAME)
print(f"Found {len(repos)} repositories.\n")
for repo in repos:
# Skip archived repositories as they cannot be edited
if repo.get('archived'):
print(f"⏭️ Skipping archived repo: {repo['name']}")
continue
node_id = repo['node_id']
enable_sponsorship(node_id, repo['name'])
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment