def __init__(self, name): logger = logging.getLogger(__name__ + '.__init__') self.name = name self.IGH = GitHub(GitHubToken(get_api_key('GH'))) self.IGL = GitLab(GitLabPrivateToken(get_api_key('GL'))) logger.info('loading org %s' % name) self.REPOS = dict() self.gh_repos = { repo.full_name.split('/')[-1]: repo for repo in filter( lambda x: (x.full_name.split('/')[0] == self.name), self.IGH.write_repositories) } self.REPOS.update(self.gh_repos) self.gl_repos = { repo.full_name.split('/')[-1]: repo for repo in filter( lambda x: (x.full_name.split('/')[0] == self.name), self.IGL.write_repositories) } self.REPOS.update(self.gl_repos) logger.info('loaded org %s with %d repositories' % (name, len(self.REPOS)))
def setUp(self): self.gh = GitHub(GitHubToken(os.environ.get('GITHUB_TEST_TOKEN', ''))) self.repo_name = 'org/test_repo' self.default_data = { 'repository': { 'full_name': self.repo_name }, 'pull_request': { 'number': 0 }, 'issue': { 'number': 0 }, 'action': 'opened', 'comment': { 'id': 1, }, 'commit': { 'sha': 'deadbeef', } } self.jwt = GitHubJsonWebToken(os.environ['GITHUB_PRIVATE_KEY'], int(os.environ['GITHUB_TEST_APP_ID'])) self.itoken = GitHubInstallationToken(60731, self.jwt) self.gh_inst = GitHub(self.itoken)
def github_webhook_receiver(request): """ Receives webhooks from GitHub and carries out the approriate action. """ webhook = json.loads(request.body.decode('utf-8')) event = request.META['HTTP_X_GITHUB_EVENT'] repo_obj, token = None, None # responding to regular webhook calls for registered events if 'repository' in webhook: repository = webhook['repository'] repo_obj = get_object_or_404(Repository, identifier=repository['id'], active=True, provider=Providers.GITHUB.value) token = repo_obj.token # webhook was received from an installation if 'installation' in webhook: installation_obj, _ = Installation.objects.get_or_create( provider=Providers.GITHUB.value, identifier=webhook['installation']['id']) token = installation_obj.token # if the webhook is irrelevant, e.g. events like `ping`, `zen` etc. if token is None: # pragma: no cover return Response(status=status.HTTP_200_OK) try: for action, objs in GitHub(token).handle_webhook(event, webhook): ResponderRegistrar.respond(action, *objs, repo=repo_obj) except NotImplementedError: # pragma: no cover pass return Response(status=status.HTTP_200_OK)
class GitHubHosterTest(IGittTestCase): def setUp(self): self.gh = GitHub(GitHubToken(os.environ.get('GITHUB_TEST_TOKEN', ''))) def test_master_repositories(self): self.assertEqual( sorted(map(lambda x: x.full_name, self.gh.master_repositories)), [ 'GitMateIO/gitmate-2', 'GitMateIO/gitmate-2-frontend', 'gitmate-test-user/empty', 'gitmate-test-user/test' ]) def test_owned_repositories(self): self.assertEqual( sorted(map(lambda x: x.full_name, self.gh.owned_repositories)), ['gitmate-test-user/empty', 'gitmate-test-user/test']) def test_write_repositories(self): self.assertEqual( sorted(map(lambda x: x.full_name, self.gh.write_repositories)), [ 'GitMateIO/IGitt', 'GitMateIO/gitmate-2', 'GitMateIO/gitmate-2-frontend', 'gitmate-test-user/empty', 'gitmate-test-user/test', 'sils/gitmate-test' ]) def test_get_repo(self): self.assertEqual( self.gh.get_repo('gitmate-test-user/test').full_name, 'gitmate-test-user/test')
class GitOrg(): def __init__(self, name): logger = logging.getLogger(__name__ + '.__init__') self.name = name self.IGH = GitHub(GitHubToken(get_api_key('GH'))) self.IGL = GitLab(GitLabPrivateToken(get_api_key('GL'))) logger.info('loading org %s' % name) self.REPOS = dict() self.gh_repos = { repo.full_name.split('/')[-1]: repo for repo in filter( lambda x: (x.full_name.split('/')[0] == self.name), self.IGH.write_repositories) } self.REPOS.update(self.gh_repos) self.gl_repos = { repo.full_name.split('/')[-1]: repo for repo in filter( lambda x: (x.full_name.split('/')[0] == self.name), self.IGL.write_repositories) } self.REPOS.update(self.gl_repos) logger.info('loaded org %s with %d repositories' % (name, len(self.REPOS))) def get_repo(self, repo_name): logger = logging.getLogger(__name__ + '.get_repo') if repo_name not in self.REPOS: full_name = '%s/%s' % (self.name, repo_name) logger.info('loading non-writable repo %s' % full_name) try: repo = self.IGH.get_repo(full_name) # Use `clone_url` to ensure the repository is usable repo.clone_url self.REPOS[repo_name] = repo logger.info('loaded non-writable GitHub repo %s' % full_name) return repo except Exception as e: logger.error('Unable to load GitHub repo %s: %s' % (full_name, e)) try: repo = self.IGL.get_repo(full_name) # Use `clone_url` to ensure the repository is usable repo.clone_url logger.info('loaded non-writable GitLab repo %s' % full_name) self.REPOS[repo_name] = repo except Exception as e: logger.error('Unable to load GitLab repo %s: %s' % (full_name, e)) return self.REPOS[repo_name]
def __init__(self, bot, name=None): super().__init__(bot, name) teams = dict() try: gh = github3.login(token=os.environ.get('GH_TOKEN')) assert gh is not None except AssertionError: self.log.error( 'Cannot create github object, please check GH_TOKEN') else: self.GH3_ORG = gh.organization(self.GH_ORG_NAME) for team in self.GH3_ORG.teams(): teams[team.name] = team self._teams = teams self.IGH = GitHub(GitHubToken(os.environ.get('GH_TOKEN'))) self.IGL = GitLab(GitLabPrivateToken(os.environ.get('GL_TOKEN'))) self.REPOS = dict() try: self.gh_repos = { repo.full_name.split('/')[-1]: repo for repo in filter( lambda x: (x.full_name.split('/')[0] == self.GH_ORG_NAME), self.IGH.write_repositories) } except RuntimeError: self.log.exception( 'Something went wrong in fetching github repos.') else: self.REPOS.update(self.gh_repos) try: self.gl_repos = { repo.full_name.split('/')[-1]: repo for repo in filter( lambda x: (x.full_name.split('/')[0] == self.GL_ORG_NAME), self.IGL.write_repositories) } except RuntimeError: # pragma: no cover, for logging self.log.exception( 'Something went wrong in fetching gitlab repos.') else: self.REPOS.update(self.gl_repos) self.invited_users = set() self.hello_world_users = set()
def __init__(self, name): self.name = name self.IGH = GitHub(GitHubToken(get_api_key('GH'))) self.IGL = GitLab(GitLabPrivateToken(get_api_key('GL'))) print('loading org %s' % name) self.REPOS = dict() self.gh_repos = { repo.full_name.split('/')[-1]: repo for repo in filter( lambda x: (x.full_name.split('/')[0] == self.name), self.IGH.write_repositories) } self.REPOS.update(self.gh_repos) self.gl_repos = { repo.full_name.split('/')[-1]: repo for repo in filter( lambda x: (x.full_name.split('/')[0] == self.name), self.IGL.write_repositories) } self.REPOS.update(self.gl_repos) print('loaded org %s' % name)
def newcomer_issue_check(user, iss): """ True if: Issue is not labeled `difficulty/newcomer` and user is not a newcomer. False if: A `difficulty/newcomer` issue is already assigned to the user. """ if (self.is_newcomer_issue(iss) and self.is_team_member(user, 'newcomers')): search_query = 'user:coala assignee:{} ' \ 'label:difficulty/newcomer'.format(user) result = GitHub.raw_search( GitHubToken(self.config['GH_TOKEN']), search_query) return not (sum(1 for _ in result) >= 1) else: return True
def get_ihoster(url): global _IGH, _IGL if url.resource == 'github.com': if not _IGH: # Allow unauthenticated requests try: token = get_api_key('GH') except Exception: token = None _IGH = GitHub(GitHubToken(token)) return _IGH elif url.resource == 'gitlab.com': if not _IGL: # https://gitlab.com/gitmate/open-source/IGitt/issues/114 _IGL = GitLab(GitLabPrivateToken(get_api_key('GL'))) return _IGL
def newcomer_issue_check(user, iss): """ True if: Issue is not labeled `difficulty/newcomer` and user is not a newcomer. False if: A `difficulty/newcomer` issue is already assigned to the user. """ if (self.is_newcomer_issue(iss) and self.TEAMS[self.GH_ORG_NAME + ' newcomers'].is_member(user)): search_query = 'user:coala assignee:{} ' \ 'label:difficulty/newcomer'.format(user) result = GitHub.raw_search( GitHubToken(os.environ.get('GH_TOKEN')), search_query) return not (sum(1 for _ in result) >= 1) else: return True
class GitOrg(): def __init__(self, name): self.name = name self.IGH = GitHub(GitHubToken(get_api_key('GH'))) self.IGL = GitLab(GitLabPrivateToken(get_api_key('GL'))) print('loading org %s' % name) self.REPOS = dict() self.gh_repos = { repo.full_name.split('/')[-1]: repo for repo in filter( lambda x: (x.full_name.split('/')[0] == self.name), self.IGH.write_repositories) } self.REPOS.update(self.gh_repos) self.gl_repos = { repo.full_name.split('/')[-1]: repo for repo in filter( lambda x: (x.full_name.split('/')[0] == self.name), self.IGL.write_repositories) } self.REPOS.update(self.gl_repos) print('loaded org %s' % name) def get_repo(self, repo_name): if repo_name not in self.REPOS: full_name = '%s/%s' % (self.name, repo_name) print('loading non-writable repo %s' % full_name) try: repo = self.IGH.get_repo(full_name) repo.identifier self.REPOS[repo_name] = repo except Exception: print('Unable to load GitHub repo %s' % full_name) try: repo = self.IGL.get_repo(full_name) repo.identifier self.REPOS[repo_name] = repo except Exception: print('Unable to load GitLab repo %s' % full_name) return self.REPOS[repo_name]
def _search_in_range( self, issue_type, created_after: Optional[datetime]=None, created_before: Optional[datetime]=None, updated_after: Optional[datetime]=None, updated_before: Optional[datetime]=None, state: Union[MergeRequestStates, IssueStates, None]=None ): """ Search for issue based on type 'issue' or 'pr' and return a list of issues. """ from IGitt.GitHub.GitHub import GitHub if state is None: query = ' type:' + issue_type + ' repo:' + self.full_name else: query = (' type:' + issue_type + ' is:' + state.value + ' repo:' + self.full_name) if ((created_after and created_before) or (updated_after and updated_before)): raise RuntimeError(('Cannot process before ' 'and after date simultaneously')) if created_after: query += (' created:>=' + str(created_after.strftime('%Y-%m-%dT%H:%M:%SZ'))) elif created_before: query += (' created:<' + str(created_before.strftime('%Y-%m-%dT%H:%M:%SZ'))) if updated_after: query += (' updated:>=' + str(updated_after.strftime('%Y-%m-%dT%H:%M:%SZ'))) elif updated_before: query += (' updated:<' + str(updated_before.strftime('%Y-%m-%dT%H:%M:%SZ'))) return list(GitHub.raw_search(self._token, query))
def get_github(token): return GitHub(GitHubToken(token))
class TestGitHubWebhook(IGittTestCase): def setUp(self): self.gh = GitHub(GitHubToken(os.environ.get('GITHUB_TEST_TOKEN', ''))) self.repo_name = 'org/test_repo' self.default_data = { 'repository': { 'full_name': self.repo_name }, 'pull_request': { 'number': 0 }, 'issue': { 'number': 0 }, 'action': 'opened', 'comment': { 'id': 1, }, 'commit': { 'sha': 'deadbeef', } } self.jwt = GitHubJsonWebToken(os.environ['GITHUB_PRIVATE_KEY'], int(os.environ['GITHUB_TEST_APP_ID'])) self.itoken = GitHubInstallationToken(60731, self.jwt) self.gh_inst = GitHub(self.itoken) def test_unknown_event(self): with self.assertRaises(NotImplementedError): list(self.gh.handle_webhook('unknown_event', self.default_data)) def test_installation_deleted_hook(self): for event, obj in self.gh_inst.handle_webhook( 'installation', { 'installation': { 'id': 0 }, 'action': 'deleted', 'sender': { 'login': '******', 'id': 0 } }): inst, sender = obj self.assertEqual(event, InstallationActions.DELETED) self.assertIsInstance(inst, GitHubInstallation) self.assertIsInstance(sender, GitHubUser) self.assertEqual(sender.identifier, 0) self.assertEqual(sender.username, 'luke_skywalker') def test_installation_created_hook(self): for event, obj in self.gh_inst.handle_webhook( 'installation', { 'installation': { 'id': 0 }, 'action': 'created', 'repositories': [{ 'id': 0, 'full_name': 'star-wars/rogue1' }], 'sender': { 'login': '******', 'id': 0 } }): inst, sender, repos = obj self.assertEqual(event, InstallationActions.CREATED) self.assertIsInstance(inst, GitHubInstallation) self.assertIsInstance(sender, GitHubUser) self.assertEqual(sender.identifier, 0) self.assertEqual(sender.username, 'luke_skywalker') self.assertIsInstance(repos[0], GitHubRepository) self.assertEqual(repos[0].identifier, 0) self.assertEqual(repos[0].full_name, 'star-wars/rogue1') def test_installation_repositories_added_hook(self): for event, obj in self.gh_inst.handle_webhook( 'installation_repositories', { 'action': 'added', 'installation': { 'id': 0 }, 'repositories_added': [{ 'id': 0, 'full_name': 'foo/bar' }], 'sender': { 'login': '******', 'id': 0 } }): inst, sender, repos = obj self.assertEqual(event, InstallationActions.REPOSITORIES_ADDED) self.assertIsInstance(inst, GitHubInstallation) self.assertTrue( all([isinstance(repo, GitHubRepository) for repo in repos])) self.assertIsInstance(sender, GitHubUser) self.assertEqual(sender.identifier, 0) self.assertEqual(sender.username, 'luke_skywalker') def test_installation_repositories_removed_hook(self): for event, obj in self.gh_inst.handle_webhook( 'installation_repositories', { 'action': 'removed', 'installation': { 'id': 0 }, 'repositories_removed': [{ 'id': 0, 'full_name': 'foo/bar' }], 'sender': { 'login': '******', 'id': 0 } }): inst, sender, repos = obj self.assertEqual(event, InstallationActions.REPOSITORIES_REMOVED) self.assertIsInstance(inst, GitHubInstallation) self.assertTrue( all([isinstance(repo, GitHubRepository) for repo in repos])) self.assertIsInstance(sender, GitHubUser) self.assertEqual(sender.identifier, 0) self.assertEqual(sender.username, 'luke_skywalker') def test_issue_hook(self): for event, obj in self.gh.handle_webhook('issues', self.default_data): self.assertEqual(event, IssueActions.OPENED) self.assertIsInstance(obj[0], GitHubIssue) def test_pr_hook(self): for event, obj in self.gh.handle_webhook('pull_request', self.default_data): self.assertEqual(event, MergeRequestActions.OPENED) self.assertIsInstance(obj[0], GitHubMergeRequest) def test_pr_merge_hook(self): data = {**self.default_data, 'action': 'closed'} data['pull_request']['merged'] = True for event, obj in self.gh.handle_webhook('pull_request', data): self.assertEqual(event, MergeRequestActions.MERGED) self.assertIsInstance(obj[0], GitHubMergeRequest) def test_issue_comment(self): for event, obj in self.gh.handle_webhook('issue_comment', self.default_data): self.assertEqual(event, IssueActions.COMMENTED) self.assertIsInstance(obj[0], GitHubIssue) self.assertIsInstance(obj[1], GitHubComment) def test_pr_comment(self): data = self.default_data data['issue']['pull_request'] = {} # Exists for PRs for event, obj in self.gh.handle_webhook('issue_comment', data): self.assertEqual(event, MergeRequestActions.COMMENTED) self.assertIsInstance(obj[0], GitHubMergeRequest) self.assertIsInstance(obj[1], GitHubComment) def test_status(self): for event, obj in self.gh.handle_webhook('status', self.default_data): self.assertEqual(event, PipelineActions.UPDATED) self.assertIsInstance(obj[0], GitHubCommit) def test_issue_label(self): self.default_data.update({ 'label': { 'name': 'title' }, 'action': 'labeled', }) for event, obj in self.gh.handle_webhook('issues', self.default_data): self.assertEqual(event, IssueActions.LABELED) self.assertIsInstance(obj[0], GitHubIssue) self.assertEqual(obj[1], 'title') self.default_data.update({ 'label': { 'name': 'title' }, 'action': 'unlabeled', }) for event, obj in self.gh.handle_webhook('issues', self.default_data): self.assertEqual(event, IssueActions.UNLABELED) self.assertIsInstance(obj[0], GitHubIssue) self.assertEqual(obj[1], 'title') def test_pull_request_label(self): self.default_data.update({ 'label': { 'name': 'title' }, 'action': 'labeled', }) for event, obj in self.gh.handle_webhook('pull_request', self.default_data): self.assertEqual(event, MergeRequestActions.LABELED) self.assertIsInstance(obj[0], GitHubMergeRequest) self.assertEqual(obj[1], 'title') self.default_data.update({ 'label': { 'name': 'title' }, 'action': 'unlabeled', }) for event, obj in self.gh.handle_webhook('pull_request', self.default_data): self.assertEqual(event, MergeRequestActions.UNLABELED) self.assertIsInstance(obj[0], GitHubMergeRequest) self.assertEqual(obj[1], 'title')
def setUp(self): self.gh = GitHub(GitHubToken(os.environ.get('GITHUB_TEST_TOKEN', '')))