Migrate metrics to the user-day usage report (legacy /copilot/metrics API was sunset 2026-04-02)#90
Open
a-magdy wants to merge 3 commits into
Open
Conversation
Switch the GitHub-API metrics path to consume the user-day usage report (`/copilot/metrics/reports/users-28-day/latest`), correlate each record with seat assignments, and aggregate results into the existing CopilotUsageOutput shape so the dashboard renders without further changes. - copilot-metrics-service.ts: download the report, join with /copilot/billing/seats data, and roll usage up by day plus team. - env-service.ts: only require GITHUB_ORGANIZATION when scope is organization, and only require GITHUB_ENTERPRISE when scope is enterprise; default scope to organization. - tsconfig.json: set target to es2015 so the build accepts iteration over Set used by the new aggregation helpers. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Adds docs/metrics-ingestion.md with a sequence overview, field reference, and an explanation of why we moved off the per-day metrics endpoint. - Adds a file header to copilot-metrics-service.ts so the three back-ends (CosmosDB / GitHub API / sample) are obvious to the next reader. Refs #2 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Author
|
@microsoft-github-policy-service agree |
…trics migration - Replace stale /copilot/metrics API link with users-28-day report endpoint - Link to docs/metrics-ingestion.md from the intro - Replace bullet-list env var sections with tables; clarify that only GITHUB_ORGANIZATION or GITHUB_ENTERPRISE is needed depending on scope (GITHUB_API_VERSION added as it was previously undocumented) - Update Azure deploy prereqs and azd example to show scope-conditional org/enterprise values; note that Bicep still requires both at deploy time Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Warning
The Copilot Metrics API used by
mainwas sunset on 2026-04-02.Without this PR, every metrics call from
services/copilot-metrics-service.tsreturns 404 and the dashboard renders no data on a fresh deployment today.Tracking issue: microsoft/copilot-metrics-dashboard#87 · GitHub changelog: "Closing down notice of legacy Copilot metrics APIs" (2026-01-29).
Closes #87
What this changes
This PR rewires
services/copilot-metrics-service.tsto source metrics from the user-day usage report instead of the per-day metrics endpoint, joins the result with seat assignments, and relaxes environment-variable validation so org-only deployments don't have to setGITHUB_ENTERPRISE.The output type (
CopilotUsageOutput[]) consumed by the dashboard UI is unchanged, so no UI work is required.See #87 for the rationale and docs/metrics-ingestion.md added in this PR for an end-to-end walkthrough.
Data flow summary
Why move off the per-day endpoint?
The per-day endpoint (
/orgs/{org}/copilot/metrics) returns counters already aggregated by day/IDE/language. It does not expose per-user data, so we couldn't:The user-day usage report exposes the underlying per-user, per-day rows. All three become local computations; the cost is the extra download + aggregation that this PR adds.
Why touch
env-service.ts?Today the validator requires all of
GITHUB_ORGANIZATION,GITHUB_ENTERPRISE,GITHUB_TOKEN,GITHUB_API_VERSIONregardless ofGITHUB_API_SCOPE. That contradicts the README and forces org-scope users to set a dummyGITHUB_ENTERPRISEvalue. This PR makes the requirement scope-aware:scope=organization→ requireGITHUB_ORGANIZATION, ignoreGITHUB_ENTERPRISE.scope=enterprise→ requireGITHUB_ENTERPRISE, ignoreGITHUB_ORGANIZATION.scopedefaults toorganizationif unset.Why
tsconfig.json?The new aggregation iterates over
Setvalues. TypeScript's defaulttarget: "es5"rejects nativefor ... ofoverSet(--downlevelIterationwould also work but is global noise). Settingtarget: "es2015"is the simplest fix and matches what every supported Node version runs natively.Files
src/dashboard/services/copilot-metrics-service.tssrc/dashboard/services/env-service.tsorganization.src/dashboard/tsconfig.jsontarget: "es2015".docs/metrics-ingestion.mdVerification
npm run build— lint + type-check + production build all pass.npm run dev—/and/seatsrender against a live org.Notes for reviewers
download_linkmay return either a JSON array or NDJSON; both are handled inparseUsageUserReport.cache: "no-store"because the dashboard always wants fresh data.hasUsageActivity).chat_*or anything containingagentis chat; everything else is treated as completion.Context — why now?
The user-day usage report API didn't exist when the dashboard was last updated.
maincurrently uses) goes GA./usageendpoints deprecated.main(01ef37d)./copilot/metrics/reports/users-28-day/latestendpoint this PR adopts.So the new endpoint is roughly three months newer than
main. The motivation for switching to it (per-user granularity, native team attribution, clean chat-vs-completion split) is described in #87.