Since we've run a script to replace labels with types on the open issues (e.g. label 'bug' → type 'Bug'), and those labels are deprecated, the script is updated to deal with issue types only. Other changes: - only get top-100 search results for each section since we only look at top-50 anyway: this way we don't need to deal with rate limiting, and the entire script runs way faster when it doesn't need to fetch 1000+ bugs - subtract the "-1" reactions from the "+1" reactions on a given issue to give a slightly more accurate picture in the overall ranking (this can further be improved by adding the distinct heart reactions but we'll leave that for another day) - only output the issues with a score > 0 - use Typer's built-in error handling for a missing argument - since we're only dealing with types and not labels now, remove the handling of potentially duplicate issues in the search results per section - make `Tracking` its own section since this issue type exists now - remove the `unlabeled` section with issues of no type since all the open issues have a type now and we intend to keep it that way for the sake of these and other stats (and also because GitHub's REST API has caught up with types but not with `no:type`) - replace pygithub and custom classes with requests directly to the GitHub API and plain data structures for a lighter footprint - spell out the date of the update in the resulting text to avoid the ambiguity (10/6 → October 06). The way the script is invoked has not been changed. Example run: ``` *Updated on December 08, 2025 06:57 AM (EST)* ## Features 1. https://github.com/zed-industries/zed/issues/11473 (679 👍) 2. https://github.com/zed-industries/zed/issues/4642 (674 👍) 3. https://github.com/zed-industries/zed/issues/10910 (638 👍) 4. https://github.com/zed-industries/zed/issues/8279 (592 👍) 5. https://github.com/zed-industries/zed/issues/5242 (581 👍) 6. https://github.com/zed-industries/zed/issues/4355 (552 👍) 7. https://github.com/zed-industries/zed/issues/15968 (453 👍) 8. https://github.com/zed-industries/zed/issues/4930 (357 👍) 9. https://github.com/zed-industries/zed/issues/5066 (345 👍) 10. https://github.com/zed-industries/zed/issues/5120 (312 👍) 11. https://github.com/zed-industries/zed/issues/7450 (310 👍) 12. https://github.com/zed-industries/zed/issues/14801 (291 👍) 13. https://github.com/zed-industries/zed/issues/10696 (276 👍) 14. https://github.com/zed-industries/zed/issues/16965 (258 👍) 15. https://github.com/zed-industries/zed/issues/4688 (231 👍) 16. https://github.com/zed-industries/zed/issues/4943 (228 👍) 17. https://github.com/zed-industries/zed/issues/9459 (223 👍) 18. https://github.com/zed-industries/zed/issues/21538 (223 👍) 19. https://github.com/zed-industries/zed/issues/11889 (194 👍) 20. https://github.com/zed-industries/zed/issues/9721 (180 👍) 21. https://github.com/zed-industries/zed/issues/5039 (172 👍) 22. https://github.com/zed-industries/zed/issues/9662 (162 👍) 23. https://github.com/zed-industries/zed/issues/4888 (160 👍) 24. https://github.com/zed-industries/zed/issues/26823 (158 👍) 25. https://github.com/zed-industries/zed/issues/21208 (151 👍) 26. https://github.com/zed-industries/zed/issues/4991 (149 👍) 27. https://github.com/zed-industries/zed/issues/6722 (144 👍) 28. https://github.com/zed-industries/zed/issues/18490 (139 👍) 29. https://github.com/zed-industries/zed/issues/10647 (138 👍) 30. https://github.com/zed-industries/zed/issues/35803 (121 👍) 31. https://github.com/zed-industries/zed/issues/4808 (118 👍) 32. https://github.com/zed-industries/zed/issues/12406 (118 👍) 33. https://github.com/zed-industries/zed/issues/37074 (118 👍) 34. https://github.com/zed-industries/zed/issues/7121 (117 👍) 35. https://github.com/zed-industries/zed/issues/15098 (112 👍) 36. https://github.com/zed-industries/zed/issues/4867 (111 👍) 37. https://github.com/zed-industries/zed/issues/4751 (108 👍) 38. https://github.com/zed-industries/zed/issues/14473 (98 👍) 39. https://github.com/zed-industries/zed/issues/6754 (97 👍) 40. https://github.com/zed-industries/zed/issues/11138 (97 👍) 41. https://github.com/zed-industries/zed/issues/17455 (90 👍) 42. https://github.com/zed-industries/zed/issues/9922 (89 👍) 43. https://github.com/zed-industries/zed/issues/4504 (87 👍) 44. https://github.com/zed-industries/zed/issues/17353 (85 👍) 45. https://github.com/zed-industries/zed/issues/4663 (82 👍) 46. https://github.com/zed-industries/zed/issues/12039 (79 👍) 47. https://github.com/zed-industries/zed/issues/11107 (75 👍) 48. https://github.com/zed-industries/zed/issues/11565 (73 👍) 49. https://github.com/zed-industries/zed/issues/22373 (72 👍) 50. https://github.com/zed-industries/zed/issues/11023 (71 👍) ## Bugs 1. https://github.com/zed-industries/zed/issues/7992 (457 👍) 2. https://github.com/zed-industries/zed/issues/12589 (113 👍) 3. https://github.com/zed-industries/zed/issues/12176 (105 👍) 4. https://github.com/zed-industries/zed/issues/14053 (96 👍) 5. https://github.com/zed-industries/zed/issues/18698 (90 👍) 6. https://github.com/zed-industries/zed/issues/8043 (73 👍) 7. https://github.com/zed-industries/zed/issues/7465 (65 👍) 8. https://github.com/zed-industries/zed/issues/9403 (56 👍) 9. https://github.com/zed-industries/zed/issues/9789 (55 👍) 10. https://github.com/zed-industries/zed/issues/30313 (52 👍) 11. https://github.com/zed-industries/zed/issues/13564 (47 👍) 12. https://github.com/zed-industries/zed/issues/18673 (47 👍) 13. https://github.com/zed-industries/zed/issues/43025 (44 👍) 14. https://github.com/zed-industries/zed/issues/15166 (43 👍) 15. https://github.com/zed-industries/zed/issues/14074 (41 👍) 16. https://github.com/zed-industries/zed/issues/38109 (39 👍) 17. https://github.com/zed-industries/zed/issues/21076 (38 👍) 18. https://github.com/zed-industries/zed/issues/32792 (38 👍) 19. https://github.com/zed-industries/zed/issues/26875 (36 👍) 20. https://github.com/zed-industries/zed/issues/21146 (35 👍) 21. https://github.com/zed-industries/zed/issues/39163 (35 👍) 22. https://github.com/zed-industries/zed/issues/13838 (32 👍) 23. https://github.com/zed-industries/zed/issues/16727 (32 👍) 24. https://github.com/zed-industries/zed/issues/9057 (31 👍) 25. https://github.com/zed-industries/zed/issues/38151 (31 👍) 26. https://github.com/zed-industries/zed/issues/38750 (30 👍) 27. https://github.com/zed-industries/zed/issues/8352 (29 👍) 28. https://github.com/zed-industries/zed/issues/11744 (29 👍) 29. https://github.com/zed-industries/zed/issues/20559 (29 👍) 30. https://github.com/zed-industries/zed/issues/23640 (29 👍) 31. https://github.com/zed-industries/zed/issues/11104 (27 👍) 32. https://github.com/zed-industries/zed/issues/13461 (27 👍) 33. https://github.com/zed-industries/zed/issues/13286 (25 👍) 34. https://github.com/zed-industries/zed/issues/29962 (25 👍) 35. https://github.com/zed-industries/zed/issues/14833 (23 👍) 36. https://github.com/zed-industries/zed/issues/15409 (23 👍) 37. https://github.com/zed-industries/zed/issues/11127 (22 👍) 38. https://github.com/zed-industries/zed/issues/12835 (22 👍) 39. https://github.com/zed-industries/zed/issues/31351 (22 👍) 40. https://github.com/zed-industries/zed/issues/33942 (22 👍) 41. https://github.com/zed-industries/zed/issues/7086 (21 👍) 42. https://github.com/zed-industries/zed/issues/13176 (20 👍) 43. https://github.com/zed-industries/zed/issues/14222 (20 👍) 44. https://github.com/zed-industries/zed/issues/29757 (20 👍) 45. https://github.com/zed-industries/zed/issues/35122 (20 👍) 46. https://github.com/zed-industries/zed/issues/29807 (19 👍) 47. https://github.com/zed-industries/zed/issues/4701 (18 👍) 48. https://github.com/zed-industries/zed/issues/35770 (18 👍) 49. https://github.com/zed-industries/zed/issues/37734 (18 👍) 50. https://github.com/zed-industries/zed/issues/4434 (17 👍) ## Tracking issues 1. https://github.com/zed-industries/zed/issues/7808 (298 👍) 2. https://github.com/zed-industries/zed/issues/24878 (101 👍) 3. https://github.com/zed-industries/zed/issues/7371 (60 👍) 4. https://github.com/zed-industries/zed/issues/26916 (51 👍) 5. https://github.com/zed-industries/zed/issues/31102 (41 👍) 6. https://github.com/zed-industries/zed/issues/25469 (30 👍) 7. https://github.com/zed-industries/zed/issues/10906 (18 👍) 8. https://github.com/zed-industries/zed/issues/9778 (11 👍) 9. https://github.com/zed-industries/zed/issues/23930 (10 👍) 10. https://github.com/zed-industries/zed/issues/23914 (8 👍) 11. https://github.com/zed-industries/zed/issues/18078 (7 👍) 12. https://github.com/zed-industries/zed/issues/25560 (6 👍) ## Crashes 1. https://github.com/zed-industries/zed/issues/13190 (33 👍) 2. https://github.com/zed-industries/zed/issues/32318 (15 👍) 3. https://github.com/zed-industries/zed/issues/39097 (14 👍) 4. https://github.com/zed-industries/zed/issues/31149 (11 👍) 5. https://github.com/zed-industries/zed/issues/36139 (10 👍) 6. https://github.com/zed-industries/zed/issues/39890 (10 👍) 7. https://github.com/zed-industries/zed/issues/16120 (9 👍) 8. https://github.com/zed-industries/zed/issues/20970 (5 👍) 9. https://github.com/zed-industries/zed/issues/28385 (5 👍) 10. https://github.com/zed-industries/zed/issues/27270 (4 👍) 11. https://github.com/zed-industries/zed/issues/30466 (4 👍) 12. https://github.com/zed-industries/zed/issues/37593 (4 👍) 13. https://github.com/zed-industries/zed/issues/27751 (3 👍) 14. https://github.com/zed-industries/zed/issues/29467 (3 👍) 15. https://github.com/zed-industries/zed/issues/39806 (3 👍) 16. https://github.com/zed-industries/zed/issues/40998 (3 👍) 17. https://github.com/zed-industries/zed/issues/10992 (2 👍) 18. https://github.com/zed-industries/zed/issues/31461 (2 👍) 19. https://github.com/zed-industries/zed/issues/37291 (2 👍) 20. https://github.com/zed-industries/zed/issues/38275 (2 👍) 21. https://github.com/zed-industries/zed/issues/43547 (2 👍) 22. https://github.com/zed-industries/zed/issues/20014 (1 👍) 23. https://github.com/zed-industries/zed/issues/30993 (1 👍) 24. https://github.com/zed-industries/zed/issues/31498 (1 👍) 25. https://github.com/zed-industries/zed/issues/31829 (1 👍) 26. https://github.com/zed-industries/zed/issues/32280 (1 👍) 27. https://github.com/zed-industries/zed/issues/36036 (1 👍) 28. https://github.com/zed-industries/zed/issues/37918 (1 👍) 29. https://github.com/zed-industries/zed/issues/39269 (1 👍) 30. https://github.com/zed-industries/zed/issues/42825 (1 👍) 31. https://github.com/zed-industries/zed/issues/43522 (1 👍) 32. https://github.com/zed-industries/zed/issues/43774 (1 👍) ## Windows 1. https://github.com/zed-industries/zed/issues/12288 (36 👍) 2. https://github.com/zed-industries/zed/issues/20559 (29 👍) 3. https://github.com/zed-industries/zed/issues/12013 (15 👍) 4. https://github.com/zed-industries/zed/issues/38682 (8 👍) 5. https://github.com/zed-industries/zed/issues/36241 (7 👍) 6. https://github.com/zed-industries/zed/issues/28497 (3 👍) 7. https://github.com/zed-industries/zed/issues/33748 (3 👍) 8. https://github.com/zed-industries/zed/issues/38348 (3 👍) 9. https://github.com/zed-industries/zed/issues/41649 (3 👍) 10. https://github.com/zed-industries/zed/issues/41734 (3 👍) 11. https://github.com/zed-industries/zed/issues/42873 (3 👍) 12. https://github.com/zed-industries/zed/issues/36318 (2 👍) 13. https://github.com/zed-industries/zed/issues/38886 (2 👍) 14. https://github.com/zed-industries/zed/issues/39038 (2 👍) 15. https://github.com/zed-industries/zed/issues/39056 (2 👍) 16. https://github.com/zed-industries/zed/issues/39189 (2 👍) 17. https://github.com/zed-industries/zed/issues/39473 (2 👍) 18. https://github.com/zed-industries/zed/issues/39764 (2 👍) 19. https://github.com/zed-industries/zed/issues/40430 (2 👍) 20. https://github.com/zed-industries/zed/issues/43051 (2 👍) 21. https://github.com/zed-industries/zed/issues/18765 (1 👍) 22. https://github.com/zed-industries/zed/issues/35174 (1 👍) 23. https://github.com/zed-industries/zed/issues/35958 (1 👍) 24. https://github.com/zed-industries/zed/issues/36193 (1 👍) 25. https://github.com/zed-industries/zed/issues/36849 (1 👍) 26. https://github.com/zed-industries/zed/issues/38760 (1 👍) 27. https://github.com/zed-industries/zed/issues/39346 (1 👍) 28. https://github.com/zed-industries/zed/issues/39435 (1 👍) 29. https://github.com/zed-industries/zed/issues/39453 (1 👍) 30. https://github.com/zed-industries/zed/issues/39927 (1 👍) 31. https://github.com/zed-industries/zed/issues/40209 (1 👍) 32. https://github.com/zed-industries/zed/issues/40277 (1 👍) 33. https://github.com/zed-industries/zed/issues/40370 (1 👍) 34. https://github.com/zed-industries/zed/issues/40392 (1 👍) 35. https://github.com/zed-industries/zed/issues/40475 (1 👍) 36. https://github.com/zed-industries/zed/issues/40585 (1 👍) 37. https://github.com/zed-industries/zed/issues/40647 (1 👍) 38. https://github.com/zed-industries/zed/issues/40954 (1 👍) 39. https://github.com/zed-industries/zed/issues/42050 (1 👍) 40. https://github.com/zed-industries/zed/issues/42366 (1 👍) 41. https://github.com/zed-industries/zed/issues/42731 (1 👍) 42. https://github.com/zed-industries/zed/issues/42861 (1 👍) 43. https://github.com/zed-industries/zed/issues/43522 (1 👍) ## Meta issues 1. https://github.com/zed-industries/zed/issues/24804 (10 👍) 2. https://github.com/zed-industries/zed/issues/36730 (3 👍) ``` Release Notes: - N/A --------- Co-authored-by: Joseph T. Lyons <JosephTLyons@gmail.com>
162 lines
4.9 KiB
Python
162 lines
4.9 KiB
Python
import os
|
|
from datetime import date, datetime, timedelta
|
|
from typing import Any, Optional
|
|
|
|
import requests
|
|
import typer
|
|
from pytz import timezone
|
|
from typer import Typer
|
|
|
|
app: Typer = typer.Typer()
|
|
|
|
AMERICA_NEW_YORK_TIMEZONE = "America/New_York"
|
|
DATETIME_FORMAT: str = "%B %d, %Y %I:%M %p"
|
|
ISSUES_PER_SECTION: int = 50
|
|
ISSUES_TO_FETCH: int = 100
|
|
|
|
REPO_OWNER = "zed-industries"
|
|
REPO_NAME = "zed"
|
|
GITHUB_API_BASE_URL = "https://api.github.com"
|
|
|
|
EXCLUDE_LABEL = "ignore top-ranking issues"
|
|
|
|
|
|
@app.command()
|
|
def main(
|
|
github_token: Optional[str] = None,
|
|
issue_reference_number: Optional[int] = None,
|
|
query_day_interval: Optional[int] = None,
|
|
) -> None:
|
|
script_start_time: datetime = datetime.now()
|
|
start_date: date | None = None
|
|
|
|
if query_day_interval:
|
|
tz = timezone(AMERICA_NEW_YORK_TIMEZONE)
|
|
today = datetime.now(tz).date()
|
|
start_date = today - timedelta(days=query_day_interval)
|
|
|
|
# GitHub Workflow will pass in the token as an argument,
|
|
# but we can place it in our env when running the script locally, for convenience
|
|
token = github_token or os.getenv("GITHUB_ACCESS_TOKEN")
|
|
if not token:
|
|
raise typer.BadParameter(
|
|
"GitHub token is required. Pass --github-token or set GITHUB_ACCESS_TOKEN env var."
|
|
)
|
|
|
|
headers = {
|
|
"Authorization": f"token {token}",
|
|
"Accept": "application/vnd.github+json",
|
|
}
|
|
|
|
section_to_issues = get_section_to_issues(headers, start_date)
|
|
issue_text: str = create_issue_text(section_to_issues)
|
|
|
|
if issue_reference_number:
|
|
update_reference_issue(headers, issue_reference_number, issue_text)
|
|
else:
|
|
print(issue_text)
|
|
|
|
run_duration: timedelta = datetime.now() - script_start_time
|
|
print(f"Ran for {run_duration}")
|
|
|
|
|
|
def get_section_to_issues(
|
|
headers: dict[str, str], start_date: date | None = None
|
|
) -> dict[str, list[dict[str, Any]]]:
|
|
"""Fetch top-ranked issues for each section from GitHub."""
|
|
|
|
section_filters = {
|
|
"Bugs": "type:Bug",
|
|
"Crashes": "type:Crash",
|
|
"Features": "type:Feature",
|
|
"Tracking issues": "type:Tracking",
|
|
"Meta issues": "type:Meta",
|
|
"Windows": 'label:"platform:windows"',
|
|
}
|
|
|
|
section_to_issues: dict[str, list[dict[str, Any]]] = {}
|
|
for section, search_qualifier in section_filters.items():
|
|
query_parts = [
|
|
f"repo:{REPO_OWNER}/{REPO_NAME}",
|
|
"is:issue",
|
|
"is:open",
|
|
f'-label:"{EXCLUDE_LABEL}"',
|
|
search_qualifier,
|
|
]
|
|
|
|
if start_date:
|
|
query_parts.append(f"created:<={start_date.strftime('%Y-%m-%d')}")
|
|
|
|
query = " ".join(query_parts)
|
|
url = f"{GITHUB_API_BASE_URL}/search/issues"
|
|
params = {
|
|
"q": query,
|
|
"sort": "reactions-+1",
|
|
"order": "desc",
|
|
"per_page": ISSUES_TO_FETCH, # this will work as long as it's ≤ 100
|
|
}
|
|
|
|
# we are only fetching one page on purpose
|
|
response = requests.get(url, headers=headers, params=params)
|
|
response.raise_for_status()
|
|
items = response.json()["items"]
|
|
|
|
issues: list[dict[str, Any]] = []
|
|
for item in items:
|
|
reactions = item["reactions"]
|
|
score = reactions["+1"] - reactions["-1"]
|
|
if score > 0:
|
|
issues.append({
|
|
"url": item["html_url"],
|
|
"score": score,
|
|
"created_at": item["created_at"],
|
|
})
|
|
|
|
if not issues:
|
|
continue
|
|
|
|
issues.sort(key=lambda x: (-x["score"], x["created_at"]))
|
|
section_to_issues[section] = issues[:ISSUES_PER_SECTION]
|
|
|
|
# Sort sections by total score (highest total first)
|
|
section_to_issues = dict(
|
|
sorted(
|
|
section_to_issues.items(),
|
|
key=lambda item: sum(issue["score"] for issue in item[1]),
|
|
reverse=True,
|
|
)
|
|
)
|
|
return section_to_issues
|
|
|
|
|
|
def update_reference_issue(
|
|
headers: dict[str, str], issue_number: int, body: str
|
|
) -> None:
|
|
url = f"{GITHUB_API_BASE_URL}/repos/{REPO_OWNER}/{REPO_NAME}/issues/{issue_number}"
|
|
response = requests.patch(url, headers=headers, json={"body": body})
|
|
response.raise_for_status()
|
|
|
|
|
|
def create_issue_text(section_to_issues: dict[str, list[dict[str, Any]]]) -> str:
|
|
tz = timezone(AMERICA_NEW_YORK_TIMEZONE)
|
|
current_datetime: str = datetime.now(tz).strftime(f"{DATETIME_FORMAT} (%Z)")
|
|
|
|
lines: list[str] = [f"*Updated on {current_datetime}*"]
|
|
|
|
for section, issues in section_to_issues.items():
|
|
lines.append(f"\n## {section}\n")
|
|
for i, issue in enumerate(issues):
|
|
lines.append(f"{i + 1}. {issue['url']} ({issue['score']} :thumbsup:)")
|
|
|
|
lines.append("\n---\n")
|
|
lines.append(
|
|
"*For details on how this issue is generated, "
|
|
"[see the script](https://github.com/zed-industries/zed/blob/main/script/update_top_ranking_issues/main.py)*"
|
|
)
|
|
|
|
return "\n".join(lines)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
app()
|