Giter Club home page Giter Club logo

mergify's Introduction

mergify's People

Contributors

adrianjost avatar arahaan avatar blindpirate avatar blueyed avatar bmuskalla avatar borda avatar bowlofeggs avatar brandonb927 avatar calvellido avatar camclrt avatar colmose avatar dependabot-preview[bot] avatar dependabot[bot] avatar edahlseng avatar erwansimonetti avatar fangyi-zhou avatar greesb avatar guillaumeoj avatar guits avatar hmemcpy avatar ignasi35 avatar jd avatar jsoref avatar mauricedb avatar mergify[bot] avatar okurz avatar sileht avatar syffe avatar v1v avatar zerdanes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mergify's Issues

Add enabling_label option

Some users do not want Mergify to automerge if the number of reviews matching is ok. However, they are happy to see the patch merge if the CI passes + reviews are OK + a label is set.

In the same vein that Mergify offers disabling_label, having a enabling_label that would be required for Mergify to be active, would help some users.

(Think of this as the +2 Approved of Gerrit)

Add support to Check API

We support only Statuses API for required_status_check/contexts.

But Github have recently added a new Checks API. And Travis for example now send
Check Runs and Check Suites to Github in additional to Statuses.

As Github support now Check Runs names for required_status_check/contexts, we should to support it, too.

To do this we have a couple of things to do:

  • Looks at Check Runs list to compute our required_statuses_succeed
  • Subscribes and handles some check_suite/check_run Github events to refresh the Mergify status

Mismatch between schema and docs for restrictions

The documentation for restrictions (https://doc.mergify.io/configuration.html#restriction) reads that a Restriction is "a dictionary with the following optional keys: teams/users."

However in rules.py it seems to be defined as a list (https://github.com/Mergifyio/mergify-engine/blob/master/mergify_engine/rules.py#L45): 'restrictions': voluptuous.Any(None, []),.

At the moment when I try to define a teams restriction, it fails with: .mergify.yml is invalid: not a valid value for dictionary value @ data['rules']['default']['protection']['restrictions']".

Locally I can get it to pass if I adjust the rule to look like 'restrictions': voluptuous.Any(None, {'teams': [str], 'users': [str]}),.

Minimum .mergify.yml to reproduce:

rules:
  default:
    protection:
      restrictions:
        teams:
          - core

Write better merge commit message

Following the comments on awesomeWM/awesome#2300, I wonder if there is a better way to handle merge commits.

The issue that gave rise to that PR is that some people see those commits as pure noise. They only allow to tell which commits were part of a pull request. In itself, along with some git-blame Voodoo, is useful in itself (to me), but could Mergify.io add more value here?

Given (I guess) you can write the merge commit message, I wonder if adding some sort of template would add value to both Mergify as-a-product and to the git log itself. The template could carry more metadata about the PR such as:

  • Who approved it
  • Each GitHub CI service summary one liner (and if they passed, of course)
  • Some user comments (like auto-append the codecov.io coverage summary
  • The date the PR was opened
  • The username of the PR author (it isn't necessarily the same as the commit author)
  • The shortlog of each commit?
  • The PR description
  • The PR name
  • "Fetch this magic URL and append the content" for user-defined extensions?

This isn't a "I WANT THIS NOW!!!11!" kind of wish. It's just an idea how to make your service more useful and create more value for everybody.

Allow using existing github restrictions

It would be great if it was possible to configure mergify to use existing github configurtions. I already use github's own protected branch system to prevent merging before CI/CD tests pass/approval/etc, and I don't want to configure that in two places. Basically, I just want mergify to press the green merge button as soon as it's available.

compute_status retry doesn't stop after 3 retries

  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/rq/worker.py", line 789, in perform_job
    rv = job.perform()
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/rq/job.py", line 573, in perform
    self._result = self._execute()
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/rq/job.py", line 579, in _execute
    return self.func(*self.args, **self.kwargs)
  File "/data/web_www/gh.mergify.io/src/mergify_engine/worker.py", line 51, in event_handler
    user, repo).handle(event_type, data)
  File "/data/web_www/gh.mergify.io/src/mergify_engine/engine.py", line 185, in handle
    incoming_pull.fullify(cache, **fullify_extra)
  File "/data/web_www/gh.mergify.io/src/mergify_engine/gh_pr_fullifier.py", line 258, in fullify
    value = method(pull, **extra)
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/tenacity/__init__.py", line 241, in wrapped_f
    return self.call(f, *args, **kw)
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/tenacity/__init__.py", line 330, in call
    start_time=start_time)
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/tenacity/__init__.py", line 279, in iter
    return fut.result()
  File "/usr/lib/python3.5/concurrent/futures/_base.py", line 398, in result
    return self.__get_result()
  File "/usr/lib/python3.5/concurrent/futures/_base.py", line 357, in __get_result
    raise self._exception
...
...
...

  File "/data/web_www/gh.mergify.io/src/mergify_engine/gh_pr_fullifier.py", line 258, in fullify
    value = method(pull, **extra)
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/tenacity/__init__.py", line 241, in wrapped_f
    return self.call(f, *args, **kw)
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/tenacity/__init__.py", line 330, in call
    start_time=start_time)
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/tenacity/__init__.py", line 279, in iter
    return fut.result()
  File "/usr/lib/python3.5/concurrent/futures/_base.py", line 398, in result
    return self.__get_result()
  File "/usr/lib/python3.5/concurrent/futures/_base.py", line 357, in __get_result
    raise self._exception
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/tenacity/__init__.py", line 333, in call
    result = fn(*args, **kwargs)
  File "/data/web_www/gh.mergify.io/src/mergify_engine/gh_pr_fullifier.py", line 161, in compute_status
    disabled = disabled_by_rules(pull, **extra)
  File "/data/web_www/gh.mergify.io/src/mergify_engine/gh_pr_fullifier.py", line 128, in disabled_by_rules
    pull_files = [f.filename for f in pull.get_files()]
  File "/data/web_www/gh.mergify.io/src/mergify_engine/gh_pr_fullifier.py", line 128, in <listcomp>
    pull_files = [f.filename for f in pull.get_files()]
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/github/PaginatedList.py", line 58, in __iter__
    newElements = self._grow()
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/github/PaginatedList.py", line 70, in _grow
    newElements = self._fetchNextPage()
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/github/PaginatedList.py", line 172, in _fetchNextPage
    headers=self.__headers
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/github/Requester.py", line 260, in requestJsonAndCheck
    return self.__check(*self.requestJson(verb, url, parameters, headers, input, self.__customConnection(url)))
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/github/Requester.py", line 317, in requestJson
    return self.__requestEncode(cnx, verb, url, parameters, headers, input, encode)
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/github/Requester.py", line 370, in __requestEncode
    status, responseHeaders, output = self.__requestRaw(cnx, verb, url, requestHeaders, encoded_input)
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/github/Requester.py", line 394, in __requestRaw
    response = cnx.getresponse()
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/github/Requester.py", line 107, in getresponse
    r = verb(url, headers=self.headers, data=self.input, timeout=self.timeout, verify=self.verify)
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/requests/sessions.py", line 521, in get
    return self.request('GET', url, **kwargs)
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/requests/sessions.py", line 508, in request
    resp = self.send(prep, **send_kwargs)
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/raven/breadcrumbs.py", line 326, in send
    resp = real_send(self, request, *args, **kwargs)
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/requests/sessions.py", line 618, in send
    r = adapter.send(request, **kwargs)
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/requests/adapters.py", line 440, in send
    timeout=timeout
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/urllib3/connectionpool.py", line 601, in urlopen
    chunked=chunked)
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/urllib3/connectionpool.py", line 387, in _make_request
    six.raise_from(e, None)
  File "<string>", line 2, in raise_from
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/urllib3/connectionpool.py", line 383, in _make_request
    httplib_response = conn.getresponse()
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/raven/breadcrumbs.py", line 375, in getresponse
    rv = real_getresponse(self, *args, **kwargs)
  File "/usr/lib/python3.5/http/client.py", line 1198, in getresponse
    response.begin()
  File "/usr/lib/python3.5/http/client.py", line 321, in begin
    self.headers = self.msg = parse_headers(self.fp)
  File "/usr/lib/python3.5/http/client.py", line 215, in parse_headers
    return email.parser.Parser(_class=_class).parsestr(hstring)
  File "/usr/lib/python3.5/email/parser.py", line 68, in parsestr
    return self.parse(StringIO(text), headersonly=headersonly)
  File "/usr/lib/python3.5/email/parser.py", line 50, in parse
    feedparser = FeedParser(self._class, policy=self.policy)
  File "/usr/lib/python3.5/email/feedparser.py", line 161, in __init__
    _factory(policy=self.policy)
