From 52f68f305752f28ad17cdca5b97b49f1ddeeb2fd Mon Sep 17 00:00:00 2001 From: jennyhickson <61183013+jennyhickson@users.noreply.github.com> Date: Mon, 23 Feb 2026 13:43:40 +0000 Subject: [PATCH 1/2] add set milestone script --- gh_review_project/cr_deadline.py | 11 +++ gh_review_project/finish_milestone.py | 23 +----- gh_review_project/set_milestone.py | 109 ++++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 21 deletions(-) create mode 100644 gh_review_project/set_milestone.py diff --git a/gh_review_project/cr_deadline.py b/gh_review_project/cr_deadline.py index 3064d7ff..a8f419d2 100644 --- a/gh_review_project/cr_deadline.py +++ b/gh_review_project/cr_deadline.py @@ -1,3 +1,14 @@ +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +# ----------------------------------------------------------------------------- + +""" +This script will update the pull requests and issues in the Simulation System +Projects as required at the code review deadline. +""" + import argparse from pathlib import Path from review_project import ProjectData, ISSUE_ID diff --git a/gh_review_project/finish_milestone.py b/gh_review_project/finish_milestone.py index b48b92b9..67b5698d 100644 --- a/gh_review_project/finish_milestone.py +++ b/gh_review_project/finish_milestone.py @@ -17,6 +17,7 @@ from pathlib import Path import argparse from review_project import ProjectData, REVIEW_ID, ISSUE_ID +from set_milestone import add_milestone def print_banner(message: str) -> None: @@ -26,26 +27,6 @@ def print_banner(message: str) -> None: print("=" * len(message)) -def closed_other( - reviews: ProjectData, current_milestone: str, dry_run: bool = False -) -> None: - """ - Set a milestone for closed PRs without one. - - reviews: ProjectData from the Review Tracker Project - current_milestone: Milestone being closed - dry_run: If true, do not actually modify the milestone - """ - - print_banner(f"Setting pull requests with no milestone to {current_milestone}") - - closed_prs = reviews.get_milestone(milestone="None", status="closed") - - for repo in closed_prs: - for pr in closed_prs[repo]: - pr.modify_milestone(current_milestone, dry_run) - - def check_ready( reviews: ProjectData, issues: ProjectData, current_milestone: str ) -> None: @@ -200,7 +181,7 @@ def main( ) # Set a milestone on closed PRs - closed_other(review_data, milestone, dry) + add_milestone(review_data, milestone, dry) # Process data and report on status check_ready(review_data, issue_data, milestone) diff --git a/gh_review_project/set_milestone.py b/gh_review_project/set_milestone.py new file mode 100644 index 00000000..a7b70963 --- /dev/null +++ b/gh_review_project/set_milestone.py @@ -0,0 +1,109 @@ +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +# ----------------------------------------------------------------------------- + +""" +This script will change the milestone on all closed pull requests that don't +have one. +""" + +import argparse +from pathlib import Path +from review_project import ProjectData, REVIEW_ID + + +def print_banner(message: str) -> None: + print("\n") + print("=" * len(message)) + print(message) + print("=" * len(message)) + + +def add_milestone( + reviews: ProjectData, current_milestone: str, dry_run: bool = False +) -> None: + """ + Set a milestone for closed PRs without one. + + reviews: ProjectData from the Review Tracker Project + current_milestone: Milestone to set + dry_run: If true, do not actually modify the milestone + """ + + print_banner(f"Setting closed pull requests with no milestone to {current_milestone}") + + closed_prs = reviews.get_milestone(milestone="None", status="closed") + + if closed_prs: + for repo in closed_prs: + for pr in closed_prs[repo]: + pr.modify_milestone(current_milestone, dry_run) + else: + print("No closed pull requests without a milestone.") + + +def parse_args(): + """ + Read command line args + """ + + testfile_path = Path(__file__).parent / "test" + + parser = argparse.ArgumentParser( + "Set all closed pull requests without a milestone to the requested milestone." + ) + + parser.add_argument("--milestone", help="Milestone to set") + parser.add_argument( + "--test", + action="store_true", + help="Use test input files.", + ) + parser.add_argument( + "--capture_project", + action="store_true", + help="Capture the current project status into the test file", + ) + parser.add_argument( + "--file", + default=testfile_path, + help="Filepath to test data for either capturing the project status, " + "or use as input data.", + ) + parser.add_argument( + "--dry", + action="store_true", + help="Dry run. Print commands, don't action them. Always true when " + "running with test data.", + ) + + args = parser.parse_args() + + args.file = Path(args.file) + args.file = args.file.expanduser().resolve() + + if args.test: + args.dry = True + + return args + + +def main( + milestone: str, test: bool, capture_project: bool, file: Path, dry: bool +) -> None: + # Get milestone data + if test: + review_data = ProjectData.from_file(REVIEW_ID, file / "pr.json") + else: + review_data = ProjectData.from_github( + REVIEW_ID, capture_project, file / "pr.json" + ) + + add_milestone(review_data, milestone, dry) + + +if __name__ == "__main__": + args = parse_args() + main(args.milestone, args.test, args.capture_project, args.file, args.dry) From b625aed638fa2f88ef082423a84e6d93eaff78f8 Mon Sep 17 00:00:00 2001 From: jennyhickson <61183013+jennyhickson@users.noreply.github.com> Date: Mon, 23 Feb 2026 13:44:46 +0000 Subject: [PATCH 2/2] black --- gh_review_project/set_milestone.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gh_review_project/set_milestone.py b/gh_review_project/set_milestone.py index a7b70963..3abf209b 100644 --- a/gh_review_project/set_milestone.py +++ b/gh_review_project/set_milestone.py @@ -32,7 +32,9 @@ def add_milestone( dry_run: If true, do not actually modify the milestone """ - print_banner(f"Setting closed pull requests with no milestone to {current_milestone}") + print_banner( + f"Setting closed pull requests with no milestone to {current_milestone}" + ) closed_prs = reviews.get_milestone(milestone="None", status="closed")