Opens an editor with the draft text, previews it, and prompts the user to post it. Returns the action taken ('r', 'c', or False).
(session, pr, initial_text, base=None)
| 525 | webbrowser.open_new(target_url) |
| 526 | |
| 527 | def post_draft_review(session, pr, initial_text, base=None): |
| 528 | """ |
| 529 | Opens an editor with the draft text, previews it, and prompts the user to |
| 530 | post it. Returns the action taken ('r', 'c', or False). |
| 531 | """ |
| 532 | rfa_msg = textwrap.dedent("""\n\n |
| 533 | 🛟 **Need Help?** |
| 534 | If you need technical help resolving these issues, please consult with the |
| 535 | Component Lead. If you need administrative overrides, please see the |
| 536 | `#ceph-upstream-releases` channel on [Slack](https://docs.ceph.com/en/latest/start/get-involved/) |
| 537 | **and** request a review from the @Ceph Release Manager. |
| 538 | """) |
| 539 | editor = os.environ.get('EDITOR', 'vim') |
| 540 | with tempfile.NamedTemporaryFile(mode='w+', suffix='.md', delete=False) as tf: |
| 541 | tf.write(initial_text) |
| 542 | tf_path = tf.name |
| 543 | |
| 544 | try: |
| 545 | while True: |
| 546 | try: |
| 547 | subprocess.run([editor, tf_path]) |
| 548 | except FileNotFoundError: |
| 549 | log.error(f"Editor '{editor}' not found. Please set the EDITOR environment variable.") |
| 550 | return False |
| 551 | with open(tf_path, 'r', encoding='utf-8') as f_read: |
| 552 | final_text = f_read.read().strip() |
| 553 | |
| 554 | print("\n" + "="*80) |
| 555 | print("DRAFT REVIEW PREVIEW:") |
| 556 | print("-" * 80) |
| 557 | print(final_text) |
| 558 | print("="*80 + "\n") |
| 559 | |
| 560 | confirm = input(f"Post this feedback to PR #{pr}? [r/c/e/m/N] (r=request changes, c=comment, e=edit again, m=skip to merge, n=cancel): ").strip().lower() |
| 561 | if confirm == 'm': |
| 562 | raise SkipToMerge() |
| 563 | elif confirm in ('r', 'c'): |
| 564 | event = 'REQUEST_CHANGES' if confirm == 'r' else 'COMMENT' |
| 565 | endpoint = f"https://api.github.com/repos/{BASE_PROJECT}/{BASE_REPO}/pulls/{pr}/reviews" |
| 566 | r = session.post(endpoint, auth=GithubBearerAuth(), json={'body': final_text, 'event': event}) |
| 567 | if r.status_code in (200, 201): |
| 568 | log.info(f"Successfully posted {event} to PR #{pr}") |
| 569 | return confirm |
| 570 | else: |
| 571 | log.error(f"Failed to post review: {r.status_code} {r.text}") |
| 572 | return False |
| 573 | elif confirm == 'e': |
| 574 | continue |
| 575 | else: |
| 576 | print("Review cancelled.") |
| 577 | return False |
| 578 | finally: |
| 579 | os.unlink(tf_path) |
| 580 | |
| 581 | def get_custom_field(issue, field_id): |
| 582 | try: |
no test coverage detected