Пример #1
0
    def _check_issue_comment_event(
        self,
        event: Union[IssueCommentEvent, IssueCommentGitlabEvent],
        project: GitProject,
        service_config: ServiceConfig,
        job_configs: Iterable[JobConfig],
    ) -> bool:
        actor_name = event.actor
        if not actor_name:
            raise KeyError(
                f"Failed to get login of the actor from {type(event)}")
        project_url = self._strip_protocol_and_add_git(event.project_url)

        namespace_approved = self.is_approved(project_url)
        user_approved = project.can_merge_pr(actor_name)

        if namespace_approved and user_approved:
            return True

        msg = (f"Project {project_url} is not on our allowlist!"
               if not namespace_approved else
               f"Account {actor_name} has no write access!")
        logger.debug(msg)
        project.get_issue(event.issue_id).comment(msg)
        return False
Пример #2
0
    def create_issue_if_needed(project: GitProject, title: str,
                               message: str) -> Optional[Issue]:
        # TODO: Improve filtering
        issues = project.get_issue_list()
        title = f"[packit] {title}"

        if any(title in issue.title for issue in issues):
            return None

        # TODO: store in DB
        return project.create_issue(title=title, body=message)
Пример #3
0
    def _check_pr_event(
        self,
        event: Union[PullRequestGithubEvent, PullRequestCommentGithubEvent,
                     MergeRequestGitlabEvent,
                     MergeRequestCommentGitlabEvent, ],
        project: GitProject,
        service_config: ServiceConfig,
        job_configs: Iterable[JobConfig],
    ) -> bool:
        actor_name = event.actor
        if not actor_name:
            raise KeyError(
                f"Failed to get login of the actor from {type(event)}")

        project_url = self._strip_protocol_and_add_git(event.project_url)

        namespace_approved = self.is_approved(project_url)
        user_approved = (project.can_merge_pr(actor_name)
                         or project.get_pr(event.pr_id).author == actor_name)

        if namespace_approved and user_approved:
            # TODO: clear failing check when present
            return True

        msg = (
            f"Project {project_url} is not on our allowlist!"
            if not namespace_approved else
            f"Account {actor_name} has no write access nor is author of PR!")
        logger.debug(msg)
        if isinstance(
                event,
            (PullRequestCommentGithubEvent, MergeRequestCommentGitlabEvent)):
            project.get_pr(event.pr_id).comment(msg)
        else:
            for job_config in job_configs:
                job_helper = CoprBuildJobHelper(
                    service_config=service_config,
                    package_config=event.get_package_config(),
                    project=project,
                    metadata=EventData.from_event_dict(event.get_dict()),
                    db_trigger=event.db_trigger,
                    job_config=job_config,
                    targets_override=event.targets_override,
                )
                msg = ("Namespace is not allowed!"
                       if not namespace_approved else "User cannot trigger!")
                job_helper.report_status_to_all(description=msg,
                                                state=BaseCommitStatus.neutral,
                                                url=FAQ_URL)

        return False
Пример #4
0
    def get_package_config_from_repo(
        project: GitProject,
        reference: Optional[str] = None,
        base_project: Optional[GitProject] = None,
        pr_id: int = None,
        fail_when_missing: bool = True,
        spec_file_path: Optional[str] = None,
    ):
        """
        Get the package config and catch the invalid config scenario and possibly no-config scenario
        """

        if not base_project and not project:
            return None

        project_to_search_in = base_project or project
        try:
            package_config: PackageConfig = get_package_config_from_repo(
                project=project_to_search_in,
                ref=reference,
                spec_file_path=spec_file_path,
            )
            if not package_config and fail_when_missing:
                raise PackitConfigException(
                    f"No config file found in {project_to_search_in.full_repo_name} "
                    "on ref '{reference}'"
                )
        except PackitConfigException as ex:
            if pr_id:
                project.pr_comment(
                    pr_id, f"Failed to load packit config file:\n```\n{str(ex)}\n```"
                )
            else:
                # TODO: filter when https://github.com/packit/ogr/issues/308 fixed
                issues = project.get_issue_list()
                if "Invalid packit config" not in [x.title for x in issues]:
                    # TODO: store in DB
                    message = (
                        f"Failed to load packit config file:\n```\n{str(ex)}\n```\n"
                        "For more info, please check out the documentation: "
                        "http://packit.dev/packit-as-a-service/ or contact us - "
                        "[Packit team]"
                        "(https://github.com/orgs/packit/teams/the-packit-team)"
                    )

                    i = project.create_issue(
                        title="[packit] Invalid config", body=message
                    )
                    logger.debug(f"Created issue for invalid packit config: {i.url}")
            raise ex
        return package_config
