Last active
March 18, 2016 02:39
-
-
Save craigcabrey/c3a4990d70f5d16deb76 to your computer and use it in GitHub Desktop.
This file contains 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