Skip to content

Commit 3e0c545

Browse files
authored
Add GitHub PR diff context to changelog (#94)
* Include GitHub PR diffs in changelog generation * Add API version header to GitHub diff requests
1 parent ed6b3df commit 3e0c545

File tree

2 files changed

+53
-7
lines changed

2 files changed

+53
-7
lines changed

github.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from datetime import datetime, timedelta
33
from functools import lru_cache
44
from typing import Any, Dict, List
5+
import requests
56

67
from dotenv import load_dotenv
78
from gql import Client, gql
@@ -18,6 +19,14 @@
1819
)
1920
client = Client(transport=transport, fetch_schema_from_transport=True)
2021

22+
# headers used for REST API requests
23+
rest_headers = {
24+
"Authorization": f"bearer {token}",
25+
"Accept": "application/vnd.github.v3.diff",
26+
# Use the latest stable REST API version
27+
"X-GitHub-Api-Version": "2022-11-28",
28+
}
29+
2130

2231
@lru_cache(maxsize=1)
2332
def get_repo_ids():
@@ -253,3 +262,11 @@ def get_prs_with_changes_requested_by_reviewer():
253262
reviewer = review["author"]["login"]
254263
cr_prs.setdefault(reviewer, []).append(pr)
255264
return cr_prs
265+
266+
267+
def get_pr_diff(owner: str, repo: str, number: int) -> str:
268+
"""Return the diff for a pull request."""
269+
url = f"https://api.github.com/repos/{owner}/{repo}/pulls/{number}"
270+
resp = requests.get(url, headers=rest_headers)
271+
resp.raise_for_status()
272+
return resp.text

jobs.py

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from datetime import datetime, timezone
55

66
import requests
7+
import re
78
import schedule
89
from dotenv import load_dotenv
910

@@ -12,6 +13,7 @@
1213
from github import (
1314
get_prs_waiting_for_review_by_reviewer,
1415
get_prs_with_changes_requested_by_reviewer,
16+
get_pr_diff,
1517
)
1618
from linear.issues import (
1719
get_completed_issues,
@@ -64,6 +66,28 @@ def get_slack_markdown_by_linear_username(username):
6466
return "No Assignee"
6567

6668

69+
def _get_pr_diffs(issue):
70+
"""Return a list of diffs for PRs linked in the issue attachments."""
71+
diffs = []
72+
for attachment in issue.get("attachments", {}).get("nodes", []):
73+
metadata = attachment.get("metadata", {})
74+
url = metadata.get("url")
75+
if not url:
76+
continue
77+
match = re.search(r"github.com/([^/]+)/([^/]+)/pull/(\d+)", url)
78+
if not match:
79+
continue
80+
owner, repo, number = match.groups()
81+
try:
82+
diff = get_pr_diff(owner, repo, int(number))
83+
diffs.append(diff)
84+
except Exception as e: # pragma: no cover - network errors are ignored
85+
logging.error(
86+
"Failed to fetch diff for %s/%s#%s: %s", owner, repo, number, e
87+
)
88+
return diffs
89+
90+
6791
@with_retries
6892
def post_priority_bugs():
6993
config = load_config()
@@ -371,13 +395,17 @@ def post_weekly_changelog():
371395
comments = " ".join(
372396
c.get("body", "") for c in issue.get("comments", {}).get("nodes", [])
373397
)
374-
chunks.append(
375-
f"ID: {issue['id']}\n"
376-
f"Title: {issue['title']}\n"
377-
f"Platform: {issue.get('platform', '')}\n"
378-
f"Description: {desc}\n"
379-
f"Comments: {comments}"
380-
)
398+
diffs = _get_pr_diffs(issue)
399+
chunk_parts = [
400+
f"ID: {issue['id']}",
401+
f"Title: {issue['title']}",
402+
f"Platform: {issue.get('platform', '')}",
403+
f"Description: {desc}",
404+
f"Comments: {comments}",
405+
]
406+
if diffs:
407+
chunk_parts.append("Diff:\n" + "\n".join(diffs))
408+
chunks.append("\n".join(chunk_parts))
381409

382410
instructions = (
383411
"Create a short customer-facing changelog from the provided issues. "
@@ -386,6 +414,7 @@ def post_weekly_changelog():
386414
"List each change as a short sentence with no markdown or bullet characters. "
387415
"Ignore technical tasks, internal changes, and unfinished work. "
388416
"Ensure each change appears only once in the changelog. "
417+
"When a chunk includes a 'Diff:' section, use that diff as additional context. "
389418
"Return a JSON object with keys 'New Features', 'Bug Fixes', and 'Improvements'. "
390419
"Each item should be an object with fields 'id' (the issue id)"
391420
"and 'summary' (the changelog text)."

0 commit comments

Comments
 (0)