RecursionError: maximum recursion depth exceeded

The six.reraise make the end of the bt wierd, I see the 255 retry in logs.

Don't use Github branch protection for required_pull_request_reviews

Some features requested are currently not implementable:

  • Per pull request (metadata/label) for required_pull_request_reviews settings
  • Anything that will change commits sha of the the pull request head branch (like rebase/squash/...)

required_pull_request_reviews is the easiest part of Github branch protection to get rid. We already have the code in place for required_approving_review_count. dismiss_stale_reviews should be easy to implement (pull_request/synchronise event -> dismiss all reviews). Only require_code_owner_reviews is a bit of work.

Ability to automatically create GitHub releases based on milestone

The idea is to automate the release process by putting PRs in a milestone that will represent a GitHub release. So one milestone can be named v3.0.2, you put two PR in it. Once all the PRs from that milestone are merged, Mergify will create a tag and push it on GitHub.

Bonus: Mergify will also build a changelog by comparing the content of the latest tag with HEAD, e,g: git log --oneline v3.0.1..HEAD --no-decorate and put in the release message.

Thanks!

Pull PR requirements from GitHub settings

Most of the settings for Mergify are duplicates of GitHub branch protection settings. In order to avoid duplication, it would be awesome to be able to set the Mergify settings to pull from GitHub instead of specifying them again in the config.

Mergify triggers a GitHub 405 when it updates the status and pull request are closed

I don't think the status check set status fail: Validation Failed should occur.

The complete log:

2018-07-06 14:06:05,247 [27830] INFO     mergify_engine.engine: Just update cache (pull_request closed)
2018-07-06 14:06:05,248 [27830] INFO     mergify_engine.gh_pr: ceph/ceph-ansible/pull/2852@master (blocked/nc/nc/nc) set status to success (Pull request closed unmerged)
2018-07-06 14:06:05,528 [27830] ERROR    mergify_engine.gh_pr: ceph/ceph-ansible/pull/2852@master (blocked/nc/nc/nc) set status fail: Validation Failed
Traceback (most recent call last):
  File "/data/web_www/gh.mergify.io/src/mergify_engine/gh_pr.py", line 73, in mergify_engine_github_post_check_status
    'application/vnd.github.machine-man-preview+json'}
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/github/Requester.py", line 260, in requestJsonAndCheck
    return self.__check(*self.requestJson(verb, url, parameters, headers, input, self.__customConnection(url)))
  File "/var/www/gh.mergify.io/venv/lib/python3.5/site-packages/github/Requester.py", line 271, in __check
    raise self.__createException(status, responseHeaders, output)
github.GithubException.GithubException: 422 {'errors': [{'message': 'This SHA and context has reached the maximum number of statuses.', 'code': 'custom', 'resource': 'Status'}], 'message': 'Validation Failed', 'documentation_url': 'https://developer.github.com/v3/repos/statuses/#create-a-status'}

Add multiple rules management per branch

Hello,

First, thanks for this very useful service !

Sometime, for the same branch, we want a different behavior based on some criteria (PR title, user, ...).

For example, I use Pyup to manage my Python dependencies and for these changes, I only want Travis tests pass, but use another criterias for other changes on the same destination branch.

So if it could be possible to manage multiple rules for the same branch, this would be useful.

Have a nice day

Configuration file validation

It would be nice to have a tool that could validate the .mergify.yml before committing it to your repository. I ran into a few syntax errors, that were caused by whitespace issues. Having a sanity check prior to committing that file would of gotten me up and running faster.

Don't wait for CI to return to update a branch

When using strict workflow, it would be nice to update the next PR to be merged as soon as a PR is merged, without waiting for the CI to return. For example:

  • dismiss_stale_reviews: false, strict: true
  • Two pull requests are opened, CI builds starts for both of them
  • Both pull requests are approved, waiting for the CI build to finish
  • CI build passes for the first pull request, it is up to date with master, Mergify merges it
  • CI build still runs for the second pull request. When it finishes, Mergify will update the pull request with all of the changes from master, and CI build will start again for this pull request. Instead, Mergify could update the second pull request instantly as soon as it sees that it became not up-to-date. It is an approved pull request, so the only blocker for merging it is the CI build.

However, there's also one drawback: if you cancel the builds while it was at 90% and was going to fail at 95%, you won't know it was going to fail. So by retriggering the CI, you'll restart a new entire build just to know that the PR needs to be fixed, and knowing that just cost you the double amount of CI.

Obviously, that's my pessmistic side talking. If most PR pass your CI on the first run, there might be some saving. :)

Allow different merge strategies depending on PR metadata

Ref: awesomeWM/awesome#2300 (comment)

