Skip to content

Conversation

@gmondello
Copy link
Collaborator

Repository-Based Cost Center Assignment:

  • Added a new repository-based mode for assigning repositories to cost centers using custom properties, with explicit mapping, auto-discovery, and query-based sub-modes. This includes a new repository_cost_center_manager.py module, new GitHub API methods for custom property access, and full pagination and logging support. [1] [2] [3] [4]
  • Updated documentation and configuration examples to describe repository mode setup, usage, and migration, including a detailed design document (REPOSITORY_COST_CENTER_DESIGN.md). [1] [2]

Budget System Improvements:

  • Enhanced the budget system to support multiple products (Copilot, Actions, Packages, Codespaces), with product-agnostic budget creation (create_product_budget()), configurable amounts, and budget existence checking. Added a product registry for easy extension. [1] [2]
  • Introduced YAML-based budget configuration, allowing per-product enable/disable and amount settings, and integrated budget creation into repository and teams modes via the --create-budgets flag. [1] [2]

Configuration and Operational Modes:

  • Updated main.py and configuration files to support three operational modes: PRU-based, Teams-based, and Repository-based, with validation and documentation updates. [1] [2]
  • Added new configuration options for GitHub API endpoints and improved environment variable support.

Documentation:

  • Expanded the README and changelog to cover new features, usage patterns, configuration examples, and migration guidance for repository-based assignment and budget management. [1] [2] [3] [4] [5] [6]

Design and Implementation Guidance:

  • Added detailed design and implementation documents for repository-based assignment and budget improvements, including API requirements, error handling, logging, testing, and phased implementation priorities. [1] [2]

These changes collectively make the system more flexible, easier to configure and extend, and ready to support a wider range of cost tracking and budgeting use cases.

- Implement explicit mapping mode for assigning repositories to cost centers based on custom properties
- Add new RepositoryCostCenterManager class with comprehensive logging
- Extend GitHub API with custom properties endpoints (get_org_custom_properties, get_org_repositories_with_properties, etc.)
- Add repository mode configuration support in ConfigManager with validation
- Update main.py to support three operational modes (users, teams, repository)
- Add comprehensive documentation and examples in README.md and config.example.yaml
- Include detailed design document for future enhancements

Enables customers to map repositories to cost centers using existing custom properties like:
- team (platform, frontend, backend, data)
- service (web, mobile, api)
- environment (production, development)

Supports automatic cost center creation and batch repository assignment.
🎯 Budget System Enhancements:
- Add configurable budget amounts (no longer hardcoded to /bin/bash)
- Add create_product_budget() for Actions and future products
- Add check_cost_center_has_product_budget() for duplicate prevention
- Abstract budget type selection (ProductPricing vs SkuPricing)
- Support Actions budgets alongside Copilot PRU budgets
- Add product registry system for future extensibility

🔧 API Format Fixes:
- Fix repository assignment to use repository names (not IDs)
- Ensure proper 'org/repo' format for repository API calls
- Update all repository assignment logic for correct data structures

⚙️ Configuration System:
- Add budgets.enabled and budgets.products YAML configuration
- Support per-product budget amounts and enable/disable flags
- Repository mode now supports --create-budgets flag
- Enhanced config.example.yaml with budget documentation

📚 Documentation Updates:
- Add comprehensive budget configuration guide in README
- Update CHANGELOG with all new features and fixes
- Remove 'coming soon' budget language (now implemented)
- Add usage examples for budget creation across all modes

🚀 Production Ready:
- All demo session improvements now in feature branch
- Tested end-to-end with 105+ repositories
- Support for Copilot PRU (00) and Actions (25) budgets
- Extensible design for future products (Packages, Codespaces)

Resolves repository assignment API format issues and adds comprehensive
budget management system for enterprise cost center automation.
@gmondello gmondello requested a review from a team as a code owner October 28, 2025 03:54
Copilot AI review requested due to automatic review settings October 28, 2025 03:54
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces a repository-based cost center assignment mode alongside comprehensive budget system improvements, enabling organizations to assign repositories to cost centers based on custom properties and create multi-product budgets.

Key Changes:

  • Added repository-based mode for assigning repositories to cost centers using custom property mappings
  • Enhanced budget system with multi-product support (Copilot, Actions, and extensible framework for future products)
  • Introduced YAML-based budget configuration with per-product amounts and enable/disable controls

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/repository_cost_center_manager.py New module implementing explicit mapping mode for repository-to-cost-center assignments
src/github_api.py Added custom properties API methods and enhanced budget creation with product-agnostic support
src/config_manager.py Added repository mode configuration parsing and budget configuration support
main.py Integrated repository mode execution flow with plan/apply modes and budget creation
config/config.example.yaml Added repository mode and budget configuration examples with detailed documentation
REPOSITORY_COST_CENTER_DESIGN.md Comprehensive design document for repository-based assignment feature
README.md Updated documentation to describe three operational modes and budget configuration
CHANGELOG.md Documented all new features and changes
BUDGET_IMPROVEMENTS.md Design document for budget system enhancements

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

self.logger.error(f"Failed to fetch custom properties for repository '{owner}/{repo}': {str(e)}")
return []

def add_repositories_to_cost_center(self, cost_center_id: str, repository_ids: List[int]) -> bool:
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameter name repository_ids in the function signature doesn't match the actual usage in the implementation. Line 1436 shows payload = {\"repositories\": repository_ids}, but based on the calling code in repository_cost_center_manager.py line 302, this receives a list of repository names (strings like 'org/repo'), not integer IDs. The parameter should be renamed to repository_names with type List[str] to match actual usage.

Copilot uses AI. Check for mistakes.
Args:
cost_center_id: Target cost center ID (UUID)
repository_ids: List of repository IDs (integers) to add
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation states 'repository IDs (integers)' but the actual implementation expects repository names in 'org/repo' format (strings), as evidenced by the calling code passing repo_names list. Update documentation to reflect that this parameter expects repository full names as strings.

Suggested change
repository_ids: List of repository IDs (integers) to add
repository_ids: List of repository full names (strings in 'org/repo' format) to add

Copilot uses AI. Check for mistakes.
Comment on lines +497 to +498
# Import and initialize repository manager
from src.repository_cost_center_manager import RepositoryCostCenterManager

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: imports should go at the top of the file except for rare cases

Comment on lines +503 to +505
print("\n===== Repository Mode Configuration =====")
print(f"Organization: {org_name}")
print(f"Explicit Mappings: {len(config.github_cost_centers_repository_config.explicit_mappings)}")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a mix between logs and prints, are the prints on purpose or should these be logs?

Comment on lines +131 to +132
# Convert to simple object for easy access
class RepositoryConfig:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Class definitions should not be inline like this, this makes it impossible to import if ever need and adds complicated nesting to this function. Can we move this to it's own file or out of this load config function?

Comment on lines +1184 to +1186
if (budget.get('budget_scope') == 'cost_center' and
budget.get('budget_entity_name') == cost_center_id and
budget.get('budget_product_sku') == product_sku):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: maybe these checks can be extracted into a function?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants