Skip to content

Commit

Permalink
Merge pull request #402 from EverythingMe/chore/release_process
Browse files Browse the repository at this point in the history
New release process.
  • Loading branch information
arikfr committed Apr 6, 2015
2 parents 9fb33cf + f52044a commit 368f4fd
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 77 deletions.
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
NAME=redash
VERSION=`python ./manage.py version`
FULL_VERSION=$(VERSION)+b$(CIRCLE_BUILD_NUM)
BASE_VERSION=$(shell python ./manage.py version | cut -d + -f 1)
# VERSION gets evaluated every time it's referenced, therefore we need to use VERSION here instead of FULL_VERSION.
FILENAME=$(CIRCLE_ARTIFACTS)/$(NAME).$(VERSION).tar.gz

Expand All @@ -15,7 +16,7 @@ pack:
tar -zcv -f $(FILENAME) --exclude=".git*" --exclude="*.pyc" --exclude="*.pyo" --exclude="venv" --exclude="rd_ui/node_modules" --exclude="rd_ui/dist/bower_components" --exclude="rd_ui/app" *

upload:
python bin/upload_version.py $(VERSION) $(FILENAME)
python bin/release_manager.py $(CIRCLE_SHA1) $(BASE_VERSION) $(FILENAME)

test:
nosetests --with-coverage --cover-package=redash tests/*.py
Expand Down
30 changes: 0 additions & 30 deletions bin/latest_release.py

This file was deleted.

130 changes: 130 additions & 0 deletions bin/release_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import os
import sys
import json
import re
import subprocess
import requests

github_token = os.environ['GITHUB_TOKEN']
auth = (github_token, 'x-oauth-basic')
repo = 'EverythingMe/redash'

def _github_request(method, path, params=None, headers={}):
if not path.startswith('https://api.github.com'):
url = "https://api.github.com/{}".format(path)
else:
url = path

if params is not None:
params = json.dumps(params)

response = requests.request(method, url, data=params, auth=auth)
return response

def exception_from_error(message, response):
return Exception("({}) {}: {}".format(response.status_code, message, response.json().get('message', '?')))

def rc_tag_name(version):
return "v{}-rc".format(version)

def get_rc_release(version):
tag = rc_tag_name(version)
response = _github_request('get', 'repos/{}/releases/tags/{}'.format(repo, tag))

if response.status_code == 404:
return None
elif response.status_code == 200:
return response.json()

raise exception_from_error("Unknown error while looking RC release: ", response)

def create_release(version, commit_sha):
tag = rc_tag_name(version)

params = {
'tag_name': tag,
'name': "{} - RC".format(version),
'target_commitish': commit_sha,
'prerelease': True
}

response = _github_request('post', 'repos/{}/releases'.format(repo), params)

if response.status_code != 201:
raise exception_from_error("Failed creating new release", response)

return response.json()

def upload_asset(release, filepath):
upload_url = release['upload_url'].replace('{?name}', '')
filename = filepath.split('/')[-1]

with open(filepath) as file_content:
headers = {'Content-Type': 'application/gzip'}
response = requests.post(upload_url, file_content, params={'name': filename}, headers=headers, auth=auth, verify=False)

if response.status_code != 201: # not 200/201/...
raise exception_from_error('Failed uploading asset', response)

return response

def remove_previous_builds(release):
for asset in release['assets']:
response = _github_request('delete', asset['url'])
if response.status_code != 204:
raise exception_from_error("Failed deleting asset", response)

def get_changelog(commit_sha):
latest_release = _github_request('get', 'repos/{}/releases/latest'.format(repo))
if latest_release.status_code != 200:
raise exception_from_error('Failed getting latest release', latest_release)

latest_release = latest_release.json()
previous_sha = latest_release['target_commitish']

args = ['git', '--no-pager', 'log', '--merges', '--grep', 'Merge pull request', '--pretty=format:"%h|%s|%b|%p"', '{}...{}'.format(previous_sha, commit_sha)]
log = subprocess.check_output(args)
changes = ["Changes since {}:".format(latest_release['name'])]

for line in log.split('\n'):
try:
sha, subject, body, parents = line[1:-1].split('|')
except ValueError:
continue

try:
pull_request = re.match("Merge pull request #(\d+)", subject).groups()[0]
pull_request = " #{}".format(pull_request)
except Exception, ex:
pull_request = ""

author = subprocess.check_output(['git', 'log', '-1', '--pretty=format:"%an"', parents.split(' ')[-1]])[1:-1]

changes.append("{}{}: {} ({})".format(sha, pull_request, body.strip(), author))

return "\n".join(changes)

def update_release(version, build_filepath, commit_sha):
try:
release = get_rc_release(version) or create_release(version, commit_sha)
print "Using release id: {}".format(release['id'])

remove_previous_builds(release)
response = upload_asset(release, build_filepath)

changelog = get_changelog(commit_sha)

response = _github_request('patch', release['url'], {'body': changelog})
if response.status_code != 200:
raise exception_from_error("Failed updating release description", response)

except Exception, ex:
print ex

if __name__ == '__main__':
commit_sha = sys.argv[1]
version = sys.argv[2]
filepath = sys.argv[3]

# TODO: make sure running from git directory & remote = repo
update_release(version, filepath, commit_sha)
46 changes: 0 additions & 46 deletions bin/upload_version.py

This file was deleted.

0 comments on commit 368f4fd

Please sign in to comment.