Automate GitHub Copilot license cost center assignments for your enterprise with two powerful modes:
- PRU-Based Mode: Simple two-tier model (PRU overages allowed/not allowed)
- Teams-Based Mode: Automatic assignment based on GitHub team membership
Create a GitHub Personal Access Token with these scopes:
manage_billing:enterprise
(required)read:org
(required for Teams Mode)
PRU-Based Mode (Simple two-tier model)
# Clone and setup
git clone <your-repo-url>
cd cost-center-automation
pip install -r requirements.txt
# Configure
export GITHUB_TOKEN="your_token_here"
export GITHUB_ENTERPRISE="your-enterprise"
# Run (creates cost centers automatically)
python main.py --create-cost-centers --assign-cost-centers --mode apply --yes
Done! All users are now in "00 - No PRU overages" cost center.
To allow specific users PRU overages, edit config/config.yaml
:
cost_centers:
prus_exception_users:
- "alice"
- "bob"
Teams-Based Mode (Sync with GitHub teams)
# Clone and setup
git clone <your-repo-url>
cd cost-center-automation
pip install -r requirements.txt
# Configure
cp config/config.example.yaml config/config.yaml
export GITHUB_TOKEN="your_token_here"
export GITHUB_ENTERPRISE="your-enterprise"
# Edit config/config.yaml
teams:
enabled: true
scope: "organization" # or "enterprise"
organizations:
- "your-org-name"
# Run
python main.py --teams-mode --assign-cost-centers --mode apply --yes
Done! Cost centers created for each team, users automatically assigned.
See TEAMS_QUICKSTART.md for more details.
Set up GitHub Actions for automatic syncing every 6 hours - see Automation below.
PRU-Based Mode (Default)
- Simple two-tier model: PRU overages allowed/not allowed
- Automatic cost center creation with default names
- Exception list for users who need PRU access
- Incremental processing support (only new users)
Teams-Based Mode
- Organization scope: Sync teams from specific GitHub orgs
- Enterprise scope: Sync all teams across the enterprise
- Automatic cost center creation with bracket notation naming
- Orphaned user detection and removal
- Single assignment (multi-team users get last team's assignment)
- 🔄 Plan/Apply execution: Preview changes before applying
- 📊 Enhanced logging: Real-time success/failure tracking
- 🐳 Container ready: Dockerfile and docker-compose included
- ⚙️ Automation examples: GitHub Actions, cron, and shell scripts
- 🔧 Auto-creation: Automatic cost center creation (no manual UI setup)
- GitHub Enterprise Cloud with admin access
- GitHub Personal Access Token with scopes:
manage_billing:enterprise
(required for all modes)read:org
(required for Teams Mode)
- Python 3.8+ (for local execution)
Configuration lives in config/config.yaml
(copy from config/config.example.yaml
).
github:
enterprise: "" # Or set via GITHUB_ENTERPRISE env var
cost_centers:
auto_create: true # Automatically create cost centers
no_prus_cost_center_name: "00 - No PRU overages"
prus_allowed_cost_center_name: "01 - PRU overages allowed"
# Users who need PRU access
prus_exception_users:
- "alice"
- "bob"
teams:
enabled: true
scope: "organization" # or "enterprise"
mode: "auto" # One cost center per team
organizations: # Only for organization scope
- "your-org"
auto_create_cost_centers: true
remove_orphaned_users: true
Cost Center Naming:
- Organization scope:
[org team] {org-name}/{team-name}
- Enterprise scope:
[enterprise team] {team-name}
Set these instead of config file values:
GITHUB_TOKEN
(required)GITHUB_ENTERPRISE
(required)
For complete Teams Mode documentation, see:
- TEAMS_QUICKSTART.md - Step-by-step setup guide
- TEAMS_INTEGRATION.md - Full reference documentation
Organization vs Enterprise Scope
- Organization: Syncs teams from specific GitHub organizations you specify
- Enterprise: Syncs all teams across your entire GitHub Enterprise
Cost Center Naming
- Organization scope:
[org team] {org-name}/{team-name}
- Enterprise scope:
[enterprise team] {team-name}
Multi-Team Users
- Each user can only belong to ONE cost center
- Multi-team users are assigned to their last team's cost center
- Warnings logged for review before applying
For advanced use cases, map specific teams to specific cost centers:
teams:
mode: "manual"
team_mappings:
"my-org/frontend": "Engineering: Frontend"
"my-org/backend": "Engineering: Backend"
# View configuration
python main.py --show-config
python main.py --teams-mode --show-config
# List all Copilot users
python main.py --list-users
# Plan assignments (preview, no changes)
python main.py --assign-cost-centers --mode plan
# Apply assignments (with confirmation)
python main.py --assign-cost-centers --mode apply
# Apply without confirmation (automation)
python main.py --create-cost-centers --assign-cost-centers --mode apply --yes
# Incremental mode (only new users, for cron jobs)
python main.py --assign-cost-centers --incremental --mode apply --yes
# Plan assignments (preview, no changes)
python main.py --teams-mode --assign-cost-centers --mode plan
# Apply assignments (with confirmation)
python main.py --teams-mode --assign-cost-centers --mode apply
# Apply without confirmation (automation)
python main.py --teams-mode --assign-cost-centers --mode apply --yes
# Generate summary report
python main.py --teams-mode --summary-report
Note: Incremental mode is NOT supported in Teams Mode. All team members are processed every run.
Process only users added since the last run - perfect for cron jobs:
# First run: processes all users, saves timestamp
python main.py --assign-cost-centers --incremental --mode apply --yes
# Subsequent runs: only new users
python main.py --assign-cost-centers --incremental --mode apply --yes
Note: Teams Mode does not support incremental processing.
Logs are written to logs/populate_cost_centers.log
with detailed tracking:
2025-10-08 10:39:06 [INFO] ✅ Successfully added 3 users to cost center abc123
2025-10-08 10:39:06 [INFO] ✅ user1 → abc123
2025-10-08 10:39:06 [INFO] ✅ user2 → abc123
2025-10-08 10:39:06 [INFO] 📊 ASSIGNMENT RESULTS: 3/3 users successfully assigned
The included workflow automatically syncs cost centers every 6 hours:
- Add token as secret:
COST_CENTER_AUTOMATION_TOKEN
- Go to Actions tab → "Cost center automation"
- Click "Run workflow" → Select mode → Run
See .github/workflows/
for configuration.
# Build and run
docker build -t copilot-cc .
docker run --rm -e GITHUB_TOKEN=$GITHUB_TOKEN copilot-cc \
python main.py --assign-cost-centers --mode apply --yes
# Background service
docker compose up -d --build
# PRU mode with incremental processing (hourly)
0 * * * * cd /path/to/repo && ./automation/update_cost_centers.sh
# Teams mode (weekly)
0 2 * * 1 cd /path/to/repo && python main.py --teams-mode --assign-cost-centers --mode apply --yes
See automation/update_cost_centers.sh
for the included automation script.
This repository includes automatic template sync from github/cost-center-automation
.
Setup:
- Create a PAT with
Contents: Write
andPull requests: Write
- Add as secret:
TEMPLATE_SYNC_TOKEN
- Automatic sync runs every Monday, creating PRs with updates
What's synced: Code, workflows, docs, dependencies
What's protected: config/config.yaml
, .syncignore
files
Manual trigger: Actions → "Sync from template" → "Run workflow"
Issue | Solution |
---|---|
401/403 errors | Regenerate token with correct scopes |
No teams found | Verify read:org scope for Teams Mode |
Cost center creation fails | Ensure manage_billing:enterprise scope |
Multi-team user warnings | Review plan output, adjust team structure if needed |
Check logs/populate_cost_centers.log
for detailed traces. Use --verbose
for DEBUG logging.
- Fork this repository and create a branch (
feat/<name>
) - Make focused changes with clear commit messages
- Submit PR with description and link related issues
- TEAMS_QUICKSTART.md - Teams Mode setup guide
- TEAMS_INTEGRATION.md - Teams Mode reference
- ORPHANED_USERS_FEATURE.md - Orphaned users documentation
This project is licensed under the MIT License. See LICENSE file for details.
Latest Features: Teams-based assignment (organization & enterprise scope), orphaned user detection, bracket notation naming, enhanced logging, incremental processing