blob: a3ba6f01e4db5fef58d73ae51cb9bd2efdefa16f [file]
"""Subcommand to mark preparation task as complete."""
import re
from dev.release.gh import GitHub
from dev.release.release_issue import (
parse_checklist_state,
update_task_in_body,
)
from dev.release.utils import set_github_output
class CompletePrepare:
"""Class to mark preparation task as complete."""
def __init__(self, args, gh: GitHub):
self.args = args
self.gh = gh
def run(self) -> int:
"""Executes the complete-prepare subcommand (Phase 2 PR merged)."""
args = self.args
pr_number = args.pr
issue_number = args.issue
if not pr_number and not issue_number:
print("Error: Either --pr or --issue must be provided.")
return 1
if not pr_number and issue_number:
issue_body = self.gh.get_issue_body(issue_number)
state = parse_checklist_state(issue_body)
prep_task = state.get("prepare_release")
if not prep_task or not prep_task.pr:
print(
f"Error: Could not find PR reference for 'Prepare Release'"
f" in issue #{issue_number}."
)
return 1
pr_number = int(prep_task.pr.lstrip("#"))
print(f"Completing preparation for PR #{pr_number}...")
pr_info = self.gh.get_pr_info(pr_number)
if not pr_info or pr_info.get("state") != "MERGED":
state = pr_info.get("state", "UNKNOWN") if pr_info else "NOT_FOUND"
print(f"Error: PR #{pr_number} is not merged yet (state: {state}).")
return 1
if not issue_number:
# Resolve issue number from PR body
pr_body = pr_info.get("body") or ""
match = re.search(r"Work towards #(\d+)", pr_body)
if not match:
match = re.search(r"#(\d+)", pr_body)
if not match:
print(
f"Error: Could not determine tracking issue number from PR"
f" #{pr_number} body: {pr_body}"
)
return 1
issue_number = int(match.group(1))
print(f"Resolved tracking issue #{issue_number} from PR #{pr_number} body.")
commit_sha = pr_info["mergeCommit"]["oid"]
short_commit = commit_sha[:8]
print(
f"PR #{pr_number} merged at commit {commit_sha}. Updating tracking issue..."
)
# Update checklist: mark Prepare Release as done (checked) and set SUCCESS
body = self.gh.get_issue_body(issue_number)
metadata = {
"status": "done",
"pr": f"#{pr_number}",
"commit": short_commit,
}
updated_body = update_task_in_body(
body, "Prepare Release", checked=True, metadata=metadata
)
self.gh.update_issue_body(issue_number, updated_body)
print("Prepare Release task marked complete successfully!")
set_github_output("issue", str(issue_number))
return 0
@classmethod
def add_parser(cls, subparsers):
"""Adds parser for complete-prepare subcommand."""
parser = subparsers.add_parser(
"complete-prepare",
help="Mark the Prepare Release task as complete in the tracking issue.",
)
parser.add_argument(
"--pr",
type=int,
required=False,
help="The merged preparation PR number.",
)
parser.add_argument(
"--issue",
type=int,
required=False,
help="The release tracking issue number.",
)
parser.set_defaults(command=cls.run_from_args)
@classmethod
def run_from_args(cls, args):
"""Instantiates and runs the command from parsed args."""
gh = GitHub()
return cls(args, gh).run()