def hide_comments(pull: PullRequest) -> None:
        # rewriting history of branch removes commits
        # we do not want to show test results for those commits anymore
        req = Requester.Requester(token,
                                  password=None,
                                  jwt=None,
                                  base_url=MainClass.DEFAULT_BASE_URL,
                                  timeout=MainClass.DEFAULT_TIMEOUT,
                                  client_id=None,
                                  client_secret=None,
                                  user_agent="PyGithub/Python",
                                  per_page=MainClass.DEFAULT_PER_PAGE,
                                  verify=True,
                                  retry=None)

        def get_pull_request_comments(pull: PullRequest) -> List[Dict[str, Any]]:
            query = dict(
                query=r'query ListComments {'
                      r'  repository(owner:"' + repo.owner.login + r'", name:"' + repo.name + r'") {'
                      r'    pullRequest(number:' + str(pull.number) + r') {'
                      r'      comments(last: 100) {'
                      r'        nodes {'
                      r'          id, author { login }, body, isMinimized'
                      r'        }'
                      r'      }'
                      r'    }'
                      r'  }'
                      r'}'
            )

            headers, data = req.requestJsonAndCheck(
                "POST", 'https://api.github.com/graphql', input=query
            )

            return data \
                .get('data', {}) \
                .get('repository', {}) \
                .get('pullRequest', {}) \
                .get('comments', {}) \
                .get('nodes')

        def hide_comment(comment_node_id) -> bool:
            input = dict(
                query=r'mutation MinimizeComment {'
                      r'  minimizeComment(input: { subjectId: "' + comment_node_id + r'", classifier: OUTDATED } ) {'
                      r'    minimizedComment { isMinimized, minimizedReason }'
                      r'  }'
                      r'}'
            )
            headers, data = req.requestJsonAndCheck(
                "POST", 'https://api.github.com/graphql', input=input
            )
            return data.get('data').get('minimizeComment').get('minimizedComment').get('isMinimized')

        # get commits of this pull request
        commit_shas = set([commit.sha for commit in pull.get_commits()])

        # get commits of this pull request
        comments = get_pull_request_comments(pull)

        # get all comments that come from this action and are not hidden
        comments = list([comment for comment in comments
                         if comment.get('author', {}).get('login') == 'github-actions'
                         and comment.get('isMinimized') is False
                         and comment.get('body', '').startswith('## Unit Test Results\n')
                         and '\nresults for commit ' in comment.get('body')])

        # get comment node ids and their commit sha (possibly abbreviated)
        matches = [(comment.get('id'), re.search(r'^results for commit ([0-9a-f]{8,40})(?:\s.*)?$', comment.get('body'), re.MULTILINE))
                   for comment in comments]
        comment_commits = [(node_id, match.group(1)) for node_id, match in matches if match is not None]

        # get those comment node ids whose commit is not part of this pull request any more
        comment_ids = [(node_id, comment_commit_sha)
                       for (node_id, comment_commit_sha) in comment_commits
                       if not any([sha for sha in commit_shas if sha.startswith(comment_commit_sha)])]

        # we don't want to actually do this when not run by GitHub Actions GitHub App
        if os.environ.get('GITHUB_ACTIONS') is None:
            logger.warning('action not running on GitHub, skipping hiding comment')
            for node_id, comment_commit_sha in comment_ids:
                logger.info('commend for commit {} should be hidden'.format(comment_commit_sha))
            return

        # hide all those comments that do not have a commit
        for node_id, comment_commit_sha in comment_ids:
            logger.info('hiding unit test result comment for commit {}'.format(comment_commit_sha))
            hide_comment(node_id)
