name: cibuildwheel description: 'Installs and runs cibuildwheel on the current runner' inputs: package-dir: description: 'Input directory, defaults to "."' required: false default: . output-dir: description: 'Folder to place the outputs in, defaults to "wheelhouse"' required: false default: wheelhouse config-file: description: 'File containing the config, defaults to {package}/pyproject.toml' required: false default: '' only: description: 'Build a specific wheel only. No need for arch/platform if this is set' required: false default: '' extras: description: 'Comma-separated list of extras to install' required: false default: '' branding: icon: package color: yellow runs: using: composite steps: - uses: actions/setup-python@v6 id: python with: python-version: "3.11 - 3.13" update-environment: false - id: cibw run: | # Install cibuildwheel "${{ steps.python.outputs.python-path }}" -u << "EOF" import os import shutil import sys import venv from pathlib import Path from subprocess import run EXTRAS = set(e.strip() for e in "${{ inputs.extras }}".split(",") if e.strip()) class EnvBuilder(venv.EnvBuilder): def __init__(self): super().__init__() def setup_scripts(self, context): pass def post_setup(self, context): super().post_setup(context) self.bin_path = Path(context.env_exe).parent install_spec = r"${{ github.action_path }}" if EXTRAS: install_spec += f"[{','.join(sorted(EXTRAS))}]" run([sys.executable, "-m", "pip", "--python", context.env_exe, "install", install_spec], check=True) print("::group::Install cibuildwheel") venv_path = Path(r"${{ runner.temp }}") / "cibw" if venv_path.exists(): shutil.rmtree(venv_path) builder = EnvBuilder() builder.create(venv_path) cibw_bin = [p for p in builder.bin_path.glob("cibuildwheel*") if p.stem == "cibuildwheel"][0] with open(os.environ["GITHUB_OUTPUT"], "at") as f: f.write(f"cibw-bin={cibw_bin}\n") f.write(f"prepend-path={builder.bin_path if 'uv' in EXTRAS else ''}\n") print("::endgroup::") EOF shell: bash # Redirecting stderr to stdout to fix interleaving issue in Actions. - run: | prepend_path="${{ steps.cibw.outputs.prepend-path }}" if [ -n "$prepend_path" ]; then export PATH="$prepend_path:$PATH" fi "${{ steps.cibw.outputs.cibw-bin }}" \ "${{ inputs.package-dir }}" \ ${{ inputs.output-dir != '' && format('--output-dir "{0}"', inputs.output-dir) || ''}} \ ${{ inputs.config-file != '' && format('--config-file "{0}"', inputs.config-file) || ''}} \ ${{ inputs.only != '' && format('--only "{0}"', inputs.only) || ''}} \ 2>&1 shell: bash if: runner.os != 'Windows' # Windows needs powershell to interact nicely with Meson - run: | $PrependPath = "${{ steps.cibw.outputs.prepend-path }}" if ($PrependPath) { $env:PATH = "$PrependPath;$env:PATH" } & "${{ steps.cibw.outputs.cibw-bin }}" ` "${{ inputs.package-dir }}" ` ${{ inputs.output-dir != '' && format('--output-dir "{0}"', inputs.output-dir) || ''}} ` ${{ inputs.config-file != '' && format('--config-file "{0}"', inputs.config-file) || ''}} ` ${{ inputs.only != '' && format('--only "{0}"', inputs.only) || ''}} shell: pwsh if: runner.os == 'Windows'