diff --git a/.travis.yml b/.travis.yml
index 02b90836..4ad0022c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -34,7 +34,8 @@ jobs:
env:
- PYTHON=C:\\Python35\\python
- - name: Linux | s390x | Python 3.5
+ - &linux_s390x_35
+ name: Linux | s390x | Python 3.5
language: python
python: 3.5
services: docker
@@ -43,12 +44,7 @@ jobs:
allow_failures:
# must repeat the s390x job above exactly to match
- - name: Linux | s390x | Python 3.5
- language: python
- python: 3.5
- services: docker
- arch: s390x
- env: PYTHON=python
+ - *linux_s390x_35
install: $PYTHON -m pip install -r requirements-dev.txt
diff --git a/README.md b/README.md
index 7f5f0a8c..6a069aa3 100644
--- a/README.md
+++ b/README.md
@@ -18,14 +18,15 @@ What does it do?
| | macOS x86_64 | Windows 64bit | Windows 32bit | manylinux x86_64 | manylinux i686 | manylinux aarch64 | manylinux ppc64le | manylinux s390x |
|---|---|---|---|---|---|---|---|---|
| CPython 2.7 | ✅ | ✅¹ | ✅¹ | ✅ | ✅ | | | |
-| CPython 3.5 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
-| CPython 3.6 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
-| CPython 3.7 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
-| CPython 3.8 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
+| CPython 3.5 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅² |
+| CPython 3.6 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅² |
+| CPython 3.7 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅² |
+| CPython 3.8 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅² |
| PyPy 2.7 v7.3.0 | ✅ | | ✅ | ✅ | | | | |
| PyPy 3.6 v7.3.0 | ✅ | | ✅ | ✅ | | | | |
-¹ Not supported on Travis
+¹ Not supported on Travis
+² Beta support until Travis CI fixes a bug
- Builds manylinux, macOS and Windows wheels for CPython and PyPy using Azure Pipelines, Travis CI, AppVeyor, and CircleCI
- Bundles shared library dependencies on Linux and macOS through [auditwheel](https://github.com/pypa/auditwheel) and [delocate](https://github.com/matthew-brett/delocate)
@@ -75,7 +76,7 @@ env:
# Note: TWINE_PASSWORD is set to a PyPI API token in Travis settings
install:
- - python3 -m pip install cibuildwheel==1.1.0
+ - python3 -m pip install cibuildwheel==1.2.0
script:
# build the wheels, put them into './wheelhouse'
@@ -104,6 +105,7 @@ Options
| | [`CIBW_REPAIR_WHEEL_COMMAND`](https://cibuildwheel.readthedocs.io/en/stable/options/#repair-wheel-command) | Execute a shell command to repair each (non-pure Python) built wheel |
| | [`CIBW_MANYLINUX_X86_64_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) [`CIBW_MANYLINUX_I686_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) [`CIBW_MANYLINUX_PYPY_X86_64_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) | Specify alternative manylinux docker images |
| **Testing** | [`CIBW_TEST_COMMAND`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-command) | Execute a shell command to test each built wheel |
+| | [`CIBW_BEFORE_TEST`](https://cibuildwheel.readthedocs.io/en/stable/options/#before-test) | Execute shell command to prepare test environment |
| | [`CIBW_TEST_REQUIRES`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-requires) | Install Python dependencies before running the tests |
| | [`CIBW_TEST_EXTRAS`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-extras) | Install your wheel for testing using extras_require |
| **Other** | [`CIBW_BUILD_VERBOSITY`](https://cibuildwheel.readthedocs.io/en/stable/options/#build-verbosity) | Increase/decrease the output of pip wheel |
@@ -123,6 +125,7 @@ Here are some repos that use cibuildwheel.
- [apriltags2-ethz](https://github.com/safijari/apriltags2_ethz)
- [TgCrypto](https://github.com/pyrogram/tgcrypto)
- [Twisted](https://github.com/twisted/twisted)
+- [gmic-py](https://github.com/dtschump/gmic-py)
> Add your repo here! Send a PR.
@@ -138,6 +141,29 @@ This is similar to static linking, so it might have some licence implications. C
Changelog
=========
+### 1.2.0
+
+_8 March 2020_
+
+- ✨ Add support for building PyPy wheels, across Manylinux, macOS, and
+ Windows. (#185)
+- ✨ Added the ability to build ARM64 (aarch64), ppc64le, and s390x wheels,
+ using manylinux2014 and Travis CI. (#273)
+- ✨ You can now build macOS wheels on Appveyor. (#230)
+- 🛠 Changed default macOS minimum target to 10.9, from 10.6. This allows the
+ use of more modern C++ libraries, among other things. (#156)
+- 🛠 Stop building universal binaries on macOS. We now only build x86_64
+ wheels on macOS. (#220)
+- ✨ Allow chaining of commands using `&&` and `||` on Windows inside
+ CIBW_BEFORE_BUILD and CIBW_TEST_COMMAND. (#293)
+- 🛠 Improved error reporting for failed Cython builds due to stale .so files
+ (#263)
+- 🛠 Update CPython from 3.7.5 to 3.7.6 and from 3.8.0 to 3.8.2 on Mac/Windows
+- 🛠 Improved error messages when a bad config breaks cibuildwheel's PATH
+ variable. (#264)
+- ⚠️ Removed support for *running* cibuildwheel on Python 2.7. cibuildwheel
+ will continue to build Python 2.7 wheels for a little while. (#265)
+
### 1.1.0
_7 December 2019_
diff --git a/bin/bump_version.py b/bin/bump_version.py
new file mode 100755
index 00000000..8ad630ac
--- /dev/null
+++ b/bin/bump_version.py
@@ -0,0 +1,113 @@
+#!/usr/bin/env python3
+
+import click
+from pathlib import Path
+import os
+import cibuildwheel
+from packaging.version import Version, InvalidVersion
+import subprocess
+import glob
+
+config = [
+ # file path, version find/replace format
+ ('cibuildwheel/__init__.py', "__version__ = '{}'"),
+ ('setup.py', "version='{}'"),
+ ('README.md', "cibuildwheel=={}"),
+ ('examples/*', "cibuildwheel=={}"),
+]
+
+
+@click.command()
+def bump_version():
+ git_changes_result = subprocess.run(['git diff-index --quiet HEAD --'], shell=True)
+ repo_has_uncommitted_changes = git_changes_result.returncode != 0
+
+ if repo_has_uncommitted_changes:
+ print('error: Uncommitted changes detected.')
+ exit(1)
+
+ current_version = cibuildwheel.__version__
+ print( 'Current version:', current_version) # noqa
+ new_version = input(' New version: ').strip()
+
+ try:
+ Version(new_version)
+ except InvalidVersion:
+ print("error: This version doesn't conform to PEP440")
+ print(' https://www.python.org/dev/peps/pep-0440/')
+ exit(1)
+
+ actions = []
+
+ for path_pattern, version_pattern in config:
+ paths = [Path(p) for p in glob.glob(path_pattern)]
+
+ if not paths:
+ print(f'error: Pattern {path_pattern} didn’t match any files')
+ exit(1)
+
+ find_pattern = version_pattern.format(current_version)
+ replace_pattern = version_pattern.format(new_version)
+ found_at_least_one_file_needing_update = False
+
+ for path in paths:
+ contents = path.read_text(encoding='utf8')
+ if find_pattern in contents:
+ found_at_least_one_file_needing_update = True
+ actions.append(
+ (path, find_pattern, replace_pattern)
+ )
+
+ if not found_at_least_one_file_needing_update:
+ print('error: Didn’t find any occurences of “{}” in “{}”'.format(find_pattern, path_pattern))
+ exit(1)
+
+ print()
+ print("Here's the plan:")
+ print()
+
+ for action in actions:
+ print('{} {red}{}{off} → {green}{}{off}'.format(
+ *action,
+ red="\u001b[31m", green="\u001b[32m", off="\u001b[0m"
+ ))
+
+ print('Then commit, and tag as v{}'.format(new_version))
+
+ answer = input('Proceed? [y/N] ').strip()
+
+ if answer != 'y':
+ print('Aborted')
+ exit(1)
+
+ for path, find, replace in actions:
+ contents = path.read_text(encoding='utf8')
+ contents = contents.replace(find, replace)
+ path.write_text(contents, encoding='utf8')
+
+ print('Files updated. If you want to update the changelog as part of this')
+ print('commit, do that now.')
+
+ while input('Type "done" to continue: ').strip().lower() != 'done':
+ pass
+
+ subprocess.run([
+ 'git', 'commit',
+ '-a',
+ '-m', f'Bump version: v{new_version}'
+ ], check=True)
+
+ subprocess.run([
+ 'git', 'tag',
+ '-a',
+ '-m', f'v{new_version}',
+ f'v{new_version}'
+ ], check=True)
+
+ print('Done.')
+
+
+if __name__ == '__main__':
+ os.chdir(os.path.dirname(__file__))
+ os.chdir('..')
+ bump_version()
diff --git a/cibuildwheel/__init__.py b/cibuildwheel/__init__.py
index 1a72d32e..58d478ab 100644
--- a/cibuildwheel/__init__.py
+++ b/cibuildwheel/__init__.py
@@ -1 +1 @@
-__version__ = '1.1.0'
+__version__ = '1.2.0'
diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py
index 6c3963ff..ad41c485 100644
--- a/cibuildwheel/__main__.py
+++ b/cibuildwheel/__main__.py
@@ -115,6 +115,7 @@ def main():
repair_command_default = ''
repair_command = get_option_from_environment('CIBW_REPAIR_WHEEL_COMMAND', platform=platform, default=repair_command_default)
environment_config = get_option_from_environment('CIBW_ENVIRONMENT', platform=platform, default='')
+ before_test = get_option_from_environment('CIBW_BEFORE_TEST', platform=platform, default='')
dependency_versions = get_option_from_environment('CIBW_DEPENDENCY_VERSIONS', platform=platform, default='pinned')
if dependency_versions == 'pinned':
@@ -164,6 +165,7 @@ def main():
build_selector=build_selector,
repair_command=repair_command,
environment=environment,
+ before_test=before_test,
dependency_constraints=dependency_constraints,
)
diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py
index 5999c48d..d7ebfab2 100644
--- a/cibuildwheel/linux.py
+++ b/cibuildwheel/linux.py
@@ -68,7 +68,7 @@ def get_python_configurations(build_selector):
return [c for c in python_configurations if matches_platform(c.identifier) and build_selector(c.identifier)]
-def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, manylinux_images, dependency_constraints):
+def build(project_dir, output_dir, test_command, before_test, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, manylinux_images, dependency_constraints):
try:
subprocess.check_call(['docker', '--version'])
except Exception:
@@ -175,6 +175,10 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
echo "Running tests using `which python`"
+ if [ ! -z {before_build} ]; then
+ sh -c {before_build}
+ fi
+
# Install the wheel we just built
# Note: If auditwheel produced two wheels, it's because the earlier produced wheel
# conforms to multiple manylinux standards. These multiple versions of the wheel are
@@ -224,6 +228,9 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
environment_exports='\n'.join(environment.as_shell_commands()),
uid=os.getuid(),
gid=os.getgid(),
+ before_test=shlex.quote(
+ prepare_command(before_test, project='/project') if before_test else ''
+ ),
dependency_install_flags='-c /constraints.txt' if dependency_constraints else '',
)
)
diff --git a/cibuildwheel/macos.py b/cibuildwheel/macos.py
index 349b398f..fabf8edf 100644
--- a/cibuildwheel/macos.py
+++ b/cibuildwheel/macos.py
@@ -106,7 +106,7 @@ def install_pypy(version, url):
return installation_bin_path
-def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, dependency_constraints):
+def build(project_dir, output_dir, test_command, before_test, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, dependency_constraints):
abs_project_dir = os.path.abspath(project_dir)
temp_dir = tempfile.mkdtemp(prefix='cibuildwheel')
built_wheel_dir = os.path.join(temp_dir, 'built_wheel')
@@ -219,6 +219,10 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
# check that we are using the Python from the virtual environment
call(['which', 'python'], env=virtualenv_env)
+ if before_test:
+ before_test_prepared = prepare_command(before_test, project=abs_project_dir)
+ call(before_test_prepared, env=virtualenv_env, shell=True)
+
# install the wheel
call(['pip', 'install', repaired_wheel + test_extras], env=virtualenv_env)
diff --git a/cibuildwheel/windows.py b/cibuildwheel/windows.py
index ab7238bc..a9c56cf2 100644
--- a/cibuildwheel/windows.py
+++ b/cibuildwheel/windows.py
@@ -21,8 +21,7 @@ IS_RUNNING_ON_TRAVIS = os.environ.get('TRAVIS_OS_NAME') == 'windows'
def shell(args, env=None, cwd=None):
print('+ ' + ' '.join(args))
- args = ['cmd', '/E:ON', '/V:ON', '/C'] + args
- return subprocess.check_call(' '.join(args), env=env, cwd=cwd)
+ return subprocess.check_call(' '.join(args), env=env, cwd=cwd, shell=True)
def get_nuget_args(version, arch):
@@ -88,7 +87,7 @@ def install_pypy(version, arch, url):
return installation_path
-def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, dependency_constraints):
+def build(project_dir, output_dir, test_command, before_test, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, dependency_constraints):
abs_project_dir = os.path.abspath(project_dir)
temp_dir = tempfile.mkdtemp(prefix='cibuildwheel')
built_wheel_dir = os.path.join(temp_dir, 'built_wheel')
@@ -201,6 +200,10 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
# check that we are using the Python from the virtual environment
shell(['which', 'python'], env=virtualenv_env)
+ if before_test:
+ before_test_prepared = prepare_command(before_test, project=abs_project_dir)
+ shell([before_test_prepared], env=virtualenv_env)
+
# install the wheel
shell(['pip', 'install', repaired_wheel + test_extras], env=virtualenv_env)
diff --git a/docs/options.md b/docs/options.md
index 0d827274..1fd47118 100644
--- a/docs/options.md
+++ b/docs/options.md
@@ -194,7 +194,7 @@ If dependencies are required to build your wheel (for example if you include a h
The active Python binary can be accessed using `python`, and pip with `pip`; `cibuildwheel` makes sure the right version of Python and pip will be executed. `{project}` can be used as a placeholder for the absolute path to the project's root and will be replaced by `cibuildwheel`.
-On Linux and macOS, the command is run in a shell, so you can write things like `cmd1 && cmd2`.
+The command is run in a shell, so you can write things like `cmd1 && cmd2`.
Platform-specific variants also available:
`CIBW_BEFORE_BUILD_MACOS` | `CIBW_BEFORE_BUILD_WINDOWS` | `CIBW_BEFORE_BUILD_LINUX`
@@ -209,6 +209,9 @@ CIBW_BEFORE_BUILD: pip install pybind11
# chain commands using &&
CIBW_BEFORE_BUILD: yum install -y libffi-dev && pip install .
+
+# run a script that's inside your repo
+CIBW_BEFORE_BUILD: bash scripts/prepare_for_build.sh
```
@@ -229,7 +232,7 @@ The following placeholders must be used inside the command and will be replaced
- `{wheel}` for the absolute path to the built wheel
- `{dest_dir}` for the absolute path of the directory where to create the repaired wheel.
-On Linux and macOS, the command is run in a shell, so you can write things like `cmd1 && cmd2`.
+The command is run in a shell, so you can run multiple commands like `cmd1 && cmd2`.
Platform-specific variants also available:
`CIBW_REPAIR_WHEEL_COMMAND_MACOS` | `CIBW_REPAIR_WHEEL_COMMAND_WINDOWS` | `CIBW_REPAIR_WHEEL_COMMAND_LINUX`
@@ -340,7 +343,7 @@ CIBW_DEPENDENCY_VERSIONS: ./constraints.txt
Shell command to run tests after the build. The wheel will be installed automatically and available for import from the tests. `{project}` can be used as a placeholder for the absolute path to the project's root and will be replaced by `cibuildwheel`.
-On Linux and macOS, the command is run in a shell, so you can write things like `cmd1 && cmd2`.
+The command is run in a shell, so you can write things like `cmd1 && cmd2`.
Platform-specific variants also available:
`CIBW_TEST_COMMAND_MACOS` | `CIBW_TEST_COMMAND_WINDOWS` | `CIBW_TEST_COMMAND_LINUX`
@@ -395,6 +398,33 @@ Platform-specific variants also available:
CIBW_TEST_EXTRAS: test,qt
```
+### `CIBW_BEFORE_TEST` {: #before-test}
+> Execute a shell command before testing each wheel
+
+A shell command to run in **each** test virtual environment, before your wheel is installed and tested. This is useful if you need to install a non pip package, change values of environment variables
+or perform multi step pip installation (e.g. installing `scikit-build` or `cython` before install test package)
+
+The active Python binary can be accessed using `python`, and pip with `pip`; `cibuildwheel` makes sure the right version of Python and pip will be executed. `{project}` can be used as a placeholder for the absolute path to the project's root and will be replaced by `cibuildwheel`.
+
+The command is run in a shell, so you can write things like `cmd1 && cmd2`.
+
+Platform-specific variants also available:
+ `CIBW_BEFORE_TEST_MACOS` | `CIBW_BEFORE_TEST_WINDOWS` | `CIBW_BEFORE_TEST_LINUX`
+
+#### Examples
+```yaml
+# install test dependencies with overwritten environment variables.
+CIBW_BEFORE_TEST: CC=gcc CXX=g++ pip install -r requirements.txt
+
+# chain commands using &&
+CIBW_BEFORE_TEST: rm -rf ./data/cache && mkdir -p ./data/cache
+
+# install non pip python package
+CIBW_BEFORE_TEST: cd some_dir; ./configure; make; make install
+
+# install python packages that are required to install test dependencies
+CIBW_BEFORE_TEST: pip install cmake scikit-build
+```
## Other
diff --git a/examples/appveyor-minimal.yml b/examples/appveyor-minimal.yml
index a6d8654b..3b5625e1 100644
--- a/examples/appveyor-minimal.yml
+++ b/examples/appveyor-minimal.yml
@@ -12,7 +12,7 @@ stack: python 3.7
init:
- cmd: set PATH=C:\Python37;C:\Python37\Scripts;%PATH%
-install: python -m pip install cibuildwheel==1.1.0
+install: python -m pip install cibuildwheel==1.2.0
build_script: python -m cibuildwheel --output-dir wheelhouse
diff --git a/examples/azure-pipelines-minimal.yml b/examples/azure-pipelines-minimal.yml
index d5504b2d..d457e1b5 100644
--- a/examples/azure-pipelines-minimal.yml
+++ b/examples/azure-pipelines-minimal.yml
@@ -5,7 +5,7 @@ jobs:
- task: UsePythonVersion@0
- bash: |
python3 -m pip install --upgrade pip
- pip3 install cibuildwheel==1.1.0
+ pip3 install cibuildwheel==1.2.0
cibuildwheel --output-dir wheelhouse .
- task: PublishBuildArtifacts@1
inputs: {pathtoPublish: 'wheelhouse'}
@@ -16,7 +16,7 @@ jobs:
- task: UsePythonVersion@0
- bash: |
python3 -m pip install --upgrade pip
- pip3 install cibuildwheel==1.1.0
+ pip3 install cibuildwheel==1.2.0
cibuildwheel --output-dir wheelhouse .
- task: PublishBuildArtifacts@1
inputs: {pathtoPublish: 'wheelhouse'}
@@ -29,7 +29,7 @@ jobs:
displayName: Install Visual C++ for Python 2.7
- bash: |
python -m pip install --upgrade pip
- pip install cibuildwheel==1.1.0
+ pip install cibuildwheel==1.2.0
cibuildwheel --output-dir wheelhouse .
- task: PublishBuildArtifacts@1
inputs: {pathtoPublish: 'wheelhouse'}
diff --git a/examples/circleci-minimal.yml b/examples/circleci-minimal.yml
index fd6c00e8..f76b011c 100644
--- a/examples/circleci-minimal.yml
+++ b/examples/circleci-minimal.yml
@@ -11,7 +11,7 @@ jobs:
- run:
name: Build the Linux wheels.
command: |
- pip3 install --user cibuildwheel==1.1.0
+ pip3 install --user cibuildwheel==1.2.0
cibuildwheel --output-dir wheelhouse
- store_artifacts:
path: wheelhouse/
@@ -25,7 +25,7 @@ jobs:
- run:
name: Build the OS X wheels.
command: |
- pip3 install --user cibuildwheel==1.1.0
+ pip3 install --user cibuildwheel==1.2.0
cibuildwheel --output-dir wheelhouse
- store_artifacts:
path: wheelhouse/
diff --git a/examples/travis-ci-deploy-only.yml b/examples/travis-ci-deploy-only.yml
index 1e08893f..f205bc76 100644
--- a/examples/travis-ci-deploy-only.yml
+++ b/examples/travis-ci-deploy-only.yml
@@ -25,7 +25,7 @@ env:
# Note: TWINE_PASSWORD is set to a PyPI API token in Travis settings
install:
- - python3 -m pip install cibuildwheel==1.1.0
+ - python3 -m pip install cibuildwheel==1.2.0
script:
# build the wheels, put them into './wheelhouse'
diff --git a/examples/travis-ci-minimal.yml b/examples/travis-ci-minimal.yml
index d3bb5a75..2060444e 100644
--- a/examples/travis-ci-minimal.yml
+++ b/examples/travis-ci-minimal.yml
@@ -26,7 +26,7 @@ jobs:
- ln -s /c/Python38/python.exe /c/Python38/python3.exe
install:
- - python3 -m pip install cibuildwheel==1.1.0
+ - python3 -m pip install cibuildwheel==1.2.0
script:
# build the wheels, put them into './wheelhouse'
diff --git a/examples/travis-ci-test-and-deploy.yml b/examples/travis-ci-test-and-deploy.yml
index 2012a06f..5a92634a 100644
--- a/examples/travis-ci-test-and-deploy.yml
+++ b/examples/travis-ci-test-and-deploy.yml
@@ -56,7 +56,7 @@ jobs:
- stage: deploy
name: Build and deploy Linux wheels
services: docker
- install: python3 -m pip install cibuildwheel==1.1.0
+ install: python3 -m pip install cibuildwheel==1.2.0
script: python3 -m cibuildwheel --output-dir wheelhouse
after_success: |
python3 -m pip install twine
@@ -66,7 +66,7 @@ jobs:
name: Build and deploy macOS wheels
os: osx
language: shell
- install: python3 -m pip install cibuildwheel==1.1.0
+ install: python3 -m pip install cibuildwheel==1.2.0
script: python3 -m cibuildwheel --output-dir wheelhouse
after_success: |
python3 -m pip install twine
@@ -76,7 +76,7 @@ jobs:
name: Build and deploy Windows wheels
os: windows
language: shell
- install: python3 -m pip install cibuildwheel==1.1.0
+ install: python3 -m pip install cibuildwheel==1.2.0
script: python3 -m cibuildwheel --output-dir wheelhouse
after_success: |
python3 -m pip install twine
diff --git a/setup.cfg b/setup.cfg
index 4346b720..b2c53158 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,24 +1,3 @@
-[bumpversion]
-current_version = 1.1.0
-commit = True
-tag = True
-message = Bump version
-
-[bumpversion:file:setup.py]
-
-[bumpversion:file:cibuildwheel/__init__.py]
-
-[bumpversion:file:README.md]
-search = cibuildwheel=={current_version}
-replace = cibuildwheel=={new_version}
-
-[bumpversion:file:docs/setup.md]
-search = cibuildwheel=={current_version}
-replace = cibuildwheel=={new_version}
-
-[bdist_wheel]
-universal = 1
-
[flake8]
ignore = E501,W503
application-import-names = cibuildwheel
diff --git a/setup.py b/setup.py
index 010d5621..e139d8fb 100644
--- a/setup.py
+++ b/setup.py
@@ -13,7 +13,7 @@ with io.open(os.path.join(this_directory, 'README.md'), encoding='utf-8') as f:
setup(
name='cibuildwheel',
- version='1.1.0',
+ version='1.2.0',
install_requires=['bashlex!=0.13'],
description="Build Python wheels on CI with minimal configuration.",
long_description=long_description,
diff --git a/test/02_test/cibuildwheel_test.py b/test/02_test/cibuildwheel_test.py
index ca084d65..21878d2c 100644
--- a/test/02_test/cibuildwheel_test.py
+++ b/test/02_test/cibuildwheel_test.py
@@ -15,7 +15,7 @@ def test():
# the 'false ||' bit is to ensure this command runs in a shell on
# mac/linux.
'CIBW_TEST_COMMAND': 'false || nosetests {project}/test',
- 'CIBW_TEST_COMMAND_WINDOWS': 'nosetests {project}/test',
+ 'CIBW_TEST_COMMAND_WINDOWS': 'COLOR 00 || nosetests {project}/test',
})
# also check that we got the right wheels
@@ -32,7 +32,7 @@ def test_extras_require():
# the 'false ||' bit is to ensure this command runs in a shell on
# mac/linux.
'CIBW_TEST_COMMAND': 'false || nosetests {project}/test',
- 'CIBW_TEST_COMMAND_WINDOWS': 'nosetests {project}/test',
+ 'CIBW_TEST_COMMAND_WINDOWS': 'COLOR 00 || nosetests {project}/test',
})
# also check that we got the right wheels
diff --git a/test/11_before_test/cibuildwheel_test.py b/test/11_before_test/cibuildwheel_test.py
new file mode 100644
index 00000000..5aa1c4ca
--- /dev/null
+++ b/test/11_before_test/cibuildwheel_test.py
@@ -0,0 +1,23 @@
+import os
+import utils
+
+
+def test():
+ project_dir = os.path.dirname(__file__)
+
+ # build the wheels
+ actual_wheels = utils.cibuildwheel_run(project_dir, add_env={
+ # write python version information to a temporary file, this is
+ # checked in setup.py
+ 'CIBW_BEFORE_TEST': '''python -c "import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('/tmp/pythonprefix.txt', 'w').write(sys.prefix)"''',
+ 'CIBW_BEFORE_TEST_WINDOWS': '''python -c "import sys; open('c:\\pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('c:\\pythonprefix.txt', 'w').write(sys.prefix)"''',
+ 'CIBW_TEST_REQUIRES': 'nose',
+ # the 'false ||' bit is to ensure this command runs in a shell on
+ # mac/linux.
+ 'CIBW_TEST_COMMAND': 'false || nosetests {project}/test',
+ 'CIBW_TEST_COMMAND_WINDOWS': 'nosetests {project}/test',
+ })
+
+ # also check that we got the right wheels
+ expected_wheels = utils.expected_wheels('spam', '0.1.0')
+ assert set(actual_wheels) == set(expected_wheels)
diff --git a/test/11_before_test/setup.py b/test/11_before_test/setup.py
new file mode 100644
index 00000000..e3ea2938
--- /dev/null
+++ b/test/11_before_test/setup.py
@@ -0,0 +1,8 @@
+from setuptools import setup, Extension
+
+
+setup(
+ name="spam",
+ ext_modules=[Extension('spam', sources=['spam.c'])],
+ version="0.1.0",
+)
diff --git a/test/11_before_test/spam.c b/test/11_before_test/spam.c
new file mode 100644
index 00000000..d1ab0f22
--- /dev/null
+++ b/test/11_before_test/spam.c
@@ -0,0 +1,48 @@
+#include
+
+static PyObject *
+spam_system(PyObject *self, PyObject *args)
+{
+ const char *command;
+ int sts;
+
+ if (!PyArg_ParseTuple(args, "s", &command))
+ return NULL;
+ sts = system(command);
+ return PyLong_FromLong(sts);
+}
+
+/* Module initialization */
+
+#if PY_MAJOR_VERSION >= 3
+ #define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
+ #define MOD_DEF(m, name, doc, methods, module_state_size) \
+ static struct PyModuleDef moduledef = { \
+ PyModuleDef_HEAD_INIT, name, doc, module_state_size, methods, }; \
+ m = PyModule_Create(&moduledef);
+ #define MOD_RETURN(m) return m;
+#else
+ #define MOD_INIT(name) PyMODINIT_FUNC init##name(void)
+ #define MOD_DEF(m, name, doc, methods, module_state_size) \
+ m = Py_InitModule3(name, methods, doc);
+ #define MOD_RETURN(m) return;
+#endif
+
+static PyMethodDef module_methods[] = {
+ {"system", (PyCFunction)spam_system, METH_VARARGS,
+ "Execute a shell command."},
+ {NULL} /* Sentinel */
+};
+
+MOD_INIT(spam)
+{
+ PyObject* m;
+
+ MOD_DEF(m,
+ "spam",
+ "Example module",
+ module_methods,
+ -1)
+
+ MOD_RETURN(m)
+}
diff --git a/test/11_before_test/test/spam_test.py b/test/11_before_test/test/spam_test.py
new file mode 100644
index 00000000..21bad8c2
--- /dev/null
+++ b/test/11_before_test/test/spam_test.py
@@ -0,0 +1,28 @@
+import sys
+import os
+from unittest import TestCase
+
+
+class TestBeforeTest(TestCase):
+ def test_version(self):
+ # assert that the Python version as written to pythonversion.txt in the CIBW_BEFORE_TEST step
+ # is the same one as is currently running.
+ # because of use symlinks in MacOS run this test is also need
+ version_file = 'c:\\pythonversion.txt' if sys.platform == 'win32' else '/tmp/pythonversion.txt'
+ with open(version_file) as f:
+ stored_version = f.read()
+ print('stored_version', stored_version)
+ print('sys.version', sys.version)
+ assert stored_version == sys.version
+
+ def test_prefix(self):
+ # check that the prefix also was written
+ prefix_file = 'c:\\pythonprefix.txt' if sys.platform == 'win32' else '/tmp/pythonprefix.txt'
+ with open(prefix_file) as f:
+ stored_prefix = f.read()
+ print('stored_prefix', stored_prefix)
+ print('sys.prefix', sys.prefix)
+ # Works around path-comparison bugs caused by short-paths on Windows e.g.
+ # vssadm~1 instead of vssadministrator
+
+ assert os.stat(stored_prefix) == os.stat(sys.prefix)