예제 #1
0
def acknowledge_merge_on_travis(data):
    """When a user comments on a pull request with one of the automerge
    triggers (e.g. merge on green), this hook will add the 'automerge'
    label.

    Issue comment data reference:
    https://developer.github.com/v3/activity/events/types/#issuecommentevent
    """
    if data.get('action') != 'created':
        return

    # Make sure it's a PR.
    if not github_helper.is_pull_request(data):
        return

    # If comment has trigger text.
    comment = data['comment']

    if not check_for_auto_merge_trigger(comment['body']):
        return

    # If user is a collaborator.
    gh = github_helper.get_client()
    repository = github_helper.get_repository(gh, data)

    if not repository.is_collaborator(data['sender']['login']):
        logging.info(
            '{} is not an owner and is trying to tell me what to do.'.format(
                data['sender']['login']))

    # Write a comment about it.
    pr = github_helper.get_pull_request(gh, data)
    pr.create_comment('Okay! I\'ll merge when all statuses are green.')
    pr.issue().add_labels('automerge')
예제 #2
0
def pull_request_review_merge_on_travis(data):
    """When all approvers approve and statuses pass, this hook will
    automatically merge it if it's labeled with 'automerge'.

    Status data reference:
    https://developer.github.com/v3/activity/events/types/#pullrequestreviewevent
    """
    # If it's not successful don't even bother.
    if data['review']['state'] != 'approved':
        logging.info('Not approved, returning.')
        return

    # If the PR is closed, don't bother
    if data['pull_request']['state'] != 'open':
        logging.info('Closed, returning.')
        return

    gh = github_helper.get_client()

    repo = gh.repository(
        data['repository']['owner']['login'],
        data['repository']['name'])
    pr = repo.pull_request(data['pull_request']['number'])

    merge_pull_request(repo, pr, commit_sha=pr.head.sha)
def pull_request_review_merge_on_travis(data):
    """When all approvers approve and statuses pass, this hook will
    automatically merge it if it's labeled with 'automerge'.

    Status data reference:
    https://developer.github.com/v3/activity/events/types/#pullrequestreviewevent
    """
    # If it's not successful don't even bother.
    if data['review']['state'] != 'approved':
        logging.info('Not approved, returning.')
        return

    # If the PR is closed, don't bother
    if data['pull_request']['state'] != 'open':
        logging.info('Closed, returning.')
        return

    gh = github_helper.get_client()

    repo = gh.repository(
        data['repository']['owner']['login'],
        data['repository']['name'])
    pr = repo.pull_request(data['pull_request']['number'])

    merge_pull_request(repo, pr, commit_sha=pr.head.sha)
예제 #4
0
def complete_merge_on_travis(data):
    """When all statuses on a PR are green, this hook will automatically
    merge it if it's labeled with 'automerge'.

    Status data reference:
    https://developer.github.com/v3/activity/events/types/#statusevent
    """
    # TODO: Idea - if automerge has been triggered and the status fails,
    # nag the committer to fix?

    # If it's not successful don't even bother.
    if data['state'] != 'success':
        logging.info('Status not successful, returning.')
        return

    # NOTE: I'm not sure if there's a better way to do this. But, it seems
    # the status change message doesn't tell you which PR the commit is
    # from. Indeed, it's possible for a commit to actually be in multiple
    # PRs. Anyways, the idea here is to get all open PRs with the
    # tag 'automerge' and check if this commit is in that PR.
    # If so, merge.
    gh = github_helper.get_client()
    repository = github_helper.get_repository(gh, data)

    # This search actually takes a few seconds to work. Sleep for 10 seconds.
    time.sleep(10)

    results = gh.search_issues(
        query='type:pr label:automerge status:success is:open repo:{}'.format(
            data['repository']['full_name']))

    # Covert to pull requests so we can get the commits.
    pulls = [result.issue.pull_request() for result in results]
    logging.info('Found {} potential PRs: {}'.format(len(pulls), pulls))

    # See if this commit is in the PR.
    # this check isn't actually strictly necessary as the search above will
    # only return PRs that are 'green' which means we can safely merge all
    # of them. But, whatever, I'll leave it here for now anyway.
    commit_sha = data['commit']['sha']
    pulls = [
        pull for pull in pulls
        if commit_sha in [commit.sha for commit in pull.commits()]
    ]

    logging.info('Commit {} is present in PRs: {}'.format(commit_sha, pulls))

    # Merge!
    for pull in pulls:
        # By supplying the sha here, it ensures that the PR will only be
        # merged if that sha is the HEAD of the branch.
        pull.merge(sha=commit_sha, squash=True)

        # Delete the branch if it's in this repo. ALSO DON'T DELETE MASTER.
        if (pull.head.ref != 'master' and '/'.join(pull.head.repo)
                == data['repository']['full_name']):
            repository.ref('heads/{}'.format(pull.head.ref)).delete()
