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)
| Last Activity |
Author |
+Reviewers |
Repo |
Draft? |
Title |
@@ -32,6 +33,7 @@ td.bot {color: gray; font-style:italic}
| {{pr.updated_human}} |
{{pr.author}} |
+ {{pr.reviewers}} |
{{pr.repo}} |
{{pr.is_draft}} |
{{pr.title}} |
@@ -39,5 +41,33 @@ td.bot {color: gray; font-style:italic}
{% endfor %}
+
+
+
+This time, by reviewer
+
+
+
+| Reviewer |
+Last Activity |
+Author |
+Repo |
+Title |
+
+
+
+
+{% for pr in reviewer_prs %}
+
+ | {{pr.reviewer}} |
+ {{pr.updated_human}} |
+ {{pr.author}} |
+ {{pr.repo}} |
+ {{pr.title}} |
+
+{% endfor %}
+
+
+
\ No newline at end of file