mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-15 05:53:00 +00:00
add release script
modified from pyzmq mostly simpler, due to the removal of multiple Python versions needed for wheels.
This commit is contained in:
239
tools/tasks.py
Normal file
239
tools/tasks.py
Normal file
@@ -0,0 +1,239 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
invoke script for releasing jupyterhub
|
||||
|
||||
usage:
|
||||
|
||||
invoke release 1.2.3 [--upload]
|
||||
|
||||
This does:
|
||||
|
||||
- clone into /tmp/jupyterhub-repo
|
||||
- patches version.py with release version
|
||||
- creates tag (push if uploading)
|
||||
- makes a virtualenv with python3.4 (PYTHON_EXE env to override)
|
||||
- builds an sdist (optionally uploads)
|
||||
- patches version.py with post-release version (X.Y+1.Z.dev) (push if uploading)
|
||||
- unpacks sdist to /tmp/jupyterhub-release
|
||||
- builds bdist_wheel from sdist (optional upload)
|
||||
|
||||
"""
|
||||
# derived from PyZMQ release/tasks.py (used under BSD)
|
||||
|
||||
# Copyright (c) Jupyter Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import glob
|
||||
import os
|
||||
import pipes
|
||||
import shutil
|
||||
|
||||
from contextlib import contextmanager
|
||||
from distutils.version import LooseVersion as V
|
||||
|
||||
from invoke import task, run as invoke_run
|
||||
|
||||
pjoin = os.path.join
|
||||
here = os.path.dirname(__file__)
|
||||
|
||||
repo = "git@github.com:jupyter/jupyterhub"
|
||||
pkg = repo.rsplit('/', 1)[-1]
|
||||
|
||||
py_exe = os.environ.get('PYTHON_EXE', 'python3.4')
|
||||
|
||||
tmp = "/tmp"
|
||||
env_root = os.path.join(tmp, 'envs')
|
||||
repo_root = pjoin(tmp, '%s-repo' % pkg)
|
||||
sdist_root = pjoin(tmp, '%s-release' % pkg)
|
||||
|
||||
|
||||
def run(cmd, **kwargs):
|
||||
"""wrapper around invoke.run that accepts a Popen list"""
|
||||
if isinstance(cmd, list):
|
||||
cmd = " ".join(pipes.quote(s) for s in cmd)
|
||||
kwargs.setdefault('echo', True)
|
||||
return invoke_run(cmd, **kwargs)
|
||||
|
||||
|
||||
@contextmanager
|
||||
def cd(path):
|
||||
"""Context manager for temporary CWD"""
|
||||
cwd = os.getcwd()
|
||||
os.chdir(path)
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
|
||||
|
||||
@task
|
||||
def clone_repo(reset=False):
|
||||
"""Clone the repo"""
|
||||
if os.path.exists(repo_root) and reset:
|
||||
shutil.rmtree(repo_root)
|
||||
if os.path.exists(repo_root):
|
||||
with cd(repo_root):
|
||||
run("git pull")
|
||||
else:
|
||||
run("git clone %s %s" % (repo, repo_root))
|
||||
|
||||
|
||||
@task
|
||||
def patch_version(vs, path=pjoin(here, '..')):
|
||||
"""Patch zmq/sugar/version.py for the current release"""
|
||||
v = parse_vs(vs)
|
||||
version_py = pjoin(path, 'jupyterhub', 'version.py')
|
||||
print("patching %s with %s" % (version_py, vs))
|
||||
# read version.py, minus version parts
|
||||
with open(version_py) as f:
|
||||
pre_lines = []
|
||||
post_lines = []
|
||||
for line in f:
|
||||
pre_lines.append(line)
|
||||
if line.startswith("version_info"):
|
||||
break
|
||||
for line in f:
|
||||
if line.startswith(')'):
|
||||
post_lines.append(line)
|
||||
break
|
||||
for line in f:
|
||||
post_lines.append(line)
|
||||
|
||||
# write new version.py
|
||||
with open(version_py, 'w') as f:
|
||||
for line in pre_lines:
|
||||
f.write(line)
|
||||
for part in v:
|
||||
f.write(' %r,\n' % part)
|
||||
for line in post_lines:
|
||||
f.write(line)
|
||||
|
||||
# verify result
|
||||
ns = {}
|
||||
with open(version_py) as f:
|
||||
exec(f.read(), {}, ns)
|
||||
assert ns['__version__'] == vs, "%r != %r" % (ns['__version__'], vs)
|
||||
|
||||
|
||||
@task
|
||||
def tag(vs, push=False):
|
||||
"""Make the tagged release commit"""
|
||||
patch_version(vs, repo_root)
|
||||
with cd(repo_root):
|
||||
run('git commit -a -m "release {}"'.format(vs))
|
||||
run('git tag -a -m "release {0}" {0}'.format(vs))
|
||||
if push:
|
||||
run('git push')
|
||||
run('git push --tags')
|
||||
|
||||
|
||||
@task
|
||||
def untag(vs, push=False):
|
||||
"""Make the post-tag 'back to dev' commit"""
|
||||
v2 = parse_vs(vs)
|
||||
v2.append('dev')
|
||||
v2[1] += 1
|
||||
vs2 = unparse_vs(v2)
|
||||
patch_version(vs2, repo_root)
|
||||
with cd(repo_root):
|
||||
run('git commit -a -m "back to dev"')
|
||||
if push:
|
||||
run('git push')
|
||||
|
||||
|
||||
def make_env(*packages):
|
||||
"""Make a virtualenv
|
||||
|
||||
Assumes `which python` has the `virtualenv` package
|
||||
"""
|
||||
if not os.path.exists(env_root):
|
||||
os.makedirs(env_root)
|
||||
|
||||
env = os.path.join(env_root, os.path.basename(py_exe))
|
||||
py = pjoin(env, 'bin', 'python')
|
||||
# new env
|
||||
if not os.path.exists(py):
|
||||
run('python -m virtualenv {} -p {}'.format(
|
||||
pipes.quote(env),
|
||||
pipes.quote(py_exe),
|
||||
))
|
||||
py = pjoin(env, 'bin', 'python')
|
||||
run([py, '-V'])
|
||||
install(py, 'pip', 'setuptools')
|
||||
if packages:
|
||||
install(py, *packages)
|
||||
return py
|
||||
|
||||
|
||||
def build_sdist(py, upload=False):
|
||||
"""Build sdists
|
||||
|
||||
Returns the path to the tarball
|
||||
"""
|
||||
with cd(repo_root):
|
||||
cmd = [py, 'setup.py', 'sdist', '--formats=zip,gztar']
|
||||
if upload:
|
||||
cmd.append('upload')
|
||||
run(cmd)
|
||||
|
||||
return glob.glob(pjoin(repo_root, 'dist', '*.tar.gz'))[0]
|
||||
|
||||
|
||||
@task
|
||||
def sdist(vs, upload=False):
|
||||
clone_repo()
|
||||
tag(vs, push=upload)
|
||||
py = make_env()
|
||||
tarball = build_sdist(py, upload=upload)
|
||||
untag(vs, push=upload)
|
||||
return untar(tarball)
|
||||
|
||||
|
||||
def install(py, *packages):
|
||||
run([py, '-m', 'pip', 'install', '--upgrade'] + list(packages))
|
||||
|
||||
|
||||
def parse_vs(vs):
|
||||
"""version string to list"""
|
||||
return V(vs).version
|
||||
|
||||
|
||||
def unparse_vs(tup):
|
||||
"""version list to string"""
|
||||
return '.'.join(map(str, tup))
|
||||
|
||||
|
||||
def untar(tarball):
|
||||
"""extract sdist, returning path to unpacked package directory"""
|
||||
if os.path.exists(sdist_root):
|
||||
shutil.rmtree(sdist_root)
|
||||
os.makedirs(sdist_root)
|
||||
with cd(sdist_root):
|
||||
run(['tar', '-xzf', tarball])
|
||||
|
||||
return glob.glob(pjoin(sdist_root, '*'))[0]
|
||||
|
||||
|
||||
def bdist(upload=False):
|
||||
"""build a wheel, optionally uploading it"""
|
||||
py = make_env('wheel')
|
||||
cmd = [py, 'setup.py', 'bdist_wheel']
|
||||
if upload:
|
||||
cmd.append('upload')
|
||||
|
||||
run(cmd)
|
||||
|
||||
|
||||
@task
|
||||
def release(vs, upload=False):
|
||||
"""Release the package"""
|
||||
# start from scrach with clone and envs
|
||||
clone_repo(reset=True)
|
||||
if os.path.exists(env_root):
|
||||
shutil.rmtree(env_root)
|
||||
|
||||
path = sdist(vs, upload=upload)
|
||||
|
||||
with cd(path):
|
||||
bdist(upload=upload)
|
||||
|
Reference in New Issue
Block a user