예제 #5
0
def accept_invitations():
    gh = github_helper.get_client()

    invitations = gh.session.get(
        'https://api.github.com/user/repository_invitations').json()

    for invitation in invitations:
        gh.session.patch(invitation['url'])
        logging.info('Accepted invite to {}'.format(
            invitation['repository']['full_name']))
예제 #6
0
def commit_status_complete_merge_on_travis(data):
    """When all statuses on a PR are green, this hook will automatically
    merge it if it's labeled with 'automerge'.

    Status data reference:
    https://developer.github.com/v3/activity/events/types/#statusevent
    """
    # TODO: Idea - if automerge has been triggered and the status fails,
    # nag the committer to fix?

    # If it's not successful don't even bother.
    if data['state'] != 'success':
        logging.info('Status not successful, returning.')
        return

    # NOTE: I'm not sure if there's a better way to do this. But, it seems
    # the status change message doesn't tell you which PR the commit is
    # from. Indeed, it's possible for a commit to actually be in multiple
    # PRs. Anyways, the idea here is to get all open PRs with the
    # tag 'automerge' and this commit in the PR.
    commit_sha = data['commit']['sha']
    gh = github_helper.get_client()
    repository = github_helper.get_repository(gh, data)

    # Sleep for about 15 seconds. Github's search index needs a few seconds
    # before it'll find the results.
    time.sleep(15)

    query = '{} type:pr label:automerge status:success is:open repo:{}'.format(
            commit_sha, data['repository']['full_name'])
    logging.info('Querying with: {}'.format(query))
    results = gh.search_issues(query=query)

    # Covert to pull requests so we can get the commits.
    pulls = [result.issue.pull_request() for result in results]
    logging.info('Found {} potential PRs: {}'.format(
        len(pulls), pulls))

    # See if this commit is in the PR.
    # this check isn't actually strictly necessary as the search above will
    # only return PRs that are 'green' which means we can safely merge all
    # of them. But, whatever, I'll leave it here for now anyway.
    pulls = [
        pull for pull in pulls
        if commit_sha in [commit.sha for commit in pull.commits()]]

    logging.info('Commit {} is present in PRs: {}'.format(
        commit_sha, pulls))

    # Merge!
    for pull in pulls:
        merge_pull_request(repository, pull, commit_sha=commit_sha)