Ejemplo n.º 2
0
    def store_pull_request(self, pull_request: PullRequest,
                           results: Dict[str, Dict[str, Any]]):
        """Analyse pull request and save its desired features to results.

        Arguments:
            pull_request {PullRequest} -- PR that is going to be inspected and stored.
            results {Dict[str, Dict[str, Any]]} -- dictionary where all the currently
                                                PRs are stored and where the given PR
                                                will be stored.
        """
        commits = pull_request.commits
        # TODO: Use commits to extract information.
        # commits = [commit for commit in pull_request.get_commits()]

        created_at = int(pull_request.created_at.timestamp())
        closed_at = int(pull_request.closed_at.timestamp()
                        ) if pull_request.closed_at is not None else None
        merged_at = int(pull_request.merged_at.timestamp()
                        ) if pull_request.merged_at is not None else None

        closed_by = pull_request.as_issue(
        ).closed_by.login if pull_request.as_issue(
        ).closed_by is not None else None

        labels = [label.name for label in pull_request.get_labels()]

        # Evaluate size of PR
        pull_request_size = None
        if labels:
            pull_request_size = self.get_labeled_size(labels)

        if not pull_request_size:
            lines_changes = pull_request.additions + pull_request.deletions
            pull_request_size = self.assign_pull_request_size(
                lines_changes=lines_changes)

        results[str(pull_request.number)] = {
            "size":
            pull_request_size,
            "labels":
            self.get_non_standalone_labels(labels),
            "created_by":
            pull_request.user.login,
            "created_at":
            created_at,
            "closed_at":
            closed_at,
            "closed_by":
            closed_by,
            "merged_at":
            merged_at,
            "commits_number":
            commits,
            "referenced_issues":
            self.get_referenced_issues(pull_request),
            "interactions":
            self.get_interactions(pull_request.get_issue_comments()),
            "reviews":
            self.extract_pull_request_reviews(pull_request),
            "requested_reviewers":
            self.extract_pull_request_review_requests(pull_request),
        }
Ejemplo n.º 3
0
async def test_fetch_pull_requests_since_date(mocker):  # pylint: disable=too-many-locals
    """fetch_pull_requests_since_date should construct a graphql query and fetch the results of that query"""
    org = "org"
    repo = "repo"
    token = "token"
    cursor = 'some cursor'
    pr_number = 12345
    url = 'http://url.com'
    title = "A PR title"
    body = "PR body"
    updated_in_bounds = datetime(2020, 1, 2, tzinfo=timezone.utc)
    updated_out_bounds = datetime(2019, 1, 1, tzinfo=timezone.utc)
    since = date(2020, 1, 1)

    edge_in_bounds = {
        'cursor': cursor,
        'node': {
            'number': pr_number,
            'url': url,
            'updatedAt': updated_in_bounds.isoformat(),
            'title': title,
            'body': body,
        }
    }
    edge_out_bounds = {
        'cursor': None,
        'node': {
            'number': pr_number,
            'url': url,
            'updatedAt': updated_out_bounds.isoformat(),
            'title': title,
            'body': body,
        }
    }
    result_in_bounds = {
        'data': {
            'organization': {
                'repository': {
                    'pullRequests': {
                        'edges': [edge_in_bounds]
                    }
                }
            }
        }
    }
    result_out_bounds = {
        'data': {
            'organization': {
                'repository': {
                    'pullRequests': {
                        'edges': [edge_out_bounds]
                    }
                }
            }
        }
    }

    patched = mocker.async_patch(
        'github.run_query', side_effect=[result_in_bounds, result_out_bounds])

    prs = [
        pr async for pr in fetch_pull_requests_since_date(
            github_access_token=token, org=org, repo=repo, since=since)
    ]
    assert prs == ([
        PullRequest(
            number=pr_number,
            title=title,
            body=body,
            updatedAt=updated_in_bounds.date(),
            org=org,
            repo=repo,
            url=url,
        )
    ])
    patched.assert_any_call(
        github_access_token=token,
        query=make_pull_requests_query(org=org, repo=repo, cursor=None),
    )
    patched.assert_any_call(
        github_access_token=token,
        query=make_pull_requests_query(org=org, repo=repo, cursor=cursor),
    )