From 2f0be9d82d587a8949d6ec5c01d40832190708c2 Mon Sep 17 00:00:00 2001 From: Melissa DeLucchi Date: Tue, 2 Dec 2025 15:51:02 -0500 Subject: [PATCH] Add reviewers to display --- .../lsdb_interrupts/github_api.py | 4 +- .../lsdb_interrupts/open_prs.py | 74 ++++++++++++++----- templates/pr_list.jinja | 34 ++++++++- 3 files changed, 88 insertions(+), 24 deletions(-) diff --git a/src/lf_workflow_dash/lsdb_interrupts/github_api.py b/src/lf_workflow_dash/lsdb_interrupts/github_api.py index 5fb41cc2d4d..bf13e07414a 100644 --- a/src/lf_workflow_dash/lsdb_interrupts/github_api.py +++ b/src/lf_workflow_dash/lsdb_interrupts/github_api.py @@ -71,7 +71,7 @@ def get_org_repos(org: str, token: str) -> List[str]: url = f"{GITHUB_API_BASE}/orgs/{org}/repos?per_page=100" repos_data = paginate_github_api(session, url) repos = [repo["name"] for repo in repos_data if not repo["archived"]] - print(f"Found {len(repos)} repositories.") + print(f" Found {len(repos)} repositories.") return repos @@ -83,7 +83,7 @@ def get_lsdb_repos(token: str) -> List[str]: repos_data = paginate_github_api(session, url) repos = [repo["name"] for repo in repos_data] repos = [repo for repo in repos if "hats" in repo or "lsdb" in repo] - print(f"Found {len(repos)} repositories.") + print(f" Found {len(repos)} repositories.") return repos diff --git a/src/lf_workflow_dash/lsdb_interrupts/open_prs.py b/src/lf_workflow_dash/lsdb_interrupts/open_prs.py index 2f69e7f7240..87010a9bc34 100644 --- a/src/lf_workflow_dash/lsdb_interrupts/open_prs.py +++ b/src/lf_workflow_dash/lsdb_interrupts/open_prs.py @@ -26,18 +26,28 @@ def get_open_prs(org: str, repos: List[str], token: str) -> List[Dict]: url = f"{GITHUB_API_BASE}/repos/{org}/{repo}/pulls?state=open&per_page=100" pr_data = paginate_github_api(session, url) - prs = [ - { - "number": pr["number"], - "title": pr["title"], - "author": pr["user"], - "updatedAt": pr["updated_at"], - "url": pr["html_url"], - "repo": repo, - "is_draft": pr["draft"], - } - for pr in pr_data - ] + prs = [] + for pr in pr_data: + author = pr["user"]["login"] if pr["user"] else "unknown" + + # Reviewers are not returned in the pull request list response. Make a new request. + url = f"{GITHUB_API_BASE}/repos/{org}/{repo}/pulls/{pr['number']}/reviews" + reviewers = paginate_github_api(session, url) + reviewers = set(person["user"]["login"] for person in reviewers) - set([author]) + list(reviewers).sort() + + prs.append( + { + "number": pr["number"], + "title": pr["title"], + "author": pr["user"], + "updatedAt": pr["updated_at"], + "url": pr["html_url"], + "repo": repo, + "is_draft": pr["draft"], + "reviewers": reviewers, + } + ) print(f" Found {len(prs)} pull requests.") all_prs.extend(prs) @@ -47,30 +57,56 @@ def get_open_prs(org: str, repos: List[str], token: str) -> List[Dict]: return all_prs -def write_html_prs(prs: List[Dict], html_file: str): +def write_html_prs(prs: List[Dict], html_file: str, page_title: str = "Pull Requests"): """Fill in the jinja template, using the prs found""" print(f"Writing HTML output to {html_file} ...") + prs.sort(key=lambda x: x["updatedAt"], reverse=True) now = datetime.now(timezone.utc) pr_summaries = [] + reviewer_summaries = [] for pr in prs: author = pr["author"]["login"] if pr["author"] else "unknown" + updated_at = get_humanized_updated_at(pr["updatedAt"], now) + tidy_title = pr["title"].replace("&", "&").replace("<", "<").replace(">", ">") pr_summaries.append( { - "updated_human": get_humanized_updated_at(pr["updatedAt"], now), + "updated_human": updated_at, "author": author, - "title": pr["title"].replace("&", "&").replace("<", "<").replace(">", ">"), + "title": tidy_title, "url": pr["url"], "repo": pr["repo"], "is_draft": "DRAFT" if pr["is_draft"] else "", "is_bot": author in ["dependabot[bot]", "Copilot"], + "reviewers": ", ".join(pr["reviewers"]), } ) + reviewer_summaries.extend( + [ + { + "updated_human": updated_at, + "author": author, + "title": tidy_title, + "url": pr["url"], + "repo": pr["repo"], + "reviewer": reviewer, + } + for reviewer in pr["reviewers"] + ] + ) + + reviewer_summaries.sort(key=lambda x: x["reviewer"]) environment = Environment(loader=FileSystemLoader("templates/")) template = environment.get_template("pr_list.jinja") + attributes = { + "page_title": page_title, + "all_prs": pr_summaries, + "reviewer_prs": reviewer_summaries, + "num_results": len(pr_summaries), + } with open(html_file, mode="w", encoding="utf-8") as results: - results.write(template.render({"all_prs": pr_summaries, "num_results": len(pr_summaries)})) + results.write(template.render(attributes)) print(f"HTML output written to {html_file}") @@ -78,13 +114,11 @@ def main(token): """Convenience method to do the work.""" repos = get_lsdb_repos(token) prs = get_open_prs("astronomy-commons", repos, token) - prs.sort(key=lambda x: x["updatedAt"], reverse=True) - write_html_prs(prs, "html/lsdb_prs.html") + write_html_prs(prs, "html/lsdb_prs.html", "LSDB PRs") repos = get_org_repos("lincc-frameworks", token) prs = get_open_prs("lincc-frameworks", repos, token) - prs.sort(key=lambda x: x["updatedAt"], reverse=True) - write_html_prs(prs, "html/lincc_prs.html") + write_html_prs(prs, "html/lincc_prs.html", "lincc-frameworks PRs") if __name__ == "__main__": diff --git a/templates/pr_list.jinja b/templates/pr_list.jinja index bd86e4f2ea3..d7be2219247 100644 --- a/templates/pr_list.jinja +++ b/templates/pr_list.jinja @@ -2,7 +2,7 @@ -Pull Requests +{{page_title}} -

Pull Requests ({{num_results}}) (most recent activity first)

+

{{page_title}} ({{num_results}}) (most recent activity first)

+ @@ -32,6 +33,7 @@ td.bot {color: gray; font-style:italic} {{pr.author}} + @@ -39,5 +41,33 @@ td.bot {color: gray; font-style:italic} {% endfor %}
Last Activity AuthorReviewers Repo Draft? Title
{{pr.updated_human}} {{pr.reviewers}} {{pr.repo}} {{pr.is_draft}} {{pr.title}}
+ +
+
+

This time, by reviewer

+ + + + + + + + + + + + +{% for pr in reviewer_prs %} + + + + + + + +{% endfor %} + +
ReviewerLast ActivityAuthorRepoTitle
{{pr.reviewer}}{{pr.updated_human}}{{pr.author}}{{pr.repo}}{{pr.title}}
+ \ No newline at end of file