From 09ff5df2fb354a017afa02138b329e615a80c1d0 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Sat, 2 Jun 2018 21:37:44 +0200 Subject: [PATCH] Such CI, Very Wow. (#3182) --- .appveyor.yml | 37 +---- .travis.yml | 8 +- mitmproxy/utils/debug.py | 16 +- mitmproxy/version.py | 64 +++----- release/cibuild.py | 190 ++++++++++++++++-------- release/installbuilder/.gitignore | 2 +- release/installbuilder/setup/.gitignore | 2 + setup.py | 2 +- test/mitmproxy/test_version.py | 20 ++- test/release/test_cibuild.py | 136 +++++++++-------- tox.ini | 2 +- 11 files changed, 257 insertions(+), 222 deletions(-) create mode 100644 release/installbuilder/setup/.gitignore diff --git a/.appveyor.yml b/.appveyor.yml index 38a839847..21176b964 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -12,6 +12,7 @@ environment: - PYTHON: "C:\\Python36" TOXENV: "py36" PYINSTALLER: "1" + WININSTALLER: "1" install: - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" @@ -19,41 +20,17 @@ install: - "pip install -U tox" test_script: - - ps: "tox -- --verbose --cov-report=term" - ps: | - $Env:VERSION = $(python -m mitmproxy.version) - tox -e cibuild -- build - - ps: | - if($Env:RTOOL_KEY) { - $ibVersion = "18.2.0" - $ibSetup = "C:\projects\mitmproxy\release\installbuilder-installer.exe" - $ibCli = "C:\Program Files (x86)\BitRock InstallBuilder Enterprise $ibVersion\bin\builder-cli.exe" - if (!(Test-Path $ibSetup)) { - echo "Download InstallBuilder..." - (New-Object System.Net.WebClient).DownloadFile( - "https://installbuilder.bitrock.com/installbuilder-enterprise-$ibVersion-windows-installer.exe", - $ibSetup - ) - } - echo "Install InstallBuilder..." - Start-Process $ibSetup "--mode unattended --unattendedmodeui none" -PassThru -NoNewWindow -Wait - echo "Decrypt license..." - tox -e cibuild -- decrypt release\installbuilder\license.xml.enc release\installbuilder\license.xml - echo "Run InstallBuilder..." - &$ibCli ` - build ` - .\release\installbuilder\mitmproxy.xml ` - windows ` - --license .\release\installbuilder\license.xml ` - --setvars project.version=$Env:VERSION ` - --verbose - while (!(Test-Path C:\projects\mitmproxy\release\dist\mitmproxy-*-windows-installer.exe)) { Start-Sleep 0.1 } - echo "Installer build completed." + if ($env:APPVEYOR_REPO_COMMIT_MESSAGE.Contains("[notest]")) { + echo "!!!! Skipping tests." + } else { + tox -- --verbose --cov-report=term } + - ps: tox -e cibuild -- build deploy_script: ps: tox -e cibuild -- upload cache: - - C:\projects\mitmproxy\release\installbuilder-installer.exe -> .appveyor.yml + - C:\projects\mitmproxy\release\installbuilder\setup -> .appveyor.yml - C:\Users\appveyor\AppData\Local\pip\cache diff --git a/.travis.yml b/.travis.yml index 7ec2e789a..da916e3f7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -74,7 +74,13 @@ script: # Using the after_success block DOES NOT capture errors. # Pull requests might break our build - we need to check this. # Pull requests are not allowed to upload build artifacts - enforced by cibuild script. - - tox -- --verbose --cov-report=term + - | + if [[ $TRAVIS_COMMIT_MESSAGE = *"[notest]"* ]]; then + echo "!!!! Skipping tests." + else + tox -- --verbose --cov-report=term + fi + - | if [[ $CIBUILD == "1" ]] then diff --git a/mitmproxy/utils/debug.py b/mitmproxy/utils/debug.py index e8eca9063..c9ffb6141 100644 --- a/mitmproxy/utils/debug.py +++ b/mitmproxy/utils/debug.py @@ -1,7 +1,6 @@ import gc import os import platform -import re import signal import sys import threading @@ -13,21 +12,10 @@ from mitmproxy import version def dump_system_info(): - mitmproxy_version = version.get_version(True, True) - mitmproxy_version = re.sub( - r"-0x([0-9a-f]+)", - r" (commit \1)", - mitmproxy_version - ) - - # PyInstaller builds indicator, if using precompiled binary - if getattr(sys, 'frozen', False): - bin_indicator = "binary" - else: - bin_indicator = "" + mitmproxy_version = version.get_dev_version() data = [ - "Mitmproxy: {} {}".format(mitmproxy_version, bin_indicator), + "Mitmproxy: {}".format(mitmproxy_version), "Python: {}".format(platform.python_version()), "OpenSSL: {}".format(SSL.SSLeay_version(SSL.SSLEAY_VERSION).decode()), "Platform: {}".format(platform.platform()), diff --git a/mitmproxy/version.py b/mitmproxy/version.py index fd0038b40..b40fae8ba 100644 --- a/mitmproxy/version.py +++ b/mitmproxy/version.py @@ -1,9 +1,8 @@ import os import subprocess +import sys -# The actual version string. For precompiled binaries, this will be changed to include the build -# tag, e.g. "3.0.0.dev0042-0xcafeabc" -VERSION = "5.0.0" +VERSION = "5.0.0.dev" PATHOD = "pathod " + VERSION MITMPROXY = "mitmproxy " + VERSION @@ -12,50 +11,33 @@ MITMPROXY = "mitmproxy " + VERSION FLOW_FORMAT_VERSION = 7 -def get_version(dev: bool = False, build: bool = False, refresh: bool = False) -> str: +def get_dev_version() -> str: """ - Return a detailed version string, sourced either from a hardcoded VERSION constant - or obtained dynamically using git. - - Args: - dev: If True, non-tagged releases will include a ".devXXXX" suffix, where XXXX is the number - of commits since the last tagged release. - build: If True, non-tagged releases will include a "-0xXXXXXXX" suffix, where XXXXXXX are - the first seven digits of the commit hash. - refresh: If True, always try to use git instead of a potentially hardcoded constant. + Return a detailed version string, sourced either from VERSION or obtained dynamically using git. """ mitmproxy_version = VERSION - if "dev" in VERSION and not refresh: - pass # There is a hardcoded build tag, so we just use what's there. - elif dev or build: - here = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) - try: - git_describe = subprocess.check_output( - ['git', 'describe', '--long'], - stderr=subprocess.STDOUT, - cwd=here, - ) - last_tag, tag_dist, commit = git_describe.decode().strip().rsplit("-", 2) - commit = commit.lstrip("g")[:7] - tag_dist = int(tag_dist) - except Exception: - pass - else: - # Remove current suffix - mitmproxy_version = mitmproxy_version.split(".dev")[0] + here = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) + try: + git_describe = subprocess.check_output( + ['git', 'describe', '--long'], + stderr=subprocess.STDOUT, + cwd=here, + ) + last_tag, tag_dist, commit = git_describe.decode().strip().rsplit("-", 2) + commit = commit.lstrip("g")[:7] + tag_dist = int(tag_dist) + except Exception: + pass + else: + # Add commit info for non-tagged releases + if tag_dist > 0: + mitmproxy_version += f" (+{tag_dist}, commit {commit})" - # Add suffix for non-tagged releases - if tag_dist > 0: - mitmproxy_version += ".dev{tag_dist}".format(tag_dist=tag_dist) - # The wheel build tag (we use the commit) must start with a digit, so we include "0x" - mitmproxy_version += "-0x{commit}".format(commit=commit) - - if not dev: - mitmproxy_version = mitmproxy_version.split(".dev")[0] - elif not build: - mitmproxy_version = mitmproxy_version.split("-0x")[0] + # PyInstaller build indicator, if using precompiled binary + if getattr(sys, 'frozen', False): + mitmproxy_version += " binary" return mitmproxy_version diff --git a/release/cibuild.py b/release/cibuild.py index 04ca9474c..17fb85545 100755 --- a/release/cibuild.py +++ b/release/cibuild.py @@ -1,14 +1,16 @@ #!/usr/bin/env python3 -import glob -import re import contextlib +import glob import os +import pathlib import platform -import sys +import re import shutil import subprocess +import sys import tarfile +import urllib.request import zipfile import click @@ -38,26 +40,23 @@ class BuildEnviron: def __init__( self, *, - system = "", - root_dir = "", - - travis_tag = "", - travis_branch = "", - travis_pull_request = "", - - appveyor_repo_tag_name = "", - appveyor_repo_branch = "", - appveyor_pull_request_number = "", - - should_build_wheel = False, - should_build_docker = False, - should_build_pyinstaller = False, - - has_aws_creds = False, - has_twine_creds = False, - - docker_username = "", - docker_password = "", + system="", + root_dir="", + travis_tag="", + travis_branch="", + travis_pull_request="", + appveyor_repo_tag_name="", + appveyor_repo_branch="", + appveyor_pull_request_number="", + should_build_wheel=False, + should_build_docker=False, + should_build_pyinstaller=False, + should_build_wininstaller=False, + has_aws_creds=False, + has_twine_creds=False, + docker_username="", + docker_password="", + rtool_key="", ): self.system = system self.root_dir = root_dir @@ -69,6 +68,7 @@ class BuildEnviron: self.should_build_wheel = should_build_wheel self.should_build_docker = should_build_docker self.should_build_pyinstaller = should_build_pyinstaller + self.should_build_wininstaller = should_build_wininstaller self.appveyor_repo_tag_name = appveyor_repo_tag_name self.appveyor_repo_branch = appveyor_repo_branch @@ -78,33 +78,31 @@ class BuildEnviron: self.has_twine_creds = has_twine_creds self.docker_username = docker_username self.docker_password = docker_password + self.rtool_key = rtool_key @classmethod - def from_env(klass): - return klass( - system = platform.system(), - root_dir = os.path.normpath(os.path.join(os.path.dirname(__file__), "..")), - - travis_tag = os.environ.get("TRAVIS_TAG", ""), - travis_branch = os.environ.get("TRAVIS_BRANCH", ""), - travis_pull_request = os.environ.get("TRAVIS_PULL_REQUEST"), - - appveyor_repo_tag_name = os.environ.get("APPVEYOR_REPO_TAG_NAME", ""), - appveyor_repo_branch = os.environ.get("APPVEYOR_REPO_BRANCH", ""), - appveyor_pull_request_number = os.environ.get("APPVEYOR_PULL_REQUEST_NUMBER"), - - should_build_wheel = "WHEEL" in os.environ, - should_build_pyinstaller = "PYINSTALLER" in os.environ, - should_build_docker = "DOCKER" in os.environ, - - has_aws_creds = "AWS_ACCESS_KEY_ID" in os.environ, - has_twine_creds= ( + def from_env(cls): + return cls( + system=platform.system(), + root_dir=os.path.normpath(os.path.join(os.path.dirname(__file__), "..")), + travis_tag=os.environ.get("TRAVIS_TAG", ""), + travis_branch=os.environ.get("TRAVIS_BRANCH", ""), + travis_pull_request=os.environ.get("TRAVIS_PULL_REQUEST"), + appveyor_repo_tag_name=os.environ.get("APPVEYOR_REPO_TAG_NAME", ""), + appveyor_repo_branch=os.environ.get("APPVEYOR_REPO_BRANCH", ""), + appveyor_pull_request_number=os.environ.get("APPVEYOR_PULL_REQUEST_NUMBER"), + should_build_wheel="WHEEL" in os.environ, + should_build_pyinstaller="PYINSTALLER" in os.environ, + should_build_wininstaller="WININSTALLER" in os.environ, + should_build_docker="DOCKER" in os.environ, + has_aws_creds="AWS_ACCESS_KEY_ID" in os.environ, + has_twine_creds=( "TWINE_USERNAME" in os.environ and "TWINE_PASSWORD" in os.environ ), - - docker_username = os.environ.get("DOCKER_USERNAME"), - docker_password = os.environ.get("DOCKER_PASSWORD"), + docker_username=os.environ.get("DOCKER_USERNAME"), + docker_password=os.environ.get("DOCKER_PASSWORD"), + rtool_key=os.environ.get("RTOOL_KEY"), ) def archive(self, path): @@ -177,16 +175,45 @@ class BuildEnviron: "should_upload_pypi", ] for attr in lst: - print("cibuild.%s=%s" % (attr, getattr(self, attr)), file=fp) + print(f"cibuild.{attr}={getattr(self, attr)}", file=fp) + + def check_version(self) -> None: + """ + Check that version numbers match our conventions. + Raises a ValueError if there is a mismatch. + """ + with open(pathlib.Path(self.root_dir) / "mitmproxy" / "version.py") as f: + contents = f.read() + + version = re.search(r'^VERSION = "(.+?)"', contents, re.M).group(1) + + if self.tag: + # For (tagged) releases, we are strict: + # 1. The tagname must match the version in mitmproxy/version.py + # 2. The version info must be in canonical form (as recommended in PEP 440). + + if version != self.tag: + raise ValueError(f"Tag is {self.tag}, but mitmproxy/version.py is {version}.") + try: + parver.Version.parse(version, strict=True) + except parver.ParseError as e: + raise ValueError(str(e)) from e + else: + # For snapshots, we only ensure that mitmproxy/version.py contains a dev release. + version_info = parver.Version.parse(version) + if not version_info.is_devrelease: + raise ValueError("Releases must be tagged.") @property def has_docker_creds(self) -> bool: - return self.docker_username and self.docker_password + return bool(self.docker_username and self.docker_password) @property def is_prod_release(self) -> bool: + if not self.tag: + return False try: - v = parver.Version.parse(self.version) + v = parver.Version.parse(self.version, strict=True) except (parver.ParseError, BuildError): return False return not v.is_prerelease @@ -212,7 +239,7 @@ class BuildEnviron: @property def should_upload_docker(self) -> bool: return all([ - (self.tag or self.branch == "master"), + (self.is_prod_release or self.branch == "master"), self.should_build_docker, self.has_docker_creds, ]) @@ -220,7 +247,6 @@ class BuildEnviron: @property def should_upload_pypi(self) -> bool: return all([ - self.tag, self.is_prod_release, self.should_build_wheel, self.has_twine_creds, @@ -242,7 +268,7 @@ class BuildEnviron: name = self.tag or self.branch if not name: raise BuildError("We're on neither a tag nor a branch - could not establish version") - return re.sub('^v', "", name) + return name def build_wheel(be: BuildEnviron): # pragma: no cover @@ -354,6 +380,56 @@ def build_pyinstaller(be: BuildEnviron): # pragma: no cover click.echo("Packed {}.".format(be.archive_name(bdist))) +def build_wininstaller(be: BuildEnviron): # pragma: no cover + click.echo("Building wininstaller package...") + + IB_VERSION = "18.5.2" + IB_DIR = pathlib.Path(be.release_dir) / "installbuilder" + IB_SETUP = IB_DIR / "setup" / f"{IB_VERSION}-installer.exe" + IB_CLI = fr"C:\Program Files (x86)\BitRock InstallBuilder Enterprise {IB_VERSION}\bin\builder-cli.exe" + IB_LICENSE = IB_DIR / "license.xml" + + if True or not os.path.isfile(IB_CLI): + if not os.path.isfile(IB_SETUP): + click.echo("Downloading InstallBuilder...") + + def report(block, blocksize, total): + done = block * blocksize + if round(100 * done / total) != round(100 * (done - blocksize) / total): + click.secho(f"Downloading... {round(100*done/total)}%") + + urllib.request.urlretrieve( + f"https://installbuilder.bitrock.com/installbuilder-enterprise-{IB_VERSION}-windows-installer.exe", + IB_SETUP.with_suffix(".tmp"), + reporthook=report + ) + shutil.move(IB_SETUP.with_suffix(".tmp"), IB_SETUP) + + click.echo("Install InstallBuilder...") + subprocess.run([str(IB_SETUP), "--mode", "unattended", "--unattendedmodeui", "none"], + check=True) + assert os.path.isfile(IB_CLI) + + click.echo("Decrypt InstallBuilder license...") + f = cryptography.fernet.Fernet(be.rtool_key.encode()) + with open(IB_LICENSE.with_suffix(".xml.enc"), "rb") as infile, open(IB_LICENSE, + "wb") as outfile: + outfile.write(f.decrypt(infile.read())) + + click.echo("Run InstallBuilder...") + subprocess.run([ + IB_CLI, + "build", + str(IB_DIR / "mitmproxy.xml"), + "windows", + "--license", str(IB_LICENSE), + "--setvars", f"project.version={be.version}", + "--verbose" + ], check=True) + assert os.path.isfile( + os.path.join(be.dist_dir, f"mitmproxy-{be.version}-windows-installer.exe")) + + @click.group(chain=True) def cli(): # pragma: no cover """ @@ -370,6 +446,7 @@ def build(): # pragma: no cover be = BuildEnviron.from_env() be.dump_info() + be.check_version() os.makedirs(be.dist_dir, exist_ok=True) if be.should_build_wheel: @@ -379,6 +456,8 @@ def build(): # pragma: no cover build_docker_image(be, whl) if be.should_build_pyinstaller: build_pyinstaller(be) + if be.should_build_wininstaller and be.rtool_key: + build_wininstaller(be) @cli.command("upload") @@ -421,14 +500,5 @@ def upload(): # pragma: no cover subprocess.check_call(["docker", "push", be.docker_tag]) -@cli.command("decrypt") -@click.argument('infile', type=click.File('rb')) -@click.argument('outfile', type=click.File('wb')) -@click.argument('key', envvar='RTOOL_KEY') -def decrypt(infile, outfile, key): # pragma: no cover - f = cryptography.fernet.Fernet(key.encode()) - outfile.write(f.decrypt(infile.read())) - - if __name__ == "__main__": # pragma: no cover cli() diff --git a/release/installbuilder/.gitignore b/release/installbuilder/.gitignore index 00c10a2d2..b0fdb6d18 100644 --- a/release/installbuilder/.gitignore +++ b/release/installbuilder/.gitignore @@ -1,2 +1,2 @@ license.xml -*.xml.backup \ No newline at end of file +*.xml.backup diff --git a/release/installbuilder/setup/.gitignore b/release/installbuilder/setup/.gitignore new file mode 100644 index 000000000..d6b7ef32c --- /dev/null +++ b/release/installbuilder/setup/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/setup.py b/setup.py index 92ee143b0..6ba9391e2 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ with open(os.path.join(here, 'README.rst'), encoding='utf-8') as f: long_description = f.read() with open(os.path.join(here, "mitmproxy", "version.py")) as f: - VERSION = re.search(r'VERSION = "(.+?)(?:-0x|")', f.read()).group(1) + VERSION = re.search(r'VERSION = "(.+?)"', f.read()).group(1) setup( name="mitmproxy", diff --git a/test/mitmproxy/test_version.py b/test/mitmproxy/test_version.py index 8c176542d..924f2d961 100644 --- a/test/mitmproxy/test_version.py +++ b/test/mitmproxy/test_version.py @@ -1,6 +1,7 @@ import pathlib import runpy import subprocess +import sys from unittest import mock from mitmproxy import version @@ -15,22 +16,19 @@ def test_version(capsys): assert stdout.strip() == version.VERSION -def test_get_version_hardcoded(): - version.VERSION = "3.0.0.dev123-0xcafebabe" - assert version.get_version() == "3.0.0" - assert version.get_version(True) == "3.0.0.dev123" - assert version.get_version(True, True) == "3.0.0.dev123-0xcafebabe" - - def test_get_version(): - version.VERSION = "3.0.0" + version.VERSION = "3.0.0rc2" with mock.patch('subprocess.check_output') as m: m.return_value = b"tag-0-cafecafe" - assert version.get_version(True, True) == "3.0.0" + assert version.get_dev_version() == "3.0.0rc2" + + sys.frozen = True + assert version.get_dev_version() == "3.0.0rc2 binary" + sys.frozen = False m.return_value = b"tag-2-cafecafe" - assert version.get_version(True, True) == "3.0.0.dev2-0xcafecaf" + assert version.get_dev_version() == "3.0.0rc2 (+2, commit cafecaf)" m.side_effect = subprocess.CalledProcessError(-1, 'git describe --long') - assert version.get_version(True, True) == "3.0.0" + assert version.get_dev_version() == "3.0.0rc2" diff --git a/test/release/test_cibuild.py b/test/release/test_cibuild.py index 78ddf9987..efa2f0724 100644 --- a/test/release/test_cibuild.py +++ b/test/release/test_cibuild.py @@ -1,5 +1,5 @@ -import os import io +import os import pytest @@ -13,11 +13,9 @@ def test_buildenviron_live(): def test_buildenviron_common(): be = cibuild.BuildEnviron( - system = "Linux", - root_dir = "/foo", - - travis_tag = "v0.0.1", - travis_branch = "v0.x", + system="Linux", + root_dir="/foo", + travis_branch="master", ) assert be.release_dir == os.path.join(be.root_dir, "release") assert be.dist_dir == os.path.join(be.root_dir, "release", "dist") @@ -30,8 +28,8 @@ def test_buildenviron_common(): assert cs.getvalue() be = cibuild.BuildEnviron( - system = "Unknown", - root_dir = "/foo", + system="Unknown", + root_dir="/foo", ) with pytest.raises(cibuild.BuildError): be.version @@ -43,19 +41,18 @@ def test_buildenviron_pr(): # Simulates a PR. We build everything, but don't have access to secret # credential env variables. be = cibuild.BuildEnviron( - travis_tag = "", - travis_branch = "master", - travis_pull_request = "true", - - should_build_wheel = True, - should_build_pyinstaller = True, - should_build_docker = True, + travis_tag="", + travis_branch="master", + travis_pull_request="true", + should_build_wheel=True, + should_build_pyinstaller=True, + should_build_docker=True, ) assert be.is_pull_request # Mini test for appveyor be = cibuild.BuildEnviron( - appveyor_pull_request_number = "xxxx", + appveyor_pull_request_number="xxxx", ) assert be.is_pull_request assert not be.is_prod_release @@ -64,15 +61,14 @@ def test_buildenviron_pr(): def test_buildenviron_commit(): # Simulates an ordinary commit on the master branch. be = cibuild.BuildEnviron( - travis_tag = "", - travis_branch = "master", - travis_pull_request = "false", - - should_build_wheel = True, - should_build_pyinstaller = True, - should_build_docker = True, - docker_username = "foo", - docker_password = "bar", + travis_tag="", + travis_branch="master", + travis_pull_request="false", + should_build_wheel=True, + should_build_pyinstaller=True, + should_build_docker=True, + docker_username="foo", + docker_password="bar", ) assert be.docker_tag == "mitmproxy/mitmproxy:dev" assert be.should_upload_docker @@ -81,23 +77,21 @@ def test_buildenviron_commit(): assert not be.is_prod_release -def test_buildenviron_rleasetag(): +def test_buildenviron_releasetag(): # Simulates a tagged release on a release branch. be = cibuild.BuildEnviron( - system = "Linux", - root_dir = "/foo", - - travis_tag = "v0.0.1", - travis_branch = "v0.x", - - should_build_wheel = True, - should_build_docker = True, - should_build_pyinstaller = True, - has_twine_creds = True, - docker_username = "foo", - docker_password = "bar", + system="Linux", + root_dir="/foo", + travis_tag="0.0.1", + travis_branch="v0.x", + should_build_wheel=True, + should_build_docker=True, + should_build_pyinstaller=True, + has_twine_creds=True, + docker_username="foo", + docker_password="bar", ) - assert be.tag == "v0.0.1" + assert be.tag == "0.0.1" assert be.branch == "v0.x" assert be.version == "0.0.1" assert be.upload_dir == "0.0.1" @@ -110,18 +104,16 @@ def test_buildenviron_rleasetag(): def test_buildenviron_branch(): # Simulates a development branch on the main repo be = cibuild.BuildEnviron( - system = "Linux", - root_dir = "/foo", - - travis_tag = "", - travis_branch = "mybranch", - - should_build_wheel = True, - should_build_docker = True, - should_build_pyinstaller = True, - has_twine_creds = True, - docker_username = "foo", - docker_password = "bar", + system="Linux", + root_dir="/foo", + travis_tag="", + travis_branch="mybranch", + should_build_wheel=True, + should_build_docker=True, + should_build_pyinstaller=True, + has_twine_creds=True, + docker_username="foo", + docker_password="bar", ) assert be.tag == "" assert be.branch == "mybranch" @@ -133,11 +125,10 @@ def test_buildenviron_branch(): def test_buildenviron_osx(tmpdir): be = cibuild.BuildEnviron( - system = "Darwin", - root_dir = "/foo", - - travis_tag = "v0.0.1", - travis_branch = "v0.x", + system="Darwin", + root_dir="/foo", + travis_tag="0.0.1", + travis_branch="v0.x", ) assert be.platform_tag == "osx" assert be.bdists == { @@ -153,11 +144,10 @@ def test_buildenviron_osx(tmpdir): def test_buildenviron_windows(tmpdir): be = cibuild.BuildEnviron( - system = "Windows", - root_dir = "/foo", - - travis_tag = "v0.0.1", - travis_branch = "v0.x", + system="Windows", + root_dir="/foo", + travis_tag="0.0.1", + travis_branch="v0.x", ) assert be.platform_tag == "windows" assert be.bdists == { @@ -168,4 +158,26 @@ def test_buildenviron_windows(tmpdir): a = be.archive(os.path.join(tmpdir, "arch")) assert a - a.close() \ No newline at end of file + a.close() + + +@pytest.mark.parametrize("version, tag, ok", [ + ("3.0.0.dev", "", True), # regular snapshot + ("3.0.0.dev", "3.0.0", False), # forgot to remove ".dev" on bump + ("3.0.0", "", False), # forgot to re-add ".dev" + ("3.0.0", "4.0.0", False), # version mismatch + ("3.0.0", "3.0.0", True), # regular release + ("3.0.0.rc1", "3.0.0.rc1", False), # non-canonical. +]) +def test_buildenviron_check_version(version, tag, ok, tmpdir): + tmpdir.mkdir("mitmproxy").join("version.py").write(f'VERSION = "{version}"') + + be = cibuild.BuildEnviron( + root_dir=tmpdir, + travis_tag=tag + ) + if ok: + be.check_version() + else: + with pytest.raises(ValueError): + be.check_version() diff --git a/tox.ini b/tox.ini index 812f1a4b3..46e365df2 100644 --- a/tox.ini +++ b/tox.ini @@ -33,7 +33,7 @@ commands = python ./test/individual_coverage.py [testenv:cibuild] -passenv = TRAVIS_* APPVEYOR_* AWS_* TWINE_* DOCKER_* RTOOL_KEY WHEEL DOCKER PYINSTALLER +passenv = TRAVIS_* APPVEYOR_* AWS_* TWINE_* DOCKER_* RTOOL_KEY WHEEL DOCKER PYINSTALLER WININSTALLER deps = -rrequirements.txt pyinstaller==3.3.1