Beispiel #1
0
    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)))
Beispiel #2
0
 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)
Beispiel #3
0
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)
Beispiel #4
0
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')
Beispiel #5
0
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]
Beispiel #6
0
    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()
Beispiel #7
0
    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)
Beispiel #8
0
 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
Beispiel #9
0
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
Beispiel #10
0
 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
Beispiel #11
0
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]
Beispiel #12
0
    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))
Beispiel #14
0
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')
Beispiel #15
0
 def setUp(self):
     self.gh = GitHub(GitHubToken(os.environ.get('GITHUB_TEST_TOKEN', '')))