#!/usr/bin/env python3 """Add GitHub users to their appropriate teams in the cohort GitHub organisation. Uses the GitHub CLI to add each member to their corresponding team and, for leaders, to the team's leaders sub-team. Data files (place in data/): - team_assignments.json Team rosters with leaders and participants per team - discord_to_github.json Mapping of Discord IDs to GitHub usernames Env vars: - None (uses `gh` CLI for authentication) """ import json import subprocess import time from pathlib import Path DATA_DIR = Path(__file__).parent.parent.parent / "data" # Load team assignments and Discord to GitHub mappings with open(DATA_DIR / "team_assignments.json") as f: teams = json.load(f) with open(DATA_DIR / "discord_to_github.json") as f: discord_to_github = json.load(f) # Map team names to GitHub team slugs team_name_to_slug = { "Jade Jasmine": "jade-jasmine", "Crimson Dahlia": "crimson-dahlia", "Rose Camellia": "rose-camellia", "Amber Wisteria": "amber-wisteria", "Ivory Orchid": "ivory-orchid", "Teal Iris": "teal-iris", "Peach Gardenia": "peach-gardenia", "Violet Carnation": "violet-carnation", "Azure Lotus": "azure-lotus", "Coral Sunflower": "coral-sunflower", "Indigo Tulip": "indigo-tulip", "Scarlet Hydrangea": "scarlet-hydrangea", "Mint Narcissus": "mint-narcissus", "Sage Marigold": "sage-marigold", } org = "nhcarrigan-spring-2026-cohort" total_added = 0 total_skipped = 0 total_errors = 0 def add_user_to_team(username, team_slug, role="member"): """Add a user to a GitHub team""" try: # Check if user is already a member check_cmd = ( f"gh api orgs/{org}/teams/{team_slug}/memberships/{username} 2>/dev/null" ) result = subprocess.run( check_cmd, shell=True, capture_output=True, text=True, check=False ) if result.returncode == 0: print(f" ✓ {username} is already in {team_slug}") return "already_member" # Add user to team add_cmd = ( f"gh api -X PUT orgs/{org}/teams/{team_slug}/memberships/{username} " f"-f role={role}" ) result = subprocess.run( add_cmd, shell=True, capture_output=True, text=True, check=False ) if result.returncode == 0: print(f" ✓ Added {username} to {team_slug} as {role}") return "added" else: print(f" ✗ Failed to add {username} to {team_slug}: {result.stderr}") return "error" except Exception as e: print(f" ✗ Error adding {username} to {team_slug}: {str(e)}") return "error" # Process each team for team_data in teams: team_name = team_data["name"] team_slug = team_name_to_slug[team_name] print(f"\n{'=' * 60}") print(f"Processing Team {team_data['team_id']}: {team_name}") print(f"{'=' * 60}") # Add leaders to leaders team leaders_team_slug = f"{team_slug}-leaders" print(f"\nAdding leaders to {leaders_team_slug}:") for discord_id in team_data["leaders"]: github_username = discord_to_github.get(discord_id) if not github_username or github_username == "nhcarrigan-2025-hackathon": print( f" ⚠ Skipping Discord ID {discord_id} - " "Missing/invalid GitHub username" ) total_skipped += 1 continue result = add_user_to_team(github_username, leaders_team_slug, "member") if result == "added": total_added += 1 elif result == "error": total_errors += 1 # Rate limiting time.sleep(0.5) # Add participants to main team print(f"\nAdding participants to {team_slug}:") for discord_id in team_data["participants"]: github_username = discord_to_github.get(discord_id) if not github_username or github_username == "nhcarrigan-2025-hackathon": print( f" ⚠ Skipping Discord ID {discord_id} - " "Missing/invalid GitHub username" ) total_skipped += 1 continue result = add_user_to_team(github_username, team_slug, "member") if result == "added": total_added += 1 elif result == "error": total_errors += 1 # Rate limiting time.sleep(0.5) print(f"\n{'=' * 60}") print("Summary:") print(f"- Total users added: {total_added}") print(f"- Total users skipped (missing GitHub): {total_skipped}") print(f"- Total errors: {total_errors}") print(f"{'=' * 60}")