2525
2626import git
2727import git .compat
28- import github3
2928import requests
3029from git .objects import Commit
31- from github3 . pulls import ShortPullRequest
32- from github3 . repos . commit import ShortCommit
33- from github3 . repos . repo import Repository
30+ from github import GithubException
31+ from github . PullRequest import PullRequest
32+ from github . Repository import Repository
3433
3534from rebasebot import lifecycle_hooks
3635from rebasebot .github import GithubAppProvider , GitHubBranch
@@ -82,9 +81,9 @@ def _needs_rebase(gitwd: git.Repo, source: GitHubBranch, dest: GitHubBranch) ->
8281
8382def _is_pr_merged (pr_number : int , source_repo : Repository , gitwd : git .Repo , source_branch : str ) -> bool :
8483 logging .info ("Checking that PR %s has been merged and is included in %s" , pr_number , source_branch )
85- gh_pr = source_repo .pull_request (pr_number )
84+ gh_pr = source_repo .get_pull (pr_number )
8685
87- if not gh_pr .is_merged () :
86+ if not gh_pr .merged :
8887 return False
8988
9089 merge_commit_sha = gh_pr .merge_commit_sha
@@ -633,11 +632,10 @@ def _cherrypick_art_pull_request(
633632 that updates the build image, it includes it in the rebase.
634633 """
635634 logging .info ("Checking for ART pull request" )
636- for pull_request in dest_repo .pull_requests (state = "open" , base = f"{ dest .branch } " ):
637- assert isinstance (pull_request , ShortPullRequest ) # type hint
635+ for pull_request in dest_repo .get_pulls (state = "open" , base = dest .branch ):
638636 if "consistent with ART" in pull_request .title and pull_request .user .login == "openshift-bot" :
639637 logging .info (f"Found open ART image update pull requst: { pull_request .title } " )
640- remote = pull_request .head .repository
638+ remote = pull_request .head .repo
641639 remote_name = remote .name
642640 if remote_name in gitwd .remotes :
643641 gitwd .remotes [remote_name ].set_url (remote .html_url )
@@ -646,8 +644,7 @@ def _cherrypick_art_pull_request(
646644
647645 gitwd .remotes [remote_name ].fetch (pull_request .head .ref )
648646
649- for commit in pull_request .commits ():
650- assert isinstance (commit , ShortCommit )
647+ for commit in pull_request .get_commits ():
651648 _safe_cherry_pick (
652649 gitwd = gitwd ,
653650 sha = commit .sha ,
@@ -684,14 +681,19 @@ def _is_pr_required(gitwd: git.Repo, rebase: GitHubBranch, dest: GitHubBranch) -
684681 return True
685682
686683
687- def _is_pr_available (dest_repo : Repository , dest : GitHubBranch , rebase : GitHubBranch ) -> tuple [ShortPullRequest , bool ]:
684+ def _is_pr_available (
685+ dest_repo : Repository , dest : GitHubBranch , rebase : GitHubBranch
686+ ) -> tuple [PullRequest | None , bool ]:
688687 logging .info ("Checking for existing pull request" )
689688
690- pull_requests = dest_repo .pull_requests (base = dest .branch , state = "open" )
689+ pull_requests = dest_repo .get_pulls (base = dest .branch , state = "open" )
691690 # Github does not support filtering cross-repository pull requests if both repositories
692691 # are owned by the same organization. We must filter client side.
693692 for pr in pull_requests :
694- pr_repo = pr .as_dict ()["head" ]["repo" ]["full_name" ]
693+ if pr .head .repo is None :
694+ logging .warning (f"Skipping PR with deleted head repository: { pr .html_url } " )
695+ continue
696+ pr_repo = pr .head .repo .full_name
695697 if pr_repo == f"{ rebase .ns } /{ rebase .name } " and pr .head .ref == rebase .branch :
696698 logging .info ('Found existing pull request: "%s" %s' , pr .title , pr .html_url )
697699 return pr , True
@@ -702,7 +704,7 @@ def _is_pr_available(dest_repo: Repository, dest: GitHubBranch, rebase: GitHubBr
702704
703705def _create_pr (
704706 * ,
705- gh_app : github3 . GitHub ,
707+ gh_app ,
706708 dest : GitHubBranch ,
707709 source : GitHubBranch ,
708710 rebase : GitHubBranch ,
@@ -717,30 +719,19 @@ def _create_pr(
717719
718720 logging .info ("Creating a pull request" )
719721
720- # FIXME(rmanak): This hack is because github3 doesn't support setting
721- # head_repo param when creating a PR.
722- #
723- # This param is required when creating cross-repository pull requests if both repositories
724- # are owned by the same organization.
725- #
726- # https://github.com/sigmavirus24/github3.py/issues/1190
727-
728- gh_pr : requests .Response = gh_app ._post ( # pylint: disable=W0212
729- f"https://api.github.com/repos/{ dest .ns } /{ dest .name } /pulls" ,
730- data = {
731- "title" : title ,
732- "head" : rebase .branch ,
733- "head_repo" : f"{ rebase .ns } /{ rebase .name } " ,
734- "base" : dest .branch ,
735- "maintainer_can_modify" : False ,
736- },
737- json = True ,
722+ dest_repo = gh_app .get_repo (f"{ dest .ns } /{ dest .name } " )
723+
724+ pr = dest_repo .create_pull (
725+ title = title ,
726+ body = "" ,
727+ head = f"{ rebase .ns } :{ rebase .branch } " ,
728+ base = dest .branch ,
729+ maintainer_can_modify = False ,
738730 )
739731
740- logging .debug (gh_pr .json ())
741- gh_pr .raise_for_status ()
732+ logging .info (f"Created pull request: { pr .html_url } " )
742733
743- return gh_pr . json ()[ " html_url" ]
734+ return pr . html_url
744735
745736
746737def is_ref_a_tag (gitwd : git .Repo , ref : str ) -> bool :
@@ -867,12 +858,12 @@ def _init_working_dir(
867858 return gitwd
868859
869860
870- def _manual_rebase_pr_in_repo (repo : Repository ) -> ShortPullRequest | None :
861+ def _manual_rebase_pr_in_repo (repo : Repository ) -> PullRequest | None :
871862 """Checks for the presence of a rebase/manual label on the pull request."""
872- prs = repo .pull_requests ()
863+ prs = repo .get_pulls ()
873864 for pull_req in prs :
874865 for label in pull_req .labels :
875- if label [ " name" ] == "rebase/manual" :
866+ if label . name == "rebase/manual" :
876867 return pull_req
877868 return None
878869
@@ -885,7 +876,7 @@ def _push_rebase_branch(gitwd: git.Repo, rebase: GitHubBranch) -> None:
885876 raise builtins .Exception (f"Error pushing to { rebase } : { result [0 ].summary } " )
886877
887878
888- def _update_pr_title (gitwd : git .Repo , pull_req : ShortPullRequest , source : GitHubBranch , dest : GitHubBranch ) -> None :
879+ def _update_pr_title (gitwd : git .Repo , pull_req : PullRequest , source : GitHubBranch , dest : GitHubBranch ) -> None :
889880 """Updates the pull request title to match the current state of the rebase branch
890881 Only updates the title if the title contains the word Merge.
891882 Keeping everything before "Merge" and updating everything after.
@@ -902,8 +893,10 @@ def _update_pr_title(gitwd: git.Repo, pull_req: ShortPullRequest, source: GitHub
902893 return
903894
904895 logging .info (f"Updating pull request title: { computed_title } " )
905- if not pull_req .update (title = computed_title ):
906- raise PullRequestUpdateException (f"Error updating title for pull request: { pull_req .html_url } " )
896+ try :
897+ pull_req .edit (title = computed_title )
898+ except Exception as ex :
899+ raise PullRequestUpdateException (f"Error updating title for pull request: { pull_req .html_url } " ) from ex
907900 else :
908901 logging .info (
909902 f'Open pull request title "{ pull_req .title } " does not match rebasebot format. Keeping the current title.'
@@ -979,11 +972,11 @@ def run(
979972 hooks = lifecycle_hooks .LifecycleHooks (tmp_script_dir = None , args = None )
980973
981974 try :
982- dest_repo = gh_app .repository ( dest .ns , dest .name )
975+ dest_repo = gh_app .get_repo ( f" { dest .ns } / { dest .name } " )
983976 logging .info ("Destination repository is %s" , dest_repo .clone_url )
984- rebase_repo = gh_cloner_app .repository ( rebase .ns , rebase .name )
977+ rebase_repo = gh_cloner_app .get_repo ( f" { rebase .ns } / { rebase .name } " )
985978 logging .info ("rebase repository is %s" , rebase_repo .clone_url )
986- source_repo = gh_app .repository ( source .ns , source .name )
979+ source_repo = gh_app .get_repo ( f" { source .ns } / { source .name } " )
987980 logging .info ("source repository is %s" , source_repo .clone_url )
988981
989982 if not ignore_manual_label :
@@ -1171,9 +1164,11 @@ def run(
11711164 f"{ ex } " ,
11721165 )
11731166 return False
1174- except requests .exceptions .HTTPError as ex :
1175- logging .error (f"Failed to create a pull request: { ex } \n Response: %s" , ex .response .text )
1176- _message_slack (slack_webhook , f"Failed to create a pull request: { ex } \n Response: { ex .response .text } " )
1167+ except GithubException as ex :
1168+ logging .error (f"Failed to create a pull request: { ex } " )
1169+ if ex .data :
1170+ logging .error (f"Response data: { ex .data } " )
1171+ _message_slack (slack_webhook , f"Failed to create a pull request: { ex } " )
11771172
11781173 return False
11791174 except Exception as ex :
0 commit comments