Skip to content
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

feat: Support Copilot metrics endpoints #3350

Merged
merged 11 commits into from
Nov 20, 2024
214 changes: 214 additions & 0 deletions github/copilot.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,116 @@ type CopilotUsageSummary struct {
Breakdown []*CopilotUsageBreakdown `json:"breakdown"`
}

// CopilotMetricsListOptions represents the optional parameters to the CopilotService get metrics methods.
type CopilotMetricsListOptions struct {
Since *time.Time `url:"since,omitempty"`
Until *time.Time `url:"until,omitempty"`

ListOptions
}

type CopilotIdeCodeCompletionsLanguage struct {
henriklundstrom marked this conversation as resolved.
Show resolved Hide resolved
Name string `json:"name"`
TotalEngagedUsers int `json:"total_engaged_users"`
}

type CopilotIdeCodeCompletionsModelLanguage struct {
Name string `json:"name"`
TotalEngagedUsers int `json:"total_engaged_users"`
TotalCodeSuggestions int `json:"total_code_suggestions"`
TotalCodeAcceptances int `json:"total_code_acceptances"`
TotalCodeLinesSuggested int `json:"total_code_lines_suggested"`
TotalCodeLinesAccepted int `json:"total_code_lines_accepted"`
}

type CopilotIdeCodeCompletionsModel struct {
Name string `json:"name"`
IsCustomModel bool `json:"is_custom_model"`
CustomModelTrainingDate *string `json:"custom_model_training_date,omitempty"`
TotalEngagedUsers int `json:"total_engaged_users"`
Languages []*CopilotIdeCodeCompletionsModelLanguage `json:"languages"`
}

type CopilotIdeCodeCompletionsEditor struct {
Name string `json:"name"`
TotalEngagedUsers int `json:"total_engaged_users"`
Models []*CopilotIdeCodeCompletionsModel `json:"models"`
}

// CopilotIdeCodeCompletions represents Copilot usage metrics for Copilot code completions in the IDE, categorized by editor, model and language.
type CopilotIdeCodeCompletions struct {
henriklundstrom marked this conversation as resolved.
Show resolved Hide resolved
TotalEngagedUsers int `json:"total_engaged_users"`
Languages []*CopilotIdeCodeCompletionsLanguage `json:"languages"`
Editors []*CopilotIdeCodeCompletionsEditor `json:"editors"`
}

type CopilotIdeChatModel struct {
Name string `json:"name"`
IsCustomModel bool `json:"is_custom_model"`
CustomModelTrainingDate *string `json:"custom_model_training_date,omitempty"`
TotalEngagedUsers int `json:"total_engaged_users"`
TotalChats int `json:"total_chats"`
TotalChatInsertionEvents int `json:"total_chat_insertion_events"`
TotalChatCopyEvents int `json:"total_chat_copy_events"`
}

type CopilotIdeChatEditor struct {
Name string `json:"name"`
TotalEngagedUsers int `json:"total_engaged_users"`
Models []*CopilotIdeChatModel `json:"models"`
}

// CopilotIdeChat represents Copilot usage metrics for Copilot Chat in the IDE, categorized by editor and model.
type CopilotIdeChat struct {
henriklundstrom marked this conversation as resolved.
Show resolved Hide resolved
TotalEngagedUsers int `json:"total_engaged_users"`
Editors []*CopilotIdeChatEditor `json:"editors"`
}

type CopilotDotcomChatModel struct {
Name string `json:"name"`
IsCustomModel bool `json:"is_custom_model"`
CustomModelTrainingDate *string `json:"custom_model_training_date,omitempty"`
TotalEngagedUsers int `json:"total_engaged_users"`
TotalChats int `json:"total_chats"`
}

// CopilotDotcomChat represents Copilot usage metrics for Copilot Chat in the webbrowser, categorized by model.
type CopilotDotcomChat struct {
TotalEngagedUsers int `json:"total_engaged_users"`
Models []*CopilotDotcomChatModel `json:"models"`
}

type CopilotDotcomPullRequestsModel struct {
Name string `json:"name"`
IsCustomModel bool `json:"is_custom_model"`
CustomModelTrainingDate *string `json:"custom_model_training_date,omitempty"`
TotalPrSummariesCreated int `json:"total_pr_summaries_created"`
henriklundstrom marked this conversation as resolved.
Show resolved Hide resolved
TotalEngagedUsers int `json:"total_engaged_users"`
}

type CopilotDotcomPullRequestsRepository struct {
Name string `json:"name"`
TotalEngagedUsers int `json:"total_engaged_users"`
Models []*CopilotDotcomPullRequestsModel `json:"models"`
}

