Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -370,3 +370,74 @@ jobs:
CIBW_BUILD: cp314-*
CIBW_BUILD_FRONTEND: 'build[uv]'
CIBW_PLATFORM: ${{ matrix.test_select }}

test-native-linux:
needs: sample
name: Test native linux on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
container:
image: quay.io/pypa/manylinux_2_28:latest # zizmor: ignore[unpinned-images]
strategy:
fail-fast: false
matrix:
os: [ "ubuntu-latest", "ubuntu-24.04-arm" ]
steps:
- name: Prepare container
shell: bash
run: |
exec 2>&1
CPYTHON_DIR="${RUNNER_TOOL_CACHE}/Python"
if [ -d "${CPYTHON_DIR}" ]; then
echo "::group::Removing existing CPython tool cache"
set -x
rm -rf "${CPYTHON_DIR}"
set +x
echo "::endgroup::"
fi
for SOURCE_DIR in /opt/_internal/cpython-*; do
echo "::group::Adding '${SOURCE_DIR}' to the tool cache"
set -x
VERSION_MANYLINUX=${SOURCE_DIR:23}
case "${VERSION_MANYLINUX}" in
*-nogil) ARCH="${RUNNER_ARCH,,}-freethreaded";;
*) ARCH="${RUNNER_ARCH,,}";;
esac
VERSION=${VERSION_MANYLINUX%%-*}
case "${VERSION}" in
*a*) VERSION=${VERSION/a/-alpha.};;
*b*) VERSION=${VERSION/b/-beta.};;
*rc*) VERSION=${VERSION/rc/-rc.};;
esac
DEST_DIR="${CPYTHON_DIR}/${VERSION}"
mkdir -p "${DEST_DIR}"
ln -s ${SOURCE_DIR} "${DEST_DIR}/${ARCH}"
touch "${DEST_DIR}/${ARCH}.complete"
set +x
echo "::endgroup::"
done
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Download a sample project
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: sample_proj
path: sample_proj
- name: Run a sample build (GitHub Action)
uses: ./
with:
package-dir: sample_proj
output-dir: wheelhouse
env:
CIBW_CONTAINER_ENGINE: "none"
CIBW_BUILD_FRONTEND: 'build[uv]'
CIBW_SKIP: "*-musllinux*"

- name: Install dependencies
run: uv sync --no-dev --group test

- name: Test cibuildwheel
env:
CIBW_CONTAINER_ENGINE: "none"
CIBW_PLATFORM: "linux"
run: uv run --no-sync bin/run_tests.py --test-select=native
2 changes: 1 addition & 1 deletion bin/generate_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
type: string_table_array
container-engine:
oneOf:
- enum: [docker, podman]
- enum: [docker, podman, none]
- type: string
pattern: '^docker; ?(create_args|disable_host_mount):'
- type: string
Expand Down
1 change: 1 addition & 0 deletions bin/run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
if (
sys.platform.startswith("linux")
and os.environ.get("CIBW_PLATFORM", "linux") == "linux"
and os.environ.get("CIBW_CONTAINER_ENGINE", "docker") != "none"
and args.test_select in ["all", "native"]
):
# run the docker unit tests only on Linux
Expand Down
23 changes: 16 additions & 7 deletions cibuildwheel/oci_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"cibuildwheel.logger",
"cibuildwheel.util",
"cibuildwheel.util.cmd",
"cibuildwheel.util.file",
"cibuildwheel.util.helpers",
"contextlib",
"io",
Expand All @@ -32,13 +33,13 @@
import typing
import uuid
from enum import Enum
from pathlib import PurePosixPath
from typing import Literal, assert_never

from cibuildwheel.ci import CIProvider, detect_ci_provider
from cibuildwheel.errors import OCIEngineTooOldError
from cibuildwheel.logger import log
from cibuildwheel.util.cmd import call
from cibuildwheel.util.file import RemotePath, RemotePosixPath
from cibuildwheel.util.helpers import FlexibleVersion, parse_key_value_string, strtobool

TYPE_CHECKING = False
Expand All @@ -48,7 +49,7 @@
from types import TracebackType
from typing import IO, Self

from cibuildwheel.typing import PathOrStr
from cibuildwheel.typing import PathOrStr, PathT

ContainerEngineName = Literal["docker", "podman"]

Expand Down Expand Up @@ -94,13 +95,15 @@ class OCIContainerEngineConfig:
disable_host_mount: bool = False

@classmethod
def from_config_string(cls, config_string: str) -> Self:
def from_config_string(cls, config_string: str) -> Self | None:
config_dict = parse_key_value_string(
config_string,
["name"],
["create_args", "create-args", "disable_host_mount", "disable-host-mount"],
)
name = " ".join(config_dict["name"])
if name == "none":
return None
if name not in {"docker", "podman"}:
msg = f"unknown container engine {name}"
raise ValueError(msg)
Expand Down Expand Up @@ -208,6 +211,8 @@ class OCIContainer:
>>> from cibuildwheel.oci_container import * # NOQA
>>> from cibuildwheel.options import _get_pinned_container_images
>>> import pytest
>>> if os.environ.get("CIBW_CONTAINER_ENGINE", "docker") == "none":
... pytest.skip('needs a container engine')
>>> try:
... oci_platform = OCIPlatform.native()
... except OSError as ex:
Expand Down Expand Up @@ -439,7 +444,8 @@ def _remove_container(self) -> None:
log.warning(msg)
self.name = None

def copy_into(self, from_path: Path, to_path: PurePath) -> None:
def copy_into(self, from_path: Path, to_path: RemotePath) -> None:
assert isinstance(to_path, RemotePosixPath)
if from_path.is_dir():
self.call(["mkdir", "-p", to_path])
subprocess.run(
Expand Down Expand Up @@ -475,12 +481,15 @@ def copy_into(self, from_path: Path, to_path: PurePath) -> None:
exec_process.returncode, exec_process.args, None, None
)

def copy_out(self, from_path: PurePath, to_path: Path) -> None:
def copy_out(self, from_path: RemotePath, to_path: Path) -> None:
# note: we assume from_path is a dir
assert isinstance(from_path, RemotePosixPath)
to_path.mkdir(parents=True, exist_ok=True)
call(self.engine.name, "cp", f"{self.name}:{from_path}/.", to_path)

def glob(self, path: PurePosixPath, pattern: str) -> list[PurePosixPath]:
def glob(self, path: PathT, pattern: str) -> list[PathT]:
assert isinstance(path, RemotePosixPath)
result_type = type(path)
glob_pattern = path.joinpath(pattern)

path_strings = json.loads(
Expand All @@ -494,7 +503,7 @@ def glob(self, path: PurePosixPath, pattern: str) -> list[PurePosixPath]:
)
)

return [PurePosixPath(p) for p in path_strings]
return [result_type(p) for p in path_strings]

def call(
self,
Expand Down
2 changes: 1 addition & 1 deletion cibuildwheel/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ class BuildOptions:
build_verbosity: int
build_frontend: BuildFrontendConfig
config_settings: str
container_engine: OCIContainerEngineConfig
container_engine: OCIContainerEngineConfig | None
pyodide_version: str | None

@property
Expand Down
Loading
Loading