Пример #5
0
    def get_package_config_from_repo(
        project: GitProject,
        reference: Optional[str] = None,
        base_project: Optional[GitProject] = None,
        pr_id: int = None,
        fail_when_missing: bool = True,
        spec_file_path: Optional[str] = None,
    ) -> Optional[PackageConfig]:
        """
        Get the package config and catch the invalid config scenario and possibly no-config scenario
        """

        if not base_project and not project:
            return None

        project_to_search_in = base_project or project
        try:
            package_config: PackageConfig = get_package_config_from_repo(
                project=project_to_search_in,
                ref=reference,
                spec_file_path=spec_file_path,
            )
            if not package_config and fail_when_missing:
                raise PackitMissingConfigException(
                    f"No config file for packit (e.g. `.packit.yaml`) found in "
                    f"{project_to_search_in.full_repo_name} on commit {reference}"
                )
        except PackitConfigException as ex:
            message = (
                f"{str(ex)}\n\n"
                if isinstance(ex, PackitMissingConfigException)
                else f"Failed to load packit config file:\n```\n{str(ex)}\n```\n"
            )
            message += (
                "For more info, please check out the documentation: "
                "https://packit.dev/docs/packit-service or contact us - "
                "[Packit team]"
                "(https://github.com/orgs/packit/teams/the-packit-team)"
            )

            if pr_id:
                project.get_pr(pr_id).comment(message)
            elif created_issue := PackageConfigGetter.create_issue_if_needed(
                project, title="Invalid config", message=message
            ):
                logger.debug(
                    f"Created issue for invalid packit config: {created_issue.url}"
                )
            raise ex
Пример #6
0
def get_packit_config_from_repo(sourcegit_project: GitProject,
                                branch: str) -> Optional[PackageConfig]:
    for config_file_name in CONFIG_FILE_NAMES:
        try:
            config_file = sourcegit_project.get_file_content(
                path=config_file_name, ref=branch)
            logger.debug(
                f"Found a config file '{config_file_name}' "
                f"on branch '{branch}' "
                f"of the {sourcegit_project.full_repo_name} repository.")
        except FileNotFoundError:
            logger.debug(
                f"The config file '{config_file_name}' "
                f"not found on branch '{branch}' "
                f"of the {sourcegit_project.full_repo_name} repository.")
            continue

        try:
            loaded_config = anymarkup.parse(config_file)
        except Exception as ex:
            logger.error(f"Cannot load package config '{config_file_name}'.")
            raise Exception(f"Cannot load package config: {ex}.")

        return parse_loaded_config(loaded_config=loaded_config)

    return None
Пример #7
0
def test_check_and_report_pr_comment_approve(whitelist):
    event = PullRequestCommentEvent(PullRequestAction["opened"], 0, "", "", "",
                                    "", "", "lojzo", "")
    gp = GitProject("", GitService(), "")
    flexmock(gp).should_receive("pr_comment").with_args(
        0, "Account is not whitelisted!").never()
    assert whitelist.check_and_report(event, gp)
Пример #8
0
def build_handler(metadata=None, trigger=None):
    if not metadata:
        metadata = {
            "owner": "nobody",
            "targets": [
                "fedora-29-x86_64",
                "fedora-30-x86_64",
                "fedora-31-x86_64",
                "fedora-rawhide-x86_64",
            ],
        }
    jobs = [
        JobConfig(
            job=JobType.copr_build,
            trigger=trigger or JobTriggerType.pull_request,
            metadata=metadata,
        )
    ]
    pkg_conf = PackageConfig(jobs=jobs, downstream_package_name="dummy")
    event = Parser.parse_pr_event(pull_request())
    handler = CoprBuildHandler(
        config=ServiceConfig(),
        package_config=pkg_conf,
        project=GitProject("", GitService(), ""),
        event=event,
    )
    handler._api = PackitAPI(ServiceConfig, pkg_conf)
    return handler
Пример #9
0
def test_get_package_config_from_repo_alternative_config_name():
    gp = flexmock(GitProject)
    gp.should_receive("full_repo_name").and_return("a/b")
    gp.should_receive("get_file_content").with_args(path=".packit.yaml",
                                                    ref=None).and_raise(
                                                        FileNotFoundError,
                                                        "not found")
    gp.should_receive("get_file_content").with_args(
        path=".packit.yml",
        ref=None).and_return("---\nspecfile_path: packit.spec\n"
                             "synced_files:\n"
                             "  - packit.spec\n"
                             "  - src: .packit.yaml\n"
                             "    dest: .packit2.yaml")
    config = PackageConfigGetter.get_package_config_from_repo(
        project=GitProject(repo="", service=GitService(), namespace=""),
        reference=None,
        spec_file_path="packit.spec",
    )
    assert isinstance(config, PackageConfig)
    assert config.specfile_path == "packit.spec"
    assert config.synced_files == SyncFilesConfig(files_to_sync=[
        SyncFilesItem(src="packit.spec", dest="packit.spec"),
        SyncFilesItem(src=".packit.yaml", dest=".packit2.yaml"),
    ])
    assert config.create_pr
Пример #10
0
def get_package_config_from_repo(sourcegit_project: GitProject,
                                 ref: str) -> Optional[PackageConfig]:
    for config_file_name in CONFIG_FILE_NAMES:
        try:
            config_file_content = sourcegit_project.get_file_content(
                path=config_file_name, ref=ref)
            logger.debug(
                f"Found a config file '{config_file_name}' "
                f"on ref '{ref}' "
                f"of the {sourcegit_project.full_repo_name} repository.")
        except FileNotFoundError as ex:
            logger.debug(
                f"The config file '{config_file_name}' "
                f"not found on ref '{ref}' "
                f"of the {sourcegit_project.full_repo_name} repository."
                f"{ex!r}")
            continue

        try:
            loaded_config = safe_load(config_file_content)
        except Exception as ex:
            logger.error(f"Cannot load package config '{config_file_name}'.")
            raise PackitException(f"Cannot load package config: {ex}.")
        return parse_loaded_config(loaded_config=loaded_config,
                                   config_file_path=config_file_name)

    logger.warning(f"No config file found on ref '{ref}' "
                   f"of the {sourcegit_project.full_repo_name} repository.")
    return None
Пример #11
0
def test_get_packit_config_from_repo(content):
    flexmock(GitProject).should_receive("get_file_content").and_return(content)
    git_project = GitProject(repo="", service=GitService(), namespace="")
    config = get_packit_config_from_repo(sourcegit_project=git_project, ref="")
    assert isinstance(config, PackageConfig)
    assert config.specfile_path == "packit.spec"
    assert set(config.synced_files) == {"packit.spec", ".packit.yaml"}
def build_helper(
    event: Union[PullRequestEvent, PullRequestCommentEvent, CoprBuildEvent,
                 PushGitHubEvent, ReleaseEvent, ],
    metadata=None,
    trigger=None,
    jobs=None,
):
    if not metadata:
        metadata = {
            "owner":
            "nobody",
            "targets": [
                "fedora-29-x86_64",
                "fedora-30-x86_64",
                "fedora-31-x86_64",
                "fedora-rawhide-x86_64",
            ],
        }
    jobs = jobs or []
    jobs.append(
        JobConfig(
            type=JobType.copr_build,
            trigger=trigger or JobConfigTriggerType.pull_request,
            metadata=metadata,
        ))
    pkg_conf = PackageConfig(jobs=jobs, downstream_package_name="dummy")
    handler = CoprBuildJobHelper(
        config=ServiceConfig(),
        package_config=pkg_conf,
        project=GitProject("", GitService(), ""),
        event=event,
    )
    handler._api = PackitAPI(ServiceConfig(), pkg_conf)
    return handler
Пример #13
0
def test_check_and_report_calls_method(whitelist, event, method, approved):
    gp = GitProject("", GitService(), "")
    mocked_gp = (flexmock(gp).should_receive(method).with_args(
        0, "Neither account bar nor owner foo are on our whitelist!"))
    mocked_gp.never() if approved else mocked_gp.once()
    assert (whitelist.check_and_report(
        event, gp, config=flexmock(deployment=Deployment.stg)) is approved)
