Example #1
0
class BitbucketGitRepoApiAdapter(GitRepoApi):
    def __init__(
        self,
        git_provider_url: str,
        username: Optional[str],
        password: Optional[str],
        organisation: str,
        repository_name: str,
    ) -> None:
        self.__bitbucket = Bitbucket(git_provider_url, username, password)
        self.__git_provider_url = git_provider_url
        self.__organisation = organisation
        self.__repository_name = repository_name

    def get_username(self) -> Optional[str]:
        return str(self.__bitbucket.username)

    def get_password(self) -> Optional[str]:
        return str(self.__bitbucket.password)

    def get_clone_url(self) -> str:
        try:
            repo = self.__bitbucket.get_repo(self.__organisation, self.__repository_name)
        except requests.exceptions.ConnectionError as ex:
            raise GitOpsException(f"Error connecting to '{self.__git_provider_url}''") from ex
        if "errors" in repo:
            for error in repo["errors"]:
                exception = error["exceptionName"]
                if exception == "com.atlassian.bitbucket.auth.IncorrectPasswordAuthenticationException":
                    raise GitOpsException("Bad credentials")
                if exception == "com.atlassian.bitbucket.project.NoSuchProjectException":
                    raise GitOpsException(f"Organisation '{self.__organisation}' does not exist")
                if exception == "com.atlassian.bitbucket.repository.NoSuchRepositoryException":
                    raise GitOpsException(f"Repository '{self.__organisation}/{self.__repository_name}' does not exist")
                raise GitOpsException(error["message"])
        if "links" not in repo:
            raise GitOpsException(f"Repository '{self.__organisation}/{self.__repository_name}' does not exist")
        for clone_link in repo["links"]["clone"]:
            if clone_link["name"] == "http":
                repo_url = clone_link["href"]
        if not repo_url:
            raise GitOpsException("Couldn't determine repository URL.")
        return str(repo_url)

    def create_pull_request_to_default_branch(
        self, from_branch: str, title: str, description: str
    ) -> GitRepoApi.PullRequestIdAndUrl:
        to_branch = self.__get_default_branch()
        return self.create_pull_request(from_branch, to_branch, title, description)

    def create_pull_request(
        self, from_branch: str, to_branch: str, title: str, description: str
    ) -> GitRepoApi.PullRequestIdAndUrl:
        pull_request = self.__bitbucket.open_pull_request(
            self.__organisation,
            self.__repository_name,
            self.__organisation,
            self.__repository_name,
            from_branch,
            to_branch,
            title,
            description,
        )
        if "errors" in pull_request:
            raise GitOpsException(pull_request["errors"][0]["message"])
        return GitRepoApi.PullRequestIdAndUrl(pr_id=pull_request["id"], url=pull_request["links"]["self"][0]["href"])

    def merge_pull_request(self, pr_id: int, merge_method: Literal["squash", "rebase", "merge"] = "merge") -> None:
        pull_request = self.__bitbucket.get_pullrequest(self.__organisation, self.__repository_name, pr_id)
        self.__bitbucket.merge_pull_request(
            self.__organisation, self.__repository_name, pull_request["id"], pull_request["version"]
        )

    def add_pull_request_comment(self, pr_id: int, text: str, parent_id: Optional[int] = None) -> None:
        pull_request_comment = self.__bitbucket.add_pull_request_comment(
            self.__organisation, self.__repository_name, pr_id, text, parent_id
        )
        if "errors" in pull_request_comment:
            raise GitOpsException(pull_request_comment["errors"][0]["message"])

    def delete_branch(self, branch: str) -> None:
        branch_hash = self.get_branch_head_hash(branch)
        result = self.__bitbucket.delete_branch(self.__organisation, self.__repository_name, branch, branch_hash)
        if result and "errors" in result:
            raise GitOpsException(result["errors"][0]["message"])

    def get_branch_head_hash(self, branch: str) -> str:
        branches = self.__bitbucket.get_branches(self.__organisation, self.__repository_name, filter=branch, limit=1)
        if not branches:
            raise GitOpsException(f"Branch '{branch}' not found'")
        return str(branches[0]["latestCommit"])

    def get_pull_request_branch(self, pr_id: int) -> str:
        pull_request = self.__bitbucket.get_pullrequest(self.__organisation, self.__repository_name, pr_id)
        if "errors" in pull_request:
            raise GitOpsException(pull_request["errors"][0]["message"])
        return str(pull_request["fromRef"]["displayId"])

    def __get_default_branch(self) -> str:
        default_branch = self.__bitbucket.get_default_branch(self.__organisation, self.__repository_name)
        return str(default_branch["id"])
Example #2
0
bitbucket = Bitbucket(url='http://localhost:7990',
                      username='******',
                      password='******')
pr_id = 12345

pr = bitbucket.get_pullrequest("project_name", "repository_name", pr_id)
ver = pr.json().get("version")
print("PR version: {}".format(ver))

response = bitbucket.decline_pull_request("project_name", "repository_name",
                                          pr_id, ver)
print("Declined: {}".format(response))
ver = response.json().get("version")
print("PR version: {}".format(ver))

response = bitbucket.reopen_pull_request("project_name", "repository_name",
                                         pr_id, ver)
print("Reopen: {}".format(response))
ver = response.json().get("version")
print("PR version: {}".format(ver))

response = bitbucket.is_pull_request_can_be_merged("project_name",
                                                   "repository_name", pr_id)
print("Reopen: {}".format(response))
print("PR version: {}".format(ver))

response = bitbucket.merge_pull_request("project_name", "repository_name",
                                        pr_id, ver)
print("Merged: {}".format(response))
Example #3
0
class BitBucketGitUtil(AbstractGitUtil):
    def __init__(self, tmp_dir, git_provider_url, organisation,
                 repository_name, username, password, git_user, git_email):
        super().__init__(tmp_dir, username, password, git_user, git_email)
        self._git_provider_url = git_provider_url
        self._organisation = organisation
        self._repository_name = repository_name
        self._bitbucket = Bitbucket(self._git_provider_url, self._username,
                                    self._password)

    def get_clone_url(self):
        try:
            repo = self._bitbucket.get_repo(self._organisation,
                                            self._repository_name)
        except requests.exceptions.ConnectionError as ex:
            raise GitOpsException(
                f"Error connecting to '{self._git_provider_url}''") from ex
        if "errors" in repo:
            for error in repo["errors"]:
                exception = error["exceptionName"]
                if exception == "com.atlassian.bitbucket.auth.IncorrectPasswordAuthenticationException":
                    raise GitOpsException("Bad credentials")
                if exception == "com.atlassian.bitbucket.project.NoSuchProjectException":
                    raise GitOpsException(
                        f"Organisation '{self._organisation}' does not exist")
                if exception == "com.atlassian.bitbucket.repository.NoSuchRepositoryException":
                    raise GitOpsException(
                        f"Repository '{self._organisation}/{self._repository_name}' does not exist"
                    )
                raise GitOpsException(error["message"])
        if "links" not in repo:
            raise GitOpsException(
                f"Repository '{self._organisation}/{self._repository_name}' does not exist"
            )
        for clone_link in repo["links"]["clone"]:
            if clone_link["name"] == "http":
                repo_url = clone_link["href"]
        if not repo_url:
            raise GitOpsException("Couldn't determine repository URL.")
        return repo_url

    def create_pull_request(self, from_branch, to_branch, title, description):
        pull_request = self._bitbucket.open_pull_request(
            self._organisation,
            self._repository_name,
            self._organisation,
            self._repository_name,
            from_branch,
            to_branch,
            title,
            description,
        )
        if "errors" in pull_request:
            raise GitOpsException(pull_request["errors"][0]["message"])
        return pull_request

    def get_pull_request_url(self, pull_request):
        return pull_request["links"]["self"][0]["href"]

    def merge_pull_request(self, pull_request):
        self._bitbucket.merge_pull_request(self._organisation,
                                           self._repository_name,
                                           pull_request["id"],
                                           pull_request["version"])

    def add_pull_request_comment(self, pr_id, text, parent_id):
        pull_request_comment = self._bitbucket.add_pull_request_comment(
            self._organisation, self._repository_name, pr_id, text, parent_id)
        if "errors" in pull_request_comment:
            raise GitOpsException(pull_request_comment["errors"][0]["message"])
        return pull_request_comment

    def delete_branch(self, branch):
        branches = self._bitbucket.get_branches(self._organisation,
                                                self._repository_name,
                                                filter=branch,
                                                limit=1)
        if not branches:
            raise GitOpsException(f"Branch '{branch}' not found'")
        result = self._bitbucket.delete_branch(self._organisation,
                                               self._repository_name, branch,
                                               branches[0]["latestCommit"])
        if result and "errors" in result:
            raise GitOpsException(result["errors"][0]["message"])

    def get_pull_request_branch(self, pr_id):
        pull_request = self._bitbucket.get_pullrequest(self._organisation,
                                                       self._repository_name,
                                                       pr_id)
        if "errors" in pull_request:
            raise GitOpsException(pull_request["errors"][0]["message"])
        return pull_request["fromRef"]["displayId"]