def commit_status_complete_merge_on_travis(data):
    """When all statuses on a PR are green, this hook will automatically
    merge it if it's labeled with 'automerge'.

    Status data reference:
    https://developer.github.com/v3/activity/events/types/#statusevent
    """
    # TODO: Idea - if automerge has been triggered and the status fails,
    # nag the committer to fix?

    # If it's not successful don't even bother.
    if data['state'] != 'success':
        logging.info('Status not successful, returning.')
        return

    # NOTE: I'm not sure if there's a better way to do this. But, it seems
    # the status change message doesn't tell you which PR the commit is
    # from. Indeed, it's possible for a commit to actually be in multiple
    # PRs. Anyways, the idea here is to get all open PRs with the
    # tag 'automerge' and this commit in the PR.
    commit_sha = data['commit']['sha']
    gh = github_helper.get_client()
    repository = github_helper.get_repository(gh, data)

    # Sleep for about 15 seconds. Github's search index needs a few seconds
    # before it'll find the results.
    time.sleep(15)

    query = '{} type:pr label:automerge is:open repo:{}'.format(
            commit_sha, data['repository']['full_name'])
    logging.info('Querying with: {}'.format(query))
    results = gh.search_issues(query=query)

    # Covert to pull requests so we can get the commits.
    pulls = [result.issue.pull_request() for result in results]
    logging.info('Found {} potential PRs: {}'.format(
        len(pulls), pulls))

    # See if this commit is in the PR.
    # this check isn't actually strictly necessary as the search above will
    # only return PRs that are 'green' which means we can safely merge all
    # of them. But, whatever, I'll leave it here for now anyway.
    pulls = [
        pull for pull in pulls
        if commit_sha in [commit.sha for commit in pull.commits()]]

    logging.info('Commit {} is present in PRs: {}'.format(
        commit_sha, pulls))

    # Merge!
    for pull in pulls:
        merge_pull_request(repository, pull, commit_sha=commit_sha)
예제 #8
0
def create_webhook(owner, repository):
    gh = github_helper.get_client()
    repo = gh.repository(owner, repository)

    hook = repo.create_hook(
        name='web',
        config={
            'url': webhook_url(),
            'content_type': 'json',
            'secret': webhook_secret().decode('utf-8')},
        events=['*'])

    return hook
예제 #9
0
def create_webhooks():
    """Auto-creates webhooks

    * Gets all open issues assigned to the bot.
    * Checks to see if the issue is title 'add webhook'.
    * Checks the creator and the bot are both admins.
    * Creates the hook and leaves a comment.
    """

    gh = github_helper.get_client()
    issues = gh.issues(filter='assigned', state='open')

    for issue in issues:
        # Does someone want us to add the webhook?
        if issue.title.lower() not in ('add webhook', 'create webhook'):
            return

        logging.info('Processing issue {}'.format(issue.url))

        # Make sure the user who filed the issue is an admin.
        permission = github_helper.get_permission(
            gh, issue.repository[0],
            issue.repository[1],
            issue.user.login)

        if permission != 'admin':
            logging.info(
                'Not installing webhook because {} is not an '
                'admin.'.format(issue.user.login))
            return

        # Make sure we're an admin.
        repo = gh.repository(*issue.repository)

        if not repo.permissions['admin']:
            logging.info(
                'Not installing hook because depbot is not an admin')
            # TODO: leave a comment?
            return

        # Create the webhook.
        try:
            webhook_helper.create_webhook(repo.owner, repo.name)
            issue.create_comment('Webhook added!')
        except github3.exceptions.UnprocessableEntity:
            # Webhook already exists
            logging.info('Hook already existed.')
            issue.create_comment('Webhook is already here!')

        issue.close()
def acknowledge_merge_on_travis(data):
    """When a user comments on a pull request with one of the automerge
    triggers (e.g. merge on green), this hook will add the 'automerge'
    label.

    Issue comment data reference:
    https://developer.github.com/v3/activity/events/types/#issuecommentevent
    """
    if data.get('action') != 'created':
        return

    # Make sure it's a PR.
    if not github_helper.is_pull_request(data):
        return

    # If comment has trigger text.
    comment = data['comment']

    if not check_for_auto_merge_trigger(comment['body']):
        return

    # If user is a collaborator.
    gh = github_helper.get_client()
    repository = github_helper.get_repository(gh, data)

    if not repository.is_collaborator(data['sender']['login']):
        logging.info(
            '{} is not an owner and is trying to tell me what to do.'.format(
                data['sender']['login']))

    # Write a comment about it.
    pr = github_helper.get_pull_request(gh, data)
    pr.create_comment(
        'Okay! I\'ll merge when all statuses are green and all reviewers '
        'approve.')
    pr.issue().add_labels('automerge')
    pr.issue().assign(github_helper.github_user())