Пример #14
0
def get_package_config_from_repo(sourcegit_project: GitProject,
                                 ref: str) -> Optional[PackageConfig]:
    for config_file_name in CONFIG_FILE_NAMES:
        try:
            config_file_content = sourcegit_project.get_file_content(
                path=config_file_name, ref=ref)
        except FileNotFoundError:
            # do nothing
            pass
        else:
            logger.debug(
                f"Found a config file '{config_file_name}' "
                f"on ref '{ref}' "
                f"of the {sourcegit_project.full_repo_name} repository.")
            break
    else:
        logger.warning(
            f"No config file ({CONFIG_FILE_NAMES}) found on ref '{ref}' "
            f"of the {sourcegit_project.full_repo_name} repository.")
        return None

    try:
        loaded_config = safe_load(config_file_content)
    except Exception as ex:
        logger.error(f"Cannot load package config {config_file_name!r}. {ex}")
        raise PackitConfigException(
            f"Cannot load package config {config_file_name!r}. {ex}")
    return parse_loaded_config(
        loaded_config=loaded_config,
        config_file_path=config_file_name,
        repo_name=sourcegit_project.repo,
        spec_file_path=get_specfile_path_from_repo(sourcegit_project, ref),
    )
Пример #15
0
def test_check_and_report_pr_comment_reject(whitelist):
    event = PullRequestCommentEvent(PullRequestAction["opened"], 0, "brcalnik",
                                    "", "", "", "", "rakosnicek", "")
    gp = GitProject("", GitService(), "")
    flexmock(gp).should_receive("pr_comment").with_args(
        0,
        "Neither account rakosnicek nor owner brcalnik are on our whitelist!"
    ).once()
    assert not whitelist.check_and_report(event, gp)
Пример #16
0
    def get_current_branch_pr(self, git_project: GitProject) -> PullRequest:
        """
        If the current branch is assoctiated with a PR, get it, otherwise return None
        """
        current_branch = self.get_current_branch()

        pr_re = re.compile(r"^pr/(\d+)$")
        m = pr_re.match(current_branch)
        if m:
            pr_id = int(m.group(1))
            pr = git_project.get_pr(pr_id)
            return pr

        # FIXME: could this logic be in ogr? input: branch + repo, output: pr
        for pr in git_project.get_pr_list():
            if (pr.source_branch == current_branch
                    and pr.author == git_project.service.user.get_username()):
                return pr
Пример #17
0
def test_get_packit_config_from_repo(content):
    flexmock(GitProject).should_receive("get_file_content").and_return(content)
    git_project = GitProject(repo="", service=GitService(), namespace="")
    config = get_packit_config_from_repo(sourcegit_project=git_project, ref="")
    assert isinstance(config, PackageConfig)
    assert Path(config.specfile_path).name == "packit.spec"
    assert config.synced_files == SyncFilesConfig(files_to_sync=[
        SyncFilesItem(src="packit.spec", dest="packit.spec"),
        SyncFilesItem(src=".packit.yaml", dest=".packit2.yaml"),
    ])
Пример #18
0
def test_get_package_config_from_repo_spec_file_not_defined(content):
    gp = flexmock(GitProject)
    gp.should_receive("full_repo_name").and_return("a/b")
    gp.should_receive("get_file_content").and_return(content)
    gp.should_receive("get_files").and_return(["packit.spec"])
    git_project = GitProject(repo="", service=GitService(), namespace="")
    config = get_package_config_from_repo(project=git_project, ref="")
    assert isinstance(config, PackageConfig)
    assert Path(config.specfile_path).name == "packit.spec"
    assert config.create_pr
Пример #19
0
    def get_package_config_from_repo(
        self,
        project: GitProject,
        reference: str,
        pr_id: int = None,
        fail_when_missing: bool = True,
    ):
        """
        Get the package config and catch the invalid config scenario and possibly no-config scenario
        Static because of the easier mocking.
        """
        try:
            package_config: PackageConfig = get_package_config_from_repo(
                project, reference
            )
            if not package_config and fail_when_missing:
                raise PackitConfigException(
                    f"No config file found in {project.full_repo_name}"
                )
        except PackitConfigException as ex:
            if pr_id:
                project.pr_comment(
                    pr_id, f"Failed to load packit config file:\n```\n{str(ex)}\n```"
                )
            else:
                # TODO: filter when https://github.com/packit-service/ogr/issues/308 fixed
                issues = project.get_issue_list()
                if "Invalid packit config" not in [x.title for x in issues]:
                    # TODO: store in DB
                    message = (
                        f"Failed to load packit config file:\n```\n{str(ex)}\n```\n"
                        "For more info, please check out the documentation: "
                        "http://packit.dev/packit-as-a-service/ or contact us - "
                        "[Packit team]"
                        "(https://github.com/orgs/packit-service/teams/the-packit-team)"
                    )

                    i = project.create_issue(
                        title="[packit] Invalid config", body=message
                    )
                    logger.debug(f"Created issue for invalid packit config: {i.url}")
            raise ex
        return package_config
Пример #20
0
def get_specfile_path_from_repo(project: GitProject) -> Optional[str]:
    """
    Get the path of the spec file in the given repo if present.
    :param project: GitProject
    :return: str path of the spec file or None
    """
    spec_files = project.get_files(filter_regex=r".+\.spec$")
    if not spec_files:
        logger.debug(f"No spec file found in {project.full_repo_name}")
        return None
    return spec_files[0]
Пример #21
0
def get_specfile_path_from_repo(project: GitProject):
    """
    Get the path of the spec file in the given repo if present.
    :param project: GitProject
    :return: str path of the spec file
    """
    try:
        return project.get_files(filter_regex=".*.spec")[0]
    except Exception as ex:
        logger.debug(f"Cannot find the spec file: {ex}")
        return None
Пример #22
0
def test_get_package_config_from_repo_not_found_exception_pr():
    gp = flexmock(GitProject)
    gp.should_receive("full_repo_name").and_return("a/b")
    gp.should_receive("get_file_content").and_raise(FileNotFoundError, "not found")
    gp.should_receive("pr_comment").and_return(None).once()
    with pytest.raises(PackitConfigException):
        PackageConfigGetter.get_package_config_from_repo(
            project=GitProject(repo="", service=GitService(), namespace=""),
            reference=None,
            pr_id=2,
        )
Пример #23
0
def test_get_package_config_from_repo_not_found():
    gp = flexmock(GitProject)
    gp.should_receive("full_repo_name").and_return("a/b")
    gp.should_receive("get_file_content").and_raise(FileNotFoundError,
                                                    "not found")
    assert (PackageConfigGetter.get_package_config_from_repo(
        project=GitProject(repo="", service=GitService(), namespace=""),
        reference=None,
        pr_id=2,
        fail_when_missing=False,
    ) is None)
Пример #24
0
def test_check_and_report_calls_method(whitelist, event, method, approved):
    gp = GitProject("", GitService(), "")
    mocked_gp = (flexmock(gp).should_receive(method).with_args(
        0, "Neither account bar nor owner foo are on our whitelist!"))
    mocked_gp.never() if approved else mocked_gp.once()
    whitelist_mock = flexmock(DBWhitelist).should_receive("get_account")
    if approved:
        whitelist_mock.and_return(DBWhitelist(status="approved_manually"))
    else:
        whitelist_mock.and_return(None)
    assert (whitelist.check_and_report(
        event, gp, config=flexmock(deployment=Deployment.stg)) is approved)
Пример #25
0
def test_get_package_config_from_repo_not_found_exception_existing_issue():
    gp = flexmock(GitProject)
    gp.should_receive("full_repo_name").and_return("a/b")
    gp.should_receive("get_file_content").and_raise(FileNotFoundError,
                                                    "not found")
    gp.should_receive("get_issue_list").and_return(
        [flexmock(title="Invalid packit config")]).once()
    with pytest.raises(PackitConfigException):
        PackageConfigGetter.get_package_config_from_repo(
            project=GitProject(repo="", service=GitService(), namespace=""),
            reference=None,
        )
Пример #26
0
def get_specfile_path_from_repo(project: GitProject, ref: str = None) -> Optional[str]:
    """
    Get the path of the spec file in the given repo if present.
    :param project: GitProject
    :param ref: git ref (defaults to repo's default branch)
    :return: str path of the spec file or None
    """
    spec_files = project.get_files(ref=ref, filter_regex=r".+\.spec$")

    if not spec_files:
        logger.debug(f"No spec file found in {project.full_repo_name!r}")
        return None
    return spec_files[0]
Пример #27
0
def test_get_package_config_from_repo_spec_file_not_defined(content):
    specfile_path = "packit.spec"
    gp = flexmock(GitProject)
    gp.should_receive("full_repo_name").and_return("a/b")
    gp.should_receive("get_file_content").and_return(content)
    gp.should_receive("get_files").and_return([specfile_path])
    git_project = GitProject(repo="", service=GitService(), namespace="")
    config = get_package_config_from_repo(project=git_project)
    assert isinstance(config, PackageConfig)
    assert Path(config.specfile_path).name == specfile_path
    assert config.create_pr
    for j in config.jobs:
        assert j.specfile_path == specfile_path
        assert j.downstream_package_name == config.downstream_package_name
        assert j.upstream_package_name == config.upstream_package_name
