Skip to content

Conversation

@henriklundstrom
Copy link
Contributor

Implements the new endpoints for retrieving reports of copilot metrics for enterprises and organizations. See https://docs.github.com/en/enterprise-cloud@latest/rest/copilot/copilot-usage-metrics?apiVersion=2022-11-28. The API does not return the reports directly, but rather returns signed download URLs with a limited expiration time. The proposed implementation simply returns the API response, leaving the actual downloading of the reports to the user.

Will require an update to the openapi_operations.yaml-file.

@codecov
Copy link

codecov bot commented Dec 29, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.40%. Comparing base (c65cb55) to head (cc49b28).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3893      +/-   ##
==========================================
+ Coverage   92.35%   92.40%   +0.04%     
==========================================
  Files         202      202              
  Lines       14762    14854      +92     
==========================================
+ Hits        13634    13726      +92     
  Misses        926      926              
  Partials      202      202              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@gmlewis
Copy link
Collaborator

gmlewis commented Dec 29, 2025

Will require an update to the openapi_operations.yaml-file.

Thank you, @henriklundstrom! I've updated the openapi_operations.yaml file in #3895.
If you merge master into this PR and push the result, then fix the linting errors, we should be ready to review this PR.

@henriklundstrom
Copy link
Contributor Author

Will require an update to the openapi_operations.yaml-file.

Thank you, @henriklundstrom! I've updated the openapi_operations.yaml file in #3895. If you merge master into this PR and push the result, then fix the linting errors, we should be ready to review this PR.

Thanks, I've merged the latest master into this branch.

@gmlewis gmlewis added the NeedsReview PR is awaiting a review before merging. label Dec 29, 2025
Copy link
Collaborator

@gmlewis gmlewis left a comment

Choose a reason for hiding this comment

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

Thank you, @henriklundstrom!
LGTM.
Awaiting second LGTM+Approval from any other contributor to this repo before merging.

cc: @stevehipwell - @alexandear - @zyfy29

Comment on lines 193 to 199
// CopilotMetricsReportResponse represents the response from Copilot metrics report endpoints.
type CopilotMetricsReportResponse struct {
DownloadLinks []string `json:"download_links"`
ReportDay *string `json:"report_day,omitempty"` // For 1-day reports
ReportStartDay *string `json:"report_start_day,omitempty"` // For 28-day reports
ReportEndDay *string `json:"report_end_day,omitempty"` // For 28-day reports
}
Copy link
Contributor

Choose a reason for hiding this comment

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

It's better to create a separate response struct for each endpoint and mix them.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I agree, that's actually cleaner. I've pushed a change.

}

