Skip to content

Instantly share code, notes, and snippets.

@pyokagan
Created December 16, 2016 14:10
Show Gist options
  • Select an option

  • Save pyokagan/a7905f12c8248e20a4cf83b5ace5748a to your computer and use it in GitHub Desktop.

Select an option

Save pyokagan/a7905f12c8248e20a4cf83b5ace5748a to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import sys
import re
import argparse
import subprocess
import requests
def get_remote_owner_repo(remote):
"Returns the github owner and repo of the remote"
cmd = ['git', 'config', 'remote.{}.url'.format(remote)]
url = subprocess.check_output(cmd, universal_newlines=True)
url = url.strip()
match = re.match(r'^[email protected]:([^/]+)/(.+)$', url)
if not match:
raise ValueError('invalid remote url {}'.format(url))
owner, repo = match.groups()
if repo.endswith('.git'):
repo = repo[:-len('.git')]
return owner, repo
def fetch_pr(remote, pr):
"Fetches the PR into FETCH_HEAD"
cmd = ['git', 'fetch', '-q', remote, 'pull/{0}/head'.format(pr)]
subprocess.check_call(cmd)
def get_latest_pr_tag(pr):
"Returns the latest PR tag, if any. Otherwise, None"
cmd = ['git', 'tag', '-l', 'pr/{}-*'.format(pr)]
out = subprocess.check_output(cmd, universal_newlines=True)
out = out.strip()
if not out:
return None, None
out = out.split('\n')
out.sort()
match = re.match(r'(.+)-v(\d+)$', out[-1])
base, version = match.groups()
return base, int(version)
def get_pr_info(owner, repo, pr):
url = 'https://api.github.com/repos/{}/{}/pulls/{}'.format(owner, repo, pr)
r = requests.get(url)
if r.status_code == 404:
raise ValueError('No such PR {}/{}/{}'.format(owner, repo, pr))
r.raise_for_status()
return r.json()
def make_tag(name, head):
cmd = ['git', 'tag', name, head]
subprocess.check_call(cmd)
def main(args, prog=None):
p = argparse.ArgumentParser(prog=prog)
p.add_argument('remote')
p.add_argument('pr', type=int)
args = p.parse_args(args)
owner, repo = get_remote_owner_repo(args.remote)
pr_info = get_pr_info(owner, repo, args.pr)
tag_base, tag_version = get_latest_pr_tag(args.pr)
if not tag_base:
default_tag_base = pr_info['head']['ref']
tag_base = input('Branch name [{}]: '.format(default_tag_base))
if not tag_base:
tag_base = default_tag_base
tag_base = 'pr/{}-{}'.format(args.pr, tag_base)
tag_version = 0
tag_version += 1
fetch_pr(args.remote, args.pr)
tag_name = '{}-v{}'.format(tag_base, tag_version)
make_tag(tag_name, 'FETCH_HEAD')
print('Created tag', tag_name)
if __name__ == '__main__':
sys.exit(main(sys.argv[1:], sys.argv[0]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment