def store_issue(issue: Issue, data: Dict[str, Dict[str, Any]]): """Extract required information from issue and store it to the current data. This is targeted only for issues that are not Pull Requests. Arguments: issue {Issue} -- Issue (that is not PR). data {Dict[str, Union[str, int]])} -- Dictionary where the issue will be stored. """ if issue.pull_request is not None: return # we analyze issues and prs differentely created_at = issue.created_at.timestamp() closed_at = issue.closed_at.timestamp() time_to_close = closed_at - created_at labels = [label.name for label in issue.get_labels()] data[issue.number] = { "created_by": issue.user.login, "created_at": created_at, "closed_by": issue.closed_by.login, "closed_at": closed_at, "labels": get_non_standalone_labels(labels), "time_to_close": time_to_close, "interactions": get_interactions(issue.get_comments()), }
def parser_issue(issue: Issue) -> dict: info = {} info["title"] = issue.title info["labels"] = GithubObjectParser.parser_labels(issue.labels) info["time"] = issue.created_at.strftime('%Y/%m/%d') #info["comments"] = issue.get_comments info["comments"] = GithubObjectParser.parser_comments(issue.get_comments()) return info
def make_issue(number): """Helper method to create a fake Issue and ParsedIssue given a number""" return Issue( number=number, title=f"Issue {number}", status="closed", org=TEST_ORG, repo=TEST_REPO, updatedAt=datetime(2019, 6, 5, tzinfo=timezone.utc), url="http://b.net/example/uri" )
def fetch_issues( since: datetime, until: datetime) -> Tuple[Sequence[Issue], Sequence[PullRequest]]: zh = ZenHubAPI(config['zenhub_key'], config['zenhub_pkey']) gh = github.Github(config['github_key']) closed_range = f'{since.strftime("%Y-%m-%d")}..{until.strftime("%Y-%m-%d")}' issues = itertools.chain.from_iterable( (gh.search_issues('is:issue', repo=gh.get_repo(int(repo)).full_name, closed=closed_range) for repo in config['repos'])) prs = itertools.chain.from_iterable( (gh.search_issues('is:pr', repo=gh.get_repo(int(repo)).full_name, closed=closed_range) for repo in config['repos'])) return [Issue(iss, zh) for iss in issues], [PullRequest(pr, zh) for pr in prs]
def try_assign(issue: github.Issue): # find the most recent assignment request assignment_request = None for comment in issue.get_comments().reversed: if '/assign' in comment.body: assignment_request = comment break if not assignment_request: # Looks like no one wants this issue return if not issue.assignees: # If no one has been assigned yet, let the user take the issue issue.add_to_assignees(assignment_request.user) issue.create_comment(f'assigned {assignment_request.user.login}') return # Disable this logic due to an issue. Will re-visit this logic # and will be re-enabled after testing #if issue_age(issue) > 30: # # If the issue is 1 months old and the original assignees haven't # # closed it yet, let's assume that they've stopped working on it and # # allow the new user to have this issue # old_assignees = issue.assignees # for assignee in old_assignees: # issue.remove_from_assignees(assignee) # issue.add_to_assignees(assignment_request.user) # comment_body = f'unassigned: {", ".join([str(a) for a in old_assignees])}\n' + \ # f'assigned: {assignment_request.user.login}' # issue.create_comment(comment_body) # return # If we've made it here, a user has requested to be assigned to a non-stale # issue which is already assigned. Just notify the core team and let them # handle the conflict. comment_body = f'Unable to assign {assignment_request.user.login}. Please ' + \ f'contact a member of the @airshipit/airship-cores team for ' + \ f'help with assignments.' issue.create_comment(comment_body)
def remove_label(issue: github.Issue, label: str): try: LOG.debug(f'Removing `{label}` label from issue #{issue_number}') issue.remove_from_labels(label) except github.GithubException: LOG.debug(f'`{label}` tag does not exist on issue #{issue_number}')