Exemple #1
0
 def __init__(self, config: Config) -> None:
     self.config = config
     self.consumerino = Consumerino()
Exemple #2
0
 def __init__(self):
     # TODO: the url template should be configurable
     self.datagrepper_url = (
         "https://apps.fedoraproject.org/datagrepper/id?id={msg_id}&is_raw=true"
     )
     self.consumerino = Consumerino()
Exemple #3
0
class PackitBotAPI:
    def __init__(self, config: Config) -> None:
        self.config = config
        self.consumerino = Consumerino()

    @property  # type: ignore
    @lru_cache()
    def _github_service(self):
        return GithubService(token=self.config.github_token)

    @property  # type: ignore
    @lru_cache()
    def _pagure_service(self):
        return PagureService(token=self.config.pagure_user_token)

    def watch_upstream_pull_request(self):
        for topic, action, msg in self.consumerino.iterate_pull_requests():
            if action in ["opened", "synchronize", "reopened"]:
                self.sync_upstream_pull_request_with_fedmsg(fedmsg=msg)

    def sync_upstream_pull_request_with_fedmsg(self, fedmsg: Dict):
        repo_name = fedmsg["msg"]["pull_request"]["head"]["repo"]["name"]
        namespace = fedmsg["msg"]["pull_request"]["head"]["repo"]["owner"][
            "login"]
        ref = fedmsg["msg"]["pull_request"]["head"]["ref"]
        pr_id = fedmsg["msg"]["pull_request"]["number"]

        github_repo = self._github_service.get_project(  # type: ignore
            repo=repo_name, namespace=namespace)
        local_project = LocalProject(git_project=github_repo)

        package_config = get_packit_config_from_repo(
            sourcegit_project=github_repo, ref=ref)

        if not package_config:
            logger.debug(
                f"No packit config: skipping pull-request {pr_id} for {namespace}/{repo_name}."
            )
            return
        self.sync_upstream_pull_request(
            package_config=package_config,
            pr_id=pr_id,
            dist_git_branch="master",
            upstream_local_project=local_project,
        )

    def sync_upstream_pull_request(
        self,
        package_config: PackageConfig,
        pr_id: int,
        dist_git_branch: str,
        upstream_local_project: LocalProject,
    ):
        logger.info("syncing the upstream code to downstream")
        packit_api = PackitAPI(
            config=self.config,
            package_config=package_config,
            upstream_local_project=upstream_local_project,
        )
        packit_api.sync_pr(pr_id=pr_id, dist_git_branch=dist_git_branch)

    def watch_upstream_release(self):
        """
        Listen on fedmsg and sync the upstream releases to the upstream pull-request.
        """
        for topic, msg in self.consumerino.iterate_releases():
            self.sync_upstream_release_with_fedmsg(fedmsg=msg)

    def sync_upstream_release_with_fedmsg(self, fedmsg: Dict):
        """
        Sync the upstream release to the distgit pull-request.

        :param fedmsg: fedmsg dict
        """
        repo_name = fedmsg["msg"]["repository"]["name"]
        namespace = fedmsg["msg"]["repository"]["owner"]["login"]
        version = fedmsg["msg"]["release"]["tag_name"]
        https_url = fedmsg["msg"]["repository"]["html_url"]

        github_repo = self._github_service.get_project(  # type: ignore
            repo=repo_name, namespace=namespace)
        local_project = LocalProject(git_project=github_repo)

        package_config = get_packit_config_from_repo(
            sourcegit_project=github_repo, ref=version)

        if not package_config:
            logger.info(
                f"No packit config: skipping release {version} for {namespace}/{repo_name}."
            )
            return

        if not package_config.upstream_project_url:
            package_config.upstream_project_url = https_url

        # TODO: https://github.com/packit-service/packit/issues/103
        self.sync_upstream_release(
            package_config=package_config,
            version=version,
            dist_git_branch="master",
            upstream_local_project=local_project,
        )

    def sync_upstream_release(
        self,
        package_config: PackageConfig,
        version: Optional[str],
        dist_git_branch: str,
        upstream_local_project: LocalProject,
    ):
        """
        Sync the upstream release to the distgit pull-request.

        :param package_config: PackageConfig
        :param version: not used now, str
        :param dist_git_branch: str
        :param upstream_local_project: LocalProject instance
        """
        logger.info("syncing the upstream code to downstream")
        packit_api = PackitAPI(
            config=self.config,
            package_config=package_config,
            upstream_local_project=upstream_local_project,
        )
        packit_api.sync_release(dist_git_branch=dist_git_branch,
                                version=version)

    def watch_fedora_ci(self):
        for topic, msg in self.consumerino.iterate_dg_pr_flags():
            self.sync_fedora_ci_with_fedmsg(fedmsg=msg)

    def sync_fedora_ci_with_fedmsg(self, fedmsg: Dict):
        raise NotImplementedError(
            "The watching of the Fedora CI is not implemented yet.")
        """
        repo_name = fedmsg["msg"]["pull_request"]["project"]["name"]
        namespace = fedmsg["msg"]["pull_request"]["project"]["namespace"]
        pr_id = fedmsg["msg"]["pull_request"]["id"]

        pagure_repo = self._pagure_service.get_project(  # type: ignore
            repo=repo_name, namespace=namespace
        )

        pull_request = pagure_repo.get_pr_info(pr_id=pr_id)

        # TODO: Finish parsing fedmsg and call sync_fedora_ci
        """

    def sync_fedora_ci(self, package_config: PackageConfig):
        raise NotImplementedError(
            "The watching of the Fedora CI is not implemented yet.")
        """
Exemple #4
0
class SourceGitAPI:
    def __init__(self):
        # TODO: the url template should be configurable
        self.datagrepper_url = (
            "https://apps.fedoraproject.org/datagrepper/id?id={msg_id}&is_raw=true"
        )
        self.consumerino = Consumerino()

    def fetch_fedmsg_dict(self, msg_id: str) -> Dict[str, Any]:
        """
        Fetch selected message from datagrepper

        :param msg_id: str
        :return: dict, the fedmsg
        """
        logger.debug(f"Proccessing message: {msg_id}")
        url = self.datagrepper_url.format(msg_id=msg_id)
        response = requests.get(url)
        msg_dict = response.json()
        return msg_dict

    def sync_upstream_pr_to_distgit(self, fedmsg_dict: Dict[str, Any]) -> None:
        """
        Take the input fedmsg (github push or pr create) and sync the content into dist-git

        :param fedmsg_dict: dict, code change on github
        """
        logger.info("syncing the upstream code to downstream")
        with Synchronizer(
                self.github_token,
                self.pagure_user_token,
                self.pagure_package_token,
                self.pagure_fork_token,
        ) as sync:
            sync.sync_using_fedmsg_dict(fedmsg_dict)

    def keep_syncing_upstream_pulls(self) -> None:
        """
        Watch Fedora messages and keep syncing upstream PRs downstream. This runs forever.
        """
        with Synchronizer(
                self.github_token,
                self.pagure_user_token,
                self.pagure_package_token,
                self.pagure_fork_token,
        ) as sync:
            for topic, action, msg in self.consumerino.iterate_gh_pulls():
                # TODO:
                #   handle edited (what's that?)
                #   handle closed (merged & not merged)
                if action in ["opened", "synchronize", "reopened"]:
                    sync.sync_using_fedmsg_dict(msg)

    def process_ci_result(self, fedmsg_dict: Dict[str, Any]) -> None:
        """
        Take the CI result, figure out if it's related to source-git and if it is, report back to upstream

        :param fedmsg_dict: dict, flag added in pagure
        """
        sg = SourceGitCheckHelper(self.github_token, self.pagure_user_token)
        sg.process_new_dg_flag(fedmsg_dict)

    def keep_fwding_ci_results(self) -> None:
        """
        Watch Fedora messages and keep reporting CI results back to upstream PRs. This runs forever.
        """
        for topic, msg in self.consumerino.iterate_dg_pr_flags():
            self.process_ci_result(msg)

    @property
    @lru_cache()
    def github_token(self) -> str:
        return os.environ["GITHUB_TOKEN"]

    @property
    @lru_cache()
    def pagure_user_token(self) -> str:
        return os.environ["PAGURE_USER_TOKEN"]

    @property
    @lru_cache()
    def pagure_package_token(self) -> str:
        """ this token is used to comment on pull requests """
        # FIXME: make this more easier to be used -- no need for a dedicated token
        return os.environ["PAGURE_PACKAGE_TOKEN"]

    @property
    @lru_cache()
    def pagure_fork_token(self) -> str:
        """ this is needed to create pull requests """
        # FIXME: make this more easier to be used -- no need for a dedicated token
        return os.environ["PAGURE_FORK_TOKEN"]