Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

grab maximum amount of comments to fix issue with --merge-pr if there any many comments in a PR #2553

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from

Conversation

boegel
Copy link
Member

@boegel boegel commented Aug 23, 2018

This fixes a problem I ran into when merging easybuilders/easybuild-easyconfigs#6677 using eb --merge-pr:

$ eb --merge-pr 6677

== temporary log file in case of crash /Users/kehoste/work/TMP/eb-OIjkhI/easybuild-VQoHGP.log

easybuilders/easybuild-easyconfigs PR #6677 was submitted by akesandgren, you are using GitHub account 'boegel'

Checking eligibility of easybuilders/easybuild-easyconfigs PR #6677 for merging...
* targets develop branch: OK
* test suite passes: OK
* last test report is successful: FAILED => not eligible for merging!
* last test report is successful: FAILED => not eligible for merging!
* last test report is successful: OK
* approved review: OK (by boegel)
* milestone is set: OK (3.7.0)

WARNING: Review indicates this PR should not be merged (use -f/--force to do so anyway)

The problem is that this PR has many comments, exceeded the default number of comments that are returned by the GitHub API.

There's still a problem when a PR has more than 100 comments, but to fix that we'll need to make the fetching of comments page-aware, cfr. https://developer.github.com/v3/#pagination + https://developer.github.com/v3/guides/traversing-with-pagination/

@boegel boegel added the bug fix label Aug 23, 2018
@boegel boegel added this to the 3.7.0 milestone Aug 23, 2018
@boegel boegel requested a review from damianam August 23, 2018 12:49
@damianam
Copy link
Member

@boegel I think it is possible to disable pagination altogether: https://github.com/api-platform/docs/blob/master/core/pagination.md

Whether that makes sense or not..... I am not sure. It could potentially be a problem, but I doubt in reality it will happen, as it would need a very large number of comments to be an issue.

'-D',
'--github-user=%s' % GITHUB_TEST_ACCOUNT,
]
stdout, stderr = self._run_mock_eb(args, do_build=True, raise_error=True, testing=False)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a silly comment: Doesn't it make sense to set do_build=False and testing=True? I took a brief look at the _run_mock_eb code (and eb_main, and main), and I don't think it makes any difference, but still.....

@@ -1004,7 +1005,7 @@ def merge_pr(pr):

# also fetch comments
comments_url = lambda g: g.repos[pr_target_account][pr_target_repo].issues[pr].comments
status, comments_data = github_api_get_request(comments_url, github_user)
status, comments_data = github_api_get_request(comments_url, github_user, per_page=GITHUB_MAX_PER_PAGE)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment here stating that a PR with lots of comments (> GITHUB_MAX_PER_PAGE ) might fail?

@boegel boegel modified the milestones: 3.7.0, next release Sep 4, 2018
@boegel boegel modified the milestones: 3.7.1, next release Oct 4, 2018
@boegel boegel modified the milestones: 3.8.0, 3.8.1 Nov 20, 2018
@boegel boegel modified the milestones: 3.8.1, 3.x Jan 16, 2019
@migueldiascosta
Copy link
Member

more generically (since other types of API calls can also be paginated and the defaults can be different), we could traverse pages whenever they are present (according to the Link header)

I had to slightly change vsc.utils.rest in order for head() to actually return the headers, e.g.

--- a/lib/vsc/utils/rest.py
+++ b/lib/vsc/utils/rest.py
@@ -174,11 +174,14 @@ class Client(object):
         # TODO: in recent python: Context manager
         conn = self.get_connection(method, url, body, headers)
         status = conn.code
-        body = conn.read()
-        try:
-            pybody = json.loads(body)
-        except ValueError:
-            pybody = body
+        if method == self.HEAD:
+            pybody = conn.headers
+        else:
+            body = conn.read()
+            try:
+                pybody = json.loads(body)
+            except ValueError:
+                pybody = body
         fancylogger.getLogger().debug('reponse len: %s ', len(pybody))
         conn.close()
         return status, pybody

but once we have the headers, githup_api_get_request could generically handle pagination with something like

--- a/easybuild/tools/github.py
+++ b/easybuild/tools/github.py
@@ -243,10 +243,36 @@ def github_api_get_request(request_f, github_user=None, token=None, **kwargs):
     url = request_f(RestClient(GITHUB_API_URL, username=github_user, token=token))
 
     try:
-        status, data = url.get(**kwargs)
+        status, headers = url.head(**kwargs)
     except socket.gaierror as err:
-        _log.warning("Error occurred while performing get request: %s", err)
-        status, data = 0, None
+        _log.warning("Error occurred while getting headers from request: %s", err)
+        status, headers = 0, None
+
+    npages = 1
+    if headers:
+        links = headers.getheader('Link')
+        if links:
+            match = re.search(r"page=(\d+)>; rel=\"last\"", links)
+            if match:
+                npages = int(match.groups()[0])
+
+    if npages > 1:
+        data = []
+        for page in range(1, npages+1):
+            kwargs['page'] = page
+            try:
+                status, page_data = url.get(**kwargs)
+            except socket.gaierror as err:
+                _log.warning("Error occurred while performing get request: %s", err)
+                status, page_data = 0, None
+                break
+            data.extend(page_data)
+    else:
+        try:
+            status, data = url.get(**kwargs)
+        except socket.gaierror as err:
+            _log.warning("Error occurred while performing get request: %s", err)
+            status, data = 0, None
 
     _log.debug("get request result for %s: status: %d, data: %s", url, status, data)
     return (status, data)

?

@boegel
Copy link
Member Author

boegel commented Feb 7, 2019

@migueldiascosta Are you up for opening a PR to vsc-base for making that change?

We'll need to keep in mind to port that change into the 4.x branch here where we've ingested vsc-base...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants