Exemple #1
0
    def _notify_broken_definition_owners(self, failed_descriptor):
        definition_descriptor = failed_descriptor.definition_descriptor
        main_repo = definition_descriptor.main_repo
        github_cfg = github_cfg_for_hostname(self._cfg_set,
                                             main_repo['hostname'])
        github_api = _create_github_api_object(github_cfg)
        repo_owner, repo_name = main_repo['path'].split('/')

        githubrepobranch = GitHubRepoBranch(
            github_config=github_cfg,
            repo_owner=repo_owner,
            repo_name=repo_name,
            branch=main_repo['branch'],
        )

        repo_helper = GitHubRepositoryHelper.from_githubrepobranch(
            githubrepobranch=githubrepobranch, )

        codeowners_enumerator = CodeownersEnumerator()
        codeowners_resolver = CodeOwnerEntryResolver(github_api=github_api)
        recipients = set(
            codeowners_resolver.resolve_email_addresses(
                codeowners_enumerator.enumerate_remote_repo(
                    github_repo_helper=repo_helper)))

        # in case no codeowners are available, resort to using the committer
        if not recipients:
            head_commit = repo_helper.repository.commit(main_repo['branch'])
            user_ids = {
                user_info.get('login')
                for user_info in (head_commit.committer, head_commit.author)
                if user_info.get('login')
            }
            for user_id in user_ids:
                user = github_api.user(user_id)
                if user.email:
                    recipients.add(user.email)

        # if there are still no recipients available print a warning
        if not recipients:
            warning(
                textwrap.dedent(f"""
                Unable to determine recipient for pipeline '{definition_descriptor.pipeline_name}'
                found in branch '{main_repo['branch']}' ({main_repo['path']}). Please make sure that
                CODEOWNERS and committers have exposed a public e-mail address in their profile.
                """))
        else:
            info(
                f'Sending notification e-mail to {recipients} ({main_repo["path"]})'
            )
            email_cfg = self._cfg_set.email()
            _send_mail(
                email_cfg=email_cfg,
                recipients=recipients,
                subject='Your pipeline definition in {repo} is erroneous'.
                format(repo=main_repo['path'], ),
                mail_template=
                (f"The pipeline definition for pipeline '{definition_descriptor.pipeline_name}' "
                 f" on branch '{main_repo['branch']}' contains errors.\n\n"
                 f"Error details:\n{str(failed_descriptor.error_details)}"))
Exemple #2
0
def determine_mail_recipients(src_dir, github_cfg_name):
    '''
    returns a generator yielding all email addresses for the given (git) repository work tree
    Email addresses are looked up:
    - from head commit: author and committer
    - from *CODEOWNERS files [0]

    Email addresses are not de-duplicated (this should be done by consumers)

    [0] https://help.github.com/articles/about-codeowners/
    '''
    cfg_factory = ctx().cfg_factory()

    github_cfg = cfg_factory.github(github_cfg_name)
    github_api = githubutil._create_github_api_object(github_cfg)

    # commiter/author from head commit
    repo = git.Repo(ensure_directory_exists(src_dir))
    head_commit = repo.commit(repo.head)
    yield head_commit.author.email.lower()
    yield head_commit.committer.email.lower()

    # codeowners
    parser = CodeownersParser(repo_dir=src_dir)
    resolver = CodeOwnerEntryResolver(github_api=github_api)

    codeowner_entries = parser.parse_codeowners_entries()
    yield from resolver.resolve_email_addresses(codeowner_entries)
Exemple #3
0
def determine_codeowner_file_recipients(
        github_api,
        codeowners_files=(),
):
    '''returns a generator yielding e-mail adresses from the given CODEOWNERS file(s).
    '''
    enumerator = CodeownersEnumerator()
    resolver = CodeOwnerEntryResolver(github_api=github_api)

    def enumerate_entries_from_codeowners_files(codeowners_files):
        for codeowners_file in codeowners_files:
            yield from enumerator.enumerate_single_file(codeowners_file)

    entries = enumerate_entries_from_codeowners_files(codeowners_files)
    yield from resolver.resolve_email_addresses(entries)
Exemple #4
0
def _codeowners_parser_from_component(
    component: cm.Component,
    branch_name: str = 'master',
):
    main_source = cnudie.util.determine_main_source_for_component(
        component=component,
        absent_ok=False,
    )
    if not main_source.access.type is cm.AccessType.GITHUB:
        raise NotImplementedError(main_source.access.type)

    access = main_source.access
    github_api = ccc.github.github_api_from_gh_access(access=access)

    repo_helper = ccc.github.repo_helper(
        host=access.hostname(),
        org=access.org_name(),
        repo=access.repository_name(),
        branch=branch_name,
    )

    resolver = CodeOwnerEntryResolver(github_api=github_api)
    enumerator = CodeownersEnumerator()

    return resolver, enumerator.enumerate_remote_repo(
        github_repo_helper=repo_helper)
Exemple #5
0
def determine_local_repository_codeowners_recipients(
        github_api,
        src_dirs=(),
):
    '''returns a generator yielding e-mail adresses from all given repository work
    tree's CODEOWNERS files.
    '''
    enumerator = CodeownersEnumerator()
    resolver = CodeOwnerEntryResolver(github_api=github_api)

    def enumerate_entries_from_src_dirs(src_dirs):
        for src_dir in src_dirs:
            yield from enumerator.enumerate_local_repo(repo_dir=src_dir)

    entries = enumerate_entries_from_src_dirs(src_dirs)

    yield from resolver.resolve_email_addresses(entries)
Exemple #6
0
def _codeowners_parser_from_component_name(component_name: str, branch_name='master'):
    component_name = product.model.ComponentName(component_name)
    github_cfg = ccc.github.github_cfg_for_hostname(
        cfg_factory=ctx().cfg_factory(),
        host_name=component_name.github_host(),
    )
    github_api = ccc.github.github_api(github_cfg=github_cfg)

    repo_helper = ccc.github.repo_helper(
        host=component_name.github_host(),
        org=component_name.github_organisation(),
        repo=component_name.github_repo(),
        branch=branch_name,
    )

    resolver = CodeOwnerEntryResolver(github_api=github_api)
    enumerator = CodeownersEnumerator()

    return resolver, enumerator.enumerate_remote_repo(github_repo_helper=repo_helper)
Exemple #7
0
def _codeowners_parser_from_component_name(component_name: str,
                                           branch_name='master'):
    component_name = product.model.ComponentName(component_name)
    github_cfg = github.util.github_cfg_for_hostname(
        cfg_factory=ctx().cfg_factory(),
        host_name=component_name.github_host(),
    )
    github_api = github.util._create_github_api_object(github_cfg=github_cfg)

    githubrepobranch = github.util.GitHubRepoBranch(
        github_config=github_cfg,
        repo_owner=component_name.github_organisation(),
        repo_name=component_name.github_repo(),
        branch=branch_name,
    )

    github_repo_helper = github.util.GitHubRepositoryHelper.from_githubrepobranch(
        githubrepobranch=githubrepobranch, )

    resolver = CodeOwnerEntryResolver(github_api=github_api)
    enumerator = CodeownersEnumerator()

    return resolver, enumerator.enumerate_remote_repo(
        github_repo_helper=github_repo_helper)