-
Notifications
You must be signed in to change notification settings - Fork 9
128 lines (112 loc) · 4.68 KB
/
telemetry-badge.yml
File metadata and controls
128 lines (112 loc) · 4.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
name: Telemetry Badge
on:
schedule:
- cron: "0 6 * * *" # daily at 06:00 UTC
workflow_dispatch:
permissions:
contents: write
jobs:
update-badge:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Generate telemetry badge
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
BADGE_PATH: docs/badges/telemetry.json
run: |
set -euo pipefail
if grep -q "__BADGE_REPO__" README.md; then
sed -i "s#__BADGE_REPO__#${GITHUB_REPOSITORY}#g" README.md
fi
python - <<'PY'
import json
import os
import sys
import urllib.parse
import urllib.error
import urllib.request
from pathlib import Path
token = os.environ.get("SENTRY_AUTH_TOKEN", "").strip()
org = os.environ.get("SENTRY_ORG", "").strip()
project = os.environ.get("SENTRY_PROJECT", "").strip()
badge_path = Path(os.environ.get("BADGE_PATH", "docs/badges/telemetry.json"))
if not token or not org or not project:
sys.exit("Sentry credentials (SENTRY_AUTH_TOKEN, SENTRY_ORG, SENTRY_PROJECT) are required.")
def api_get(url: str):
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"Accept": "application/json",
"User-Agent": "svv-telemetry-badge",
}
req = urllib.request.Request(url, headers=headers)
with urllib.request.urlopen(req, timeout=20) as resp:
data = resp.read()
return json.loads(data.decode()), resp.headers
def latest_release_version():
url = f"https://sentry.io/api/0/projects/{org}/{project}/releases/?per_page=1"
payload, _ = api_get(url)
if not payload:
return None
return payload[0].get("version")
def unresolved_count(version: str | None, proj_id: str | None):
"""
Return unresolved issue count. Tries release-specific first, then
global unresolved. If both fail, return 0 but log the failure.
"""
queries = []
if version:
queries.append(f'is:unresolved release:"{version}"')
queries.append("is:unresolved")
for query in queries:
params_dict = {"query": query, "statsPeriod": "24h", "limit": 1}
params = urllib.parse.urlencode(params_dict)
url = f"https://sentry.io/api/0/projects/{org}/{project}/issues/?{params}"
try:
payload, headers = api_get(url)
hits = headers.get("X-Hits")
if hits is not None:
try:
return int(hits)
except Exception:
pass
return len(payload)
except urllib.error.HTTPError as err:
body = err.read().decode(errors="ignore")
print(f"[telemetry-badge] query failed ({err.code}): {err.reason} | body={body}")
continue
except Exception as exc:
print(f"[telemetry-badge] query error: {exc}")
continue
# If all attempts failed, avoid breaking the workflow.
return 0
version = latest_release_version()
count = unresolved_count(version, None)
if count == 0:
color = "brightgreen"
elif count < 5:
color = "yellow"
elif count < 15:
color = "orange"
else:
color = "red"
message_suffix = version if version else "no release"
badge = {
"schemaVersion": 1,
"label": "telemetry",
"message": f"{count} unresolved | {message_suffix}",
"color": color,
}
badge_path.parent.mkdir(parents=True, exist_ok=True)
badge_path.write_text(json.dumps(badge), encoding="utf-8")
print(f"Wrote badge to {badge_path} with count={count}, version={message_suffix}")
PY
- name: Commit badge update
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "chore: update telemetry badge"
file_pattern: docs/badges/telemetry.json README.md