Пример #28
0
    def _check_issue_comment_event(
        self,
        event: Union[IssueCommentEvent, IssueCommentGitlabEvent],
        project: GitProject,
        service_config: ServiceConfig,
        job_configs: Iterable[JobConfig],
    ) -> bool:
        account_name = event.user_login
        if not account_name:
            raise KeyError(f"Failed to get account_name from {type(event)}")
        namespace = event.repo_namespace

        namespace_approved = self.is_approved(namespace)
        user_approved = project.can_merge_pr(account_name)

        if namespace_approved and user_approved:
            return True

        msg = (f"Namespace {namespace} is not on our allowlist!"
               if not namespace_approved else
               f"Account {account_name} has no write access!")
        logger.error(msg)
        project.issue_comment(event.issue_id, msg)
        return False
Пример #29
0
def build_helper(
    event: Union[
        PullRequestGithubEvent,
        PullRequestCommentGithubEvent,
        PushGitHubEvent,
        ReleaseEvent,
    ],
    metadata=None,
    trigger=None,
    jobs=None,
    db_trigger=None,
):
    if not metadata:
        metadata = JobMetadataConfig(
            targets=[
                "fedora-29-x86_64",
                "fedora-30-x86_64",
                "fedora-31-x86_64",
                "fedora-rawhide-x86_64",
            ],
            owner="nobody",
        )
    jobs = jobs or []
    jobs.append(
        JobConfig(
            type=JobType.production_build,
            trigger=trigger or JobConfigTriggerType.pull_request,
            metadata=metadata,
        )
    )

    pkg_conf = PackageConfig(jobs=jobs, downstream_package_name="dummy")
    handler = KojiBuildJobHelper(
        service_config=ServiceConfig(),
        package_config=pkg_conf,
        job_config=pkg_conf.jobs[0],
        project=GitProject(repo=flexmock(), service=flexmock(), namespace=flexmock()),
        metadata=flexmock(
            trigger=event.trigger,
            pr_id=event.pr_id,
            git_ref=event.git_ref,
            commit_sha=event.commit_sha,
            identifier=event.identifier,
        ),
        db_trigger=db_trigger,
    )
    handler._api = PackitAPI(config=ServiceConfig(), package_config=pkg_conf)
    return handler
Пример #30
0
def test_copr_build_success_gitlab_comment(gitlab_mr_event):
    helper = build_helper(
        event=gitlab_mr_event,
        db_trigger=flexmock(
            job_config_trigger_type=JobConfigTriggerType.pull_request, id=123),
    )
    flexmock(BaseBuildJobHelper).should_receive(
        "is_gitlab_instance").and_return(True)
    flexmock(BaseBuildJobHelper).should_receive("base_project").and_return(
        GitProject(
            repo="the-example-repo",
            service=flexmock(),
            namespace="the-example-namespace",
        ))
    flexmock(GitProject).should_receive("request_access").and_return()
    flexmock(GitProject).should_receive("pr_comment").and_return()
    flexmock(BaseBuildJobHelper).should_receive(
        "is_reporting_allowed").and_return(False)
    flexmock(GitProject).should_receive("get_pr").and_return(flexmock())
    flexmock(SRPMBuildModel).should_receive("create").and_return(
        SRPMBuildModel(success=True))
    flexmock(CoprBuildModel).should_receive("get_or_create").and_return(
        CoprBuildModel(id=1))
    flexmock(MergeRequestGitlabEvent).should_receive("db_trigger").and_return(
        flexmock())

    flexmock(PackitAPI).should_receive("create_srpm").and_return("my.srpm")

    # copr build
    flexmock(CoprHelper).should_receive(
        "create_copr_project_if_not_exists").and_return(None)
    flexmock(CoprHelper).should_receive("get_copr_client").and_return(
        flexmock(
            config={"copr_url": "https://copr.fedorainfracloud.org/"},
            build_proxy=flexmock().should_receive(
                "create_from_file").and_return(
                    flexmock(id=2,
                             projectname="the-project-name",
                             ownername="the-owner")).mock(),
            mock_chroot_proxy=flexmock().should_receive("get_list").and_return(
                {target: ""
                 for target in DEFAULT_TARGETS}).mock(),
        ))
    flexmock(Pushgateway).should_receive("push_copr_build_created")

    flexmock(Celery).should_receive("send_task").once()
    assert helper.run_copr_build()["success"]