// CopilotMetricsDailyReportResponse represents the response from 1-day Copilot metrics report endpoints.
type CopilotMetricsDailyReportResponse struct {
Copy link
Contributor

Choose a reason for hiding this comment

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

Response is not needed, I think

Suggested change
type CopilotMetricsDailyReportResponse struct {
type CopilotMetricsDailyReport struct {

// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/copilot/copilot-usage-metrics#get-copilot-enterprise-usage-metrics-for-a-specific-day
//
//meta:operation GET /enterprises/{enterprise}/copilot/metrics/reports/enterprise-1-day
func (s *CopilotService) GetEnterpriseMetricsReport1Day(ctx context.Context, enterprise string, opts *CopilotMetricsReportOptions) (*CopilotMetricsDailyReportResponse, *Response, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

We should be consistent with the existing endpoints. Currently, we have:

git grep -nP '^[[:space:]]*func (?!Test).*Metrics' \
  -- ':!**/*_test.go' ':!github/github-accessors.go'
github/copilot.go:479:func (s *CopilotService) GetEnterpriseMetrics(ctx context.Context, enterprise string, opts *CopilotMetricsListOptions) ([]*CopilotMetrics, *Response, error) {
github/copilot.go:505:func (s *CopilotService) GetEnterpriseTeamMetrics(ctx context.Context, enterprise, team string, opts *CopilotMetricsListOptions) ([]*CopilotMetrics, *Response, error) {
github/copilot.go:531:func (s *CopilotService) GetOrganizationMetrics(ctx context.Context, org string, opts *CopilotMetricsListOptions) ([]*CopilotMetrics, *Response, error) {
github/copilot.go:557:func (s *CopilotService) GetOrganizationTeamMetrics(ctx context.Context, org, team string, opts *CopilotMetricsListOptions) ([]*CopilotMetrics, *Response, error) {
github/repos_community_health.go:49:func (s *RepositoriesService) GetCommunityHealthMetrics(ctx context.Context, owner, repo string) (*CommunityHealthMetrics, *Response, error) {

I propose the following:

Suggested change
func (s *CopilotService) GetEnterpriseMetricsReport1Day(ctx context.Context, enterprise string, opts *CopilotMetricsReportOptions) (*CopilotMetricsDailyReportResponse, *Response, error) {
func (s *CopilotService) GetEnterpriseDailyMetricsReport(ctx context.Context, enterprise string, opts *CopilotMetricsReportOptions) (*CopilotMetricsDailyReport, *Response, error) {

What do you think?

// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/copilot/copilot-usage-metrics#get-copilot-enterprise-usage-metrics
//
//meta:operation GET /enterprises/{enterprise}/copilot/metrics/reports/enterprise-28-day/latest
func (s *CopilotService) GetEnterpriseMetricsReport28Day(ctx context.Context, enterprise string) (*CopilotMetricsPeriodReportResponse, *Response, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
func (s *CopilotService) GetEnterpriseMetricsReport28Day(ctx context.Context, enterprise string) (*CopilotMetricsPeriodReportResponse, *Response, error) {
func (s *CopilotService) GetEnterpriseMetricsReport(ctx context.Context, enterprise string) (*CopilotMetricsReport, *Response, error) {

// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/copilot/copilot-usage-metrics#get-copilot-users-usage-metrics-for-a-specific-day
//
//meta:operation GET /enterprises/{enterprise}/copilot/metrics/reports/users-1-day
func (s *CopilotService) GetEnterpriseMetricsReportUsers1Day(ctx context.Context, enterprise string, opts *CopilotMetricsReportOptions) (*CopilotMetricsDailyReportResponse, *Response, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
func (s *CopilotService) GetEnterpriseMetricsReportUsers1Day(ctx context.Context, enterprise string, opts *CopilotMetricsReportOptions) (*CopilotMetricsDailyReportResponse, *Response, error) {
func (s *CopilotService) GetEnterpriseUsersDailyMetricsReport(ctx context.Context, enterprise string, opts *CopilotMetricsReportOptions) (*CopilotMetricsDailyReport, *Response, error) {

// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/copilot/copilot-usage-metrics#get-copilot-users-usage-metrics
//
//meta:operation GET /enterprises/{enterprise}/copilot/metrics/reports/users-28-day/latest
func (s *CopilotService) GetEnterpriseMetricsReportUsers28Day(ctx context.Context, enterprise string) (*CopilotMetricsPeriodReportResponse, *Response, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
func (s *CopilotService) GetEnterpriseMetricsReportUsers28Day(ctx context.Context, enterprise string) (*CopilotMetricsPeriodReportResponse, *Response, error) {
func (s *CopilotService) GetEnterpriseUsersMetricsReport(ctx context.Context, enterprise string) (*CopilotMetricsReport, *Response, error) {

// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/copilot/copilot-usage-metrics#get-copilot-organization-usage-metrics-for-a-specific-day
//
//meta:operation GET /orgs/{org}/copilot/metrics/reports/organization-1-day
func (s *CopilotService) GetOrganizationMetricsReport1Day(ctx context.Context, org string, opts *CopilotMetricsReportOptions) (*CopilotMetricsDailyReportResponse, *Response, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
func (s *CopilotService) GetOrganizationMetricsReport1Day(ctx context.Context, org string, opts *CopilotMetricsReportOptions) (*CopilotMetricsDailyReportResponse, *Response, error) {
func (s *CopilotService) GetOrganizationDailyMetricsReport(ctx context.Context, org string, opts *CopilotMetricsReportOptions) (*CopilotMetricsDailyReport, *Response, error) {

// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/copilot/copilot-usage-metrics#get-copilot-organization-usage-metrics
//
//meta:operation GET /orgs/{org}/copilot/metrics/reports/organization-28-day/latest
func (s *CopilotService) GetOrganizationMetricsReport28Day(ctx context.Context, org string) (*CopilotMetricsPeriodReportResponse, *Response, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
func (s *CopilotService) GetOrganizationMetricsReport28Day(ctx context.Context, org string) (*CopilotMetricsPeriodReportResponse, *Response, error) {
func (s *CopilotService) GetOrganizationMetricsReport(ctx context.Context, org string) (*CopilotMetricsReport, *Response, error) {

// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/copilot/copilot-usage-metrics#get-copilot-organization-users-usage-metrics-for-a-specific-day
//
//meta:operation GET /orgs/{org}/copilot/metrics/reports/users-1-day
func (s *CopilotService) GetOrganizationMetricsReportUsers1Day(ctx context.Context, org string, opts *CopilotMetricsReportOptions) (*CopilotMetricsDailyReportResponse, *Response, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
func (s *CopilotService) GetOrganizationMetricsReportUsers1Day(ctx context.Context, org string, opts *CopilotMetricsReportOptions) (*CopilotMetricsDailyReportResponse, *Response, error) {
func (s *CopilotService) GetOrganizationUsersDailyMetricsReport(ctx context.Context, org string, opts *CopilotMetricsReportOptions) (*CopilotMetricsDailyReport, *Response, error) {

// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/copilot/copilot-usage-metrics#get-copilot-organization-users-usage-metrics
//
//meta:operation GET /orgs/{org}/copilot/metrics/reports/users-28-day/latest
func (s *CopilotService) GetOrganizationMetricsReportUsers28Day(ctx context.Context, org string) (*CopilotMetricsPeriodReportResponse, *Response, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
func (s *CopilotService) GetOrganizationMetricsReportUsers28Day(ctx context.Context, org string) (*CopilotMetricsPeriodReportResponse, *Response, error) {
func (s *CopilotService) GetOrganizationUsersMetricsReport(ctx context.Context, org string) (*CopilotMetricsReport, *Response, error) {

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

Labels

NeedsReview PR is awaiting a review before merging.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants