def handle_github_open_issue(issue: dict, repository: dict) -> None: # pragma: no cover """Will handle with care.""" _LOGGER.info(f"An Issue has been opened: {issue['url']}") if issue["title"].startswith("Automatic update of dependency"): _LOGGER.info( f"{issue['url']} is an 'automatic update of dependencies', not sending notification" ) return if issue["title"].startswith("Initial dependency lock"): _LOGGER.info( f"{issue['url']} is an 'automatic dependency lock', not sending notification" ) return if issue["title"].startswith( "Failed to update dependencies to their latest version"): _LOGGER.info( f"{issue['url']} is an 'failed to update dependencies', not sending notification" ) return notify_channel( "new_issue", f"{issue['user']['login']} just opened an issue: {issue['title']}... 🚨", issue["html_url"]) analysis = analyse_github_issue(issue) if "flake" in analysis["status"].keys(): _LOGGER.debug( f"{issue['number']} seems to be a flake: {analysis['status']['reason']}" ) repo = GitHubRepository(GitHubToken(_SESHETA_GITHUB_ACCESS_TOKEN), repository["full_name"]) try: repo.create_label("flake", "#f3ccff") repo.create_label("human_intervention_required", "#f3ccff") repo.create_label("potential_flake", "#f3ccff") except IGitt.ElementAlreadyExistsError as excptn: _LOGGER.error(excptn) igitt_issue = GitHubIssue(GitHubToken(_SESHETA_GITHUB_ACCESS_TOKEN), repository["full_name"], issue["number"]) labels = igitt_issue.labels labels.add("human_intervention_required") labels.add("potential_flake") igitt_issue.labels = labels
def raw_search(token, raw_query): """ Handles a GitHub search. Search syntax reference at https://help.github.com/articles/understanding-the-search-syntax/ :param token: A GitHubToken object to use for authentication. :param raw_query: A string with the search query following syntax. :yields: Search results as GitHubIssue(...) and GitHubMergeRequest(...) objects for Issues and Merge Requests respectively. """ base_url = '/search/issues' query_params = {'q': raw_query, 'per_page': '100'} resp = get(token, base_url, query_params) issue_url_re = re.compile( r'https://(?:.+)/(\S+)/(\S+)/(issues|pull)/(\d+)') for item in resp: user, repo, item_type, item_number = issue_url_re.match( item['html_url']).groups() if item_type == 'issues': yield GitHubIssue.from_data(item, token, user + '/' + repo, int(item_number)) elif item_type == 'pull': yield GitHubMergeRequest.from_data(item, token, user + '/' + repo, int(item_number))
def mentioned_issues(self) -> Set[GitHubIssue]: """ Returns a set of GitHubIssue objects which are related to the pull request. """ issues = self._get_mentioned_issues() return { GitHubIssue(self._token, repo_name, number) for number, repo_name in issues }
def closes_issues(self) -> Set[GitHubIssue]: """ Returns a set of GitHubIssue objects which would be closed upon merging this pull request. """ issues = self._get_closes_issues() return { GitHubIssue(self._token, repo_name, number) for number, repo_name in issues }
def filter_issues(self, state: str='opened') -> set: """ Filters the issues from the repository based on properties. :param state: 'opened' or 'closed' or 'all'. """ params = {'state': GH_ISSUE_STATE_TRANSLATION[state]} return {GitHubIssue.from_data(res, self._token, self.full_name, res['number']) for res in get(self._token, self._url + '/issues', params) if 'pull_request' not in res}
def create_issue(self, title: str, body: str='') -> GitHubIssue: """ Create a new issue in the repository. >>> from os import environ >>> repo = GitHubRepository(environ['GITHUB_TEST_TOKEN'], ... 'gitmate-test-user/test') >>> iss = repo.create_issue('test issue title', 'test body title') >>> isinstance(iss, GitHubIssue) True """ return GitHubIssue.create(self._token, self.full_name, title, body)
def test_assignee(self): self.assertEqual(self.iss.assignees, set()) iss = GitHubIssue(self.token, 'gitmate-test-user/test', 41) user = GitHubUser(self.token, 'meetmangukiya') iss.assignees = set() self.assertEqual(iss.assignees, set()) iss.assignees = {user} self.assertEqual(iss.assignees, {user}) iss.assignees = set() self.assertEqual(iss.assignees, set()) iss = GitHubIssue(self.token, 'gitmate-test-user/test', 107) self.assertEqual(iss.assignees, set())
def get_issue(self, issue_number: int): """ Retrieves an issue: >>> from os import environ >>> repo = GitHubRepository(GitHubToken(environ['GITHUB_TEST_TOKEN']), ... 'gitmate-test-user/test') >>> repo.get_issue(1).title 'test issue' :param issue_number: The issue ID of the issue to retrieve. :return: An Issue object. :raises ElementDoesntExistError: If the issue doesn't exist. :raises RuntimeError: If something goes wrong (network, auth...). """ return GitHubIssue(self._token, self.full_name, issue_number)
def _handle_webhook_issues(self, data, repository): """Handles 'issues' event.""" issue = data['issue'] issue_obj = GitHubIssue.from_data(issue, self._token, repository, issue['number']) trigger_event = { 'opened': IssueActions.OPENED, 'closed': IssueActions.CLOSED, 'reopened': IssueActions.REOPENED, 'labeled': IssueActions.LABELED, 'unlabeled': IssueActions.UNLABELED, }.get(data['action'], IssueActions.ATTRIBUTES_CHANGED) if (trigger_event is IssueActions.LABELED or trigger_event is IssueActions.UNLABELED): yield trigger_event, [issue_obj, data['label']['name']] else: yield trigger_event, [issue_obj]
def _handle_webhook_issue_comment(self, data, repository): """Handles 'issue_comment' event.""" if data['action'] != 'deleted': comment_obj = GitHubComment.from_data(data['comment'], self._token, repository, CommentType.MERGE_REQUEST, data['comment']['id']) if 'pull_request' in data['issue']: yield (MergeRequestActions.COMMENTED, [ GitHubMergeRequest.from_data(data['issue'], self._token, repository, data['issue']['number']), comment_obj ]) else: yield IssueActions.COMMENTED, [ GitHubIssue.from_data(data['issue'], self._token, repository, data['issue']['number']), comment_obj ]
def test_description_is_string(self): issue = GitHubIssue(self.token, 'gitmate-test-user/test', 12) issue.data['body'] = None self.assertEqual(issue.description, '')
def test_issue_create(self): iss = GitHubIssue.create(self.token, 'gitmate-test-user/test', 'test title', 'test body') self.assertEqual(iss.state, IssueStates.OPEN)
def setUp(self): self.token = GitHubToken(os.environ.get('GITHUB_TEST_TOKEN', '')) self.iss = GitHubIssue(self.token, 'gitmate-test-user/test', 39)
class GitHubIssueTest(IGittTestCase): def setUp(self): self.token = GitHubToken(os.environ.get('GITHUB_TEST_TOKEN', '')) self.iss = GitHubIssue(self.token, 'gitmate-test-user/test', 39) def test_repo(self): self.assertEqual(self.iss.repository.full_name, 'gitmate-test-user/test') def test_title(self): self.iss.title = 'new title' self.assertEqual(self.iss.title, 'new title') def test_assignee(self): self.assertEqual(self.iss.assignees, set()) iss = GitHubIssue(self.token, 'gitmate-test-user/test', 41) user = GitHubUser(self.token, 'meetmangukiya') iss.assignees = set() self.assertEqual(iss.assignees, set()) iss.assignees = {user} self.assertEqual(iss.assignees, {user}) iss.assignees = set() self.assertEqual(iss.assignees, set()) iss = GitHubIssue(self.token, 'gitmate-test-user/test', 107) self.assertEqual(iss.assignees, set()) def test_number(self): self.assertEqual(self.iss.number, 39) def test_description(self): self.iss.description = 'new description' self.assertEqual(self.iss.description, 'new description') def test_author(self): self.assertEqual(self.iss.author.username, 'meetmangukiya') def test_comment(self): self.iss.add_comment('this is a comment') self.assertEqual(self.iss.comments[0].body, 'this is a comment') def test_issue_labels(self): self.iss.labels = set() self.assertEqual(self.iss.labels, set()) self.iss.labels = self.iss.labels | {'dem'} self.iss.labels = self.iss.labels # Doesn't do a request :) self.assertEqual(len(self.iss.available_labels), 4) def test_time(self): self.assertEqual(self.iss.created, datetime.datetime(2017, 6, 6, 9, 36, 15)) self.assertEqual(self.iss.updated, datetime.datetime(2017, 10, 18, 8, 31, 13)) def test_state(self): self.iss.close() self.assertEqual(self.iss.state, IssueStates.CLOSED) self.assertEqual(str(self.iss.state), 'closed') self.iss.reopen() self.assertEqual(self.iss.state, IssueStates.OPEN) self.assertEqual(str(self.iss.state), 'open') def test_issue_create(self): iss = GitHubIssue.create(self.token, 'gitmate-test-user/test', 'test title', 'test body') self.assertEqual(iss.state, IssueStates.OPEN) def test_description_is_string(self): issue = GitHubIssue(self.token, 'gitmate-test-user/test', 12) issue.data['body'] = None self.assertEqual(issue.description, '') def test_reactions(self): issue = GitHubIssue(self.token, 'gitmate-test-user/test', 12) self.assertEqual(sorted([r.name for r in issue.reactions]), ['heart', 'hooray', 'laugh']) def test_mrs_closed_by(self): issue = GitHubIssue(self.token, 'gitmate-test-user/test', 131) self.assertEqual({int(i.number) for i in issue.mrs_closed_by}, {132})
def test_reactions(self): issue = GitHubIssue(self.token, 'gitmate-test-user/test', 12) self.assertEqual(sorted([r.name for r in issue.reactions]), ['heart', 'hooray', 'laugh'])
def test_mrs_closed_by(self): issue = GitHubIssue(self.token, 'gitmate-test-user/test', 131) self.assertEqual({int(i.number) for i in issue.mrs_closed_by}, {132})
def setUp(self): self.token = GitHubToken(os.environ.get('GITHUB_TEST_TOKEN', '')) self.iss = GitHubIssue(self.token, 'gitmate-test-user/test', 12) self.reaction = GitHubReaction(self.token, self.iss, 17051518)