Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Cirrus CI #1191

Merged
merged 18 commits into from Aug 30, 2022
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
44 changes: 44 additions & 0 deletions .cirrus.yml
@@ -0,0 +1,44 @@
run_tests: &RUN_TESTS
install_cibuildwheel_script:
- python -m pip install -e ".[dev]" pytest-custom-exit-code
run_cibuildwheel_tests_script:
- python ./bin/run_tests.py


linux_x86_task:
compute_engine_instance:
image_project: cirrus-images
image: family/docker-builder
platform: linux
cpu: 8
memory: 8G

install_pre_requirements_script:
- apt install -y python3-venv python-is-python3
<<: *RUN_TESTS

windows_x86_task:
# The task takes ~55 minutes while the timeout happens
# after 60 minutes by default, let's allow some wiggle room.
timeout_in: 90m
windows_container:
image: cirrusci/windowsservercore:visualstudio2022
cpu: 8
memory: 8G

install_pre_requirements_script:
- choco install -y --no-progress python3 --version 3.10.6
- refreshenv
- echo PATH=%PATH% >> "%CIRRUS_ENV%"
<<: *RUN_TESTS

macos_arm64_task:
macos_instance:
image: ghcr.io/cirruslabs/macos-monterey-xcode

env:
PATH: /opt/homebrew/opt/python@3.10/bin:$PATH
install_pre_requirements_script:
- brew install python@3.10
- ln -s python3 /opt/homebrew/opt/python@3.10/bin/python
<<: *RUN_TESTS
10 changes: 5 additions & 5 deletions CI.md
@@ -1,10 +1,10 @@
This is a summary of the Python versions and platforms covered by the different CI platforms:

| | 3.7 | 3.8 | 3.9 | 3.10 |
|----------|-----------------------|---------------------------|----------|----------------|
| Linux | AppVeyor¹ / Travis CI | Azure Pipelines / GitLab | CircleCI | GitHub Actions |
| macOS | AppVeyor¹ / Travis CI | Azure Pipelines | CircleCI | GitHub Actions |
| Windows | AppVeyor¹ / Travis CI | Azure Pipelines | | GitHub Actions |
| | 3.7 | 3.8 | 3.9 | 3.10 |
|----------|-----------------------|---------------------------|----------|---------------------------|
| Linux | AppVeyor¹ / Travis CI | Azure Pipelines / GitLab | CircleCI | GitHub Actions, Cirrus CI |
| macOS | AppVeyor¹ / Travis CI | Azure Pipelines | CircleCI | GitHub Actions, Cirrus CI |
| Windows | AppVeyor¹ / Travis CI | Azure Pipelines | | GitHub Actions, Cirrus CI |

> ¹ AppVeyor only runs the "basic" test to reduce load.

