Skip to content

Commit 4dfbc13

Browse files
committed
add github notification
ghstack-source-id: d7ee0a4 Pull-Request: #7096
1 parent be13115 commit 4dfbc13

File tree

2 files changed

+56
-4
lines changed

2 files changed

+56
-4
lines changed

aws/lambda/benchmark_regression_summary_report/common/config_model.py

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
from __future__ import annotations
22

33
import json
4-
from dataclasses import dataclass, field
4+
import requests
5+
from dataclasses import dataclass, field, fields
56
from datetime import timedelta
6-
from typing import Any, Dict, Literal, Optional
7+
from typing import Any, ClassVar, Dict, Literal, Optional, Type
78

89
from jinja2 import Environment, meta, Template
910

@@ -152,16 +153,66 @@ def is_violation(self, value: float, baseline: float) -> bool:
152153

153154
raise ValueError(f"Unknown condition: {self.condition}")
154155

156+
class BaseNotificationConfig:
157+
# every subclass must override this
158+
type_tag: ClassVar[str]
159+
160+
@classmethod
161+
def from_dict(cls: Type[T], d: Dict[str, Any]) -> T:
162+
# pick only known fields for this dataclass
163+
kwargs = {f.name: d.get(f.name) for f in fields(cls)}
164+
return cls(**kwargs) # type: ignore
165+
166+
@classmethod
167+
def matches(cls, d: Dict[str, Any]) -> bool:
168+
return d.get("type") == cls.type_tag
169+
170+
171+
@dataclass
172+
class GitHubNotificationConfig(BaseNotificationConfig):
173+
type: str = "github"
174+
repo: str = ""
175+
issue_number: str = ""
176+
type_tag: ClassVar[str] = "github"
177+
178+
def create_github_comment(self, body: str, github_token: str) -> Dict[str, Any]:
179+
"""
180+
Create a new comment on a GitHub issue.
181+
Args:
182+
notification_config: dict with keys:
183+
- type: must be "github"
184+
- repo: "owner/repo"
185+
- issue: issue number (string or int)
186+
body: text of the comment
187+
token: GitHub personal access token or GitHub Actions token
188+
189+
Returns:
190+
The GitHub API response as a dict (JSON).
191+
"""
192+
url = f"https://api.github.com/repos/{self.repo}/issues/{self.issue_number}/comments"
193+
headers = {
194+
"Authorization": f"token {github_token}",
195+
"Accept": "application/vnd.github+json",
196+
"User-Agent": "bench-reporter/1.0",
197+
}
198+
resp = requests.post(url, headers=headers, json={"body": body})
199+
resp.raise_for_status()
200+
return resp.json()
201+
155202

156203
@dataclass
157204
class Policy:
158205
frequency: Frequency
159206
range: RangeConfig
160207
metrics: Dict[str, RegressionPolicy]
161208

162-
# TODO(elainewy): add notification config
163209
notification_config: Optional[Dict[str, Any]] = None
164210

211+
def get_github_notification_config(self) -> Optional[GitHubNotificationConfig]:
212+
if not self.notification_config:
213+
return None
214+
return notification_from_dict(self.notification_config) # type: ignore
215+
165216

166217
# -------- Top-level benchmark regression config --------
167218
@dataclass

aws/lambda/benchmark_regression_summary_report/lambda_function.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,8 @@ def get_baseline(self, config: BenchmarkConfig, end_time: dt.datetime):
211211
)
212212

213213
logger.info(
214-
"found %s # of data, with time range %s",
214+
"[%s] found %s # of data, with time range %s",
215+
config.id,
215216
len(raw_data.time_series),
216217
raw_data.time_range,
217218
)

0 commit comments

Comments
 (0)