mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-26 18:18:25 +00:00
add release
This commit is contained in:
commit
dd2c500294
6
release/.env
Normal file
6
release/.env
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
DIR="$( dirname "${BASH_SOURCE[0]}" )"
|
||||||
|
ACTIVATE_DIR="$(if [ -f "$DIR/../venv.mitmproxy/bin/activate" ]; then echo 'bin'; else echo 'Scripts'; fi;)"
|
||||||
|
if [ -z "$VIRTUAL_ENV" ] && [ -f "$DIR/../venv.mitmproxy/$ACTIVATE_DIR/activate" ]; then
|
||||||
|
echo "Activating mitmproxy virtualenv..."
|
||||||
|
source "$DIR/../venv.mitmproxy/$ACTIVATE_DIR/activate"
|
||||||
|
fi
|
9
release/.gitignore
vendored
Normal file
9
release/.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
.DS_Store
|
||||||
|
MANIFEST
|
||||||
|
*.py[cdo]
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
/build
|
||||||
|
/dist
|
||||||
|
/mitmproxy_rtool.egg-info
|
83
release/README.mkd
Normal file
83
release/README.mkd
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
|
||||||
|
General build and release utilities for the mitmproxy, netlib and pathod
|
||||||
|
projects. These tools assume a directory structure with all repositories at the
|
||||||
|
same level, for example:
|
||||||
|
|
||||||
|
/src
|
||||||
|
/mitmproxy
|
||||||
|
/netlib
|
||||||
|
/pathod
|
||||||
|
/release
|
||||||
|
|
||||||
|
|
||||||
|
# Release policies
|
||||||
|
|
||||||
|
- By default, every release is a new minor (`0.x`) release and it will be
|
||||||
|
pushed for all three projects.
|
||||||
|
|
||||||
|
- Only if an emergency bugfix is needed, we push a new `0.x.y` bugfix release
|
||||||
|
for a single project. This matches with what we do in `setup.py`:
|
||||||
|
|
||||||
|
"netlib>=%s, <%s" % (version.MINORVERSION, version.NEXT_MINORVERSION)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Release Checklist
|
||||||
|
|
||||||
|
## Check out release versions
|
||||||
|
|
||||||
|
- Check out the versions of pathod, netlib and mitmproxy due to be released
|
||||||
|
|
||||||
|
- Verify that repositories are in a clean state:
|
||||||
|
|
||||||
|
`./build git status`
|
||||||
|
|
||||||
|
- Ensure that the website style assets have been compiled for production, and
|
||||||
|
synced to the docs.
|
||||||
|
|
||||||
|
- Render the docs, update CONTRIBUTORS file:
|
||||||
|
|
||||||
|
./build docs contributors
|
||||||
|
|
||||||
|
|
||||||
|
## Test
|
||||||
|
|
||||||
|
- Test the source distributions:
|
||||||
|
|
||||||
|
./build test
|
||||||
|
|
||||||
|
This does the following:
|
||||||
|
- creates a venv in release/venv
|
||||||
|
- creates source distributions in release/release
|
||||||
|
- installs the source distributions in the venv
|
||||||
|
- and runs all installed tools
|
||||||
|
|
||||||
|
|
||||||
|
## Release
|
||||||
|
|
||||||
|
- Make a release commit for all projects, tag and push it:
|
||||||
|
|
||||||
|
./build git commit -am "Release v0.13"
|
||||||
|
./build git tag v0.13
|
||||||
|
./build git push --tags
|
||||||
|
|
||||||
|
- Build the OSX binaries
|
||||||
|
- Follow instructions in osx-binaries
|
||||||
|
- Move to download dir:
|
||||||
|
|
||||||
|
mv ./tmp/osx-mitmproxy-VERSION.tar.gz ~/mitmproxy/www.mitmproxy.org/src/download
|
||||||
|
|
||||||
|
- Move all source distributions from `./dist` to the server:
|
||||||
|
|
||||||
|
mv ./dist/* ~/mitmproxy/www.mitmproxy.org/src/download
|
||||||
|
|
||||||
|
- Upload distributions in `./dist` to PyPI:
|
||||||
|
|
||||||
|
./build upload
|
||||||
|
|
||||||
|
You can test with [testpypi.python.org](https://testpypi.python.org/pypi) by passing `--repository test`.
|
||||||
|
([more info](https://tom-christie.github.io/articles/pypi/))
|
||||||
|
|
||||||
|
- Now bump the version number to be ready for the next cycle
|
||||||
|
|
||||||
|
`./build set-version 0.13`
|
68
release/rtool.pem
Normal file
68
release/rtool.pem
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
Proc-Type: 4,ENCRYPTED
|
||||||
|
DEK-Info: AES-128-CBC,7A4E07094E1AC0B74BB3D172A73A62DB
|
||||||
|
|
||||||
|
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
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAs0xeGx+bc+NCLGRJDr6y
|
||||||
|
qv825685l1Tb6lhLvYVYUFJfcxL1V79ML13CO09TPxGTbmKw7iI33ef9N2mUHHVe
|
||||||
|
24EjcSnYZ2Zx5zYIY4ejnDKCzM0md9XA3RpfTI9F3zGsJPt72veyHy6alCbF4NgX
|
||||||
|
FgAvp2UJmWwTLnJj3oIEwfGJeEcQRKjCFjSJlHGxbB6L0MSCgRtDxwlBfinzkriZ
|
||||||
|
0C8YyVv6u+DidHtobbZvwk/4uV3+KhoDfkpT2VE57a2KXr4c9Fekzr6szduFMkcI
|
||||||
|
KPqKouOOnaiNjOoKofbZ5I6cB6qoMkh+ebJvfPuEYBwhHmDDhpdjdk5v3LkeD5kt
|
||||||
|
0GtOaF5A3LbdZhgsC+1v1dHrL6Vndrb9KhO8ATHvlzJOonV73AoJFygp6upCvIt+
|
||||||
|
tPUuy3VE0kjc2mJDDJr5V28pSBJ5r9uz1rXZWP+9aduR3M+RUGzHS7cUdsl+lHyQ
|
||||||
|
TFQAQIDhWXyokMGqVZBm9xJ2KcDiQAEr5+kP0BrhPmBtfHSnLA1tIXlFcOqakvyQ
|
||||||
|
q1cACMvwbkZpupTqMhCr2S4V9dKxnlO5EIWYJmme9moU/zu1KA0mcwqfnNeDOR2J
|
||||||
|
6c3/x3E+AqBoFzDQb6LQ2Iw+9bkKWKgDml4paLPu/ot8vA2ZB9/mujFUvp/1MLuD
|
||||||
|
5I1jQDXFbjAgAnaSyqyW368CAwEAAQ==
|
||||||
|
-----END PUBLIC KEY-----
|
439
release/rtool.py
Normal file
439
release/rtool.py
Normal file
@ -0,0 +1,439 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
from __future__ import absolute_import, print_function, division
|
||||||
|
from os.path import join
|
||||||
|
import contextlib
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import re
|
||||||
|
import shlex
|
||||||
|
import runpy
|
||||||
|
import zipfile
|
||||||
|
import tarfile
|
||||||
|
import platform
|
||||||
|
import click
|
||||||
|
import pysftp
|
||||||
|
import fnmatch
|
||||||
|
from six.moves import shlex_quote
|
||||||
|
|
||||||
|
# https://virtualenv.pypa.io/en/latest/userguide.html#windows-notes
|
||||||
|
# scripts and executables on Windows go in ENV\Scripts\ instead of ENV/bin/
|
||||||
|
if platform.system() == "Windows":
|
||||||
|
VENV_BIN = "Scripts"
|
||||||
|
else:
|
||||||
|
VENV_BIN = "bin"
|
||||||
|
|
||||||
|
if platform.system() == "Windows":
|
||||||
|
def Archive(name):
|
||||||
|
a = zipfile.ZipFile(name, "w")
|
||||||
|
a.add = a.write
|
||||||
|
return a
|
||||||
|
else:
|
||||||
|
def Archive(name):
|
||||||
|
return tarfile.open(name, "w:gz")
|
||||||
|
|
||||||
|
RELEASE_DIR = join(os.path.dirname(os.path.realpath(__file__)))
|
||||||
|
DIST_DIR = join(RELEASE_DIR, "dist")
|
||||||
|
ROOT_DIR = join(RELEASE_DIR, "..")
|
||||||
|
|
||||||
|
BUILD_DIR = join(RELEASE_DIR, "build")
|
||||||
|
PYINSTALLER_TEMP = join(BUILD_DIR, "pyinstaller")
|
||||||
|
PYINSTALLER_DIST = join(BUILD_DIR, "binaries")
|
||||||
|
|
||||||
|
VENV_DIR = join(BUILD_DIR, "venv")
|
||||||
|
VENV_PIP = join(VENV_DIR, VENV_BIN, "pip")
|
||||||
|
VENV_PYINSTALLER = join(VENV_DIR, VENV_BIN, "pyinstaller")
|
||||||
|
|
||||||
|
ALL_PROJECTS = {
|
||||||
|
"netlib": {
|
||||||
|
"tools": [],
|
||||||
|
"vfile": join(ROOT_DIR, "netlib/netlib/version.py"),
|
||||||
|
"dir": join(ROOT_DIR, "netlib"),
|
||||||
|
"python_version": "py2.py3" # this is the format in wheel filenames
|
||||||
|
},
|
||||||
|
"pathod": {
|
||||||
|
"tools": ["pathod", "pathoc"],
|
||||||
|
"vfile": join(ROOT_DIR, "pathod/libpathod/version.py"),
|
||||||
|
"dir": join(ROOT_DIR, "pathod"),
|
||||||
|
"python_version": "py2"
|
||||||
|
},
|
||||||
|
"mitmproxy": {
|
||||||
|
"tools": ["mitmproxy", "mitmdump", "mitmweb"],
|
||||||
|
"vfile": join(ROOT_DIR, "mitmproxy/libmproxy/version.py"),
|
||||||
|
"dir": join(ROOT_DIR, "mitmproxy"),
|
||||||
|
"python_version": "py2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if platform.system() == "Windows":
|
||||||
|
ALL_PROJECTS["mitmproxy"]["tools"].remove("mitmproxy")
|
||||||
|
|
||||||
|
projects = {}
|
||||||
|
|
||||||
|
|
||||||
|
def get_version(project):
|
||||||
|
return runpy.run_path(projects[project]["vfile"])["VERSION"]
|
||||||
|
|
||||||
|
|
||||||
|
def get_snapshot_version(project):
|
||||||
|
last_tag, tag_dist, commit = subprocess.check_output(
|
||||||
|
["git", "describe", "--tags", "--long"],
|
||||||
|
cwd=projects[project]["dir"]
|
||||||
|
).strip().rsplit("-", 2)
|
||||||
|
tag_dist = int(tag_dist)
|
||||||
|
if tag_dist == 0:
|
||||||
|
return get_version(project)
|
||||||
|
else:
|
||||||
|
return "{version}dev{tag_dist:04}-{commit}".format(
|
||||||
|
version=get_version(project), # this should already be the next version
|
||||||
|
tag_dist=tag_dist,
|
||||||
|
commit=commit
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def archive_name(project):
|
||||||
|
platform_tag = {
|
||||||
|
"Darwin": "osx",
|
||||||
|
"Windows": "win32",
|
||||||
|
"Linux": "linux"
|
||||||
|
}.get(platform.system(), platform.system())
|
||||||
|
if platform.system() == "Windows":
|
||||||
|
ext = "zip"
|
||||||
|
else:
|
||||||
|
ext = "tar.gz"
|
||||||
|
return "{project}-{version}-{platform}.{ext}".format(
|
||||||
|
project=project,
|
||||||
|
version=get_version(project),
|
||||||
|
platform=platform_tag,
|
||||||
|
ext=ext
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def sdist_name(project):
|
||||||
|
return "{project}-{version}.tar.gz".format(
|
||||||
|
project=project,
|
||||||
|
version=get_version(project)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def wheel_name(project):
|
||||||
|
return "{project}-{version}-{py_version}-none-any.whl".format(
|
||||||
|
project=project,
|
||||||
|
version=get_version(project),
|
||||||
|
py_version=projects[project]["python_version"]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def empty_pythonpath():
|
||||||
|
"""
|
||||||
|
Make sure that the regular python installation is not on the python path,
|
||||||
|
which would give us access to modules installed outside of our virtualenv.
|
||||||
|
"""
|
||||||
|
pythonpath = os.environ.get("PYTHONPATH", "")
|
||||||
|
os.environ["PYTHONPATH"] = ""
|
||||||
|
yield
|
||||||
|
os.environ["PYTHONPATH"] = pythonpath
|
||||||
|
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def chdir(path):
|
||||||
|
old_dir = os.getcwd()
|
||||||
|
os.chdir(path)
|
||||||
|
yield
|
||||||
|
os.chdir(old_dir)
|
||||||
|
|
||||||
|
|
||||||
|
@click.group(chain=True)
|
||||||
|
@click.option(
|
||||||
|
'--project', '-p',
|
||||||
|
multiple=True, type=click.Choice(ALL_PROJECTS.keys()), default=ALL_PROJECTS.keys()
|
||||||
|
)
|
||||||
|
def cli(project):
|
||||||
|
"""
|
||||||
|
mitmproxy build tool
|
||||||
|
"""
|
||||||
|
for name in project:
|
||||||
|
projects[name] = ALL_PROJECTS[name]
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command("contributors")
|
||||||
|
def contributors():
|
||||||
|
"""
|
||||||
|
Update CONTRIBUTORS.md
|
||||||
|
"""
|
||||||
|
for project, conf in projects.items():
|
||||||
|
with chdir(conf["dir"]):
|
||||||
|
print("Updating %s/CONTRIBUTORS..." % project)
|
||||||
|
contributors_data = subprocess.check_output(
|
||||||
|
shlex.split("git shortlog -n -s")
|
||||||
|
)
|
||||||
|
with open("CONTRIBUTORS", "w") as f:
|
||||||
|
f.write(contributors_data)
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command("set-version")
|
||||||
|
@click.argument('version')
|
||||||
|
def set_version(version):
|
||||||
|
"""
|
||||||
|
Update version information
|
||||||
|
"""
|
||||||
|
print("Update versions...")
|
||||||
|
version = ", ".join(version.split("."))
|
||||||
|
for p, conf in projects.items():
|
||||||
|
print("Update %s..." % os.path.normpath(conf["vfile"]))
|
||||||
|
with open(conf["vfile"], "rb") as f:
|
||||||
|
content = f.read()
|
||||||
|
new_content = re.sub(
|
||||||
|
r"IVERSION\s*=\s*\([\d,\s]+\)", "IVERSION = (%s)" % version,
|
||||||
|
content
|
||||||
|
)
|
||||||
|
with open(conf["vfile"], "wb") as f:
|
||||||
|
f.write(new_content)
|
||||||
|
|
||||||
|
|
||||||
|
def _git(project, args):
|
||||||
|
print("%s> %s..." % (project, " ".join(shlex_quote(a) for a in args)))
|
||||||
|
subprocess.check_call(
|
||||||
|
["git"] + list(args),
|
||||||
|
cwd=projects[project]["dir"]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command("git")
|
||||||
|
@click.argument('args', nargs=-1, required=True)
|
||||||
|
def git(args):
|
||||||
|
"""
|
||||||
|
Run a git command on every project
|
||||||
|
"""
|
||||||
|
for project, conf in projects.items():
|
||||||
|
_git(project, args)
|
||||||
|
print("")
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command("sdist")
|
||||||
|
def sdist():
|
||||||
|
"""
|
||||||
|
Build a source distribution
|
||||||
|
"""
|
||||||
|
with empty_pythonpath():
|
||||||
|
print("Building release...")
|
||||||
|
if os.path.exists(DIST_DIR):
|
||||||
|
shutil.rmtree(DIST_DIR)
|
||||||
|
for project, conf in projects.items():
|
||||||
|
print("Creating %s source distribution..." % project)
|
||||||
|
subprocess.check_call(
|
||||||
|
[
|
||||||
|
"python", "./setup.py", "-q",
|
||||||
|
"sdist", "--dist-dir", DIST_DIR, "--formats=gztar",
|
||||||
|
"bdist_wheel", "--dist-dir", DIST_DIR,
|
||||||
|
],
|
||||||
|
cwd=conf["dir"]
|
||||||
|
)
|
||||||
|
|
||||||
|
print("Creating virtualenv for test install...")
|
||||||
|
if os.path.exists(VENV_DIR):
|
||||||
|
shutil.rmtree(VENV_DIR)
|
||||||
|
subprocess.check_call(["virtualenv", "-q", VENV_DIR])
|
||||||
|
|
||||||
|
with chdir(DIST_DIR):
|
||||||
|
for project, conf in projects.items():
|
||||||
|
print("Installing %s..." % project)
|
||||||
|
subprocess.check_call([VENV_PIP, "install", "-q", sdist_name(project)])
|
||||||
|
|
||||||
|
print("Running binaries...")
|
||||||
|
for project, conf in projects.items():
|
||||||
|
for tool in conf["tools"]:
|
||||||
|
tool = join(VENV_DIR, VENV_BIN, tool)
|
||||||
|
print("> %s --version" % tool)
|
||||||
|
print(subprocess.check_output([tool, "--version"]))
|
||||||
|
|
||||||
|
print("Virtualenv available for further testing:")
|
||||||
|
print("source %s" % os.path.normpath(join(VENV_DIR, VENV_BIN, "activate")))
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command("bdist")
|
||||||
|
@click.option("--use-existing-sdist/--no-use-existing-sdist", default=False)
|
||||||
|
@click.argument("pyinstaller_version", envvar="PYINSTALLER_VERSION", default="PyInstaller~=3.1.1")
|
||||||
|
@click.pass_context
|
||||||
|
def bdist(ctx, use_existing_sdist, pyinstaller_version):
|
||||||
|
"""
|
||||||
|
Build a binary distribution
|
||||||
|
"""
|
||||||
|
if os.path.exists(PYINSTALLER_TEMP):
|
||||||
|
shutil.rmtree(PYINSTALLER_TEMP)
|
||||||
|
if os.path.exists(PYINSTALLER_DIST):
|
||||||
|
shutil.rmtree(PYINSTALLER_DIST)
|
||||||
|
|
||||||
|
if not use_existing_sdist:
|
||||||
|
ctx.invoke(sdist)
|
||||||
|
|
||||||
|
print("Installing PyInstaller...")
|
||||||
|
subprocess.check_call([VENV_PIP, "install", "-q", pyinstaller_version])
|
||||||
|
|
||||||
|
for p, conf in projects.items():
|
||||||
|
if conf["tools"]:
|
||||||
|
with Archive(join(DIST_DIR, archive_name(p))) as archive:
|
||||||
|
for tool in conf["tools"]:
|
||||||
|
spec = join(conf["dir"], "release", "%s.spec" % tool)
|
||||||
|
print("Building %s binary..." % tool)
|
||||||
|
subprocess.check_call(
|
||||||
|
[
|
||||||
|
VENV_PYINSTALLER,
|
||||||
|
"--clean",
|
||||||
|
"--workpath", PYINSTALLER_TEMP,
|
||||||
|
"--distpath", PYINSTALLER_DIST,
|
||||||
|
# This is PyInstaller, so setting a
|
||||||
|
# different log level obviously breaks it :-)
|
||||||
|
# "--log-level", "WARN",
|
||||||
|
spec
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Test if it works at all O:-)
|
||||||
|
executable = join(PYINSTALLER_DIST, tool)
|
||||||
|
if platform.system() == "Windows":
|
||||||
|
executable += ".exe"
|
||||||
|
print("> %s --version" % executable)
|
||||||
|
subprocess.check_call([executable, "--version"])
|
||||||
|
|
||||||
|
archive.add(executable, os.path.basename(executable))
|
||||||
|
print("Packed {}.".format(archive_name(p)))
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command("upload-release")
|
||||||
|
@click.option('--username', prompt=True)
|
||||||
|
@click.password_option(confirmation_prompt=False)
|
||||||
|
@click.option('--repository', default="pypi")
|
||||||
|
@click.option("--sdist/--no-sdist", default=True)
|
||||||
|
@click.option("--wheel/--no-wheel", default=True)
|
||||||
|
def upload_release(username, password, repository, sdist, wheel):
|
||||||
|
"""
|
||||||
|
Upload source distributions to PyPI
|
||||||
|
"""
|
||||||
|
for project in projects.keys():
|
||||||
|
files = []
|
||||||
|
if sdist:
|
||||||
|
files.append(sdist_name(project))
|
||||||
|
if wheel:
|
||||||
|
files.append(wheel_name(project))
|
||||||
|
for f in files:
|
||||||
|
print("Uploading {} to {}...".format(f, repository))
|
||||||
|
subprocess.check_call([
|
||||||
|
"twine",
|
||||||
|
"upload",
|
||||||
|
"-u", username,
|
||||||
|
"-p", password,
|
||||||
|
"-r", repository,
|
||||||
|
join(DIST_DIR, f)
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command("upload-snapshot")
|
||||||
|
@click.option("--host", envvar="SNAPSHOT_HOST", prompt=True)
|
||||||
|
@click.option("--port", envvar="SNAPSHOT_PORT", type=int, default=22)
|
||||||
|
@click.option("--user", envvar="SNAPSHOT_USER", prompt=True)
|
||||||
|
@click.option("--private-key", default=join(RELEASE_DIR, "rtool.pem"))
|
||||||
|
@click.option("--private-key-password", envvar="SNAPSHOT_PASS", prompt=True, hide_input=True)
|
||||||
|
@click.option("--sdist/--no-sdist", default=False)
|
||||||
|
@click.option("--wheel/--no-wheel", default=False)
|
||||||
|
@click.option("--bdist/--no-bdist", default=False)
|
||||||
|
def upload_snapshot(host, port, user, private_key, private_key_password, sdist, wheel, bdist):
|
||||||
|
"""
|
||||||
|
Upload snapshot to snapshot server
|
||||||
|
"""
|
||||||
|
with pysftp.Connection(host=host,
|
||||||
|
port=port,
|
||||||
|
username=user,
|
||||||
|
private_key=private_key,
|
||||||
|
private_key_pass=private_key_password) as sftp:
|
||||||
|
for project, conf in projects.items():
|
||||||
|
dir_name = "snapshots/v{}".format(get_version(project))
|
||||||
|
sftp.makedirs(dir_name)
|
||||||
|
with sftp.cd(dir_name):
|
||||||
|
files = []
|
||||||
|
if sdist:
|
||||||
|
files.append(sdist_name(project))
|
||||||
|
if wheel:
|
||||||
|
files.append(wheel_name(project))
|
||||||
|
if bdist and conf["tools"]:
|
||||||
|
files.append(archive_name(project))
|
||||||
|
|
||||||
|
for f in files:
|
||||||
|
local_path = join(DIST_DIR, f)
|
||||||
|
remote_filename = f.replace(get_version(project), get_snapshot_version(project))
|
||||||
|
symlink_path = "../{}".format(f.replace(get_version(project), "latest"))
|
||||||
|
|
||||||
|
old_version = f.replace(get_version(project), "*")
|
||||||
|
for f in sftp.listdir():
|
||||||
|
if fnmatch.fnmatch(f, old_version):
|
||||||
|
print("Removing {}...".format(f))
|
||||||
|
sftp.remove(f)
|
||||||
|
|
||||||
|
print("Uploading {} as {}...".format(f, remote_filename))
|
||||||
|
with click.progressbar(length=os.stat(local_path).st_size) as bar:
|
||||||
|
sftp.put(
|
||||||
|
local_path,
|
||||||
|
"." + remote_filename,
|
||||||
|
callback=lambda done, total: bar.update(done - bar.pos)
|
||||||
|
)
|
||||||
|
# We hide the file during upload.
|
||||||
|
sftp.rename("." + remote_filename, remote_filename)
|
||||||
|
|
||||||
|
# add symlink
|
||||||
|
if sftp.lexists(symlink_path):
|
||||||
|
print("Removing {}...".format(symlink_path))
|
||||||
|
sftp.remove(symlink_path)
|
||||||
|
sftp.symlink("v{}/{}".format(get_version(project), remote_filename), symlink_path)
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command("wizard")
|
||||||
|
@click.option('--next-version', prompt=True)
|
||||||
|
@click.option('--username', prompt="PyPI Username")
|
||||||
|
@click.password_option(confirmation_prompt=False, prompt="PyPI Password")
|
||||||
|
@click.option('--repository', default="pypi")
|
||||||
|
@click.pass_context
|
||||||
|
def wizard(ctx, next_version, username, password, repository):
|
||||||
|
"""
|
||||||
|
Interactive Release Wizard
|
||||||
|
"""
|
||||||
|
for project, conf in projects.items():
|
||||||
|
is_dirty = subprocess.check_output(["git", "status", "--porcelain"], cwd=conf["dir"])
|
||||||
|
if is_dirty:
|
||||||
|
raise RuntimeError("%s repository is not clean." % project)
|
||||||
|
|
||||||
|
# update contributors file
|
||||||
|
ctx.invoke(contributors)
|
||||||
|
|
||||||
|
# Build test release
|
||||||
|
ctx.invoke(bdist)
|
||||||
|
|
||||||
|
try:
|
||||||
|
click.confirm("Please test the release now. Is it ok?", abort=True)
|
||||||
|
except click.Abort:
|
||||||
|
# undo changes
|
||||||
|
ctx.invoke(git, args=["checkout", "CONTRIBUTORS"])
|
||||||
|
raise
|
||||||
|
|
||||||
|
# Everything ok - let's ship it!
|
||||||
|
for p in projects.keys():
|
||||||
|
_git(p, ["tag", "v" + get_version(p)])
|
||||||
|
ctx.invoke(git, args=["push", "--tags"])
|
||||||
|
ctx.invoke(
|
||||||
|
upload_release,
|
||||||
|
username=username, password=password, repository=repository
|
||||||
|
)
|
||||||
|
|
||||||
|
click.confirm("Now please wait until CI has built binaries. Finished?")
|
||||||
|
|
||||||
|
# version bump commit
|
||||||
|
ctx.invoke(set_version, version=next_version)
|
||||||
|
ctx.invoke(
|
||||||
|
git, args=["commit", "-a", "-m", "bump version"]
|
||||||
|
)
|
||||||
|
ctx.invoke(git, args=["push"])
|
||||||
|
|
||||||
|
click.echo("All done!")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
cli()
|
20
release/setup.py
Normal file
20
release/setup.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
from setuptools import setup
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name='mitmproxy-rtool',
|
||||||
|
version="1.0",
|
||||||
|
py_modules=["rtool"],
|
||||||
|
install_requires=[
|
||||||
|
"click>=6.2, <7.0",
|
||||||
|
"twine>=1.6.5, <1.7",
|
||||||
|
"virtualenv>=14.0.5, <14.1",
|
||||||
|
"wheel>=0.29.0, <0.30",
|
||||||
|
"six>=1.10.0, <1.11",
|
||||||
|
"pysftp>=0.2.8, <0.3",
|
||||||
|
],
|
||||||
|
entry_points={
|
||||||
|
"console_scripts": [
|
||||||
|
"rtool=rtool:cli",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user