lbry-desktop/release_on_tag.py
2017-02-20 21:00:54 -06:00

128 lines
3.7 KiB
Python

import argparse
import glob
import json
import logging
import os
import platform
import re
import subprocess
import sys
import zipfile
import github
import requests
import uritemplate
from lbrynet.core import log_support
def main(args=None):
gh_token = os.environ['GH_TOKEN']
auth = github.Github(gh_token)
app_repo = auth.get_repo('lbryio/lbry-app')
# TODO: switch lbryio/lbrynet-daemon to lbryio/lbry
daemon_repo = auth.get_repo('lbryio/lbrynet-daemon')
artifact = get_artifact()
current_tag = None
try:
current_tag = subprocess.check_output(
['git', 'describe', '--exact-match', 'HEAD']).strip()
except subprocess.CalledProcessError:
log.info('Stopping as we are not currently on a tag')
return
if not check_repo_has_tag(app_repo, current_tag):
log.info('Tag %s is not in repo %s', current_tag, app_repo)
# TODO: maybe this should be an error
return
release = get_release(app_repo, current_tag)
upload_asset(release, artifact, gh_token)
release = get_release(daemon_repo, current_tag)
artifact = os.path.join('app', 'dist', 'lbrynet-daemon')
if platform.system() == 'Windows':
artifact += '.exe'
asset_to_upload = get_asset(artifact, get_system_label())
upload_asset(release, asset_to_upload, gh_token)
def check_repo_has_tag(repo, target_tag):
tags = repo.get_tags().get_page(0)
for tag in tags:
if tag.name == target_tag:
return True
return False
def get_release(current_repo, current_tag):
return current_repo.get_release(current_tag)
def get_artifact():
system = platform.system()
if system == 'Darwin':
return glob.glob('dist/mac/LBRY*.dmg')[0]
elif system == 'Linux':
return glob.glob('dist/LBRY*.deb')[0]
elif system == 'Windows':
return glob.glob('dist/LBRY*.exe')[0]
else:
raise Exception("I don't know about any artifact on {}".format(system))
def get_system_label():
system = platform.system()
if system == 'Darwin':
return 'macOS'
else:
return system
def get_asset(filename, label):
label = '-{}'.format(label)
base, ext = os.path.splitext(filename)
# TODO: probably want to clean this up
zipfilename = '{}{}.zip'.format(base, label)
with zipfile.ZipFile(zipfilename, 'w') as myzip:
myzip.write(filename)
return zipfilename
def upload_asset(release, asset_to_upload, token):
basename = os.path.basename(asset_to_upload)
if is_asset_already_uploaded(release, basename):
return
upload_uri = uritemplate.expand(
release.upload_url, {'name': basename})
# using requests.post fails miserably with SSL EPIPE errors. I spent
# half a day trying to debug before deciding to switch to curl.
cmd = [
'curl', '-sS', '-X', 'POST', '-u', ':{}'.format(os.environ['GH_TOKEN']),
'--header', 'Content-Type:application/zip',
'--data-binary', '@{}'.format(asset_to_upload), upload_uri
]
raw_output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
output = json.loads(raw_output)
if 'errors' in output:
raise Exception(output)
else:
log.info('Successfully uploaded to %s', output['browser_download_url'])
def is_asset_already_uploaded(release, basename):
for asset in release.raw_data['assets']:
if asset['name'] == basename:
log.info('File %s has already been uploaded to %s', basename, release.tag_name)
return True
return False
if __name__ == '__main__':
log = logging.getLogger('release-on-tag')
log_support.configure_console(level='DEBUG')
sys.exit(main())
else:
log = logging.getLogger(__name__)