-
Notifications
You must be signed in to change notification settings - Fork 0
Add GitHub Copilot metrics dashboa autoCorrect AI dashboard #2
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
Changes from all commits
87a9a8e
a12c4db
7d4d0d0
8f5e7df
a432b3c
b7886c6
083dbe7
9288a38
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| name: Copilot Metrics Collector | ||
|
|
||
| on: | ||
| schedule: | ||
| # Runs every day at 06:00 UTC (after GitHub's nightly data refresh) | ||
| - cron: "0 6 * * *" | ||
| workflow_dispatch: | ||
| # Also allows manual triggering from the Actions tab | ||
|
|
||
| permissions: | ||
| contents: write # needed to commit the updated metrics file back to the repo | ||
|
|
||
| jobs: | ||
| fetch-metrics: | ||
| runs-on: ubuntu-latest | ||
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up Python | ||
| uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: "3" | ||
|
|
||
| - name: Fetch Copilot usage metrics | ||
| env: | ||
| COPILOT_METRICS_TOKEN: ${{ secrets.COPILOT_METRICS_TOKEN }} | ||
| ORG: DewDropstempest | ||
| run: | | ||
| python - <<'PYEOF' | ||
| import json | ||
| import os | ||
| import urllib.request | ||
| import urllib.error | ||
| from datetime import datetime, timezone | ||
|
|
||
| token = os.environ["COPILOT_METRICS_TOKEN"] | ||
| org = os.environ["ORG"] | ||
|
|
||
| url = f"https://api.github.com/orgs/{org}/copilot/usage" | ||
|
|
||
| req = urllib.request.Request( | ||
| url, | ||
| headers={ | ||
| "Authorization": f"Bearer {token}", | ||
| "Accept": "application/vnd.github+json", | ||
| "X-GitHub-Api-Version": "2022-11-28", | ||
| }, | ||
| ) | ||
|
|
||
| try: | ||
| with urllib.request.urlopen(req) as resp: | ||
| data = json.loads(resp.read().decode()) | ||
| except urllib.error.HTTPError as e: | ||
| body = e.read().decode() | ||
| print(f"HTTP {e.code}: {body}") | ||
| raise SystemExit(f"Failed to fetch metrics: {e.code}") | ||
|
|
||
| # ── Normalise field names ────────────────────────────────────────── | ||
| # The API returns either the v1 shape (total_suggestions_count, etc.) | ||
| # or the v2 shape (totals.suggestions, etc.). We normalise to v1. | ||
| normalised = [] | ||
| for day in data: | ||
| entry = {"day": day.get("day", day.get("date", "unknown"))} | ||
| if "total_suggestions_count" in day: | ||
| # v1 shape – already in the format we want | ||
| entry["total_active_users"] = day.get("total_active_users", 0) | ||
| entry["total_suggestions_count"] = day.get("total_suggestions_count", 0) | ||
| entry["total_acceptances_count"] = day.get("total_acceptances_count", 0) | ||
| entry["total_lines_suggested"] = day.get("total_lines_suggested", 0) | ||
| entry["total_lines_accepted"] = day.get("total_lines_accepted", 0) | ||
| elif "copilot_ide_code_completions" in day: | ||
| # v2 / newer shape | ||
| cc = day.get("copilot_ide_code_completions") or {} | ||
| entry["total_active_users"] = day.get("total_active_users", 0) | ||
| entry["total_suggestions_count"] = cc.get("total_suggestions_count", 0) | ||
| entry["total_acceptances_count"] = cc.get("total_acceptances_count", 0) | ||
| entry["total_lines_suggested"] = cc.get("total_lines_suggested", 0) | ||
| entry["total_lines_accepted"] = cc.get("total_lines_accepted", 0) | ||
|
Comment on lines
+77
to
+80
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In the Useful? React with 👍 / 👎. |
||
| else: | ||
| # Fallback – store whatever we got so the dashboard can adapt | ||
| entry.update({k: v for k, v in day.items() if k != "breakdown"}) | ||
| normalised.append(entry) | ||
|
|
||
| out_path = "copilot-dashboard/data/metrics.json" | ||
| os.makedirs(os.path.dirname(out_path), exist_ok=True) | ||
|
|
||
| with open(out_path, "w") as f: | ||
| json.dump(normalised, f, indent=2) | ||
|
|
||
| print(f"Wrote {len(normalised)} day(s) of metrics to {out_path}") | ||
| PYEOF | ||
|
|
||
| - name: Commit updated metrics | ||
| run: | | ||
| git config user.name "github-actions[bot]" | ||
| git config user.email "github-actions[bot]@users.noreply.github.com" | ||
| git add copilot-dashboard/data/metrics.json | ||
| if git diff --cached --quiet; then | ||
| echo "No changes to metrics data – skipping commit." | ||
| else | ||
| git commit -m "chore: update Copilot metrics [skip ci]" | ||
| git push | ||
| fi | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| # Copilot Metrics Dashboard | ||
|
|
||
| A self-hosted dashboard that pulls GitHub Copilot usage data daily and | ||
| displays it as interactive charts — no third-party service required. | ||
|
|
||
| --- | ||
|
|
||
| ## How it works | ||
|
|
||
| 1. A GitHub Actions workflow (`copilot-metrics.yml`) runs every day at 06:00 UTC. | ||
| 2. It calls the [GitHub Copilot Usage API](https://docs.github.com/en/rest/copilot/copilot-usage) and saves the results to `data/metrics.json`. | ||
| 3. The dashboard (`index.html`) reads that JSON file and renders charts automatically. | ||
|
|
||
| --- | ||
|
|
||
| ## ✅ One-time setup (the only manual step) | ||
|
|
||
| You need to create a secret called **`COPILOT_METRICS_TOKEN`** in this repository. | ||
|
|
||
| ### Step 1 — Create a Personal Access Token | ||
|
|
||
| 1. Go to **GitHub.com → your profile → Settings → Developer settings → Personal access tokens → Fine-grained tokens** | ||
| 2. Click **"Generate new token"** | ||
| 3. Set: | ||
| - **Token name**: `copilot-metrics-dashboard` (or anything you like) | ||
| - **Resource owner**: `DewDropstempest` (the organization) | ||
| - **Repository access**: `Only select repositories` → pick this repo | ||
| - **Permissions → Organization permissions → GitHub Copilot Business → Access: Read-only** | ||
| 4. Click **"Generate token"** and **copy the token value** (you only see it once) | ||
|
|
||
| > If Fine-grained tokens don't show a Copilot permission yet, create a **Classic token** with the `manage_billing:copilot` scope instead. | ||
|
|
||
| ### Step 2 — Add the secret to this repository | ||
|
|
||
| 1. Go to **this repository → Settings → Secrets and variables → Actions** | ||
| 2. Click **"New repository secret"** | ||
| 3. Name: `COPILOT_METRICS_TOKEN` | ||
| 4. Value: paste the token you just copied | ||
| 5. Click **"Add secret"** | ||
|
|
||
| That's it — you're done! | ||
|
|
||
| --- | ||
|
|
||
| ## Viewing the dashboard | ||
|
|
||
| ### Option A — GitHub Pages (recommended, zero extra cost) | ||
|
|
||
| 1. Go to **this repository → Settings → Pages** | ||
| 2. Under **"Source"** choose **"Deploy from a branch"** | ||
| 3. Branch: `main` (or whichever branch this code is on), Folder: `/copilot-dashboard` | ||
| 4. Click **Save** | ||
|
|
||
| Your dashboard will be live at: | ||
| ``` | ||
| https://DewDropstempest.github.io/psl/ | ||
| ``` | ||
|
|
||
| ### Option B — Open locally | ||
|
|
||
| Just open `copilot-dashboard/index.html` in any modern browser (after the first | ||
| workflow run has populated `data/metrics.json`). | ||
|
|
||
| --- | ||
|
|
||
| ## Triggering the first run | ||
|
|
||
| Don't want to wait until 06:00 UTC? Run it now: | ||
|
|
||
| 1. Go to **this repository → Actions → Copilot Metrics Collector** | ||
| 2. Click **"Run workflow" → Run workflow** | ||
|
|
||
| The `data/metrics.json` file will be committed automatically and the dashboard will show data within a minute or two. | ||
|
|
||
| --- | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| | Symptom | Likely cause | Fix | | ||
| |---------|-------------|-----| | ||
| | Workflow fails with `HTTP 403` | Token missing or wrong scope | Re-check Step 1 — ensure Copilot read permission is set | | ||
| | Workflow succeeds but dashboard shows "No data yet" | API returned an empty array | Make sure Copilot is enabled for the org and at least one seat is active | | ||
| | Workflow fails with `HTTP 404` | Org doesn't have Copilot Business/Enterprise | Purchase a Copilot plan for the org | | ||
| | Dashboard shows stale data | Workflow hasn't run yet today | Trigger manually (see above) | |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| [] |
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.
The workflow calls
https://api.github.com/orgs/{org}/copilot/usage, but GitHub’s Copilot metrics endpoints changed and the legacy set was shut down on April 2, 2026; organization usage data is now retrieved through/orgs/{org}/copilot/metrics/reports/.... In this job, a non-200 response triggersSystemExit, so the scheduled run never writes new data and the dashboard remains stale/empty.Useful? React with 👍 / 👎.