Skip to content

Commit a57668b

Browse files
Adding note generator
1 parent 9a4b11c commit a57668b

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed

code/tests/tools/generate-note.py

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import argparse
2+
import requests
3+
import os
4+
from datetime import datetime
5+
6+
GITHUB_API = "https://api.github.com"
7+
8+
def fetch_milestone_issues(owner, repo, milestone_title, token=None):
9+
headers = {"Authorization": f"token {token}"} if token else {}
10+
11+
# Find milestone ID
12+
milestone_url = f"{GITHUB_API}/repos/{owner}/{repo}/milestones"
13+
milestone_resp = requests.get(milestone_url, headers=headers).json()
14+
milestone_id = next((m['number'] for m in milestone_resp if m['title'] == milestone_title), None)
15+
if milestone_id is None:
16+
raise ValueError(f"Milestone '{milestone_title}' not found.")
17+
18+
# Fetch issues
19+
issues_url = f"{GITHUB_API}/repos/{owner}/{repo}/issues"
20+
issues = []
21+
page = 1
22+
while True:
23+
params = {
24+
"milestone": milestone_id,
25+
"state": "closed",
26+
"per_page": 100,
27+
"page": page
28+
}
29+
page_issues = requests.get(issues_url, headers=headers, params=params).json()
30+
if not page_issues:
31+
break
32+
issues.extend(page_issues)
33+
page += 1
34+
35+
return issues
36+
37+
def group_issues_by_label(issues):
38+
grouped = {"feature": [], "bug": [], "enhancement": [], "other": []}
39+
for issue in issues:
40+
labels = [label["name"] for label in issue["labels"]]
41+
added = False
42+
for key in grouped:
43+
if key in labels:
44+
grouped[key].append(issue)
45+
added = True
46+
break
47+
if not added:
48+
grouped["other"].append(issue)
49+
return grouped
50+
51+
def fetch_repo_description(owner, repo, token=None):
52+
headers = {"Authorization": f"token {token}"} if token else {}
53+
url = f"{GITHUB_API}/repos/{owner}/{repo}"
54+
resp = requests.get(url, headers=headers).json()
55+
return resp.get("description", "")
56+
57+
def generate_markdown(milestone, grouped_issues, repo_description=""):
58+
today = datetime.today().strftime("%Y-%m-%d")
59+
output = [f"# 📦 Release Notes for `{milestone}`", f"_Date: {today}_"]
60+
61+
if repo_description:
62+
output.append(f"\n> {repo_description}\n")
63+
64+
output.append(f"\n## [{milestone}] – {today}")
65+
66+
if grouped_issues["feature"]:
67+
output.append("\n### 🚀 Features")
68+
for issue in grouped_issues["feature"]:
69+
output.append(f"- {issue['title']} (#{issue['number']})")
70+
71+
if grouped_issues["bug"]:
72+
output.append("\n### 🐞 Bug Fixes")
73+
for issue in grouped_issues["bug"]:
74+
output.append(f"- {issue['title']} (#{issue['number']})")
75+
76+
if grouped_issues["enhancement"]:
77+
output.append("\n### 🛠 Enhancements")
78+
for issue in grouped_issues["enhancement"]:
79+
output.append(f"- {issue['title']} (#{issue['number']})")
80+
81+
if grouped_issues["other"]:
82+
output.append("\n### 📦 Other")
83+
for issue in grouped_issues["other"]:
84+
output.append(f"- {issue['title']} (#{issue['number']})")
85+
86+
# 🧩 WrapDB Git Definition
87+
output.append("\n### 🧩 WrapDB Git Definition")
88+
output.append("```ini")
89+
output.append("# ======================")
90+
output.append("# Git Wrap package definition")
91+
output.append("# ======================")
92+
output.append("[wrap-git]")
93+
output.append("url = https://github.com/fossillogic/fossil-test.git")
94+
output.append(f"revision = v{milestone}")
95+
output.append("")
96+
output.append("[provide]")
97+
output.append("fossil-test = fossil_test_dep")
98+
output.append("```")
99+
100+
return "\n".join(output)
101+
102+
def save_to_file(content, filename):
103+
with open(filename, "a") as f:
104+
f.write("\n\n" + content.strip() + "\n")
105+
106+
def main():
107+
parser = argparse.ArgumentParser(description="Pizza Changelog and Release Note Generator")
108+
parser.add_argument("--owner", required=True, help="GitHub repository owner")
109+
parser.add_argument("--repo", required=True, help="GitHub repository name")
110+
parser.add_argument("--milestone", required=True, help="Milestone title")
111+
parser.add_argument("--token", help="GitHub personal access token (optional)")
112+
parser.add_argument("--out", default="CHANGELOG.md", help="Output changelog file")
113+
parser.add_argument("--release-file", action="store_true", help="Also save to release_notes_<milestone>.md")
114+
args = parser.parse_args()
115+
116+
issues = fetch_milestone_issues(args.owner, args.repo, args.milestone, args.token)
117+
grouped = group_issues_by_label(issues)
118+
markdown = generate_markdown(args.milestone, grouped, fetch_repo_description(args.owner, args.repo, args.token))
119+
120+
save_to_file(markdown, args.out)
121+
print(f"✅ Changelog updated: {args.out}")
122+
123+
if args.release_file:
124+
rel_file = f"release_notes_{args.milestone.replace('.', '_')}.md"
125+
save_to_file(markdown, rel_file)
126+
print(f"📝 Release note saved: {rel_file}")
127+
128+
if __name__ == "__main__":
129+
main()

0 commit comments

Comments
 (0)