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)}"))
def _enumerate_required_org_webhooks( whd_deployment_cfg: WebhookDispatcherDeploymentConfig, ): '''Returns tuples of 'github orgname', 'github api object' and 'webhook url' ''' cfg_factory = ctx().cfg_factory() whd_cfg_name = whd_deployment_cfg.webhook_dispatcher_config_name() whd_cfg = cfg_factory.webhook_dispatcher(whd_cfg_name) concourse_cfg_names = whd_cfg.concourse_config_names() concourse_cfgs = map(cfg_factory.concourse, concourse_cfg_names) for concourse_cfg in concourse_cfgs: job_mapping_set = cfg_factory.job_mapping( concourse_cfg.job_mapping_cfg_name()) for github_orgname, github_cfg_name in _enumerate_github_org_configs( job_mapping_set): github_api = _create_github_api_object( github_cfg=cfg_factory.github(github_cfg_name), ) webhook_url = create_url_from_attributes( netloc=whd_deployment_cfg.ingress_host(), scheme='https', path='github-webhook', params='', query='{name}={value}'.format( name=github.webhook.DEFAULT_ORG_HOOK_QUERY_KEY, value=whd_cfg_name), fragment='') yield (github_orgname, github_api, webhook_url)
def enumerate_definition_descriptors(self): github_cfg = github_cfg_for_hostname( cfg_factory=self.cfg_set, host_name=self._repository_url.hostname, ) github_api = _create_github_api_object(github_cfg=github_cfg) github_org, github_repo = self._repository_url.path.lstrip('/').split( '/') repository = github_api.repository(github_org, github_repo) yield from self._scan_repository_for_definitions( repository=repository, github_cfg=github_cfg, org_name=github_org, )
def assign_github_team_to_repo( github_cfg_name: str, github_org_name: str, auth_token: CliHint(help="Token from an org admin user. Token must have 'admin:org' scope"), team_name: str='ci' ): ''' Assign team 'team_name' to all repositories in organization 'github_org_name' and give the team admin rights on those repositories. The team will be created if it does not exist and the technical github user (from github_cfg_name) will be assigned to the team. The token of the technical github user must have the privilege to create webhooks (scope admin:repo_hook) 'auth_token' must grant 'admin:org' privileges. ''' cfg_factory = ctx().cfg_factory() github_cfg = cfg_factory.github(github_cfg_name) github_username = github_cfg.credentials().username() # overwrite auth_token github_cfg.credentials().set_auth_token(auth_token=auth_token) github = _create_github_api_object( github_cfg=github_cfg, ) _create_team( github=github, organization_name=github_org_name, team_name=team_name ) _add_user_to_team( github=github, organization_name=github_org_name, team_name=team_name, user_name=github_username ) _add_all_repos_to_team( github=github, organization_name=github_org_name, team_name=team_name )
def enumerate_definition_descriptors(self): executor = ThreadPoolExecutor(max_workers=8) # scan github repositories for github_org_cfg in self.job_mapping.github_organisations(): github_cfg = self.cfg_set.github(github_org_cfg.github_cfg_name()) github_org_name = github_org_cfg.org_name() info('scanning github organisation {gho}'.format( gho=github_org_name)) github_api = _create_github_api_object(github_cfg) github_org = github_api.organization(github_org_name) scan_repository_for_definitions = functools.partial( self._scan_repository_for_definitions, github_cfg=github_cfg, org_name=github_org_name, ) for definition_descriptors in executor.map( scan_repository_for_definitions, github_org.repositories(), ): yield from definition_descriptors