-
Notifications
You must be signed in to change notification settings - Fork 2.2k
feat: Add support for GitHub Budgets API #3931
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3931 +/- ##
==========================================
+ Coverage 92.44% 92.48% +0.04%
==========================================
Files 203 205 +2
Lines 14960 15042 +82
==========================================
+ Hits 13830 13912 +82
Misses 927 927
Partials 203 203 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
gmlewis
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, @youneedgreg!
Just a few tweaks, please, then we should be ready for a second LGTM+Approval from any other contributor to this repo before merging.
cc: @stevehipwell - @alexandear - @zyfy29 - @Not-Dhananjay-Mishra
|
Also, please fix the linter failures and check the code coverage. Step 4 in CONTRIBUTING.md discusses these things. |
github/billing_budgets.go
Outdated
| // | ||
| // GitHub API docs: https://docs.github.com/rest/billing/budgets#get-all-budgets-for-an-organization | ||
| // | ||
| // meta:operation GET /organizations/{org}/settings/billing/budgets |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency use //meta: (no space).
| // meta:operation GET /organizations/{org}/settings/billing/budgets | |
| //meta:operation GET /organizations/{org}/settings/billing/budgets |
Same applies to other occurrences in this PR.
github/billing_budgets.go
Outdated
| // GitHub API docs: https://docs.github.com/rest/billing/budgets#delete-a-budget-for-an-organization | ||
| // | ||
| // meta:operation DELETE /organizations/{org}/settings/billing/budgets/{budget_id} | ||
| func (s *BillingService) DeleteOrganizationBudget(ctx context.Context, org string, budgetID string) (*Response, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to Docs this endpoint also returns an object.

github/enterprise_billing_budgets.go
Outdated
|
|
||
| // GetEnterpriseBudget gets a specific budget for an enterprise. | ||
| // | ||
| // GitHub API docs: https://docs.github.com/rest/billing/budgets#get-a-budget-for-an-enterprise |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // GitHub API docs: https://docs.github.com/rest/billing/budgets#get-a-budget-for-an-enterprise | |
| // GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/billing/budgets#get-a-budget-by-id |
https://docs.github.com/en/enterprise-cloud@latest/rest/billing/budgets#get-a-budget-by-id
github/enterprise_billing_budgets.go
Outdated
|
|
||
| // CreateEnterpriseBudget creates a specific budget for an enterprise. | ||
| // | ||
| // GitHub API docs: https://docs.github.com/rest/billing/budgets#create-a-budget |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // GitHub API docs: https://docs.github.com/rest/billing/budgets#create-a-budget | |
| // GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/billing/budgets#create-a-budget |
https://docs.github.com/en/enterprise-cloud@latest/rest/billing/budgets#create-a-budget
github/enterprise_billing_budgets.go
Outdated
|
|
||
| // UpdateEnterpriseBudget updates a specific budget for an enterprise. | ||
| // | ||
| // GitHub API docs: https://docs.github.com/rest/billing/budgets#update-a-budget-for-an-enterprise |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // GitHub API docs: https://docs.github.com/rest/billing/budgets#update-a-budget-for-an-enterprise | |
| // GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/billing/budgets#update-a-budget |
https://docs.github.com/en/enterprise-cloud@latest/rest/billing/budgets#update-a-budget
github/enterprise_billing_budgets.go
Outdated
|
|
||
| // DeleteEnterpriseBudget deletes a specific budget for an enterprise. | ||
| // | ||
| // GitHub API docs: https://docs.github.com/rest/billing/budgets#delete-a-budget-for-an-enterprise |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // GitHub API docs: https://docs.github.com/rest/billing/budgets#delete-a-budget-for-an-enterprise | |
| // GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/billing/budgets#delete-a-budget |
https://docs.github.com/en/enterprise-cloud@latest/rest/billing/budgets#delete-a-budget
github/enterprise_billing_budgets.go
Outdated
|
|
||
| // ListEnterpriseBudgets lists all budgets for an enterprise. | ||
| // | ||
| // GitHub API docs: https://docs.github.com/rest/billing/budgets#get-all-budgets-for-an-enterprise |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // GitHub API docs: https://docs.github.com/rest/billing/budgets#get-all-budgets-for-an-enterprise | |
| // GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/billing/budgets#get-all-budgets |
https://docs.github.com/en/enterprise-cloud@latest/rest/billing/budgets#get-all-budgets
| ) | ||
|
|
||
| // Budget represents a GitHub budget. | ||
| type Budget struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Response schema of Budget
{
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "ID of the budget."
},
"budget_scope": {
"type": "string",
"description": "The type of scope for the budget",
"enum": [
"enterprise",
"organization",
"repository",
"cost_center"
],
"examples": [
"enterprise"
]
},
"budget_entity_name": {
"type": "string",
"description": "The name of the entity to apply the budget to",
"examples": [
"octocat/hello-world"
]
},
"budget_amount": {
"type": "integer",
"description": "The budget amount in whole dollars. For license-based products, this represents the number of licenses."
},
"prevent_further_usage": {
"type": "boolean",
"description": "Whether to prevent additional spending once the budget is exceeded",
"examples": [
true
]
},
"budget_product_sku": {
"type": "string",
"description": "A single product or sku to apply the budget to.",
"examples": [
"actions_linux"
]
},
"budget_type": {
"type": "string",
"description": "The type of pricing for the budget",
"enum": [
"ProductPricing",
"SkuPricing"
],
"examples": [
"ProductPricing"
]
},
"budget_alerting": {
"type": "object",
"properties": {
"will_alert": {
"type": "boolean",
"description": "Whether alerts are enabled for this budget",
"examples": [
true
]
},
"alert_recipients": {
"type": "array",
"items": {
"type": "string"
},
"description": "Array of user login names who will receive alerts",
"examples": [
"mona",
"lisa"
]
}
}
}
},
"required": [
"id",
"budget_amount",
"prevent_further_usage",
"budget_product_sku",
"budget_type",
"budget_alerting",
"budget_scope",
"budget_entity_name"
]
}it has few missing items -
budget_scope, budget_entity_name, budget_amount, prevent_further_usage, budget_product_sku.
github/enterprise_billing_budgets.go
Outdated
| // GitHub API docs: https://docs.github.com/rest/billing/budgets#delete-a-budget-for-an-enterprise | ||
| // | ||
| // meta:operation DELETE /enterprises/{enterprise}/settings/billing/budgets/{budget_id} | ||
| func (s *EnterpriseService) DeleteEnterpriseBudget(ctx context.Context, enterprise string, budgetID string) (*Response, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
Hi @gmlewis , finished and made sure all checks passed, Thank you. |
github/enterprise_billing_budgets.go
Outdated
| // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/billing/budgets#get-all-budgets | ||
| // | ||
| //meta:operation GET /enterprises/{enterprise}/settings/billing/budgets | ||
| func (s *EnterpriseService) ListEnterpriseBudgets(ctx context.Context, enterprise string) ([]*Budget, *Response, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we call this in Enterprise service we can simplify naming:
| func (s *EnterpriseService) ListEnterpriseBudgets(ctx context.Context, enterprise string) ([]*Budget, *Response, error) { | |
| func (s *EnterpriseService) ListBudgets(ctx context.Context, enterprise string) ([]*Budget, *Response, error) { |
Am I missing something?
| // GitHub API docs: https://docs.github.com/rest/billing/budgets#get-all-budgets-for-an-organization | ||
| // | ||
| //meta:operation GET /organizations/{org}/settings/billing/budgets | ||
| func (s *BillingService) ListOrganizationBudgets(ctx context.Context, org string) ([]*Budget, *Response, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This endpoint returns a response with the following shape:
{
"budgets": [
{
"id": "2066deda-923f-43f9-88d2-62395a28c0cdd",
"budget_type": "ProductPricing",
"budget_product_skus": [
"actions"
],
"budget_scope": "enterprise",
"budget_amount": 1000,
"prevent_further_usage": true,
"budget_alerting": {
"will_alert": true,
"alert_recipients": [
"enterprise-admin",
"billing-manager"
]
}
},
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"budget_type": "SkuPricing",
"budget_product_skus": [
"actions_linux"
],
"budget_scope": "organization",
"budget_amount": 500,
"prevent_further_usage": false,
"budget_alerting": {
"will_alert": true,
"alert_recipients": [
"org-owner"
]
}
}
],
"has_next_page": false
}
I believe it should return a struct like
{
Budgets []Budget `json:"budgets"`
HasNextPage bool `json:"has_next_page,omitempty"`
}| // GitHub API docs: https://docs.github.com/rest/billing/budgets#update-a-budget-for-an-organization | ||
| // | ||
| //meta:operation PATCH /organizations/{org}/settings/billing/budgets/{budget_id} | ||
| func (s *BillingService) UpdateOrganizationBudget(ctx context.Context, org, budgetID string, budget *Budget) (*Budget, *Response, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This endpoint returns a response with the following shape:
{
"message": "Budget successfully updated.",
"budget": {
"id": "2066deda-923f-43f9-88d2-62395a28c0cdd",
"budget_type": "SkuPricing",
"budget_product_sku": "actions",
"budget_scope": "enterprise",
"budget_amount": 500,
"prevent_further_usage": true,
"budget_alerting": {
"will_alert": true,
"alert_recipients": ["mona"]
}
}
}
I believe it should return a struct like
{
Budget Budget `json:"budget"`
Message string `json:"message"`
}| // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/billing/budgets#get-all-budgets | ||
| // | ||
| //meta:operation GET /enterprises/{enterprise}/settings/billing/budgets | ||
| func (s *EnterpriseService) ListBudgets(ctx context.Context, enterprise string) ([]*Budget, *Response, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as comment
| // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/billing/budgets#create-a-budget | ||
| // | ||
| //meta:operation POST /enterprises/{enterprise}/settings/billing/budgets | ||
| func (s *EnterpriseService) CreateBudget(ctx context.Context, enterprise string, budget *Budget) (*Budget, *Response, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as comment
| // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/billing/budgets#update-a-budget | ||
| // | ||
| //meta:operation PATCH /enterprises/{enterprise}/settings/billing/budgets/{budget_id} | ||
| func (s *EnterpriseService) UpdateBudget(ctx context.Context, enterprise, budgetID string, budget *Budget) (*Budget, *Response, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as comment

Pull Request Description: Add Support for GitHub Budgets API
Closes #3930
Summary
This PR adds support for the GitHub Budgets REST API, allowing users to programmatically manage budgets for both Organizations and Enterprises. This includes listing, retrieving, creating (Enterprise only), updating, and deleting budgets.
Changes
Data Structures
limit_amount,current_amount, and alerting configurations.Organization Budgets ([BillingService])
Added the following methods to [BillingService]:
GET /organizations/{org}/settings/billing/budgetsGET /organizations/{org}/settings/billing/budgets/{budget_id}PATCH /organizations/{org}/settings/billing/budgets/{budget_id}DELETE /organizations/{org}/settings/billing/budgets/{budget_id}Enterprise Budgets ([EnterpriseService])
Added the following methods to [EnterpriseService]:
GET /enterprises/{enterprise}/settings/billing/budgetsGET /enterprises/{enterprise}/settings/billing/budgets/{budget_id}POST /enterprises/{enterprise}/settings/billing/budgetsPATCH /enterprises/{enterprise}/settings/billing/budgets/{budget_id}DELETE /enterprises/{enterprise}/settings/billing/budgets/{budget_id}Verification Plan
Automated Tests
Budgetstruct.All tests passed: