Esempio n. 1
0
def add_welcome_comment(
    pr: MergeRequest,
    autorespond_text: str='Hi! This is GitMate v2.0!'
):
    """
    Adds a welcome comment to pull requests.
    """
    sign = TimestampSigner().sign(autorespond_text)
    msg = ('{}\n\n(Powered by [GitMate.io](https://gitmate.io))\n\n'
           '<!-- Timestamp signature `{}` -->'.format(autorespond_text, sign))
    pr.add_comment(msg)
Esempio n. 2
0
def gitmate_ack(pr: MergeRequest,
                comment: Comment,
                ack_strs: str = 'ack, reack',
                unack_strs: str = 'unack'):
    """
    A responder to ack and unack commits
    """
    body = comment.body.lower()
    commits = pr.commits
    perm_level = pr.repository.get_permission_level(comment.author)
    comment_slices = map_comment_parts_to_keywords(ack_strs, unack_strs, body)

    has_commit_sha = any(
        sha_compiled.search(string) for _list in comment_slices.values()
        for string in _list)

    # return right away if the comment isn't related to ack / unack command
    if not any(comment_slices) or not has_commit_sha:
        return
    elif perm_level.value < AccessLevel.CAN_WRITE.value:
        msg = ('Sorry @{}, you do not have the necessary permission '
               'levels to perform the action.'.format(comment.author.username))
        pr.add_comment(msg)
        return

    db_pr, created = MergeRequestModel.objects.get_or_create(
        repo=Repository.from_igitt_repo(pr.repository),
        number=pr.number,
        defaults={'acks': dict()})

    if created:
        # GitMate was integrated to the repo after syncing the pull request
        add_review_status(pr)
        db_pr.refresh_from_db()

    for commit in commits:
        for substring in comment_slices['unack']:
            if commit.sha[:6] in substring:
                db_pr.acks[_get_commit_hash(commit)] = _status_to_dict(
                    unack(commit))

        for substring in comment_slices['ack']:
            if commit.sha[:6] in substring:
                db_pr.acks[_get_commit_hash(commit)] = _status_to_dict(
                    ack(commit))

    db_pr.save()
    pr.head.set_status(db_pr.ack_state)
Esempio n. 3
0
def apply_command_on_merge_request(
    pr: MergeRequest,
    comment: Comment,
    enable_rebase: bool = False,
    enable_merge: bool = False,
    enable_fastforward: bool = False,
    merge_admin_only: bool = True,
    fastforward_admin_only: bool = True,
):
    """
    Performs a merge, fastforward or rebase of a merge request when an
    authorized user posts a command mentioning the keywords ``merge``,
    ``fastforward``/``ff`` or ``rebase`` respectively.

    e.g. ``@gitmate-bot rebase`` rebases the pull request with master.
    """
    username = Repository.from_igitt_repo(pr.repository).user.username
    cmd, cmd_past = get_matched_command(comment.body, username)
    enabled_cmd = {
        'rebase': enable_rebase,
        'merge': enable_merge,
        'fastforward': enable_fastforward
    }.get(cmd)

    if enabled_cmd:
        if not verify_command_access(comment, merge_admin_only,
                                     fastforward_admin_only, cmd):
            pr.add_comment(
                f'Hey @{comment.author.username}, you do not have the access '
                f'to perform the {cmd} action with [GitMate.io]'
                '(https://gitmate.io). Please ask a maintainer to give you '
                'access. :warning:')
            return

        pr.add_comment(
            f'Hey! I\'m [GitMate.io](https://gitmate.io)! This pull request is'
            f' being {cmd_past} automatically. Please **DO NOT** push while '
            f'{cmd} is in progress or your changes would be lost permanently '
            ':warning:')
        head_clone_url = pr.source_repository.clone_url
        base_clone_url = pr.target_repository.clone_url
        output = run_in_container(settings.REBASER_IMAGE, 'python', 'run.py',
                                  cmd, head_clone_url, base_clone_url,
                                  pr.head_branch_name, pr.base_branch_name)
        output = json.loads(output)
        if output['status'] == 'success':
            pr.add_comment(
                f'Automated {cmd} with [GitMate.io](https://gitmate.io) was '
                'successful! :tada:')
        elif 'error' in output:
            # hiding oauth token for safeguarding user privacy
            error = output['error'].replace(head_clone_url,
                                            '<hidden_oauth_token>')
            error = error.replace(base_clone_url, '<hidden_oauth_token>')
            pr.add_comment(f'Automated {cmd} failed! Please {cmd} your pull '
                           'request manually via the command line.\n\n'
                           'Reason:\n```\n{}\n```'.format(error))