Created
March 5, 2018 03:39
-
-
Save craigcabrey/050b01c682050bc2747bfd10d296a716 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import functools | |
import git | |
import github | |
import tempfile | |
import textwrap | |
changes_requested_label = 'changes requested' | |
merge_label = 'ready to merge' | |
rebase_label = 'needs rebase' | |
review_label = 'needs review' | |
repo_url = '' | |
github_repo = '' | |
token = '' | |
def merge(target_branch, default_branch='develop'): | |
with tempfile.TemporaryDirectory() as temp_dir: | |
repo = git.Repo.clone_from(repo_url, temp_dir) | |
origin = repo.remotes[0] | |
try: | |
repo.git.rebase('{0}/{1}'.format(origin.name, target_branch)) | |
origin.push('refs/heads/{0}:refs/heads/{0}'.format(default_branch)) | |
origin.push(':refs/heads/{0}'.format(target_branch)) | |
return True | |
except git.GitCommandError: | |
return False | |
def main(): | |
gh = github.Github(token) | |
repo = gh.get_repo(github_repo) | |
HEAD = repo.get_branch(repo.default_branch).commit.sha | |
pulls = repo.get_pulls() | |
for pull in pulls: | |
commits = [commit for commit in pull.get_commits()] | |
# Check if the parent(s) of the first commit of the PR is HEAD | |
is_rebased = any(parent.sha == HEAD for parent in commits[0].parents) | |
issue = repo.get_issue(pull.number) | |
new_labels = [label.name for label in issue.labels] | |
if changes_requested_label not in new_labels: | |
for pr_commit in commits: | |
message_lines = pr_commit.commit.message.split() | |
if 50 < len(message_lines[0]): | |
pull.create_issue_comment(textwrap.dedent(''' | |
Commit messages do not conform to best practices. | |
Please ensure your subject line (first line of the | |
message) is 50 characters or less. Each line of the | |
body should be 72 characters or less. | |
''')) | |
new_labels.append(changes_requested_label) | |
break | |
if not is_rebased: | |
new_labels.append(rebase_label) | |
else: | |
if rebase_label in new_labels: | |
new_labels.remove(rebase_label) | |
if len(new_labels) == 0 or new_labels == [rebase_label]: | |
new_labels.append(review_label) | |
new_labels = list(set(new_labels)) | |
issue.edit(labels=new_labels) | |
statuses = functools.reduce( | |
lambda x, y: x + y, | |
[[s for s in c.get_statuses()] for c in commits] | |
) | |
failure = any(status.state == 'failure' for status in statuses) | |
if not failure and new_labels == [merge_label]: | |
print('Merging pull request #{0}'.format(pull.number)) | |
if merge(pull.head.ref, repo.default_branch): | |
# Last commit of the merged PR becomes the new HEAD | |
HEAD = commits[-1].sha | |
else: | |
pull.create_issue_comment( | |
':warning: **Warning!** Failed to auto-merge.' | |
) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment