Skip to content

Commit

Permalink
Merge pull request #1632 from brave/npm-run-pr
Browse files Browse the repository at this point in the history
Create new `npm run pr` task
  • Loading branch information
bsclifton authored Feb 13, 2019
2 parents 6bebe37 + 983ce6a commit 5d0a465
Show file tree
Hide file tree
Showing 3 changed files with 614 additions and 2 deletions.
198 changes: 198 additions & 0 deletions script/lib/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import re
import requests
import sys
import base64
from util import execute, scoped_cwd

REQUESTS_DIR = os.path.abspath(os.path.join(__file__, '..', '..', '..',
'vendor', 'requests'))
Expand Down Expand Up @@ -80,3 +82,199 @@ def __getattr__(self, attr):

name = '%s/%s' % (self._name, attr)
return _Callable(self._gh, name)


def get_authenticated_user_login(token):
"""given a valid GitHub access token, return the associated GitHub user login"""
# for more info see: https://developer.github.com/v3/users/#get-the-authenticated-user
user = GitHub(token).user()
try:
response = user.get()
return response['login']
except Exception as e:
print('[ERROR] ' + str(e))


def parse_user_logins(token, login_csv, verbose=False):
"""given a list of logins in csv format, parse into a list and validate logins"""
if login_csv is None:
return []
login_csv = login_csv.replace(" ", "")
parsed_logins = login_csv.split(',')

users = GitHub(token).users()

invalid_logins = []

# check login/username against GitHub
# for more info see: https://developer.github.com/v3/users/#get-a-single-user
for login in parsed_logins:
try:
response = users(login).get()
if verbose:
print('[INFO] Login "' + login + '" found: ' + str(response))
except Exception as e:
if verbose:
print('[INFO] Login "' + login + '" does not appear to be valid. ' + str(e))
invalid_logins.append(login)

if len(invalid_logins) > 0:
raise Exception('Invalid logins found. Are they misspelled? ' + ','.join(invalid_logins))

return parsed_logins


def parse_labels(token, repo_name, label_csv, verbose=False):
global config
if label_csv is None:
return []
label_csv = label_csv.replace(" ", "")
parsed_labels = label_csv.split(',')

invalid_labels = []

# validate labels passed in are correct
# for more info see: https://developer.github.com/v3/issues/labels/#get-a-single-label
repo = GitHub(token).repos(repo_name)
for label in parsed_labels:
try:
response = repo.labels(label).get()
if verbose:
print('[INFO] Label "' + label + '" found: ' + str(response))
except Exception as e:
if verbose:
print('[INFO] Label "' + label + '" does not appear to be valid. ' + str(e))
invalid_labels.append(label)

if len(invalid_labels) > 0:
raise Exception('Invalid labels found. Are they misspelled? ' + ','.join(invalid_labels))

return parsed_labels


def get_file_contents(token, repo_name, filename, branch=None):
# NOTE: API only supports files up to 1MB in size
# for more info see: https://developer.github.com/v3/repos/contents/
repo = GitHub(token).repos(repo_name)
get_data = {}
if branch:
get_data['ref'] = branch
file = repo.contents(filename).get(params=get_data)
if file['encoding'] == 'base64':
return base64.b64decode(file['content'])
return file['content']


def add_reviewers_to_pull_request(token, repo_name, pr_number, reviewers=[], verbose=False, dryrun=False):
# add reviewers to pull request
# for more info see: https://developer.github.com/v3/pulls/review_requests/
repo = GitHub(token).repos(repo_name)
patch_data = {}
if len(reviewers) > 0:
patch_data['reviewers'] = reviewers
if dryrun:
print('[INFO] would call `repo.pulls(' + str(pr_number) +
').requested_reviewers.post(' + str(patch_data) + ')`')
return
response = repo.pulls(pr_number).requested_reviewers.post(data=patch_data)
if verbose:
print('repo.pulls(' + str(pr_number) + ').requested_reviewers.post(data) response:\n' + str(response))
return response


def get_milestones(token, repo_name, verbose=False):
# get all milestones for a repo
# for more info see: https://developer.github.com/v3/issues/milestones/
repo = GitHub(token).repos(repo_name)
response = repo.milestones.get()
if verbose:
print('repo.milestones.get() response:\n' + str(response))
return response


def create_pull_request(token, repo_name, title, body, branch_src, branch_dst,
open_in_browser=False, verbose=False, dryrun=False):
post_data = {
'title': title,
'head': branch_src,
'base': branch_dst,
'body': body,
'maintainer_can_modify': True
}
# create the pull request
# for more info see: http://developer.github.com/v3/pulls
if dryrun:
print('[INFO] would call `repo.pulls.post(' + str(post_data) + ')`')
if open_in_browser:
print('[INFO] would open PR in web browser')
return 1234
repo = GitHub(token).repos(repo_name)
response = repo.pulls.post(data=post_data)
if verbose:
print('repo.pulls.post(data) response:\n' + str(response))
if open_in_browser:
import webbrowser
webbrowser.open(response['html_url'])
return int(response['number'])


def set_issue_details(token, repo_name, issue_number, milestone_number=None,
assignees=[], labels=[], verbose=False, dryrun=False):
patch_data = {}
if milestone_number:
patch_data['milestone'] = milestone_number
if len(assignees) > 0:
patch_data['assignees'] = assignees
if len(labels) > 0:
patch_data['labels'] = labels
# TODO: error if no keys in patch_data

# add milestone and assignee to issue / pull request
# for more info see: https://developer.github.com/v3/issues/#edit-an-issue
if dryrun:
print('[INFO] would call `repo.issues(' + str(issue_number) + ').patch(' + str(patch_data) + ')`')
return
repo = GitHub(token).repos(repo_name)
response = repo.issues(issue_number).patch(data=patch_data)
if verbose:
print('repo.issues(' + str(issue_number) + ').patch(data) response:\n' + str(response))


def fetch_origin_check_staged(path):
"""given a path on disk (to a git repo), fetch origin and ensure there aren't unstaged files"""
with scoped_cwd(path):
execute(['git', 'fetch', 'origin'])
status = execute(['git', 'status', '-s']).strip()
if len(status) > 0:
print('[ERROR] There appear to be unstaged changes.\n' +
'Please resolve these before running (ex: `git status`).')
return 1
return 0


def get_local_branch_name(path):
with scoped_cwd(path):
return execute(['git', 'rev-parse', '--abbrev-ref', 'HEAD']).strip()


def get_title_from_first_commit(path, branch_to_compare):
"""get the first commit subject (useful for the title of a pull request)"""
with scoped_cwd(path):
local_branch = execute(['git', 'rev-parse', '--abbrev-ref', 'HEAD']).strip()
title_list = execute(['git', 'log', 'origin/' + branch_to_compare +
'..HEAD', '--pretty=format:%s', '--reverse'])
title_list = title_list.split('\n')
if len(title_list) == 0:
raise Exception('No commits found! Local branch matches "' + branch_to_compare + '"')
return title_list[0]


def push_branches_to_remote(path, branches_to_push, dryrun=False):
if dryrun:
print('[INFO] would push the following local branches to remote: ' + str(branches_to_push))
else:
with scoped_cwd(path):
for branch_to_push in branches_to_push:
print('- pushing ' + branch_to_push + '...')
# TODO: if they already exist, force push?? or error??
execute(['git', 'push', '-u', 'origin', branch_to_push])
14 changes: 12 additions & 2 deletions script/lib/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,21 @@
from .config import get_raw_version

BRAVE_REPO = "brave/brave-browser"
BRAVE_CORE_REPO = "brave/brave-core"


def channels():
return ['nightly', 'dev', 'beta', 'release']


def get_channel_display_name():
d = {'beta': 'Beta', 'canary': 'Canary', 'dev': 'Developer',
'release': 'Release'}
raw = channels()
d = {
'canary': 'Canary',
raw[1]: 'Developer',
raw[2]: 'Beta',
raw[3]: 'Release'
}
return d[release_channel()]


Expand Down
Loading

0 comments on commit 5d0a465

Please sign in to comment.