-
Notifications
You must be signed in to change notification settings - Fork 373
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a script that generates a changelog from recent PRs and their lab…
…els (#1718) * Add a script that generates a changelog from recent PRs and their labels * Fix typo * Add emojis for all categories, and list commits oldest -> newest * Cleanup * py-format * Add option to include labels * py-format
- Loading branch information
Showing
3 changed files
with
178 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
#!/usr/bin/env python3 | ||
|
||
""" | ||
Summarizes recent PRs based on their GitHub labels. | ||
The result can be copy-pasted into CHANGELOG.md, though it often needs some manual editing too. | ||
""" | ||
|
||
import re | ||
import sys | ||
from typing import Any, List, Optional, Tuple | ||
|
||
import requests | ||
from git import Repo # pip install GitPython | ||
from tqdm import tqdm | ||
|
||
|
||
def get_github_token() -> str: | ||
import os | ||
|
||
token = os.environ.get("GH_ACCESS_TOKEN", "") | ||
if token != "": | ||
return token | ||
|
||
home_dir = os.path.expanduser("~") | ||
token_file = os.path.join(home_dir, ".githubtoken") | ||
|
||
try: | ||
with open(token_file, "r") as f: | ||
token = f.read().strip() | ||
return token | ||
except Exception: | ||
pass | ||
|
||
print("ERROR: expected a GitHub token in the environment variable GH_ACCESS_TOKEN or in ~/.githubtoken") | ||
sys.exit(1) | ||
|
||
|
||
OWNER = "rerun-io" | ||
REPO = "rerun" | ||
COMMIT_RANGE = "latest..HEAD" | ||
INCLUDE_LABELS = False # It adds quite a bit of visual noise | ||
|
||
|
||
def pr_title_labels(pr_number: int) -> Tuple[Optional[str], List[str]]: | ||
url = f"https://api.github.com/repos/{OWNER}/{REPO}/pulls/{pr_number}" | ||
gh_access_token = get_github_token() | ||
headers = {"Authorization": f"Token {gh_access_token}"} | ||
response = requests.get(url, headers=headers) | ||
json = response.json() | ||
|
||
# Check if the request was successful (status code 200) | ||
if response.status_code == 200: | ||
labels = [label["name"] for label in json["labels"]] | ||
return (json["title"], labels) | ||
else: | ||
print(f"ERROR: {response.status_code} - {json['message']}") | ||
return (None, []) | ||
|
||
|
||
def commit_title_pr_number(commit: Any) -> Tuple[str, Optional[int]]: | ||
match = re.match(r"(.*) \(#(\d+)\)", commit.summary) | ||
if match: | ||
return (str(match.group(1)), int(match.group(2))) | ||
else: | ||
return (commit.summary, None) | ||
|
||
|
||
def print_section(title: str, items: List[str]) -> None: | ||
if 0 < len(items): | ||
print(f"#### {title}") | ||
for line in items: | ||
print(f"- {line}") | ||
print() | ||
|
||
|
||
repo = Repo(".") | ||
commits = list(repo.iter_commits(COMMIT_RANGE)) | ||
commits.reverse() # Most recent last | ||
|
||
# Sections: | ||
analytics = [] | ||
enhancement = [] | ||
bugs = [] | ||
dev_experience = [] | ||
docs = [] | ||
examples = [] | ||
misc = [] | ||
performance = [] | ||
python = [] | ||
renderer = [] | ||
rfc = [] | ||
rust = [] | ||
ui = [] | ||
viewer = [] | ||
web = [] | ||
|
||
for commit in tqdm(commits, desc="Processing commits"): | ||
(title, pr_number) = commit_title_pr_number(commit) | ||
if pr_number is None: | ||
# Someone committed straight to main: | ||
summary = f"{title} [{commit.hexsha}](https://github.com/{OWNER}/{REPO}/commit/{commit.hexsha})" | ||
misc.append(summary) | ||
else: | ||
(pr_title, labels) = pr_title_labels(pr_number) | ||
title = pr_title or title # We prefer the PR title if available | ||
summary = f"{title} [#{pr_number}](https://github.com/{OWNER}/{REPO}/pull/{pr_number})" | ||
|
||
if INCLUDE_LABELS and 0 < len(labels): | ||
summary += f" ({', '.join(labels)})" | ||
|
||
added = False | ||
|
||
if labels == ["⛴ release"]: | ||
# Ignore release PRs | ||
continue | ||
|
||
# Some PRs can show up underm multiple sections: | ||
if "🐍 python API" in labels: | ||
python.append(summary) | ||
added = True | ||
if "🦀 rust SDK" in labels: | ||
rust.append(summary) | ||
added = True | ||
if "📊 analytics" in labels: | ||
analytics.append(summary) | ||
added = True | ||
|
||
if not added: | ||
# Put the remaining PRs under just one section: | ||
if "🪳 bug" in labels or "💣 crash" in labels: | ||
bugs.append(summary) | ||
elif "📉 performance" in labels: | ||
performance.append(summary) | ||
elif "examples" in labels: | ||
examples.append(summary) | ||
elif "📖 documentation" in labels: | ||
docs.append(summary) | ||
elif "ui" in labels: | ||
ui.append(summary) | ||
elif "📺 re_viewer" in labels: | ||
viewer.append(summary) | ||
elif "🔺 re_renderer" in labels: | ||
renderer.append(summary) | ||
elif "🕸️ web" in labels: | ||
web.append(summary) | ||
elif "enhancement" in labels: | ||
enhancement.append(summary) | ||
elif "🧑💻 dev experience" in labels: | ||
dev_experience.append(summary) | ||
elif "💬 discussion" in labels: | ||
rfc.append(summary) | ||
elif not added: | ||
misc.append(summary) | ||
|
||
print() | ||
# Most interesting first: | ||
print_section("🐍 Python SDK", python) | ||
print_section("🦀 Rust SDK", rust) | ||
print_section("🪳 Bug Fixes", bugs) | ||
print_section("🚀 Performance Improvements", performance) | ||
print_section("🧑🏫 Examples", examples) | ||
print_section("📚 Docs", docs) | ||
print_section("🖼 UI Improvements", ui) | ||
print_section("🤷♂️ Other Viewer Improvements", viewer) | ||
print_section("🕸️ Web", web) | ||
print_section("🎨 Renderer Improvements", renderer) | ||
print_section("✨ Other Enhancement", enhancement) | ||
print_section("📈 Analytics", analytics) | ||
print_section("🗣 Merged RFCs", rfc) | ||
print_section("🧑💻 Dev-experience", dev_experience) | ||
print_section("🤷♂️ Other", misc) |
58fde68
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.
Rust Benchmark
datastore/insert/batch/rects/insert
614660
ns/iter (± 2797
)617798
ns/iter (± 2294
)0.99
datastore/latest_at/batch/rects/query
1860
ns/iter (± 2
)1830
ns/iter (± 1
)1.02
datastore/latest_at/missing_components/primary
288
ns/iter (± 0
)289
ns/iter (± 0
)1.00
datastore/latest_at/missing_components/secondaries
462
ns/iter (± 0
)447
ns/iter (± 0
)1.03
datastore/range/batch/rects/query
152737
ns/iter (± 316
)153749
ns/iter (± 251
)0.99
mono_points_arrow/generate_message_bundles
47719562
ns/iter (± 1172319
)47092378
ns/iter (± 853262
)1.01
mono_points_arrow/generate_messages
125221480
ns/iter (± 1085920
)123513169
ns/iter (± 1380848
)1.01
mono_points_arrow/encode_log_msg
155424404
ns/iter (± 1007078
)157619842
ns/iter (± 1814858
)0.99
mono_points_arrow/encode_total
328100145
ns/iter (± 2593450
)329033469
ns/iter (± 1723866
)1.00
mono_points_arrow/decode_log_msg
179814536
ns/iter (± 880070
)180134730
ns/iter (± 875308
)1.00
mono_points_arrow/decode_message_bundles
54792433
ns/iter (± 768811
)53748777
ns/iter (± 782433
)1.02
mono_points_arrow/decode_total
228898481
ns/iter (± 1395282
)231988721
ns/iter (± 1345301
)0.99
batch_points_arrow/generate_message_bundles
285400
ns/iter (± 2281
)287678
ns/iter (± 874
)0.99
batch_points_arrow/generate_messages
6035
ns/iter (± 66
)6093
ns/iter (± 18
)0.99
batch_points_arrow/encode_log_msg
380886
ns/iter (± 2348
)392686
ns/iter (± 1010
)0.97
batch_points_arrow/encode_total
688488
ns/iter (± 5164
)708178
ns/iter (± 3015
)0.97
batch_points_arrow/decode_log_msg
358703
ns/iter (± 1400
)366401
ns/iter (± 1746
)0.98
batch_points_arrow/decode_message_bundles
1609
ns/iter (± 20
)1609
ns/iter (± 5
)1
batch_points_arrow/decode_total
363971
ns/iter (± 1491
)372919
ns/iter (± 1592
)0.98
arrow_mono_points/insert
6181458622
ns/iter (± 33632406
)6641633300
ns/iter (± 18770550
)0.93
arrow_mono_points/query
1804337
ns/iter (± 23690
)1929164
ns/iter (± 33196
)0.94
arrow_batch_points/insert
3122613
ns/iter (± 101923
)3323001
ns/iter (± 76848
)0.94
arrow_batch_points/query
15453
ns/iter (± 222
)15249
ns/iter (± 105
)1.01
arrow_batch_vecs/insert
43589
ns/iter (± 154
)44494
ns/iter (± 142
)0.98
arrow_batch_vecs/query
480922
ns/iter (± 1102
)480999
ns/iter (± 666
)1.00
tuid/Tuid::random
34
ns/iter (± 0
)34
ns/iter (± 0
)1
This comment was automatically generated by workflow using github-action-benchmark.