-
Notifications
You must be signed in to change notification settings - Fork 6.9k
Add /tag-and-rerun-ci #13521
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add /tag-and-rerun-ci #13521
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -43,31 +43,38 @@ def load_permissions(user_login): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sys.exit(1) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def handle_tag_run_ci(gh_repo, pr, comment, user_perms): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def handle_tag_run_ci(gh_repo, pr, comment, user_perms, react_on_success=True): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Handles the /tag-run-ci-label command. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Returns True if action was taken, False otherwise. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not user_perms.get("can_tag_run_ci_label", False): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print("Permission denied: can_tag_run_ci_label is false.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return False | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print("Permission granted. Adding 'run-ci' label.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pr.add_to_labels("run-ci") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # React to the comment with +1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| comment.create_reaction("+1") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print("Label added and comment reacted.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if react_on_success: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| comment.create_reaction("+1") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print("Label added and comment reacted.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print("Label added (reaction suppressed).") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return True | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def handle_rerun_failed_ci(gh_repo, pr, comment, user_perms): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def handle_rerun_failed_ci(gh_repo, pr, comment, user_perms, react_on_success=True): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Handles the /rerun-failed-ci command. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Reruns workflows with 'failure' or 'skipped' conclusions. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Returns True if action was taken, False otherwise. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not user_perms.get("can_rerun_failed_ci", False): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print("Permission denied: can_rerun_failed_ci is false.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return False | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print("Permission granted. Triggering rerun of failed workflows.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print("Permission granted. Triggering rerun of failed or skipped workflows.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Get the SHA of the latest commit in the PR | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| head_sha = pr.head.sha | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -78,22 +85,35 @@ def handle_rerun_failed_ci(gh_repo, pr, comment, user_perms): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rerun_count = 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for run in runs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # We only care about completed runs that failed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if run.status == "completed" and run.conclusion == "failure": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f"Rerunning workflow: {run.name} (ID: {run.id})") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if run.status != "completed": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if run.conclusion == "failure": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f"Rerunning failed workflow: {run.name} (ID: {run.id})") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # PyGithub uses rerun_failed_jobs() or rerun() depending on version/intent | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # The traceback suggested rerun_failed_jobs | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Use rerun_failed_jobs for efficiency on failures | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run.rerun_failed_jobs() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rerun_count += 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| except Exception as e: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f"Failed to rerun workflow {run.id}: {e}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| elif run.conclusion == "skipped": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f"Rerunning skipped workflow: {run.name} (ID: {run.id})") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Skipped workflows don't have 'failed jobs', so we use full rerun() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run.rerun() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rerun_count += 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| except Exception as e: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f"Failed to rerun workflow {run.id}: {e}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+91
to
+107
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To improve maintainability and reduce code duplication, you can refactor the logic for handling 'failure' and 'skipped' conclusions. The current implementation has two very similar
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if rerun_count > 0: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| comment.create_reaction("+1") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f"Triggered rerun for {rerun_count} failed workflows.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f"Triggered rerun for {rerun_count} workflows.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if react_on_success: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| comment.create_reaction("+1") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return True | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print("No failed workflows found to rerun.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print("No failed or skipped workflows found to rerun.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return False | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def main(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -121,7 +141,6 @@ def main(): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| comment = repo.get_issue(pr_number).get_comment(comment_id) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 4. Parse Command and Execute | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # split lines to handle cases where there might be text after the command | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| first_line = comment_body.split("\n")[0].strip() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if first_line.startswith("/tag-run-ci-label"): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -130,6 +149,24 @@ def main(): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| elif first_line.startswith("/rerun-failed-ci"): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| handle_rerun_failed_ci(repo, pr, comment, user_perms) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| elif first_line.startswith("/tag-and-rerun-ci"): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Perform both actions, but suppress individual reactions | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print("Processing combined command: /tag-and-rerun-ci") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tagged = handle_tag_run_ci( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| repo, pr, comment, user_perms, react_on_success=False | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rerun = handle_rerun_failed_ci( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| repo, pr, comment, user_perms, react_on_success=False | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # If at least one action was successful, add the reaction here | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if tagged or rerun: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| comment.create_reaction("+1") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print("Combined command processed successfully; reaction added.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print("Combined command finished, but no actions were taken.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f"Unknown or ignored command: {first_line}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should also consider the
cancelledconclustion.