Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions backend/plugins/gh-copilot/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,32 @@ It follows the same structure/patterns as other DevLake data-source plugins (not

## What it collects

**Phase 1 endpoints** (GitHub Copilot REST API):
### ⚠️ Current API Status

- `GET /orgs/{org}/copilot/billing`
- `GET /orgs/{org}/copilot/billing/seats`
- `GET /orgs/{org}/copilot/metrics`
**DEPRECATED Endpoints (Currently Used - Sunset April 2, 2026)**:
- `GET /orgs/{org}/copilot/metrics` - Legacy org-level usage metrics (up to 100 days)

**Migration Required**: The plugin currently uses the legacy Copilot Metrics API which will be **sunset on April 2, 2026**. Migration to the new Usage Metrics Reports API is planned.

### Recommended New Endpoints (Migration Target)

**Organization-level Usage Metrics Reports** (Two-step flow: metadata → download JSON):
- `GET /orgs/{org}/copilot/metrics/reports/organization-1-day?day=YYYY-MM-DD` - Single day report
- `GET /orgs/{org}/copilot/metrics/reports/organization-28-day/latest` - Latest 28-day report

**Enterprise-level Usage Metrics Reports**:
- `GET /enterprises/{enterprise}/copilot/metrics/reports/enterprise-1-day?day=YYYY-MM-DD` - Single day report
- `GET /enterprises/{enterprise}/copilot/metrics/reports/enterprise-28-day/latest` - Latest 28-day report

**Seat Management** (Still valid):
- `GET /orgs/{org}/copilot/billing` - Organization billing information
- `GET /orgs/{org}/copilot/billing/seats` - Seat assignments and license usage

**API Documentation**:
- New API: https://docs.github.com/en/rest/copilot/copilot-usage-metrics
- Legacy API: https://docs.github.com/en/rest/copilot/copilot-metrics (deprecated)

**Research Documentation**: See the `copilot-metrics-research/` directory in this repository for detailed API research and migration strategy.

**Stored data (tool layer)**:

Expand Down
20 changes: 20 additions & 0 deletions backend/plugins/gh-copilot/tasks/api_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,26 @@ func handleGitHubRetryAfter(res *http.Response, logger log.Logger, now nowFunc,
return errors.HttpStatus(http.StatusTooManyRequests).New("GitHub rate limited the request")
}

// CreateApiClient creates an API client for GitHub Copilot REST API endpoints.
//
// ⚠️ DEPRECATION WARNING: This client currently uses the legacy Copilot Metrics API
// which will be sunset on April 2, 2026. Migration to the new Usage Metrics Reports
// API is required.
//
// Current endpoints (DEPRECATED):
// - GET /orgs/{org}/copilot/metrics (organization-level usage metrics - DEPRECATED)
// - GET /orgs/{org}/copilot/billing/seats (seat assignments - still valid)
//
// New recommended endpoints (migration target):
// - GET /orgs/{org}/copilot/metrics/reports/organization-1-day?day=YYYY-MM-DD
// - GET /orgs/{org}/copilot/metrics/reports/organization-28-day/latest
// - GET /enterprises/{enterprise}/copilot/metrics/reports/enterprise-1-day?day=YYYY-MM-DD
//
// The new endpoints use a two-step flow: request report metadata → download JSON files.
// See the copilot-metrics-research directory in this repository for detailed migration strategy.
//
// API Version: 2022-11-28 (GitHub REST API versioning)
// Documentation: https://docs.github.com/en/rest/copilot/copilot-usage-metrics
func CreateApiClient(taskCtx plugin.TaskContext, connection *models.GhCopilotConnection) (*helper.ApiAsyncClient, errors.Error) {
apiClient, err := helper.NewApiClientFromConnection(taskCtx.GetContext(), taskCtx, connection)
if err != nil {
Expand Down
25 changes: 25 additions & 0 deletions backend/plugins/gh-copilot/tasks/metrics_collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,31 @@ func computeMetricsDateRange(now time.Time, since *time.Time) (start time.Time,
return start, until
}

// CollectCopilotOrgMetrics collects organization-level Copilot usage metrics from GitHub.
//
// ⚠️ DEPRECATION WARNING: This collector uses the DEPRECATED endpoint that will
// be sunset on April 2, 2026. Migration to the new Usage Metrics Reports API is required.
//
// Current API Endpoint (DEPRECATED): GET /orgs/{org}/copilot/metrics
// This endpoint provides up to 100 days of daily usage metrics including:
// - Active users and engagement levels
// - Code completion suggestions and acceptances
// - Language and IDE breakdowns
// - Chat usage statistics
//
// New recommended endpoints (migration target):
// - GET /orgs/{org}/copilot/metrics/reports/organization-1-day?day=YYYY-MM-DD
// - GET /orgs/{org}/copilot/metrics/reports/organization-28-day/latest
//
// The new endpoints use a two-step flow:
// 1. Request report metadata (returns download_links)
// 2. Download JSON files from signed URLs
// 3. Parse downloaded JSON/JSONL data
//
// See the copilot-metrics-research/copilot_implementation_strategy.md file in this
// repository for migration details.
//
// The collector supports incremental collection based on the last sync time.
func CollectCopilotOrgMetrics(taskCtx plugin.SubTaskContext) errors.Error {
data, ok := taskCtx.TaskContext().GetData().(*GhCopilotTaskData)
if !ok {
Expand Down
10 changes: 10 additions & 0 deletions backend/plugins/gh-copilot/tasks/seat_collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ func parseCopilotSeatsFromResponse(res *http.Response) ([]json.RawMessage, error
return wrapped.Seats, nil
}

// CollectCopilotSeatAssignments collects Copilot seat assignment data from GitHub.
//
// API Endpoint: GET /orgs/{org}/copilot/billing/seats
// This endpoint provides information about:
// - Assigned Copilot seats (users with access)
// - Assignment timestamps
// - Last activity dates
// - Pending invitations
//
// The data helps track Copilot adoption and license utilization.
func CollectCopilotSeatAssignments(taskCtx plugin.SubTaskContext) errors.Error {
data, ok := taskCtx.TaskContext().GetData().(*GhCopilotTaskData)
if !ok {
Expand Down
Loading