1313
1414import click
1515import requests
16+ import stamina
1617from gidgethub import sansio
1718
1819from . import __version__
5556 PUSHING_TO_REMOTE_FAILED
5657
5758 PR_CREATING
59+ PR_CREATING_FAILED
5860 PR_OPENING
5961
6062 REMOVING_BACKPORT_BRANCH
@@ -95,6 +97,10 @@ class InvalidRepoException(Exception):
9597 pass
9698
9799
100+ class GitHubException (Exception ):
101+ pass
102+
103+
98104class CherryPicker :
99105 ALLOWED_STATES = WORKFLOW_STATES .BACKPORT_PAUSED , WORKFLOW_STATES .UNSET
100106 """The list of states expected at the start of the app."""
@@ -430,16 +436,21 @@ def push_to_remote(self, base_branch, head_branch, commit_message=""):
430436 gh_auth = os .getenv ("GH_AUTH" )
431437 if gh_auth :
432438 set_state (WORKFLOW_STATES .PR_CREATING )
433- self .create_gh_pr (
434- base_branch ,
435- head_branch ,
436- commit_message = commit_message ,
437- gh_auth = gh_auth ,
438- )
439+ try :
440+ self .create_gh_pr (
441+ base_branch ,
442+ head_branch ,
443+ commit_message = commit_message ,
444+ gh_auth = gh_auth ,
445+ )
446+ except GitHubException :
447+ set_state (WORKFLOW_STATES .PR_CREATING_FAILED )
448+ raise
439449 else :
440450 set_state (WORKFLOW_STATES .PR_OPENING )
441451 self .open_pr (self .get_pr_url (base_branch , head_branch ))
442452
453+ @stamina .retry (on = GitHubException , timeout = 120 )
443454 def create_gh_pr (self , base_branch , head_branch , * , commit_message , gh_auth ):
444455 """
445456 Create PR in GitHub
@@ -458,14 +469,22 @@ def create_gh_pr(self, base_branch, head_branch, *, commit_message, gh_auth):
458469 "draft" : self .config ["draft_pr" ],
459470 }
460471 url = CREATE_PR_URL_TEMPLATE .format (config = self .config )
461- response = requests .post (url , headers = request_headers , json = data , timeout = 10 )
462- if response .status_code == requests .codes .created :
463- response_data = response .json ()
464- click .echo (f"Backport PR created at { response_data ['html_url' ]} " )
465- self .pr_number = response_data ["number" ]
472+ try :
473+ response = requests .post (
474+ url , headers = request_headers , json = data , timeout = 30
475+ )
476+ except requests .exceptions .RequestException as req_exc :
477+ raise GitHubException (f"Creating PR on GitHub failed: { req_exc } " )
466478 else :
467- click .echo (response .status_code )
468- click .echo (response .text )
479+ sc = response .status_code
480+ txt = response .text
481+ if sc != requests .codes .created :
482+ raise GitHubException (
483+ f"Unexpected response ({ sc } ) when creating PR on GitHub: { txt } "
484+ )
485+ response_data = response .json ()
486+ click .echo (f"Backport PR created at { response_data ['html_url' ]} " )
487+ self .pr_number = response_data ["number" ]
469488
470489 def open_pr (self , url ):
471490 """
@@ -543,9 +562,14 @@ def backport(self):
543562 raise
544563 else :
545564 if self .push :
546- self .push_to_remote (
547- maint_branch , cherry_pick_branch , commit_message
548- )
565+ try :
566+ self .push_to_remote (
567+ maint_branch , cherry_pick_branch , commit_message
568+ )
569+ except GitHubException :
570+ click .echo (self .get_exit_message (maint_branch ))
571+ self .set_paused_state ()
572+ raise
549573 if not self .is_mirror ():
550574 self .cleanup_branch (cherry_pick_branch )
551575 else :
0 commit comments