// CopilotDotcomPullRequests represents Copilot usage metrics for pull requests in the webbrowser, categorized by repository and model.
type CopilotDotcomPullRequests struct {
TotalEngagedUsers int `json:"total_engaged_users"`
Repositories []*CopilotDotcomPullRequestsRepository `json:"repositories"`
}

// CopilotMetrics represents Copilot usage metrics for a given day.
type CopilotMetrics struct {
Date string `json:"date"`
TotalActiveUsers int `json:"total_active_users"`
TotalEngagedUsers int `json:"total_engaged_users"`
henriklundstrom marked this conversation as resolved.
Show resolved Hide resolved
CopilotIdeCodeCompletions *CopilotIdeCodeCompletions `json:"copilot_ide_code_completions"`
CopilotIdeChat *CopilotIdeChat `json:"copilot_ide_chat"`
CopilotDotcomChat *CopilotDotcomChat `json:"copilot_dotcom_chat"`
CopilotDotcomPullRequests *CopilotDotcomPullRequests `json:"copilot_dotcom_pull_requests"`
}

func (cp *CopilotSeatDetails) UnmarshalJSON(data []byte) error {
// Using an alias to avoid infinite recursion when calling json.Unmarshal
type alias CopilotSeatDetails
Expand Down Expand Up @@ -482,3 +592,107 @@ func (s *CopilotService) GetOrganizationTeamUsage(ctx context.Context, org, team

return usage, resp, nil
}

// GetEnterpriseMetrics gets Copilot usage metrics for an enterprise.
//
// GitHub API docs: https://docs.github.com/en/rest/copilot/copilot-metrics#get-copilot-metrics-for-an-enterprise
//
//meta:operation GET /enterprises/{enterprise}/copilot/metrics
func (s *CopilotService) GetEnterpriseMetrics(ctx context.Context, enterprise string, opts *CopilotMetricsListOptions) ([]*CopilotMetrics, *Response, error) {
u := fmt.Sprintf("enterprises/%v/copilot/metrics", enterprise)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}

req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}

var metrics []*CopilotMetrics
resp, err := s.client.Do(ctx, req, &metrics)
if err != nil {
return nil, resp, err
}

return metrics, resp, nil
}

// GetEnterpriseTeamMetrics gets Copilot usage metrics for an enterprise team.
//
// GitHub API docs: https://docs.github.com/en/rest/copilot/copilot-metrics#get-copilot-metrics-for-an-enterprise-team
//
//meta:operation GET /enterprises/{enterprise}/team/{team_slug}/copilot/metrics
func (s *CopilotService) GetEnterpriseTeamMetrics(ctx context.Context, enterprise, team string, opts *CopilotMetricsListOptions) ([]*CopilotMetrics, *Response, error) {
u := fmt.Sprintf("enterprises/%v/team/%v/copilot/metrics", enterprise, team)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}

req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}

var metrics []*CopilotMetrics
resp, err := s.client.Do(ctx, req, &metrics)
if err != nil {
return nil, resp, err
}

return metrics, resp, nil
}

// GetOrganizationMetrics gets Copilot usage metrics for an organization.
//
// GitHub API docs: https://docs.github.com/en/rest/copilot/copilot-metrics#get-copilot-metrics-for-an-organization
//
//meta:operation GET /orgs/{org}/copilot/metrics
func (s *CopilotService) GetOrganizationMetrics(ctx context.Context, org string, opts *CopilotMetricsListOptions) ([]*CopilotMetrics, *Response, error) {
u := fmt.Sprintf("orgs/%v/copilot/metrics", org)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}

req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}

var metrics []*CopilotMetrics
resp, err := s.client.Do(ctx, req, &metrics)
if err != nil {
return nil, resp, err
}

return metrics, resp, nil
}

// GetOrganizationTeamMetrics gets Copilot usage metrics for an organization team.
//
// GitHub API docs: https://docs.github.com/en/rest/copilot/copilot-metrics#get-copilot-metrics-for-a-team
//
//meta:operation GET /orgs/{org}/team/{team_slug}/copilot/metrics
func (s *CopilotService) GetOrganizationTeamMetrics(ctx context.Context, org, team string, opts *CopilotMetricsListOptions) ([]*CopilotMetrics, *Response, error) {
u := fmt.Sprintf("orgs/%v/team/%v/copilot/metrics", org, team)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}

req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}

var metrics []*CopilotMetrics
resp, err := s.client.Do(ctx, req, &metrics)
if err != nil {
return nil, resp, err
}

return metrics, resp, nil
}
Loading
Loading