From 11c626cf8418dbac1c6aea701a298e3c166b4721 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sun, 16 Aug 2015 20:09:33 +1200 Subject: [PATCH] OSX binary builds in Python script --- .gitignore | 1 + README | 83 +++++++++++++++++++++++++++++++++++++++++--- osx-binaries | 7 ---- release-checklist.md | 60 -------------------------------- requirements.txt | 1 - rtool | 70 ++++++++++++++++++++++++++++++++----- 6 files changed, 141 insertions(+), 81 deletions(-) delete mode 100644 release-checklist.md diff --git a/.gitignore b/.gitignore index dfd657451..b3f4fc3e0 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ MANIFEST /venv /release /build +/pyinstallerdist diff --git a/README b/README index 58e917f0f..7754125d0 100644 --- a/README +++ b/README @@ -3,8 +3,81 @@ 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 + /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` diff --git a/osx-binaries b/osx-binaries index 657dbae93..2d1acccc7 100755 --- a/osx-binaries +++ b/osx-binaries @@ -33,13 +33,6 @@ if [ ! -f $VENV/bin/pyinstaller ] $VENV/bin/pip install --upgrade macholib fi -# readline.so is actually a symlink to a Python file, which breaks PyInstaller -# (and readline itself). Why? Who knows. Re-address this when this stupidity -# ceases to be. -echo "Removing broken readline..." -rm -f $VENV/lib/python2.7/readline.so - - echo "Clearing caches..." rm -f dist/* rm -rf $TMPDIR diff --git a/release-checklist.md b/release-checklist.md deleted file mode 100644 index 59fa7623d..000000000 --- a/release-checklist.md +++ /dev/null @@ -1,60 +0,0 @@ -# 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: - - **TODO**: We just shipped 0.12 - do we bump to 0.12.1 or 0.13 now? - We should probably just leave it as-is and only bump once we actually do the next release. - - - Bump the version number in `version.py` for all projects: - `./build set-version 0.13` - - Also, we need a release policy. I propose the following: - - 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)` diff --git a/requirements.txt b/requirements.txt index 0bb2e3785..de1b90b2a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,2 @@ click>=4.1 twine>=1.5.0 -pyinstaller diff --git a/rtool b/rtool index 356ea963b..bb33604b0 100755 --- a/rtool +++ b/rtool @@ -20,11 +20,23 @@ if os.name == "nt": else: VENV_BIN = "bin" + + RELEASE_DIR = join(os.path.dirname(os.path.realpath(__file__))) DIST_DIR = join(RELEASE_DIR, "release") ROOT_DIR = join(RELEASE_DIR, "..") MITMPROXY_DIR = join(ROOT_DIR, "mitmproxy") -TEST_VENV_DIR = join(RELEASE_DIR, "venv") + +PYINSTALLER_URL =\ + "https://github.com/pyinstaller/pyinstaller/archive/develop.zip" +PYINSTALLER_CACHE = os.path.expanduser( + "~/Library/Application Support/pyinstaller" +) +PYINSTALLER_DIST = join(RELEASE_DIR, "pyinstallerdist") + +VENV_DIR = join(RELEASE_DIR, "venv") +VENV_PIP = join(VENV_DIR, VENV_BIN, "pip") +VENV_PYINSTALLER = join(VENV_DIR, VENV_BIN, "pyinstaller") PROJECTS = ("netlib", "pathod", "mitmproxy") TOOLS = { @@ -172,6 +184,49 @@ def sdist(projects): ) +@cli.command("osxbin") +@click.option( + '--project', '-p', 'projects', + multiple=True, type=click.Choice(PROJECTS), default=PROJECTS +) +@click.pass_context +def osxbin(ctx, projects): + if not os.path.exists(VENV_PYINSTALLER): + subprocess.check_call( + [ + VENV_PIP, + "install", + PYINSTALLER_URL + ] + ) + + shutil.rmtree(PYINSTALLER_CACHE, ignore_errors=True) + shutil.rmtree("./build", ignore_errors=True) + shutil.rmtree(PYINSTALLER_DIST, ignore_errors=True) + for p in projects: + specs = glob.glob(os.path.join(ROOT_DIR, p, "release/*.spec")) + for spec in specs: + subprocess.check_call( + [ + VENV_PYINSTALLER, + "--distpath", PYINSTALLER_DIST, + spec + ] + ) + if specs and os.path.exists(PYINSTALLER_DIST): + bins = os.listdir(PYINSTALLER_DIST) + for bin in bins: + subprocess.check_call( + [ + os.path.join(PYINSTALLER_DIST, bin), + "--version" + ] + ) + + + + + @cli.command("mkvenv") @click.option( '--project', '-p', 'projects', @@ -185,28 +240,27 @@ def mkvenv(ctx, projects): ctx.invoke(sdist) with empty_pythonpath(): print("Creating virtualenv for test install...") - if os.path.exists(TEST_VENV_DIR): - shutil.rmtree(TEST_VENV_DIR) - subprocess.check_call(["virtualenv", "-q", TEST_VENV_DIR]) + if os.path.exists(VENV_DIR): + shutil.rmtree(VENV_DIR) + subprocess.check_call(["virtualenv", "-q", VENV_DIR]) - pip = join(TEST_VENV_DIR, VENV_BIN, "pip") with chdir(DIST_DIR): for project in projects: print("Installing %s..." % project) dist = join(ROOT_DIR, project) - subprocess.check_call([pip, "install", "-q", dist]) + subprocess.check_call([VENV_PIP, "install", "-q", dist]) print("Running binaries...") for project in projects: for tool in TOOLS[project]: - tool = join(TEST_VENV_DIR, VENV_BIN, tool) + tool = join(VENV_DIR, VENV_BIN, tool) print(tool) print(subprocess.check_output([tool, "--version"])) print("Virtualenv available for further testing:") print( "source %s" % os.path.normpath( - join(TEST_VENV_DIR, VENV_BIN, "activate") + join(VENV_DIR, VENV_BIN, "activate") ) )