Expand Down
23 changes: 14 additions & 9 deletions README.md
Expand Up @@ -8,6 +8,7 @@ cibuildwheel
[![Appveyor status](https://ci.appveyor.com/api/projects/status/gt3vwl88yt0y3hur/branch/main?svg=true)](https://ci.appveyor.com/project/joerick/cibuildwheel/branch/main)
[![CircleCI Status](https://img.shields.io/circleci/build/gh/pypa/cibuildwheel/main?logo=circleci)](https://circleci.com/gh/pypa/cibuildwheel)
[![Azure Status](https://dev.azure.com/joerick0429/cibuildwheel/_apis/build/status/pypa.cibuildwheel?branchName=main)](https://dev.azure.com/joerick0429/cibuildwheel/_build/latest?definitionId=4&branchName=main)
[![Cirrus CI Status](https://img.shields.io/cirrus/github/pypa/cibuildwheel/main?logo=cirrusci)](https://cirrus-ci.com/github/pypa/cibuildwheel)


[Documentation](https://cibuildwheel.readthedocs.org)
Expand Down Expand Up @@ -39,7 +40,7 @@ What does it do?
<sup>³ Alpine 3.14 and very briefly 3.15's default python3 [was not able to load](https://github.com/pypa/cibuildwheel/issues/934) musllinux wheels. This has been fixed; please upgrade the python package if using Alpine from before the fix.</sup><br>

- Builds manylinux, musllinux, macOS 10.9+, and Windows wheels for CPython and PyPy
- Works on GitHub Actions, Azure Pipelines, Travis CI, AppVeyor, CircleCI, and GitLab CI
- Works on GitHub Actions, Azure Pipelines, Travis CI, AppVeyor, CircleCI, GitLab CI, and Cirrus CI
- Bundles shared library dependencies on Linux and macOS through [auditwheel](https://github.com/pypa/auditwheel) and [delocate](https://github.com/matthew-brett/delocate)
- Runs your library's tests against the wheel-installed version of your library

Expand All @@ -50,16 +51,19 @@ Usage

`cibuildwheel` runs inside a CI service. Supported platforms depend on which service you're using:

| | Linux | macOS | Windows | Linux ARM |
|-----------------|-------|-------|---------|--------------|
| GitHub Actions | ✅ | ✅ | ✅ | ✅¹ |
| Azure Pipelines | ✅ | ✅ | ✅ | |
| Travis CI | ✅ | | ✅ | ✅ |
| AppVeyor | ✅ | ✅ | ✅ | |
| CircleCI | ✅ | ✅ | | |
| Gitlab CI | ✅ | | | |
| | Linux | macOS | Windows | Linux ARM | macOS ARM |
|-----------------|-------|-------|---------|-----------|-----------|
| GitHub Actions | ✅ | ✅ | ✅ | ✅¹ | ✅² |
| Azure Pipelines | ✅ | ✅ | ✅ | | ✅² |
| Travis CI | ✅ | | ✅ | ✅ | ✅² |
| AppVeyor | ✅ | ✅ | ✅ | | ✅² |
| CircleCI | ✅ | ✅ | | | ✅² |
| Gitlab CI | ✅ | | | | ✅² |
| Cirrus CI | ✅ | ✅³ | ✅ | ✅ | ✅ |

<sup>¹ [Requires emulation](https://cibuildwheel.readthedocs.io/en/stable/faq/#emulation), distributed separately. Other services may also support Linux ARM through emulation or third-party build hosts, but these are not tested in our CI.</sup><br>
<sup>² [Uses cross-compilation](https://cibuildwheel.readthedocs.io/en/stable/faq/#universal2). It is not possible to test `arm64` and the `arm64` part of a `universal2` wheel on this CI platform.</sup><br>
<sup>³ [Uses cross-compilation](https://cibuildwheel.readthedocs.io/en/stable/faq/#universal2). Thanks to Rosetta 2 emulation, it is possible to test `x86_64` and both parts of a `universal2` wheel on this CI platform.</sup><br>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I said in my previous comment, I'm not sure cross-compilation is the right term here, could anyone confirm whether "emulation" makes more sense here?

Suggested change
<sup[Uses cross-compilation](https://cibuildwheel.readthedocs.io/en/stable/faq/#universal2). Thanks to Rosetta 2 emulation, it is possible to test `x86_64` and both parts of a `universal2` wheel on this CI platform.</sup><br>
<sup[Uses Rosetta 2 emulation](https://cibuildwheel.readthedocs.io/en/stable/faq/#universal2). Thanks to the emulation, it is possible to test `x86_64` and both parts of a `universal2` wheel on this CI platform.</sup><br>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, technically it's both! Cross-compilation is right, the wheel is built using cross-compilation, but we can still test the wheel using Rosetta 2 emulation.

I think the existing copy is fine as-is.


<!--intro-end-->

Expand Down Expand Up @@ -179,6 +183,7 @@ Here are some repos that use cibuildwheel.
[circleci icon]: docs/data/readme_icons/circleci.svg
[gitlab icon]: docs/data/readme_icons/gitlab.svg
[travisci icon]: docs/data/readme_icons/travisci.svg
[cirrusci icon]: docs/data/readme_icons/cirrusci.svg
[windows icon]: docs/data/readme_icons/windows.svg
[apple icon]: docs/data/readme_icons/apple.svg
[linux icon]: docs/data/readme_icons/linux.svg
Expand Down
1 change: 1 addition & 0 deletions bin/projects.py
Expand Up @@ -32,6 +32,7 @@
"circleci",
"gitlab",
"travisci",
"cirrusci",
"windows",
"apple",
"linux",
Expand Down
5 changes: 5 additions & 0 deletions bin/run_example_ci_configs.py
Expand Up @@ -66,6 +66,11 @@ def generate_basic_project(path):
dst_config_path=".gitlab-ci.yml",
badge_md="[![Gitlab](https://gitlab.com/pypa/cibuildwheel/badges/{branch}/pipeline.svg)](https://gitlab.com/pypa/cibuildwheel/-/commits/{branch})",
),
CIService(
name="cirrus-ci",
dst_config_path=".cirrus.yml",
badge_md="[![Cirrus CI](https://api.cirrus-ci.com/github/pypa/cibuildwheel.svg?branch={branch})](https://cirrus-ci.com/github/pypa/cibuildwheel/{branch})",
),
]


Expand Down
6 changes: 3 additions & 3 deletions cibuildwheel/__main__.py
Expand Up @@ -160,9 +160,9 @@ def build_in_directory(args: CommandLineArguments) -> None:
textwrap.dedent(
"""
cibuildwheel: Unable to detect platform. cibuildwheel should run on your CI server;
Travis CI, AppVeyor, Azure Pipelines, GitHub Actions, CircleCI, and Gitlab are
supported. You can run on your development machine or other CI providers using the
--platform argument. Check --help output for more information.
Travis CI, AppVeyor, Azure Pipelines, GitHub Actions, CircleCI, Gitlab, and Cirrus CI
are supported. You can run on your development machine or other CI providers
using the --platform argument. Check --help output for more information.
"""
),
file=sys.stderr,
Expand Down
1 change: 1 addition & 0 deletions cibuildwheel/linux.py
Expand Up @@ -349,6 +349,7 @@ def build(options: Options, tmp_path: Path) -> None: # pylint: disable=unused-a
If you're building on Travis CI, add `services: [docker]` to
your .travis.yml. If you're building on Circle CI in Linux,
add a `setup_remote_docker` step to your .circleci/config.yml.
If you're building on Cirrus CI, use `docker_builder` task.
"""
),
file=sys.stderr,
Expand Down
3 changes: 3 additions & 0 deletions cibuildwheel/util.py
Expand Up @@ -393,6 +393,7 @@ class CIProvider(Enum):
azure_pipelines = "azure_pipelines"
github_actions = "github_actions"
gitlab = "gitlab"
cirrus_ci = "cirrus_ci"
other = "other"


Expand All @@ -409,6 +410,8 @@ def detect_ci_provider() -> CIProvider | None:
return CIProvider.github_actions
elif "GITLAB_CI" in os.environ:
return CIProvider.gitlab
elif "CIRRUS_CI" in os.environ:
return CIProvider.cirrus_ci
elif strtobool(os.environ.get("CI", "false")):
return CIProvider.other
else:
Expand Down
2 changes: 1 addition & 1 deletion docs/data/projects.yml
Expand Up @@ -4,7 +4,7 @@
# stars: GitHub repo (optional, if different from package, such as for Twisted)
# pypi: The pypi name, if different from the GitHub package name
# os: Operating system list, [windows, apple, linux] (optional)
# ci: [appveyor, github, azurepipelines, circleci, gitlab, travisci] (optional)
# ci: [appveyor, github, azurepipelines, circleci, gitlab, travisci, cirrusci] (optional)
# notes: (text, optional)

- name: abess
Expand Down
1 change: 1 addition & 0 deletions docs/data/readme_icons/cirrusci.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions docs/faq.md
Expand Up @@ -81,6 +81,14 @@ Here's an example GitHub Actions workflow with a job that builds for Apple Silic
{% include "../examples/github-apple-silicon.yml" %}
```

Here's an example Cirrus CI workflow with a job that builds for macOS Intel through Rosetta 2 emulation and for Apple Silicon natively:

> .cirrus.yml

```yml
{% include "../examples/cirrus-ci-intel-mac.yml" %}
```

### Building non-native architectures using emulation {: #emulation}

cibuildwheel supports building non-native architectures on Linux, via
Expand Down
10 changes: 10 additions & 0 deletions docs/options.md
Expand Up @@ -73,6 +73,16 @@ cibuildwheel to run tests, add the following YAML to your CI config file:
CIBW_TEST_COMMAND: "pytest {project}/tests"
```

!!! tab "Cirrus CI"

> .cirrus.yml ([docs](https://cirrus-ci.org/guide/writing-tasks/#environment-variables))

```yaml
env:
CIBW_TEST_REQUIRES: pytest
CIBW_TEST_COMMAND: "pytest {project}/tests"
```

### Configuration file {: #configuration-file}

You can configure cibuildwheel with a config file, such as `pyproject.toml`.
Expand Down
14 changes: 14 additions & 0 deletions docs/setup.md
Expand Up @@ -312,6 +312,20 @@ Commit this file, and push to Gitlab. The pipeline should start automatically.

Gitlab will store the built wheels for you - you can access them from the Pipelines view. Check out the Gitlab [docs](https://docs.gitlab.com/ee/ci/yaml/) for more info on this config file.

## Cirrus CI [linux/mac/windows] {: #cirrus-ci}

To build Linux, Mac, and Windows wheels on Cirrus CI, create a `.cirrus.yml` file in your repo,

> .cirrus.yml

```yaml
{% include "../examples/cirrus-ci-minimal.yml" %}
```

Commit this file, enable building of your repo on Cirrus CI, and push.

Cirrus CI will store the built wheels for you - you can access them from the individual task view. Check out the Cirrus CI [docs](https://cirrus-ci.org/guide/writing-tasks/) for more info on this config file.

> ⚠️ Got an error? Check the [FAQ](faq.md).

# Next steps
Expand Down
21 changes: 21 additions & 0 deletions examples/cirrus-ci-intel-mac.yml
@@ -0,0 +1,21 @@
build_and_store_wheels: &BUILD_AND_STORE_WHEELS
install_cibuildwheel_script:
- python -m pip install cibuildwheel==2.9.0
run_cibuildwheel_script:
- cibuildwheel
wheels_artifacts:
path: "wheelhouse/*"


macos_task:
name: Build macOS x86_64 and arm64 wheels.
macos_instance:
image: ghcr.io/cirruslabs/macos-monterey-xcode

env:
PATH: /opt/homebrew/opt/python@3.10/bin:$PATH
CIBW_ARCHS_MACOS: x86_64 arm64
install_pre_requirements_script:
- brew install python@3.10
- ln -s python3 /opt/homebrew/opt/python@3.10/bin/python
<<: *BUILD_AND_STORE_WHEELS
46 changes: 46 additions & 0 deletions examples/cirrus-ci-minimal.yml
@@ -0,0 +1,46 @@
build_and_store_wheels: &BUILD_AND_STORE_WHEELS
install_cibuildwheel_script:
- python -m pip install cibuildwheel==2.9.0
run_cibuildwheel_script:
- cibuildwheel
wheels_artifacts:
path: "wheelhouse/*"


linux_x86_task:
name: Build Linux x86 wheels.
compute_engine_instance:
image_project: cirrus-images
image: family/docker-builder
platform: linux
cpu: 4
memory: 4G

install_pre_requirements_script:
- apt install -y python3-venv python-is-python3
<<: *BUILD_AND_STORE_WHEELS

windows_x86_task:
name: Build Windows x86 wheels.
windows_container:
image: cirrusci/windowsservercore:visualstudio2022
cpu: 4
memory: 4G

install_pre_requirements_script:
- choco install -y --no-progress python3 --version 3.10.6
- refreshenv
- echo PATH=%PATH% >> "%CIRRUS_ENV%"
<<: *BUILD_AND_STORE_WHEELS

macos_arm64_task:
name: Build macOS arm64 wheels.
macos_instance:
image: ghcr.io/cirruslabs/macos-monterey-xcode

env:
PATH: /opt/homebrew/opt/python@3.10/bin:$PATH
install_pre_requirements_script:
- brew install python@3.10
- ln -s python3 /opt/homebrew/opt/python@3.10/bin/python
<<: *BUILD_AND_STORE_WHEELS
5 changes: 4 additions & 1 deletion test/test_dependency_versions.py
@@ -1,5 +1,6 @@
from __future__ import annotations

import platform
import re
import textwrap

Expand Down Expand Up @@ -60,6 +61,8 @@ def test_pinned_versions(tmp_path, python_version, build_frontend_env):
build_environment = {}

if python_version == "3.6":
if utils.platform == "macos" and platform.machine() == "arm64":
pytest.skip("macOS arm64 does not support Python 3.6")
Jackenmen marked this conversation as resolved.
Show resolved Hide resolved
constraint_filename = "constraints-python36.txt"
build_pattern = "[cp]p36-*"
elif python_version == "3.7":
Expand Down Expand Up @@ -120,7 +123,7 @@ def test_dependency_constraints_file(tmp_path, build_frontend_env):
tool_versions = {
"pip": "20.0.2",
"setuptools": "53.0.0",
"wheel": "0.34.2",
"wheel": "0.36.2",
"virtualenv": "20.11.2",
}

Expand Down
6 changes: 3 additions & 3 deletions test/test_subdir_package.py
Expand Up @@ -51,13 +51,13 @@ def test(capfd, tmp_path):
add_env={
"CIBW_BEFORE_BUILD": "python {project}/bin/before_build.py",
"CIBW_TEST_COMMAND": "python {package}/test/run_tests.py",
# this shouldn't depend on the version of python, so build only CPython 3.6
"CIBW_BUILD": "cp36-*",
# this shouldn't depend on the version of python, so build only CPython 3.10
"CIBW_BUILD": "cp310-*",
},
)

# check that the expected wheels are produced
expected_wheels = [w for w in utils.expected_wheels("spam", "0.1.0") if "cp36" in w]
expected_wheels = [w for w in utils.expected_wheels("spam", "0.1.0") if "cp310" in w]
assert set(actual_wheels) == set(expected_wheels)

captured = capfd.readouterr()
Expand Down
5 changes: 5 additions & 0 deletions test/test_testing.py
Expand Up @@ -142,6 +142,11 @@ def test_failing_test(tmp_path):
# problems with this, so let's check that.
"CIBW_MANYLINUX_I686_IMAGE": "manylinux1",
"CIBW_MANYLINUX_X86_64_IMAGE": "manylinux1",
# CPython 3.8 when running on macOS arm64 is unusual. The build
# always runs in x86_64, so the arm64 tests are not run. See
# #1169 for reasons why. That means the build succeeds, which
# we don't want. So we skip that build.
"CIBW_SKIP": "cp38-macosx_arm64",
},
)

Expand Down
1 change: 1 addition & 0 deletions unit_test/main_tests/main_platform_test.py
Expand Up @@ -19,6 +19,7 @@ def test_unknown_platform_non_ci(monkeypatch, capsys):
monkeypatch.delenv("GITHUB_ACTIONS", raising=False)
monkeypatch.delenv("GITLAB_CI", raising=False)
monkeypatch.delenv("CIRCLECI", raising=False)
monkeypatch.delenv("CIRRUS_CI", raising=False)
monkeypatch.delenv("CIBW_PLATFORM", raising=False)

with pytest.raises(SystemExit) as exit:
Expand Down