Hello, I could not find it in the doc (but didn't look too deep either), so I open this issue. Feel free to close it with RTFM if it already exists.

Current situation:

Larger PR with many small commits would lose valuable association metadata if each commit is rebased on top of master without a merge commit. On the other hand, small one liners commit with merge commits are plan noise. Given they obviously exist, then of course they were merged, no need for a commit to say that.

So as @blueyed propose, having a way to configure Mergify to use different merge strategies in different situation would make sense. The most obvious threshold is commit count, but I guess it could also be number of line changed or number of files too (but I personally don't really care about those 2)

Possible rule bypass

The fix for #24 (which is 74c6856) allows a configuration bypass:
I just add a PR that changes .mergify.yml to require zero reviews etc. Unless something in the code prevents "just merge anything"-configs, this PR will be merged. Assuming the project in question also uses Travis, this method could e.g. be used to extract secrets from Travis (which is why Travis uses the .travis.yml from the default branch and not from the PR).

Ref: awesomeWM/awesome#2260 (comment)

Only merge if all required reviewers approved a PR

Stolen from isaacs/github#1205:

I would like to have a flag on the repo that when enabled requires all assigned reviewers to approve the PR before it can be merged.

We are currently using the specific number of reviews required, but this is too rigid for our workflow. For us, the number of reviewers required depends on what was touched by the PR.

We have automation that assigns the necessary reviewers to our PRs. Having a simple check that required all assigned reviewers to approve the PR is the last piece of our workflow puzzle.

Path based reviews

Hi, not sure if this is the right place to ask or propose this idea but what would be really great is if you could automatically merge PRs that only affect changed files of a certain path.
The use case would be something like a central repository that is used for meta data such as for example Symfony's recipes contrib repo (https://github.com/symfony/recipes-contrib).
There are loads of recipes for all kinds of different vendors and everybody is allowed to add PRs but you cannot grant 500 people push access but rather just want them to review and approve PRs that affect e.g. their own vendor path.
That's why it would be awesome if you could configure people that are sort of "owner" of a given path so that even though these users do not have push access to the repo, they can trigger mergify by approving the PR.

So something like

path_owners:
   - { path: '/vendor', users: ['foobar', 'other-person'] }
   - { path: '/different-path/sub-directory', users: ['john-doe'] }

Not sure if you understand what I'm talking about ๐Ÿ˜„

Change the way we compute required reviews

If not all collaborator have review permissions, the shown number may be wrong.

We should looks at the permission to not count collaborateur that can't review.

We should look at "Restrictions" to get the list of contributors.

Add a rebase_and_merge strategy

Hello, me again,

In our current quest to use Mergify (as @jd proposed) to standardize our merging workflow, we come across this:

screenshot_20180722_074613

As seen in this screenshot, the graph is a bit messy. This will happen a lot more often with Mergify because maintainers tend to review the pull requests in bunch. GitHub as a "rebase this pull request" button. Gerrit even make pressing the button mandatory.

Having Mergify.io take care of this would be greatly appreciated in the short term. I would consider this (from my point of view), an high priority feature.

The rebase_and_merge strategy

It would be greatly appreciated if Mergify could automatically rebase the branches before merging them.

Of course, in some case it can fail, so, just as the normal "rebase" strategy has a fallback, "rebase_and_merge" also need a fallback. Given it would create 2 fallback variables, maybe it is also better to make a more generic "chain of strategy priority" configuration table instead of having a single default merging strategy and a bunch of variables to configure what happens when it fails. Given the other possible strategies (see below and #112), you probably need a way to make configuration more future proof.

The autosquash_and_merge strategy

git rebase --autosquash exists to allow fixup commits to be squashed together. GitHub PR led to the bad habit of using force-push to update them because autosquashing isn't one of their official merge strategy. fixup commits make PR easier to review because you don't lose the previous code a comment is replaying upon.

Again, of course, this strategy can fail like the above. It can also fail because the PR submitter unchecked the (enabled by default) option to let project maintainers update the pull request content.

Split engine into two parts

The engine class currently does two things:

  • refresh the cache
  • processes the queue

Whe should split that into 2 classes.

Post a complete status message

Mergify currently writes only one of them:

  • X/X approvals required
  • Waiting for status checks success

It should show both.

Allow to merge with 0 reviewer

The number of reviewer required is at least 1. Some people would like to merge pull requests as soon as the CI pass, no matter what. This would be especially useful with #42.

Allow to track dependencies between PR

It's common for some projects to build pull requests that have dependency. It'd be nice if Mergify was able to track those dependencies and merge the PR accordingly, in the right order, following the direct (acyclic) graph.

Make engine backend more scalable

All events of a repository must go to the same worker currently.
To hashring to dispatch the worker is static and on the wsgi side for now.
We should move it to the worker side, so we can dynamically change the number of workers.

The first step to do thing is to move to celery to be able to reconfigure on the fly the redis queues we are listening to.
Then we can use a tooz like library to have a dynamically hashring.

Allow contributor to clean up commit message before merge.

Many times, when a patch is submitted as a PR, there will be back and forth to get it in shape to be merged. A lot of people like to make those fixes in incremental patches to make it easier to see what they have changed. At the end of the process, these patches are squashed into the original. I would be nice if we could use something like require_code_owner_reviews to allow the author a chance to squash it themselves, fix the commit message, and then hand it back to mergify. The current behavior of this setting looks like it uses the code_owners file, which is different than what I am trying to suggest, which is the author of this patch.

Add support to Checks API

We support only Statuses API for required_status_check/contexts.

But Github have recently added a new Checks API. And Travis for example now send
Check Runs and Check Suites to Github in additional to Statuses.

As Github support now Check Runs names for required_status_check/contexts, we should to support it, too.

To do this we have a couple of things to do:

  • Looks at Check Runs list to compute our required_statuses_succeed
  • Subscribes and handles some check_suite/check_run Github events to refresh the Mergify status

Add support to Checks API

We support only Statuses API for required_status_check/contexts.

But Github have recently added a new Checks API. And Travis for example now send
Check Runs and Check Suites to Github in additional to Statuses.

As Github support now Check Runs names for required_status_check/contexts, we should to support it, too.

To do this we have a couple of things to do:

  • Looks at Check Runs list to compute our required_statuses_succeed
  • Subscribes and handles some check_suite/check_run Github events to refresh the Mergify status

Don't rebase PR if strict is false

Currently PR are always rebase before being merged, whatever the status of strict is. If strict is false, the PR can be merged without rebasing.

Provide weight in service check status

When a PR is going to be merged, the check status is set to "Will be merged soon". When several PR are in the process of being merged, some have a bigger weight; it'd be great to expose that ordering if possible in the check status.

For example, it could be "Will be merged once PR#XYZ is merged".

Unable to update PR with target branch when PR is created from a branch in the same repo

When a PR is created from a branch that is in the same repo (i.e. not from a fork), GitHub replies with maintainer_can_modify=false, making Mergify saying that it can't rebase the PR.

That seems to be wrong as the permission would allow him to modify the branch. I imagine it's a bug in the GitHub API somehow.

That's a problem with the strict workflow only.

{
  "url": "https://api.github.com/repos/jd/daiquiri/pulls/29",
  "id": 197637101,
  "node_id": "MDExOlB1bGxSZXF1ZXN0MTk3NjM3MTAx",
  "html_url": "https://github.com/jd/daiquiri/pull/29",
  "diff_url": "https://github.com/jd/daiquiri/pull/29.diff",
  "patch_url": "https://github.com/jd/daiquiri/pull/29.patch",
  "issue_url": "https://api.github.com/repos/jd/daiquiri/issues/29",
  "number": 29,
  "state": "open",
  "locked": false,
  "title": "Add build to .gitignore",
  "user": {
    "login": "jd",
    "id": 2644,
    "node_id": "MDQ6VXNlcjI2NDQ=",
    "avatar_url": "https://avatars0.githubusercontent.com/u/2644?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/jd",
    "html_url": "https://github.com/jd",
    "followers_url": "https://api.github.com/users/jd/followers",
    "following_url": "https://api.github.com/users/jd/following{/other_user}",
    "gists_url": "https://api.github.com/users/jd/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/jd/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/jd/subscriptions",
    "organizations_url": "https://api.github.com/users/jd/orgs",
    "repos_url": "https://api.github.com/users/jd/repos",
    "events_url": "https://api.github.com/users/jd/events{/privacy}",
    "received_events_url": "https://api.github.com/users/jd/received_events",
    "type": "User",
    "site_admin": false
  },
  "body": "",
  "created_at": "2018-06-27T07:17:25Z",
  "updated_at": "2018-06-27T07:17:25Z",
  "closed_at": null,
  "merged_at": null,
  "merge_commit_sha": "ab6c4c8b64e1de13174478916de304f0adf100a3",
  "assignee": null,
  "assignees": [

  ],
  "requested_reviewers": [

  ],
  "requested_teams": [

  ],
  "labels": [

  ],
  "milestone": null,
  "commits_url": "https://api.github.com/repos/jd/daiquiri/pulls/29/commits",
  "review_comments_url": "https://api.github.com/repos/jd/daiquiri/pulls/29/comments",
  "review_comment_url": "https://api.github.com/repos/jd/daiquiri/pulls/comments{/number}",
  "comments_url": "https://api.github.com/repos/jd/daiquiri/issues/29/comments",
  "statuses_url": "https://api.github.com/repos/jd/daiquiri/statuses/f283fde121dc319e2a615665ea4de81fc0d6d3a5",
  "head": {
    "label": "jd:gitignore",
    "ref": "gitignore",
    "sha": "f283fde121dc319e2a615665ea4de81fc0d6d3a5",
    "user": {
      "login": "jd",
      "id": 2644,
      "node_id": "MDQ6VXNlcjI2NDQ=",
      "avatar_url": "https://avatars0.githubusercontent.com/u/2644?v=4",
      "gravatar_id": "",
      "url": "https://api.github.com/users/jd",
      "html_url": "https://github.com/jd",
      "followers_url": "https://api.github.com/users/jd/followers",
      "following_url": "https://api.github.com/users/jd/following{/other_user}",
      "gists_url": "https://api.github.com/users/jd/gists{/gist_id}",
      "starred_url": "https://api.github.com/users/jd/starred{/owner}{/repo}",
      "subscriptions_url": "https://api.github.com/users/jd/subscriptions",
      "organizations_url": "https://api.github.com/users/jd/orgs",
      "repos_url": "https://api.github.com/users/jd/repos",
      "events_url": "https://api.github.com/users/jd/events{/privacy}",
      "received_events_url": "https://api.github.com/users/jd/received_events",
      "type": "User",
      "site_admin": false
    },
    "repo": {
      "id": 91614604,
      "node_id": "MDEwOlJlcG9zaXRvcnk5MTYxNDYwNA==",
      "name": "daiquiri",
      "full_name": "jd/daiquiri",
      "owner": {
        "login": "jd",
        "id": 2644,
        "node_id": "MDQ6VXNlcjI2NDQ=",
        "avatar_url": "https://avatars0.githubusercontent.com/u/2644?v=4",
        "gravatar_id": "",
        "url": "https://api.github.com/users/jd",
        "html_url": "https://github.com/jd",
        "followers_url": "https://api.github.com/users/jd/followers",
        "following_url": "https://api.github.com/users/jd/following{/other_user}",
        "gists_url": "https://api.github.com/users/jd/gists{/gist_id}",
        "starred_url": "https://api.github.com/users/jd/starred{/owner}{/repo}",
        "subscriptions_url": "https://api.github.com/users/jd/subscriptions",
        "organizations_url": "https://api.github.com/users/jd/orgs",
        "repos_url": "https://api.github.com/users/jd/repos",
        "events_url": "https://api.github.com/users/jd/events{/privacy}",
        "received_events_url": "https://api.github.com/users/jd/received_events",
        "type": "User",
        "site_admin": false
      },
      "private": false,
      "html_url": "https://github.com/jd/daiquiri",
      "description": "Python library to easily setup basic logging functionality",
      "fork": false,
      "url": "https://api.github.com/repos/jd/daiquiri",
      "forks_url": "https://api.github.com/repos/jd/daiquiri/forks",
      "keys_url": "https://api.github.com/repos/jd/daiquiri/keys{/key_id}",
      "collaborators_url": "https://api.github.com/repos/jd/daiquiri/collaborators{/collaborator}",
      "teams_url": "https://api.github.com/repos/jd/daiquiri/teams",
      "hooks_url": "https://api.github.com/repos/jd/daiquiri/hooks",
      "issue_events_url": "https://api.github.com/repos/jd/daiquiri/issues/events{/number}",
      "events_url": "https://api.github.com/repos/jd/daiquiri/events",
      "assignees_url": "https://api.github.com/repos/jd/daiquiri/assignees{/user}",
      "branches_url": "https://api.github.com/repos/jd/daiquiri/branches{/branch}",
      "tags_url": "https://api.github.com/repos/jd/daiquiri/tags",
      "blobs_url": "https://api.github.com/repos/jd/daiquiri/git/blobs{/sha}",
      "git_tags_url": "https://api.github.com/repos/jd/daiquiri/git/tags{/sha}",
      "git_refs_url": "https://api.github.com/repos/jd/daiquiri/git/refs{/sha}",
      "trees_url": "https://api.github.com/repos/jd/daiquiri/git/trees{/sha}",
      "statuses_url": "https://api.github.com/repos/jd/daiquiri/statuses/{sha}",
      "languages_url": "https://api.github.com/repos/jd/daiquiri/languages",
      "stargazers_url": "https://api.github.com/repos/jd/daiquiri/stargazers",
      "contributors_url": "https://api.github.com/repos/jd/daiquiri/contributors",
      "subscribers_url": "https://api.github.com/repos/jd/daiquiri/subscribers",
      "subscription_url": "https://api.github.com/repos/jd/daiquiri/subscription",
      "commits_url": "https://api.github.com/repos/jd/daiquiri/commits{/sha}",
      "git_commits_url": "https://api.github.com/repos/jd/daiquiri/git/commits{/sha}",
      "comments_url": "https://api.github.com/repos/jd/daiquiri/comments{/number}",
      "issue_comment_url": "https://api.github.com/repos/jd/daiquiri/issues/comments{/number}",
      "contents_url": "https://api.github.com/repos/jd/daiquiri/contents/{+path}",
      "compare_url": "https://api.github.com/repos/jd/daiquiri/compare/{base}...{head}",
      "merges_url": "https://api.github.com/repos/jd/daiquiri/merges",
      "archive_url": "https://api.github.com/repos/jd/daiquiri/{archive_format}{/ref}",
      "downloads_url": "https://api.github.com/repos/jd/daiquiri/downloads",
      "issues_url": "https://api.github.com/repos/jd/daiquiri/issues{/number}",
      "pulls_url": "https://api.github.com/repos/jd/daiquiri/pulls{/number}",
      "milestones_url": "https://api.github.com/repos/jd/daiquiri/milestones{/number}",
      "notifications_url": "https://api.github.com/repos/jd/daiquiri/notifications{?since,all,participating}",
      "labels_url": "https://api.github.com/repos/jd/daiquiri/labels{/name}",
      "releases_url": "https://api.github.com/repos/jd/daiquiri/releases{/id}",
      "deployments_url": "https://api.github.com/repos/jd/daiquiri/deployments",
      "created_at": "2017-05-17T19:52:24Z",
      "updated_at": "2018-06-18T13:22:21Z",
      "pushed_at": "2018-06-27T07:17:25Z",
      "git_url": "git://github.com/jd/daiquiri.git",
      "ssh_url": "[email protected]:jd/daiquiri.git",
      "clone_url": "https://github.com/jd/daiquiri.git",
      "svn_url": "https://github.com/jd/daiquiri",
      "homepage": null,
      "size": 67,
      "stargazers_count": 205,
      "watchers_count": 205,
      "language": "Python",
      "has_issues": true,
      "has_projects": true,
      "has_downloads": true,
      "has_wiki": true,
      "has_pages": false,
      "forks_count": 15,
      "mirror_url": null,
      "archived": false,
      "open_issues_count": 6,
      "license": {
        "key": "apache-2.0",
        "name": "Apache License 2.0",
        "spdx_id": "Apache-2.0",
        "url": "https://api.github.com/licenses/apache-2.0",
        "node_id": "MDc6TGljZW5zZTI="
      },
      "forks": 15,
      "open_issues": 6,
      "watchers": 205,
      "default_branch": "master"
    }
  },
  "base": {
    "label": "jd:master",
    "ref": "master",
    "sha": "8aa1c56dcff6356c893fb187f04f6d29f565ee67",
    "user": {
      "login": "jd",
      "id": 2644,
      "node_id": "MDQ6VXNlcjI2NDQ=",
      "avatar_url": "https://avatars0.githubusercontent.com/u/2644?v=4",
      "gravatar_id": "",
      "url": "https://api.github.com/users/jd",
      "html_url": "https://github.com/jd",
      "followers_url": "https://api.github.com/users/jd/followers",
      "following_url": "https://api.github.com/users/jd/following{/other_user}",
      "gists_url": "https://api.github.com/users/jd/gists{/gist_id}",
      "starred_url": "https://api.github.com/users/jd/starred{/owner}{/repo}",
      "subscriptions_url": "https://api.github.com/users/jd/subscriptions",
      "organizations_url": "https://api.github.com/users/jd/orgs",
      "repos_url": "https://api.github.com/users/jd/repos",
      "events_url": "https://api.github.com/users/jd/events{/privacy}",
      "received_events_url": "https://api.github.com/users/jd/received_events",
      "type": "User",
      "site_admin": false
    },
    "repo": {
      "id": 91614604,
      "node_id": "MDEwOlJlcG9zaXRvcnk5MTYxNDYwNA==",
      "name": "daiquiri",
      "full_name": "jd/daiquiri",
      "owner": {
        "login": "jd",
        "id": 2644,
        "node_id": "MDQ6VXNlcjI2NDQ=",
        "avatar_url": "https://avatars0.githubusercontent.com/u/2644?v=4",
        "gravatar_id": "",
        "url": "https://api.github.com/users/jd",
        "html_url": "https://github.com/jd",
        "followers_url": "https://api.github.com/users/jd/followers",
        "following_url": "https://api.github.com/users/jd/following{/other_user}",
        "gists_url": "https://api.github.com/users/jd/gists{/gist_id}",
        "starred_url": "https://api.github.com/users/jd/starred{/owner}{/repo}",
        "subscriptions_url": "https://api.github.com/users/jd/subscriptions",
        "organizations_url": "https://api.github.com/users/jd/orgs",
        "repos_url": "https://api.github.com/users/jd/repos",
        "events_url": "https://api.github.com/users/jd/events{/privacy}",
        "received_events_url": "https://api.github.com/users/jd/received_events",
        "type": "User",
        "site_admin": false
      },
      "private": false,
      "html_url": "https://github.com/jd/daiquiri",
      "description": "Python library to easily setup basic logging functionality",
      "fork": false,
      "url": "https://api.github.com/repos/jd/daiquiri",
      "forks_url": "https://api.github.com/repos/jd/daiquiri/forks",
      "keys_url": "https://api.github.com/repos/jd/daiquiri/keys{/key_id}",
      "collaborators_url": "https://api.github.com/repos/jd/daiquiri/collaborators{/collaborator}",
      "teams_url": "https://api.github.com/repos/jd/daiquiri/teams",
      "hooks_url": "https://api.github.com/repos/jd/daiquiri/hooks",
      "issue_events_url": "https://api.github.com/repos/jd/daiquiri/issues/events{/number}",
      "events_url": "https://api.github.com/repos/jd/daiquiri/events",
      "assignees_url": "https://api.github.com/repos/jd/daiquiri/assignees{/user}",
      "branches_url": "https://api.github.com/repos/jd/daiquiri/branches{/branch}",
      "tags_url": "https://api.github.com/repos/jd/daiquiri/tags",
      "blobs_url": "https://api.github.com/repos/jd/daiquiri/git/blobs{/sha}",
      "git_tags_url": "https://api.github.com/repos/jd/daiquiri/git/tags{/sha}",
      "git_refs_url": "https://api.github.com/repos/jd/daiquiri/git/refs{/sha}",
      "trees_url": "https://api.github.com/repos/jd/daiquiri/git/trees{/sha}",
      "statuses_url": "https://api.github.com/repos/jd/daiquiri/statuses/{sha}",
      "languages_url": "https://api.github.com/repos/jd/daiquiri/languages",
      "stargazers_url": "https://api.github.com/repos/jd/daiquiri/stargazers",
      "contributors_url": "https://api.github.com/repos/jd/daiquiri/contributors",
      "subscribers_url": "https://api.github.com/repos/jd/daiquiri/subscribers",
      "subscription_url": "https://api.github.com/repos/jd/daiquiri/subscription",
      "commits_url": "https://api.github.com/repos/jd/daiquiri/commits{/sha}",
      "git_commits_url": "https://api.github.com/repos/jd/daiquiri/git/commits{/sha}",
      "comments_url": "https://api.github.com/repos/jd/daiquiri/comments{/number}",
      "issue_comment_url": "https://api.github.com/repos/jd/daiquiri/issues/comments{/number}",
      "contents_url": "https://api.github.com/repos/jd/daiquiri/contents/{+path}",
      "compare_url": "https://api.github.com/repos/jd/daiquiri/compare/{base}...{head}",
      "merges_url": "https://api.github.com/repos/jd/daiquiri/merges",
      "archive_url": "https://api.github.com/repos/jd/daiquiri/{archive_format}{/ref}",
      "downloads_url": "https://api.github.com/repos/jd/daiquiri/downloads",
      "issues_url": "https://api.github.com/repos/jd/daiquiri/issues{/number}",
      "pulls_url": "https://api.github.com/repos/jd/daiquiri/pulls{/number}",
      "milestones_url": "https://api.github.com/repos/jd/daiquiri/milestones{/number}",
      "notifications_url": "https://api.github.com/repos/jd/daiquiri/notifications{?since,all,participating}",
      "labels_url": "https://api.github.com/repos/jd/daiquiri/labels{/name}",
      "releases_url": "https://api.github.com/repos/jd/daiquiri/releases{/id}",
      "deployments_url": "https://api.github.com/repos/jd/daiquiri/deployments",
      "created_at": "2017-05-17T19:52:24Z",
      "updated_at": "2018-06-18T13:22:21Z",
      "pushed_at": "2018-06-27T07:17:25Z",
      "git_url": "git://github.com/jd/daiquiri.git",
      "ssh_url": "[email protected]:jd/daiquiri.git",
      "clone_url": "https://github.com/jd/daiquiri.git",
      "svn_url": "https://github.com/jd/daiquiri",
      "homepage": null,
      "size": 67,
      "stargazers_count": 205,
      "watchers_count": 205,
      "language": "Python",
      "has_issues": true,
      "has_projects": true,
      "has_downloads": true,
      "has_wiki": true,
      "has_pages": false,
      "forks_count": 15,
      "mirror_url": null,
      "archived": false,
      "open_issues_count": 6,
      "license": {
        "key": "apache-2.0",
        "name": "Apache License 2.0",
        "spdx_id": "Apache-2.0",
        "url": "https://api.github.com/licenses/apache-2.0",
        "node_id": "MDc6TGljZW5zZTI="
      },
      "forks": 15,
      "open_issues": 6,
      "watchers": 205,
      "default_branch": "master"
    }
  },
  "_links": {
    "self": {
      "href": "https://api.github.com/repos/jd/daiquiri/pulls/29"
    },
    "html": {
      "href": "https://github.com/jd/daiquiri/pull/29"
    },
    "issue": {
      "href": "https://api.github.com/repos/jd/daiquiri/issues/29"
    },
    "comments": {
      "href": "https://api.github.com/repos/jd/daiquiri/issues/29/comments"
    },
    "review_comments": {
      "href": "https://api.github.com/repos/jd/daiquiri/pulls/29/comments"
    },
    "review_comment": {
      "href": "https://api.github.com/repos/jd/daiquiri/pulls/comments{/number}"
    },
    "commits": {
      "href": "https://api.github.com/repos/jd/daiquiri/pulls/29/commits"
    },
    "statuses": {
      "href": "https://api.github.com/repos/jd/daiquiri/statuses/f283fde121dc319e2a615665ea4de81fc0d6d3a5"
    }
  },
  "author_association": "OWNER",
  "merged": false,
  "mergeable": true,
  "rebaseable": true,
  "mergeable_state": "unstable",
  "merged_by": null,
  "comments": 0,
  "review_comments": 0,
  "maintainer_can_modify": false,
  "commits": 1,
  "additions": 1,
  "deletions": 0,
  "changed_files": 1
}

or

{
  "url": "https://api.github.com/repos/ceph/ceph-ansible/pulls/2814",
  "id": 197559897,
  "node_id": "MDExOlB1bGxSZXF1ZXN0MTk3NTU5ODk3",
  "html_url": "https://github.com/ceph/ceph-ansible/pull/2814",
  "diff_url": "https://github.com/ceph/ceph-ansible/pull/2814.diff",
  "patch_url": "https://github.com/ceph/ceph-ansible/pull/2814.patch",
  "issue_url": "https://api.github.com/repos/ceph/ceph-ansible/issues/2814",
  "number": 2814,
  "state": "open",
  "locked": false,
  "title": "setup tools repo on mgr nodes when rhcs cdn debian config is set",
  "user": {
    "login": "vasukulkarni",
    "id": 2075532,
    "node_id": "MDQ6VXNlcjIwNzU1MzI=",
    "avatar_url": "https://avatars2.githubusercontent.com/u/2075532?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/vasukulkarni",
    "html_url": "https://github.com/vasukulkarni",
    "followers_url": "https://api.github.com/users/vasukulkarni/followers",
    "following_url": "https://api.github.com/users/vasukulkarni/following{/other_user}",
    "gists_url": "https://api.github.com/users/vasukulkarni/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/vasukulkarni/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/vasukulkarni/subscriptions",
    "organizations_url": "https://api.github.com/users/vasukulkarni/orgs",
    "repos_url": "https://api.github.com/users/vasukulkarni/repos",
    "events_url": "https://api.github.com/users/vasukulkarni/events{/privacy}",
    "received_events_url": "https://api.github.com/users/vasukulkarni/received_events",
    "type": "User",
    "site_admin": false
  },
  "body": "Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1594974\r\n\r\nSigned-off-by: Vasu Kulkarni <[email protected]>",
  "created_at": "2018-06-26T21:43:08Z",
  "updated_at": "2018-06-27T07:03:12Z",
  "closed_at": null,
  "merged_at": null,
  "merge_commit_sha": "0c7d9e77aad84b644b0ac64b055f1ac6e6d1e534",
  "assignee": null,
  "assignees": [

  ],
  "requested_reviewers": [

  ],
  "requested_teams": [

  ],
  "labels": [

  ],
  "milestone": null,
  "commits_url": "https://api.github.com/repos/ceph/ceph-ansible/pulls/2814/commits",
  "review_comments_url": "https://api.github.com/repos/ceph/ceph-ansible/pulls/2814/comments",
  "review_comment_url": "https://api.github.com/repos/ceph/ceph-ansible/pulls/comments{/number}",
  "comments_url": "https://api.github.com/repos/ceph/ceph-ansible/issues/2814/comments",
  "statuses_url": "https://api.github.com/repos/ceph/ceph-ansible/statuses/d5870926eaf18855a20a0cde85eb51f8c2811c5f",
  "head": {
    "label": "ceph:wip-set-mgr-deb-repo",
    "ref": "wip-set-mgr-deb-repo",
    "sha": "d5870926eaf18855a20a0cde85eb51f8c2811c5f",
    "user": {
      "login": "ceph",
      "id": 1015767,
      "node_id": "MDEyOk9yZ2FuaXphdGlvbjEwMTU3Njc=",
      "avatar_url": "https://avatars3.githubusercontent.com/u/1015767?v=4",
      "gravatar_id": "",
      "url": "https://api.github.com/users/ceph",
      "html_url": "https://github.com/ceph",
      "followers_url": "https://api.github.com/users/ceph/followers",
      "following_url": "https://api.github.com/users/ceph/following{/other_user}",
      "gists_url": "https://api.github.com/users/ceph/gists{/gist_id}",
      "starred_url": "https://api.github.com/users/ceph/starred{/owner}{/repo}",
      "subscriptions_url": "https://api.github.com/users/ceph/subscriptions",
      "organizations_url": "https://api.github.com/users/ceph/orgs",
      "repos_url": "https://api.github.com/users/ceph/repos",
      "events_url": "https://api.github.com/users/ceph/events{/privacy}",
      "received_events_url": "https://api.github.com/users/ceph/received_events",
      "type": "Organization",
      "site_admin": false
    },
    "repo": {
      "id": 17373313,
      "node_id": "MDEwOlJlcG9zaXRvcnkxNzM3MzMxMw==",
      "name": "ceph-ansible",
      "full_name": "ceph/ceph-ansible",
      "owner": {
        "login": "ceph",
        "id": 1015767,
        "node_id": "MDEyOk9yZ2FuaXphdGlvbjEwMTU3Njc=",
        "avatar_url": "https://avatars3.githubusercontent.com/u/1015767?v=4",
        "gravatar_id": "",
        "url": "https://api.github.com/users/ceph",
        "html_url": "https://github.com/ceph",
        "followers_url": "https://api.github.com/users/ceph/followers",
        "following_url": "https://api.github.com/users/ceph/following{/other_user}",
        "gists_url": "https://api.github.com/users/ceph/gists{/gist_id}",
        "starred_url": "https://api.github.com/users/ceph/starred{/owner}{/repo}",
        "subscriptions_url": "https://api.github.com/users/ceph/subscriptions",
        "organizations_url": "https://api.github.com/users/ceph/orgs",
        "repos_url": "https://api.github.com/users/ceph/repos",
        "events_url": "https://api.github.com/users/ceph/events{/privacy}",
        "received_events_url": "https://api.github.com/users/ceph/received_events",
        "type": "Organization",
        "site_admin": false
      },
      "private": false,
      "html_url": "https://github.com/ceph/ceph-ansible",
      "description": "Ansible playbooks for Ceph",
      "fork": false,
      "url": "https://api.github.com/repos/ceph/ceph-ansible",
      "forks_url": "https://api.github.com/repos/ceph/ceph-ansible/forks",
      "keys_url": "https://api.github.com/repos/ceph/ceph-ansible/keys{/key_id}",
      "collaborators_url": "https://api.github.com/repos/ceph/ceph-ansible/collaborators{/collaborator}",
      "teams_url": "https://api.github.com/repos/ceph/ceph-ansible/teams",
      "hooks_url": "https://api.github.com/repos/ceph/ceph-ansible/hooks",
      "issue_events_url": "https://api.github.com/repos/ceph/ceph-ansible/issues/events{/number}",
      "events_url": "https://api.github.com/repos/ceph/ceph-ansible/events",
      "assignees_url": "https://api.github.com/repos/ceph/ceph-ansible/assignees{/user}",
      "branches_url": "https://api.github.com/repos/ceph/ceph-ansible/branches{/branch}",
      "tags_url": "https://api.github.com/repos/ceph/ceph-ansible/tags",
      "blobs_url": "https://api.github.com/repos/ceph/ceph-ansible/git/blobs{/sha}",
      "git_tags_url": "https://api.github.com/repos/ceph/ceph-ansible/git/tags{/sha}",
      "git_refs_url": "https://api.github.com/repos/ceph/ceph-ansible/git/refs{/sha}",
      "trees_url": "https://api.github.com/repos/ceph/ceph-ansible/git/trees{/sha}",
      "statuses_url": "https://api.github.com/repos/ceph/ceph-ansible/statuses/{sha}",
      "languages_url": "https://api.github.com/repos/ceph/ceph-ansible/languages",
      "stargazers_url": "https://api.github.com/repos/ceph/ceph-ansible/stargazers",
      "contributors_url": "https://api.github.com/repos/ceph/ceph-ansible/contributors",
      "subscribers_url": "https://api.github.com/repos/ceph/ceph-ansible/subscribers",
      "subscription_url": "https://api.github.com/repos/ceph/ceph-ansible/subscription",
      "commits_url": "https://api.github.com/repos/ceph/ceph-ansible/commits{/sha}",
      "git_commits_url": "https://api.github.com/repos/ceph/ceph-ansible/git/commits{/sha}",
      "comments_url": "https://api.github.com/repos/ceph/ceph-ansible/comments{/number}",
      "issue_comment_url": "https://api.github.com/repos/ceph/ceph-ansible/issues/comments{/number}",
      "contents_url": "https://api.github.com/repos/ceph/ceph-ansible/contents/{+path}",
      "compare_url": "https://api.github.com/repos/ceph/ceph-ansible/compare/{base}...{head}",
      "merges_url": "https://api.github.com/repos/ceph/ceph-ansible/merges",
      "archive_url": "https://api.github.com/repos/ceph/ceph-ansible/{archive_format}{/ref}",
      "downloads_url": "https://api.github.com/repos/ceph/ceph-ansible/downloads",
      "issues_url": "https://api.github.com/repos/ceph/ceph-ansible/issues{/number}",
      "pulls_url": "https://api.github.com/repos/ceph/ceph-ansible/pulls{/number}",
      "milestones_url": "https://api.github.com/repos/ceph/ceph-ansible/milestones{/number}",
      "notifications_url": "https://api.github.com/repos/ceph/ceph-ansible/notifications{?since,all,participating}",
      "labels_url": "https://api.github.com/repos/ceph/ceph-ansible/labels{/name}",
      "releases_url": "https://api.github.com/repos/ceph/ceph-ansible/releases{/id}",
      "deployments_url": "https://api.github.com/repos/ceph/ceph-ansible/deployments",
      "created_at": "2014-03-03T17:12:09Z",
      "updated_at": "2018-06-27T07:00:26Z",
      "pushed_at": "2018-06-27T07:31:31Z",
      "git_url": "git://github.com/ceph/ceph-ansible.git",
      "ssh_url": "[email protected]:ceph/ceph-ansible.git",
      "clone_url": "https://github.com/ceph/ceph-ansible.git",
      "svn_url": "https://github.com/ceph/ceph-ansible",
      "homepage": null,
      "size": 4808,
      "stargazers_count": 641,
      "watchers_count": 641,
      "language": "Python",
      "has_issues": true,
      "has_projects": true,
      "has_downloads": true,
      "has_wiki": false,
      "has_pages": false,
      "forks_count": 458,
      "mirror_url": null,
      "archived": false,
      "open_issues_count": 162,
      "license": {
        "key": "apache-2.0",
        "name": "Apache License 2.0",
        "spdx_id": "Apache-2.0",
        "url": "https://api.github.com/licenses/apache-2.0",
        "node_id": "MDc6TGljZW5zZTI="
      },
      "forks": 458,
      "open_issues": 162,
      "watchers": 641,
      "default_branch": "master"
    }
  },
  "base": {
    "label": "ceph:master",
    "ref": "master",
    "sha": "fe79a5d24086fc61ae84a59bd61a053cddb62941",
    "user": {
      "login": "ceph",
      "id": 1015767,
      "node_id": "MDEyOk9yZ2FuaXphdGlvbjEwMTU3Njc=",
      "avatar_url": "https://avatars3.githubusercontent.com/u/1015767?v=4",
      "gravatar_id": "",
      "url": "https://api.github.com/users/ceph",
      "html_url": "https://github.com/ceph",
      "followers_url": "https://api.github.com/users/ceph/followers",
      "following_url": "https://api.github.com/users/ceph/following{/other_user}",
      "gists_url": "https://api.github.com/users/ceph/gists{/gist_id}",
      "starred_url": "https://api.github.com/users/ceph/starred{/owner}{/repo}",
      "subscriptions_url": "https://api.github.com/users/ceph/subscriptions",
      "organizations_url": "https://api.github.com/users/ceph/orgs",
      "repos_url": "https://api.github.com/users/ceph/repos",
      "events_url": "https://api.github.com/users/ceph/events{/privacy}",
      "received_events_url": "https://api.github.com/users/ceph/received_events",
      "type": "Organization",
      "site_admin": false
    },
    "repo": {
      "id": 17373313,
      "node_id": "MDEwOlJlcG9zaXRvcnkxNzM3MzMxMw==",
      "name": "ceph-ansible",
      "full_name": "ceph/ceph-ansible",
      "owner": {
        "login": "ceph",
        "id": 1015767,
        "node_id": "MDEyOk9yZ2FuaXphdGlvbjEwMTU3Njc=",
        "avatar_url": "https://avatars3.githubusercontent.com/u/1015767?v=4",
        "gravatar_id": "",
        "url": "https://api.github.com/users/ceph",
        "html_url": "https://github.com/ceph",
        "followers_url": "https://api.github.com/users/ceph/followers",
        "following_url": "https://api.github.com/users/ceph/following{/other_user}",
        "gists_url": "https://api.github.com/users/ceph/gists{/gist_id}",
        "starred_url": "https://api.github.com/users/ceph/starred{/owner}{/repo}",
        "subscriptions_url": "https://api.github.com/users/ceph/subscriptions",
        "organizations_url": "https://api.github.com/users/ceph/orgs",
        "repos_url": "https://api.github.com/users/ceph/repos",
        "events_url": "https://api.github.com/users/ceph/events{/privacy}",
        "received_events_url": "https://api.github.com/users/ceph/received_events",
        "type": "Organization",
        "site_admin": false
      },
      "private": false,
      "html_url": "https://github.com/ceph/ceph-ansible",
      "description": "Ansible playbooks for Ceph",
      "fork": false,
      "url": "https://api.github.com/repos/ceph/ceph-ansible",
      "forks_url": "https://api.github.com/repos/ceph/ceph-ansible/forks",
      "keys_url": "https://api.github.com/repos/ceph/ceph-ansible/keys{/key_id}",
      "collaborators_url": "https://api.github.com/repos/ceph/ceph-ansible/collaborators{/collaborator}",
      "teams_url": "https://api.github.com/repos/ceph/ceph-ansible/teams",
      "hooks_url": "https://api.github.com/repos/ceph/ceph-ansible/hooks",
      "issue_events_url": "https://api.github.com/repos/ceph/ceph-ansible/issues/events{/number}",
      "events_url": "https://api.github.com/repos/ceph/ceph-ansible/events",
      "assignees_url": "https://api.github.com/repos/ceph/ceph-ansible/assignees{/user}",
      "branches_url": "https://api.github.com/repos/ceph/ceph-ansible/branches{/branch}",
      "tags_url": "https://api.github.com/repos/ceph/ceph-ansible/tags",
      "blobs_url": "https://api.github.com/repos/ceph/ceph-ansible/git/blobs{/sha}",
      "git_tags_url": "https://api.github.com/repos/ceph/ceph-ansible/git/tags{/sha}",
      "git_refs_url": "https://api.github.com/repos/ceph/ceph-ansible/git/refs{/sha}",
      "trees_url": "https://api.github.com/repos/ceph/ceph-ansible/git/trees{/sha}",
      "statuses_url": "https://api.github.com/repos/ceph/ceph-ansible/statuses/{sha}",
      "languages_url": "https://api.github.com/repos/ceph/ceph-ansible/languages",
      "stargazers_url": "https://api.github.com/repos/ceph/ceph-ansible/stargazers",
      "contributors_url": "https://api.github.com/repos/ceph/ceph-ansible/contributors",
      "subscribers_url": "https://api.github.com/repos/ceph/ceph-ansible/subscribers",
      "subscription_url": "https://api.github.com/repos/ceph/ceph-ansible/subscription",
      "commits_url": "https://api.github.com/repos/ceph/ceph-ansible/commits{/sha}",
      "git_commits_url": "https://api.github.com/repos/ceph/ceph-ansible/git/commits{/sha}",
      "comments_url": "https://api.github.com/repos/ceph/ceph-ansible/comments{/number}",
      "issue_comment_url": "https://api.github.com/repos/ceph/ceph-ansible/issues/comments{/number}",
      "contents_url": "https://api.github.com/repos/ceph/ceph-ansible/contents/{+path}",
      "compare_url": "https://api.github.com/repos/ceph/ceph-ansible/compare/{base}...{head}",
      "merges_url": "https://api.github.com/repos/ceph/ceph-ansible/merges",
      "archive_url": "https://api.github.com/repos/ceph/ceph-ansible/{archive_format}{/ref}",
      "downloads_url": "https://api.github.com/repos/ceph/ceph-ansible/downloads",
      "issues_url": "https://api.github.com/repos/ceph/ceph-ansible/issues{/number}",
      "pulls_url": "https://api.github.com/repos/ceph/ceph-ansible/pulls{/number}",
      "milestones_url": "https://api.github.com/repos/ceph/ceph-ansible/milestones{/number}",
      "notifications_url": "https://api.github.com/repos/ceph/ceph-ansible/notifications{?since,all,participating}",
      "labels_url": "https://api.github.com/repos/ceph/ceph-ansible/labels{/name}",
      "releases_url": "https://api.github.com/repos/ceph/ceph-ansible/releases{/id}",
      "deployments_url": "https://api.github.com/repos/ceph/ceph-ansible/deployments",
      "created_at": "2014-03-03T17:12:09Z",
      "updated_at": "2018-06-27T07:00:26Z",
      "pushed_at": "2018-06-27T07:31:31Z",
      "git_url": "git://github.com/ceph/ceph-ansible.git",
      "ssh_url": "[email protected]:ceph/ceph-ansible.git",
      "clone_url": "https://github.com/ceph/ceph-ansible.git",
      "svn_url": "https://github.com/ceph/ceph-ansible",
      "homepage": null,
      "size": 4808,
      "stargazers_count": 641,
      "watchers_count": 641,
      "language": "Python",
      "has_issues": true,
      "has_projects": true,
      "has_downloads": true,
      "has_wiki": false,
      "has_pages": false,
      "forks_count": 458,
      "mirror_url": null,
      "archived": false,
      "open_issues_count": 162,
      "license": {
        "key": "apache-2.0",
        "name": "Apache License 2.0",
        "spdx_id": "Apache-2.0",
        "url": "https://api.github.com/licenses/apache-2.0",
        "node_id": "MDc6TGljZW5zZTI="
      },
      "forks": 458,
      "open_issues": 162,
      "watchers": 641,
      "default_branch": "master"
    }
  },
  "_links": {
    "self": {
      "href": "https://api.github.com/repos/ceph/ceph-ansible/pulls/2814"
    },
    "html": {
      "href": "https://github.com/ceph/ceph-ansible/pull/2814"
    },
    "issue": {
      "href": "https://api.github.com/repos/ceph/ceph-ansible/issues/2814"
    },
    "comments": {
      "href": "https://api.github.com/repos/ceph/ceph-ansible/issues/2814/comments"
    },
    "review_comments": {
      "href": "https://api.github.com/repos/ceph/ceph-ansible/pulls/2814/comments"
    },
    "review_comment": {
      "href": "https://api.github.com/repos/ceph/ceph-ansible/pulls/comments{/number}"
    },
    "commits": {
      "href": "https://api.github.com/repos/ceph/ceph-ansible/pulls/2814/commits"
    },
    "statuses": {
      "href": "https://api.github.com/repos/ceph/ceph-ansible/statuses/d5870926eaf18855a20a0cde85eb51f8c2811c5f"
    }
  },
  "author_association": "MEMBER",
  "merged": false,
  "mergeable": true,
  "rebaseable": true,
  "mergeable_state": "clean",
  "merged_by": null,
  "comments": 0,
  "review_comments": 0,
  "maintainer_can_modify": false,
  "commits": 1,
  "additions": 1,
  "deletions": 1,
  "changed_files": 1
}```

Retry when GitHub connection breaks

Sometimes, some events fail because of github connectivity issue:

  • seen a lot on worker side:requests.exceptions.ReadTimeout
  • seen one time on API side: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response',))

We should retry in such case.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.