From 80d5810e2aa3a752242060fe20923c5524595f19 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 29 May 2026 00:28:20 -0400 Subject: [PATCH] feat: add CIBUILDWHEEL_BUILD_IDENTIFIER environment variable (#2872) * feat: add CIBUILDWHEEL_BUILD_IDENTIFIER environment variable Set `CIBUILDWHEEL_BUILD_IDENTIFIER` to the current build identifier (e.g. `cp311-manylinux_x86_64`) in the environment for all per-build steps: `before_build`, the build itself, `repair_command`, `before_test`, and `test_command`. This allows scripts and commands to inspect which build is currently running, which is useful for e.g. writing per-build output files: CIBW_TEST_COMMAND='pytest --junit-xml=results-$CIBUILDWHEEL_BUILD_IDENTIFIER.xml' The variable is set after the user's environment overrides are applied and is only available for per-build steps (not `before_all`, where no single identifier applies). All six platforms are covered: linux, macOS, Windows, pyodide, Android, and iOS. Closes #944, closes #2750 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Assisted-by: OpenCode:claude-sonnet-4.6 * fix: address review comment moving this for Android Assisted-by: OpenCode:glm-5.1 Signed-off-by: Henry Schreiner --------- Signed-off-by: Henry Schreiner Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- cibuildwheel/platforms/android.py | 2 ++ cibuildwheel/platforms/ios.py | 1 + cibuildwheel/platforms/linux.py | 1 + cibuildwheel/platforms/macos.py | 1 + cibuildwheel/platforms/pyodide.py | 1 + cibuildwheel/platforms/windows.py | 1 + docs/options.md | 3 +++ 7 files changed, 10 insertions(+) diff --git a/cibuildwheel/platforms/android.py b/cibuildwheel/platforms/android.py index 59c3869f..558e7001 100644 --- a/cibuildwheel/platforms/android.py +++ b/cibuildwheel/platforms/android.py @@ -140,6 +140,7 @@ def build(options: Options, tmp_path: Path) -> None: build_path.mkdir() python_dir = setup_target_python(config, build_path) build_env, android_env = setup_env(config, build_options, build_path, python_dir) + state = BuildState( config, build_options, build_path, python_dir, build_env, android_env ) @@ -228,6 +229,7 @@ def setup_env( # Apply custom environment variables, and check environment is still valid build_env = build_options.environment.as_dictionary(build_env) + build_env["CIBUILDWHEEL_BUILD_IDENTIFIER"] = config.identifier build_env["PIP_DISABLE_PIP_VERSION_CHECK"] = "1" for command in ["python"] if use_uv else ["python", "pip"]: command_path = call("which", command, env=build_env, capture_stdout=True).strip() diff --git a/cibuildwheel/platforms/ios.py b/cibuildwheel/platforms/ios.py index 223a833f..ac4caab3 100644 --- a/cibuildwheel/platforms/ios.py +++ b/cibuildwheel/platforms/ios.py @@ -482,6 +482,7 @@ def build(options: Options, tmp_path: Path) -> None: build_frontend=build_frontend.name, xbuild_tools=build_options.xbuild_tools, ) + env["CIBUILDWHEEL_BUILD_IDENTIFIER"] = config.identifier compatible_wheel = find_compatible_wheel(built_wheels, config.identifier) if compatible_wheel: diff --git a/cibuildwheel/platforms/linux.py b/cibuildwheel/platforms/linux.py index 9b4559ba..310355d3 100644 --- a/cibuildwheel/platforms/linux.py +++ b/cibuildwheel/platforms/linux.py @@ -237,6 +237,7 @@ def build_in_container( env["PATH"] = f"{python_bin}:{env['PATH']}" env = build_options.environment.as_dictionary(env, executor=container.environment_executor) + env["CIBUILDWHEEL_BUILD_IDENTIFIER"] = config.identifier # check config python is still on PATH which_python = container.call(["which", "python"], env=env, capture_output=True).strip() diff --git a/cibuildwheel/platforms/macos.py b/cibuildwheel/platforms/macos.py index 3208bcd1..4fe002fc 100644 --- a/cibuildwheel/platforms/macos.py +++ b/cibuildwheel/platforms/macos.py @@ -466,6 +466,7 @@ def build(options: Options, tmp_path: Path) -> None: build_options.environment, build_frontend.name, ) + env["CIBUILDWHEEL_BUILD_IDENTIFIER"] = config.identifier pip_version = None if use_uv else get_pip_version(env) compatible_wheel = find_compatible_wheel(built_wheels, config.identifier) diff --git a/cibuildwheel/platforms/pyodide.py b/cibuildwheel/platforms/pyodide.py index 53c66d9f..435dafa0 100644 --- a/cibuildwheel/platforms/pyodide.py +++ b/cibuildwheel/platforms/pyodide.py @@ -391,6 +391,7 @@ def build(options: Options, tmp_path: Path) -> None: environment=build_options.environment, user_pyodide_version=build_options.pyodide_version, ) + env["CIBUILDWHEEL_BUILD_IDENTIFIER"] = config.identifier pip_version = get_pip_version(env) # The Pyodide command line runner mounts all directories in the host # filesystem into the Pyodide file system, except for the custom diff --git a/cibuildwheel/platforms/windows.py b/cibuildwheel/platforms/windows.py index 8b30c710..e05a58d6 100644 --- a/cibuildwheel/platforms/windows.py +++ b/cibuildwheel/platforms/windows.py @@ -466,6 +466,7 @@ def build(options: Options, tmp_path: Path) -> None: build_options.environment, build_frontend.name, ) + env["CIBUILDWHEEL_BUILD_IDENTIFIER"] = config.identifier pip_version = None if use_uv else get_pip_version(env) compatible_wheel = find_compatible_wheel(built_wheels, config.identifier) diff --git a/docs/options.md b/docs/options.md index e6381009..6ace324b 100644 --- a/docs/options.md +++ b/docs/options.md @@ -669,6 +669,9 @@ Platform-specific environment variables are also available:
!!! note cibuildwheel always defines the environment variable `CIBUILDWHEEL=1`. This can be useful for [building wheels with optional extensions](faq.md#optional-extensions). +!!! note + For each per-build step (`before_build`, the build itself, `repair_command`, `before_test`, `test_command`), cibuildwheel also sets `CIBUILDWHEEL_BUILD_IDENTIFIER` to the current build identifier (e.g. `cp311-manylinux_x86_64`). This can be used in scripts to distinguish different builds. + !!! note To do its work, cibuildwheel sets the variables `VIRTUALENV_PIP`, `DIST_EXTRA_CONFIG`, `SETUPTOOLS_EXT_SUFFIX`, `PIP_DISABLE_PIP_VERSION_CHECK`, `PIP_ROOT_USER_ACTION`, and it extends the variables `PATH` and `PIP_CONSTRAINT`. Your assignments to these options might be replaced or extended.